cancel
Showing results for 
Search instead for 
Did you mean: 

STM32F103CBT TIM4 PWM with DMA results in Hard Fault

TSchr.1
Associate II

Hi,

Beginner question:

Over the last few days I've tried to generate a PWM signal with a STM32F103CBT on Pin 46 (PB9) with a variable pulse width, but apart from generating a signal with a fixed Duty Cycle at the desired frequency (800kHz - I want to control a WS2812 Diode-Array), I haven't had much success.

The main problem I have is that as soon as I call "HAL_TIM_PWM_Start_DMA(&htim4,TIM_CHANNEL_4,(uint32_t*)variable_duty,10);" the MCU goes to the Hard Fault-Handler.

It appears that the setup for the half transfer complete-callback is the last line of code to be executed before the processor jumps to the hard fault handler.

I've configured the Timers and DMA entirely with the CUBEMX-Tool and only added two lines to the entire code:

uint16_t variable_duty[10] = {30,45,45,30,45,30,70,70,80,9};

and

 HAL_TIM_PWM_Start_DMA(&htim4,TIM_CHANNEL_4,(uint32_t*)variable_duty,10);

I'm pretty sure I missed something or forgot to set a variable, but so far I haven't been able to find any clues in the datasheet or the HAL-Documentation.

I hope someone here can help me with this.

Code: STM32CubeIDE-Project attached as a Zip-File

7 REPLIES 7

Which CubeMX version?

Can't this be the "DMA needs to be initialized first" bug? Doesn't the code attempt to use uninitislized pointers, pointing to undefined address space (i.e. outside RAM)?

Other than that, debug as usually - search this forum for cues how to debug faults.

JW

TSchr.1
Associate II

I managed to get the Nucleo-Example with the 103RB working on my MCU when using Timer 1 Channel 3.

It also works (kinda - Duty-Cycle is not being updated) on Timer 4 Channel 3, but it crashes to the Hard Fault-Handler once I try to use Timer 4 Channel 4.

Is Timer4 Channel 4 not capable of doing DMA-Controlled DutyCycle-Changes?

I haven't heard about the "DMA needs to be initialized first"-Bug.

Regarding the question if the code points to undefined address space: It seems to be that way.

According to the debug-window, "htim->hdma[TIM_DMA_ID_CC4]->XferHalfCpltCallback = TIM_DMADelayPulseHalfCplt;" in stm32f1xx_hal_tim.c is called, then it says "<signal handler called>() at 0xfffffff9", followed by "HardFault_Handler() at stm32f1xx_it.c:61 0x80003f0".

If the stack-dump method isn't working, track down the specific instructions that are faulting, and the processor registers at the time.

Most likely an issue with structures not being completely initialized, or corrupted. Check callback and IRQ Handlers

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

Okay, I'm not so sure anymore that it is my fault.

I just tried the example for the Nucleo-Board again with the standard-settings but selected Channel 4.

It also results in a crash of the MCU and defaulting to the Hard Fault-Handler.

Can anyone check this and confirm that "TIM_CHANNEL_4" on any Timer results in a crash on a STM32F103x?

I'm using CubeIDE Version 1.2.1 with CubeMX Version 5.5.0.201912201511

JChen.7
Associate

@TSchr.1​ 

I find the same probloms when I use 103C8 to drive WS2812!

My cube version is 5.6.0. and it worked when I use CH3@TIM4, but failed in CH4

When you set DMA in cubemx, you can only chose TIM4_UP, not TIM4_CH4 in DMA Reguest, so I think this maybe the fault point~

berendi
Principal

Check Table 78. Summary of DMA1 requests for each channel in the reference manual, try to find TIM4_CH4.

Do you notice anything? :)

I wonder, what's the mechanism behind chosing incorrect DMA channel resulting in hardfault, though.

But, being Cube/HAL, I'm not going to invest my time into investigation.

@Imen GH​ , maybe the Cube crew might want to have a look into this...

JW