AnsweredAssumed Answered

Hard fault running timer in one pulse mode

Question asked by palitsky.gennady on Jul 6, 2015
Latest reply on Jul 9, 2015 by palitsky.gennady
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 cnt shows 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

Outcomes