2023-12-03 10:06 AM
Hello,
I am verifying timer functionality on an STM32F303K8 Nucleo development board. After generating an update event, the counter register does not update immediately - in downcounting mode, it takes several nops for the counter to read the same as the auto-reload value. A code sample is attached below. Without the fifth nop, the counter reads 0 rather than 999.
.syntax unified
.thumb
.global main
main:
/* APB1 enable TIM2 */
ldr r1, =0x40021000
ldr r0, [r1, #0x1C]
orr r0, r0, #1
str r0, [r1, #0x1C]
/* TIM2 set URS and DIR*/
ldr r1, =0x40000000
mov r0, #0x0014
str r0, [r1]
/* TIM2 frequency 1kHz */
mov r0, #7999
str r0, [r1, #0x28]
/* TIM2 reload 1s */
mov r0, #999
str r0, [r1, #0x2C]
/* TIM2 generate update event */
mov r0, #1
str r0, [r1, #0x14]
nop
nop
nop
nop
nop
/* TIM2 get count */
ldr r0, [r1, #0x24]
end:
bkpt
b end
I tried alternatively to use a DSB after the update generation with no effect. This might be a contrived example, but for an API, I'd like the timer counter to be readable any time after the timer is updated. Is there any good way to account for the internal delay? I did not check, but I assume it will also be longer if APB1 is prescaled.
Thank you in advance for any assistance.
Solved! Go to Solution.
2023-12-03 10:57 AM
Reading back the value will flush the write buffers.
mov r0, #1
str r0, [r1, #0x14] ; output to write buffer
LDR R0, [R1, #0x14] ; force write buffer to complete
In this scenario what is the CPU/SYSCLK, via those of the AHB, APB2 and APB1 bus clocks?
2023-12-03 10:57 AM
Reading back the value will flush the write buffers.
mov r0, #1
str r0, [r1, #0x14] ; output to write buffer
LDR R0, [R1, #0x14] ; force write buffer to complete
In this scenario what is the CPU/SYSCLK, via those of the AHB, APB2 and APB1 bus clocks?
2023-12-03 11:43 AM
Great, the read did in fact make the correct count observable immediately. Sysclock was HSI at 8MHz with no prescalers on any bus clocks, so everything at 8MHz.
I've had issues similar to this before where a read after write flushes the write buffers and makes effects observable, but I don't have enough experience with SoCs to know when exactly this is required instead of something like a memory synchronization barrier. Would a DSB in this case only cause the CPU to wait until the write (in the CPU write buffer) is handed off to the buses, i.e. not guarantee the memory write is actually complete before reading?
Do you have any suggestions on how to approach these scenarios? Should a read back be the 'go-to' choice for making sure a write is complete?