cancel
Showing results for 
Search instead for 
Did you mean: 

Hard fault running timer in one pulse mode

Posted on July 06, 2015 at 20:17

I am working with STM32F427ZIT6 (Keil MDK-ARM 5.15) and want to implement a delay function based on Timer 6 in a single pulse mode. The delay function is:

void Delay_us(uint16_t amt_us)
{
TIM6->CNT = 0;
TIM6->ARR = amt_us;
/* start timer and monitor update flag */
TIM6->CR1 |= 0x0001;
while ((TIM6->SR & 0x0001) == 0) {;}
TIM6->SR &= 0xFFFE; /* clear update flag */
/* timer stops */
} /* end Delay_us() */

Timer 6 initialization code is exported from STM32CubeMX:

/* TIM6 init function */
void MX_TIM6_Init(void)
{
TIM_MasterConfigTypeDef sMasterConfig;
htim6.Instance = TIM6;
//HAL_TIM_Base_Init(&htim6);
htim6.Init.Prescaler = 83; //168;
htim6.Init.CounterMode = TIM_COUNTERMODE_UP;
htim6.Init.Period = 0;
HAL_TIM_Base_Init(&htim6);
HAL_TIM_OnePulse_Init(&htim6, TIM_OPMODE_SINGLE);
// sMasterConfig.MasterOutputTrigger = TIM_TRGO_ENABLE;
sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
HAL_TIMEx_MasterConfigSynchronization(&htim6, &sMasterConfig);
}

sMasterConfig.MasterOutputTrigger = TIM_TRGO_ENABLE; is commented out since I don't need a trigger output. I also tried to use the ''old way'' initialization I always used with M3:

void TIM6_Init(void)
{
__TIM6_CLK_ENABLE();
/* prescaler register is loaded with value for Fcnt = 1 MHz at 84 MHz */
TIM6->PSC = 83;
/* timer is used as upcounter (DIR=0) in one-pulse mode (OPM=1), */
/* only overflow generates an update event (URS=1), */
/* update event is generated, no interrupt */
TIM6->CR1 = 0x000C;
} 

The only thing I have in a main loop is toggling of an output pin with a delay:

while (1)
{
/* toggle PB12 (TEST1) at 10 ms */
Delay_us(10000);
cnt++;
GPIOB->ODR ^= 0x1000;
}

Variable cntshows how many times the loop was executed. When I debug the program, it goes into Hard Fault after executing a loop a few times (I saw cnt equal to 1, 2, 81 etc. - no certain value. If I replace the call to the Delay_us() by the simple delay loop (delay value is not important)

for (uint32_t i = 0; i < 1000000; i++) {;}

no Hard Fault exception is generated. What can cause such behavior? I used this method many times with multiple M3s and never had any problems. Thank you for advice, Gennady
7 REPLIES 7
Posted on July 06, 2015 at 20:26

What can cause such behavior?

An interrupt without a service routine? Touching the wrong area of memory? Does the Hard Fault seem to identify with an interrupt, or specific instructions in your code?

Tips, buy me a coffee, or three.. PayPal Venmo Up vote any posts that you find helpful, it shows what's working..
Posted on July 06, 2015 at 20:38

No interrupt is enabled for a timer. I am just polling the Update interrupt flag.

I haven't tried to further debug the Hard Fault, thought that may be there is a simple answer to my problem. Seems like I will need to do that :-(. 

Posted on July 06, 2015 at 21:30

Is this your own hardware, or a DISCOVERY/EVAL board?

Any other hardware initialized?

What is the clock source?

JW

Posted on July 06, 2015 at 21:36

It's our own board.

At this point only Timer 6 and GPIOs are initialized.

Clock source is HSE.

Gennady

Posted on July 07, 2015 at 03:16

I'm not sure what Cube is doing behind the scenes.

Is the HSE frequency compatible with the PLL settings, and the settings of the flash wait states, etc.

Tips, buy me a coffee, or three.. PayPal Venmo Up vote any posts that you find helpful, it shows what's working..
Posted on July 08, 2015 at 05:50

Seems like it has nothing to do with the Cube. I've made another project with the same functionality based on RTE - same behavior.

Nevertheless I've found that reason for a hard fault is IBUSERR. Stack pointer changes from regular 0x2000818 to 0x180007C8, what is invalid memory area.

But I still don't understand what is causing it and how it's related to operations on timer registers.

Another hint - when I load program to the flash, it sometimes works, sometimes doesn't. But it NEVER works after cycling power.  

Also I've noticed that PDR_ON pin is not connected to VCC, so power supply supervisor is not enabled. Don't know if it may have any connection with the problem.

 

Posted on July 09, 2015 at 21:13

Resolved. As I mentioned earlier, the PDR_ON pin was not connected, thus disabling power supply supervisor. Also, capacitors vcap1 and vcap2 were not in place, so even when PDR_ON was connected to VDD, the power supply supervisor didn't operate properly, I guess messing up initialization.

When this issues were corrected, the problem in discussion disappeared.

Thanks to everybody who tried to help me,

Gennady