cancel
Showing results for 
Search instead for 
Did you mean: 

Need help with the STM32F103 SysTick interrupt. (solved - self inflicted wound)

BKuhn
Associate III

See my last post for details on the non-solution.

\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\

Original post follows:

I've created a simple project that's intended to blink some LEDs every half second. As far as I can tell the SysTick interrupt never runs and the program goes off into the weeds.

I'm using Ozone and a J-link to debug the program with a F103EZ devboard as the target.

When I single step through the code I see the LEDs behave as expected. I can see the SysTick counter decrementing. I don't have the patience to single step until the counter gets to zero.

Everything behaves as expected when I single step. When I just let it run the LEDs never come on and, when I stop it, the PC and stack pointer are out in the weeds.

Here's the STM32cubeIDE project:

https://www.dropbox.com/s/jpml937l1ls98vd/temp.zip?dl=0

EDIT: By disabling the Systick interrupt and turning it into a polled system I am now functional.

I have no idea why.

I put a custom IRQ handler at EVERY location in the exception/IRQ table and it was never called so that means the SysTick interrupt wasn't firing. Why it went into the bushes is still a mystery to me.

I'm still hoping for some help in figuring out this mystery.

1 ACCEPTED SOLUTION

Accepted Solutions
BKuhn
Associate III

Never mind ...

It's working now. Apparently a self inflicted wound.

I built a new STM32cubeIDE project from scratch, generated the code, added in my LED code, built it and then used Ozone to download the target. Ran as expected. uwTick is incrementing and the LEDs are blinking.

I then used GitHUB Desktop to compare the old and new files and didn't find any differences.

I can't for the life of me understand what the old didn't work. The only thing I can guess is that I didn't use STM32cubeIDE to build the ELF file.

I really appreciate those who have looked at this.

View solution in original post

5 REPLIES 5
gbm
Lead II

Show the SysTick setup code and the interrupt handler. Don't expect folks to dowload and unpack your project to help you.

BKuhn
Associate III

I believe this is all the Systick related code.

///////////////////////////
void SysTick_Handler(void)
{
  HAL_IncTick();
}
 
///////////////////////////
__weak void HAL_IncTick(void)
{
  uwTick += uwTickFreq;
}
 
///////////////////////////
__weak HAL_StatusTypeDef HAL_InitTick(uint32_t TickPriority)
{
  /* Configure the SysTick to have interrupt in 1ms time basis*/
  if (HAL_SYSTICK_Config(SystemCoreClock / (1000U / uwTickFreq)) > 0U)
  {
    return HAL_ERROR;
  }
 
  /* Configure the SysTick IRQ priority */
  if (TickPriority < (1UL << __NVIC_PRIO_BITS))
  {
    HAL_NVIC_SetPriority(SysTick_IRQn, TickPriority, 0U);
    uwTickPrio = TickPriority;
  }
  else
  {
    return HAL_ERROR;
  }
 
  /* Return function status */
  return HAL_OK;
}
 
///////////////////////////
uint32_t HAL_SYSTICK_Config(uint32_t TicksNumb)
{
   return SysTick_Config(TicksNumb);
}
 
///////////////////////////
__STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks)
{
  if ((ticks - 1UL) > SysTick_LOAD_RELOAD_Msk)
  {
    return (1UL);                                                   /* Reload value impossible */
  }
 
  SysTick->LOAD  = (uint32_t)(ticks - 1UL);                         /* set reload register */
  NVIC_SetPriority (SysTick_IRQn, (1UL << __NVIC_PRIO_BITS) - 1UL); /* set Priority for Systick Interrupt */
  SysTick->VAL   = 0UL;                                             /* Load the SysTick Counter Value */
  SysTick->CTRL  = SysTick_CTRL_CLKSOURCE_Msk |
                   SysTick_CTRL_TICKINT_Msk   |
                   SysTick_CTRL_ENABLE_Msk;                         /* Enable SysTick IRQ and SysTick Timer */
  return (0UL);                                                     /* Function successful */
}
 
 
///////////////////////////
 
#define SysTick_CTRL_CLKSOURCE_Pos          2U                                            /*!< SysTick CTRL: CLKSOURCE Position */
#define SysTick_CTRL_CLKSOURCE_Msk         (1UL << SysTick_CTRL_CLKSOURCE_Pos)            /*!< SysTick CTRL: CLKSOURCE Mask */
HAL_TickFreqTypeDef uwTickFreq = HAL_TICK_FREQ_DEFAULT;  /* 1KHz */
 
typedef enum
{
  HAL_TICK_FREQ_10HZ         = 100U,
  HAL_TICK_FREQ_100HZ        = 10U,
  HAL_TICK_FREQ_1KHZ         = 1U,
  HAL_TICK_FREQ_DEFAULT      = HAL_TICK_FREQ_1KHZ
} HAL_TickFreqTypeDef;

gbm
Lead II

And where is your non-working blink code?

BKuhn
Associate III

Here's main.c:

//// file: main.c
#include "main.h"
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
 
  * @brief  The application entry point.
  * @retval int
  */
int main(void)
{
  HAL_Init();
  SystemClock_Config();
  MX_GPIO_Init();
  LED_G1_ON();
  LED_G2_ON();
  while (1)
  {
    
    if (HAL_GetTick()%250 == 0) {
      LED_G1_TG();
      LED_G2_TG();
    }
  }
}
 
void SystemClock_Config(void)
{
  RCC_OscInitTypeDef RCC_OscInitStruct = {0};
  RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
 
  /** Initializes the RCC Oscillators according to the specified parameters
  * in the RCC_OscInitTypeDef structure.
  */
  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
  RCC_OscInitStruct.HSIState = RCC_HSI_ON;
  RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;
  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE;
  if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
  {
    Error_Handler();
  }
 
  /** Initializes the CPU, AHB and APB buses clocks
  */
  RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
                              |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
  RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_HSI;
  RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
  RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
  RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
 
  if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_0) != HAL_OK)
  {
    Error_Handler();
  }
}
 
 
static void MX_GPIO_Init(void)
{
  GPIO_InitTypeDef GPIO_InitStruct = {0};
/* USER CODE BEGIN MX_GPIO_Init_1 */
/* USER CODE END MX_GPIO_Init_1 */
 
  /* GPIO Ports Clock Enable */
  __HAL_RCC_GPIOE_CLK_ENABLE();
  __HAL_RCC_GPIOB_CLK_ENABLE();
 
  /*Configure GPIO pin Output Level */
  HAL_GPIO_WritePin(LED_G2_GPIO_Port, LED_G2_Pin, GPIO_PIN_RESET);
 
  /*Configure GPIO pin Output Level */
  HAL_GPIO_WritePin(LED_G1_GPIO_Port, LED_G1_Pin, GPIO_PIN_RESET);
 
  /*Configure GPIO pin : LED_G2_Pin */
  GPIO_InitStruct.Pin = LED_G2_Pin;
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
  HAL_GPIO_Init(LED_G2_GPIO_Port, &GPIO_InitStruct);
 
  /*Configure GPIO pin : LED_G1_Pin */
  GPIO_InitStruct.Pin = LED_G1_Pin;
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
  HAL_GPIO_Init(LED_G1_GPIO_Port, &GPIO_InitStruct);
}
 
void Error_Handler(void)
{
  /* USER CODE BEGIN Error_Handler_Debug */
  /* User can add his own implementation to report the HAL error return state */
  __disable_irq();
  while (1)
  {
  }
}
 
#ifdef  USE_FULL_ASSERT
 
void assert_failed(uint8_t *file, uint32_t line)
{
 
}
#endif /* USE_FULL_ASSERT */

here's main.h

//// file: main.h
#ifdef __cplusplus
extern "C" {
#endif
#include "stm32f1xx_hal.h"
#define LED_G1_Port GPIOB
#define LED_G1_Pin  GPIO_PIN_5
#define LED_G2_Port GPIOE
#define LED_G2_Pin  GPIO_PIN_5
 
#define LED_G1_ON()  HAL_GPIO_WritePin(LED_G1_Port, LED_G1_Pin, GPIO_PIN_RESET)
#define LED_G1_OFF() HAL_GPIO_WritePin(LED_G1_Port, LED_G1_Pin, GPIO_PIN_SET)
#define LED_G1_TG()  HAL_GPIO_TogglePin(LED_G1_Port, LED_G1_Pin)
#define LED_G2_ON()  HAL_GPIO_WritePin(LED_G2_Port, LED_G2_Pin, GPIO_PIN_RESET)
#define LED_G2_OFF() HAL_GPIO_WritePin(LED_G2_Port, LED_G2_Pin, GPIO_PIN_SET)
#define LED_G2_TG()  HAL_GPIO_TogglePin(LED_G2_Port, LED_G2_Pin)
 
#define LED_ALL_ON() \
    do               \
    {                \
        LED_G1_ON(); \
        LED_G2_ON(); \
    } while(0)
#define LED_ALL_OFF() \
    do                \
    {                 \
        LED_G1_OFF(); \
        LED_G2_OFF(); \
    } while(0)
#define LED_ALL_TG() \
    do               \
    {                \
        LED_G1_TG(); \
        LED_G2_TG(); \
    } while(0)
 
void Error_Handler(void);
#ifdef __cplusplus
}
#endif
 

BKuhn
Associate III

Never mind ...

It's working now. Apparently a self inflicted wound.

I built a new STM32cubeIDE project from scratch, generated the code, added in my LED code, built it and then used Ozone to download the target. Ran as expected. uwTick is incrementing and the LEDs are blinking.

I then used GitHUB Desktop to compare the old and new files and didn't find any differences.

I can't for the life of me understand what the old didn't work. The only thing I can guess is that I didn't use STM32cubeIDE to build the ELF file.

I really appreciate those who have looked at this.