Electronic – STM32L100 SysStick not divided by 8

armassemblerstm32

This is probably some stupid mistake, but I can't understand what's going on.

I have a Discovery board with STM32L100RC.

The HSI oscillator runs at 16 MHz and is selected as the system clock source, so everything should be running at 16 MHz. AHB prescaller is disabled.

According to the datasheet, the clock is divided by 8 before being sent to systick.

I have SysTick reload configured as 0xFFFFFF (which would give me 1 Hz if SysTick was at 16 MHz). And I am getting 1 Hz SysTick interrupt.

Problem is, that would mean the main clock is running at 128 MHz – certainly not.

What would explain the SysTick frequency I am getting?

Is the datasheet wrong?


For completenes, code used for setting up the clocks:

                ALIGN
RCC_CNF
                PUSH    {LR}
                ; FLASH timing config

                LDR     R0, =FLASH_ACR
                LDR     R1, [R0]
                ORR     R1, R1, #FLASH_ACR_ACC64
                STR     R1, [R0]

                LDR     R1, [R0]
                ORR     R1, R1, #(FLASH_ACR_PRFTEN :OR: FLASH_ACR_LATENCY)
                STR     R1, [R0]

                ; Enable HSI

                LDR     R0, =RCC_CR
                LDR     R1, [R0]
                ORR     R1, R1, #RCC_CR_HSION
                STR     R1, [R0]


                ; Wait for HSIRDY
                ALIGN
NO_HSI_RDY      LDR     R1, [R0]
                TST     R1, #RCC_CR_HSIRDY
                BEQ     NO_HSI_RDY

                ; Select HSI as clock source

                LDR     R0, =RCC_CFGR
                LDR     R1, [R0]
                BIC     R1, R1, #RCC_CFGR_SW
                ORR     R1, R1, #RCC_CFGR_SW_HSI
                STR     R1, [R0]

                POP     {PC}

And my SysTick config code:

                ; Configure SysTick
                LDR     R0, =SysTick_CSR
                LDR     R1, [R0]
                ; use internal clock & enable counting
                ORR     R1, R1, #(SysTick_CSR_ENABLE :OR: SysTick_CSR_CLKSOURCE)
                STR     R1, [R0]

                ; Configure the reload register
                LDR     R1, =0xFFFFFF
                LDR     R0, =SysTick_RELOAD
                STR     R1, [R0]

                ; Enable SysTick interrupt
                LDR     R0, =SysTick_CSR
                LDR     R1, [R0]
                ORR     R1, R1, #(SysTick_CSR_TICKINT)
                STR     R1, [R0]

In the interrupt handler, I'm just toggling a LED.

Best Answer

Okay, I figured no-one would answer me here, so I tried some experimentation.

Turns out, as of ARMv6, the meaning of the SysTick_CSR_CLKSOURCE is changed:

  • 0 = system clock / 8
  • 1 = system clock

I had it configured to 1, which explains everything.

If only the datasheets weren't so confusing...