cancel
Showing results for 
Search instead for 
Did you mean: 

Another DMA Not Working Question - Init In Correct Order

nobbyv77
Associate II

Started a project based on the STM32L010 which needs to receive six bytes from the UART. Works fine if I use it in interrupt mode. Does NOT work if I use it in DMA mode. Saw multiple posts about the DMA needing to be init'd before the peripheral in question. Made sure this is the case. Still nothing: IRQ does not fire, callback is not called. What am I missing?

/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_DMA_Init(void);
static void MX_USART2_UART_Init(void);
/* USER CODE BEGIN PFP */
 
/* USER CODE END PFP */
 
/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */
 
/* USER CODE END 0 */
 
/**
  * @brief  The application entry point.
  * @retval int
  */
int main(void)
{
  /* USER CODE BEGIN 1 */
uint8_t RX_Data[6] = {6};
  /* USER CODE END 1 */
 
  /* MCU Configuration--------------------------------------------------------*/
 
  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();
 
  /* Configure the system clock */
  SystemClock_Config();
 
  /* Initialize all configured peripherals */
  MX_DMA_Init();
  MX_GPIO_Init();
  MX_USART2_UART_Init();
 
  uint8_t Result = HAL_UART_Receive_DMA(&huart2, RX_Data, 6);
 
  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
	  //uint8_t Result = HAL_UART_Receive_DMA(&huart2, RX_Data, 6);
	  //uint8_t Result = HAL_UART_Receive_IT(&huart2, RX_Data, 6);
 
	  if( Result == HAL_OK )
	  {
		  HAL_Delay(20);
	  }
  }
}

void HAL_UART_RxCpltCallback (UART_HandleTypeDef *huart)
{
	HAL_Delay(20);
}

* @brief USART2 Initialization Function
  * @param None
  * @retval None
  */
static void MX_USART2_UART_Init(void)
{
 
  /* USER CODE BEGIN USART2_Init 0 */
 
  /* USER CODE END USART2_Init 0 */
 
  /* USER CODE BEGIN USART2_Init 1 */
 
  /* USER CODE END USART2_Init 1 */
  huart2.Instance = USART2;
  huart2.Init.BaudRate = 57600;
  huart2.Init.WordLength = UART_WORDLENGTH_8B;
  huart2.Init.StopBits = UART_STOPBITS_1;
  huart2.Init.Parity = UART_PARITY_NONE;
  huart2.Init.Mode = UART_MODE_TX_RX;
  huart2.Init.HwFlowCtl = UART_HWCONTROL_NONE;
  huart2.Init.OverSampling = UART_OVERSAMPLING_16;
  huart2.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE;
  huart2.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;
  if (HAL_UART_Init(&huart2) != HAL_OK)
  {
    Error_Handler();
  }
  /* USER CODE BEGIN USART2_Init 2 */
 
  /* USER CODE END USART2_Init 2 */
 
}
 
/**
  * Enable DMA controller clock
  */
static void MX_DMA_Init(void)
{
 
  /* DMA controller clock enable */
  __HAL_RCC_DMA1_CLK_ENABLE();
 
  /* DMA interrupt init */
  /* DMA1_Channel2_3_IRQn interrupt configuration */
  HAL_NVIC_SetPriority(DMA1_Channel2_3_IRQn, 0, 0);
  HAL_NVIC_EnableIRQ(DMA1_Channel2_3_IRQn);
 
}

6 REPLIES 6

Divide and conquer: check whether DMA itself works, e.g. by observing its registers or by observing content of buffer in memory.

If DMA does not work, check if UART Rx works, again by observing its registers (note that that's intrusive for the overall working), and if does not work, check relevant GPIO.

If DMA does work, then follow the generic "interrupt does not fire" checklist.

All in all, it's just the usual "read out and check content of registers of all related modules".

JW

nobbyv77
Associate II

UART works fine; can receive in interrupt mode (or polling mode). The DMA registers look correct per the datasheet (unless I'm missing something). CCR and CNDTR are set exactly as I'd expect:


_legacyfs_online_stmicro_images_0693W00000biVZSQA2.png 

From the "ISR does not fire" checklist:

1) Breakpoint is directly in ISR

2) Other ISRs (UART in interrupt mode) runs

3) No other interrupts are enabled (besides UART and sys tick)

4) Interrupt is enabled at source

Pity you didn't show the DMA_CSELR register too.

When data arrive, does CNDTR decrement? When 3 bytes arrive, is the respective HT flag in DMA_ISR set? Doesn't interrupt end up in some default interrupt handler (i.e. is the ISR's address inserted at correct position in vector table?)

JW

It dawned to me.

* Which* STM32L010 ?

They are NOT created equal!


_legacyfs_online_stmicro_images_0693W00000biVoDQAU.png
_legacyfs_online_stmicro_images_0693W00000biVoSQAU.pngJW

nobbyv77
Associate II

Good thought, but using STM32L010F4P6.

Try the Channel 5 plumbing

If it's not triggering trace the plumbing through the DMA's mux, back to the USART

Avoid inspecting USART registers in the debugger's peripheral view.

Instrument and print values as read by your code during normal execution, it'll be less invasive.

Double check vectors, in C++ .CPP case watch for name mangling, and assure that the right entry in the vector table points to the handler it should be using.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..