Hardfault after start Timer in DMA mode
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2020-05-16 04:27 AM
hey!
I'm using timer 1 in OC mode with toggling the output. I also want to change the timer overflow value with the values predefined in the buffer.
I define buffer as:
uint16_t data[5] = { 50, 50, 100, 50, 50};
Then in main I call:
HAL_TIM_OC_Start_DMA(&htim1, TIM_CHANNEL_1, (uint32_t *) data, 5);
Hardfault strikes inside HAL_TIM_OC_Start_DMA:
htim->hdma[TIM_DMA_ID_CC1]->XferCpltCallback = TIM_DMADelayPulseCplt;
htim->hdma[TIM_DMA_ID_CC1]->XferHalfCpltCallback = TIM_DMADelayPulseHalfCplt;
My question is how avoid this.
Attached Cube initialization of TIM and DMA.
Alternatively, maybe there is different approach. My goal is to get signal without interrupts that looks like this with exact frequency:
0 1 0 1 0 1 1 0 1 0 1
Thanks
Solved! Go to Solution.
Accepted Solutions
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2020-05-16 12:24 PM
Ok, now it works.
I start timer and OC separately like this and got desired pulse train:
HAL_TIM_OC_Start(&htim1, TIM_CHANNEL_1);
HAL_TIM_Base_Start_DMA(&htim1, (uint32_t *) data, 10);
Thanks everybody!
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2020-05-16 06:35 AM
Debug hardfault as usually - read out stack, find the instruction which caused the fault, its vicinity in disasm and related values in registers.
JW
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2020-05-16 07:15 AM
HAL is difficult to figure out. You might get results sooner using the well documented register interface directly. The examples in AN4776 General-purpose timer cookbook are helpful.
Alternatively you can consider using a SPI port for the purpose, but the frequency choices are quite limited.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2020-05-16 07:59 AM
Set up a circular DMA transfer to the GPIO->BSRR port you want to use. Trigger it with a timer at the desired frequency. You can set up most of that in CubeMX.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2020-05-16 10:11 AM
Yeah, I should go bare registers-path
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2020-05-16 10:13 AM
I don't think I understand "DMA transfer to the GPIO->BSRR port". Is it memory -> memory transfer?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2020-05-16 10:15 AM
Unfortunately it didn't give me much, I know where it happens and stack, still don't know why it happens. Thanks anyway!
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2020-05-16 10:31 AM
So, where it happens and stack?
JW
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2020-05-16 10:36 AM
It would be still timed by a timer, but at even intervals, a word is copied from memory to a GPIO output register. Isn't worth​ the hassle in your case, it would be more useful when you wanted lots of outgoing pulses in parallel.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2020-05-16 12:24 PM
Ok, now it works.
I start timer and OC separately like this and got desired pulse train:
HAL_TIM_OC_Start(&htim1, TIM_CHANNEL_1);
HAL_TIM_Base_Start_DMA(&htim1, (uint32_t *) data, 10);
Thanks everybody!