cancel
Showing results for 
Search instead for 
Did you mean: 

Hardfault after start Timer in DMA mode

VLajo.1
Associate II

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

1 ACCEPTED SOLUTION

Accepted Solutions
VLajo.1
Associate II

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!

View solution in original post

10 REPLIES 10

Debug hardfault as usually - read out stack, find the instruction which caused the fault, its vicinity in disasm and related values in registers.

JW

berendi
Principal

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.

TDK
Guru

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.

If you feel a post has answered your question, please click "Accept as Solution".

Yeah, I should go bare registers-path

I don't think I understand "DMA transfer to the GPIO->BSRR port". Is it memory -> memory transfer?

Unfortunately it didn't give me much, I know where it happens and stack, still don't know why it happens. Thanks anyway!

So, where it happens and stack?

JW

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.

VLajo.1
Associate II

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!