2024-06-14 03:24 AM - edited 2024-06-14 03:44 AM
After setting configuration registers in HAL_DMA_Start_IT, DMA fails to fire back interrupt, HAL_DMA_IRQHandler(). The TransferComplete call back routine is not called but only once after reset since HAL_DMA_IRQHandler() is called only once after initialization. Flags CC1DE and CC1IE are set after initialization and never change there after. I am trying to read a parallel ADC through GPIO using DMA with interrupt and timer input capture. I am using STM32L496ZG ucontroller and used CUBEMX to generate code.
Also, I am using Timer2 with input capture mode to request DMA transfer. And using MCO to generate 2 MHz to feed to PA0 for timer2 ch1.
I searched the forum and checked almost everything. I used latest CUBEMX 6.11.1 version.
Your help is greatly appreciated.
Thanks
Here is my initzn part;
HAL_Init();
/* Configure the system clock */
SystemClock_Config();
/* Initialize all configured peripherals */
MX_DMA_Init();
MX_GPIO_Init();
MX_TIM2_Init();
MX_USART2_UART_Init();
if(DWT_Delay_Init())
HAL_UART_Transmit(&huart2, (uint8_t *)"\r\nClkTick started", 17, HAL_MAX_DELAY);
else
HAL_UART_Transmit(&huart2, (uint8_t *)"\r\nClkTicks fail to start", 4, HAL_MAX_DELAY);
/* USER CODE BEGIN 2 */
if (HAL_DMA_Start_IT(htim2.hdma[TIM_DMA_ID_CC1], &GPIOE->IDR, (uint32_t)&aDST_Buffer, BUFFER_SIZE) != HAL_OK)
{
/* Transfer Error */
Error_Handler();
}
// Attach DMA callback functions
htim2.hdma[TIM_DMA_ID_CC1]->XferHalfCpltCallback = HalfTransferComplete;
htim2.hdma[TIM_DMA_ID_CC1]->XferCpltCallback = TransferComplete;
htim2.hdma[TIM_DMA_ID_CC1]->XferErrorCallback = TransferError;
// Enable timer to trigger DMA transfer - CC1DE bit
__HAL_TIM_ENABLE_DMA(&htim2, TIM_DMA_CC1);
// Enable timer input capture
HAL_TIM_IC_Start_IT(&htim2, TIM_CHANNEL_1);
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
}
DMA Req setting: >Mode: Normal.
And this is the data transfer callback routines:
static void HalfTransferComplete(DMA_HandleTypeDef *hdma_tim2_ch1) {
int position = 0;
LastITHalfComplete = 1;
/*Copy the first part of the received buffer */
for (int i = 0; i < HALF_BUFFER_SIZE; i++) {
aFull_Buffer[FullDataIndex] = aDST_Buffer[i+position];
FullDataIndex++;
//HAL_GPIO_TogglePin(GPIOE, GPIO_PIN_1);
}
}
static void TransferComplete(DMA_HandleTypeDef *hdma_tim2_ch1)
{
int position = HALF_BUFFER_SIZE;
LastITHalfComplete = 0;
/* Copy the second part of the received buffer */
for (int i = 0; i < HALF_BUFFER_SIZE; i++) {
aFull_Buffer[FullDataIndex] = aDST_Buffer[i+position];
FullDataIndex++;
HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_0);
}
transferComplete = 1;
}
static void TransferError(DMA_HandleTypeDef *hdma_tim2_ch1) {
HAL_GPIO_TogglePin(GPIOB,GPIO_PIN_14);
}
Solved! Go to Solution.
2024-06-26 02:44 AM - edited 2024-06-26 09:09 PM
2024-06-26 03:11 AM
> Can you elaborate this ?
> only TIM1 and TIM8 can trigger DMA2 streams.
> How to make TIM1 to trigger DMA2 transfer?
Sorry, I mis-read the STM32 model you are using.
In 'L496, both DMAs can access GPIOs, but Cube/HAL and CubeMX probably don't support timer-triggered transfers between arbitrary addresses in the memory space. You may need to use register-level programming for that, or some workaround.
I don't use Cube/CubeMX.
JW
2024-06-26 05:19 AM
@waclawek.jan wrote:You may need to use register-level programming for that, or some workaround.
Oh thats bad news.
2024-06-27 02:50 AM
Thanks @KnarfB.
Tried looking for ipsr number. But can't get it. Can u plz give me a clue how to look for it? Sorry for my weak skills.
2024-06-28 05:34 AM - edited 2024-06-28 05:36 AM
@KnarfB Tried your solution. That fixed it. Now the program doesn't loop around Default_Handler anymore.
Actually, I didn't wrote any void DMA2_Channel5_IRQHandler(void) routine. Now the program visits DMA2_Channel5_IRQHandler() function once.
Thanks KnarfB for nice solution.
Now back to original problem. The program executes this DMA2_Channel5_IRQHandler() only once and and never comes back to it. So no change in SRAM variable after first transfer.
I think the timer is not triggering it to happen...
2024-08-30 08:09 AM - edited 2024-08-30 08:12 AM
Seems like HAL libraries have still loop holes to be fixed. Jan, you are right.
I used LL library for Timer1 along with DMA and it worked. I can see the change in GPIO inputs during debug.
Thanks for supporting me.