what is pData in HAL_IM_IC_START_DMA?

106 views Asked by At

I can't understand the pData value meaning when using HAL_IM_IC_START_DMA function

I'm getting started on STM32F103C8T6. When I use Input Capture of timer 2 to measurement the frequency of timer 1 by determine the time between 2 rising edge method. I can not understand the number value of "pData" meaning. At first, I think it is the counter number value of timer at the moment the rising edge, but it not. The Autoreload maximum of timer 2 just 65535 (about 2^16), but the number display in live expression is maximum 2^32. So I can't understand how to calculate the frequency of it.
So anyone help me to understand that value, please.

This is the part of main code that I worked on

#include "main.h"

/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */

/* USER CODE END Includes */

/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */

/* USER CODE END PTD */

/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */

#define numval  100

/* USER CODE END PD */

/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */

/* USER CODE END PM */

/* Private variables ---------------------------------------------------------*/
TIM_HandleTypeDef htim1;
TIM_HandleTypeDef htim2;
DMA_HandleTypeDef hdma_tim2_ch1;
DMA_HandleTypeDef hdma_tim2_ch2_ch4;

/* USER CODE BEGIN PV */

/* USER CODE END PV */

/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_DMA_Init(void);
static void MX_TIM1_Init(void);
static void MX_TIM2_Init(void);
/* USER CODE BEGIN PFP */

/* USER CODE END PFP */

/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */

uint32_t riseData[numval];
uint32_t fallData[numval];

/* USER CODE END 0 */

/**
  * @brief  The application entry point.
  * @retval int
  */
int main(void)
{
  /* USER CODE BEGIN 1 */

  /* USER CODE END 1 */

  /* MCU Configuration--------------------------------------------------------*/

  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();

  /* USER CODE BEGIN Init */

  /* USER CODE END Init */

  /* Configure the system clock */
  SystemClock_Config();

  /* USER CODE BEGIN SysInit */

  /* USER CODE END SysInit */

  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_DMA_Init();
  MX_TIM1_Init();
  MX_TIM2_Init();
  /* USER CODE BEGIN 2 */
  HAL_GPIO_WritePin(GPIOC, GPIO_PIN_13, SET);
  TIM1->CCR1 = 500;
  HAL_TIM_PWM_Start(&htim1, TIM_CHANNEL_1);
  HAL_TIM_IC_Start_DMA(&htim2, TIM_CHANNEL_2, riseData, numval);
  HAL_TIM_IC_Start_DMA(&htim2, TIM_CHANNEL_2, fallData, numval);
  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
      HAL_Delay(500);
      HAL_TIM_IC_Start_DMA(&htim2, TIM_CHANNEL_2, riseData, numval);
      HAL_TIM_IC_Start_DMA(&htim2, TIM_CHANNEL_2, fallData, numval);

  }
  /* USER CODE END 3 */
}

And the configuration of timerĀ 2 (timer use for input capture). I have enabled DMA and interrupt function
enter image description here

And the value display enter image description here

1

There are 1 answers

3
Geisterfahrer On

Answering your question, the pData is a pointer to a buffer that specifies the destination address in memory where data will be transferred from the TIM2.

One possible issue in your code is the calling of HAL_TIM_IC_Start_DMA without any synchronization between them. I would say the values are bigger than 65535 due to an overflow, for the DMAs overwrite the data.

To solve this you can use the following function between the callings in the While-loop.

/**
  * @brief  Polling for transfer complete.
  * @param  hdma    pointer to a DMA_HandleTypeDef structure that contains
  *                  the configuration information for the specified DMA Channel.
  * @param  CompleteLevel Specifies the DMA level complete.  
  * @param  Timeout       Timeout duration.
  * @retval HAL status
  */
HAL_StatusTypeDef HAL_DMA_PollForTransfer(DMA_HandleTypeDef *hdma, uint32_t CompleteLevel, uint32_t Timeout)

As it is necessary to wait until the DMA transmission is completed, the value for CompleteLevel might be HAL_DMA_FULL_TRANSFER.

An example:

while (HAL_DMA_PollForTransfer(&hdma_tim2_ch2, HAL_DMA_FULL_TRANSFER, HAL_MAX_DELAY) != HAL_OK);

With that, you can ensure your DMA will complete its transmission before starting the next DMA call.