cancel
Showing results for 
Search instead for 
Did you mean: 

LDR instruction after STR outputs old data when reading from timer peripheral

liampwll
Associate II

I have a bit of code as follows:

str   r3, [r0, #68]
ldr   r3, [r0, #68]

where [r0, #68] is TIM20.BDTR on a STM32G474. I would expect that the LDR would output the same data that was just stored, however it seems that out outputs the previous data. I also tried putting a DMB between the two instructions but the same result still occurred. Inserting 5 DMB instructions seems to cause a long enough delay that the correct data is returned.

This obviously has the potential to be problematic in a few scenarios, but I can't find any documentation from ST on this behaviour, so does anyone know if such documentation exists?

1 ACCEPTED SOLUTION

Accepted Solutions
STOne-32
ST Employee

Hi @liampwll ,

That is the best workaround :

 80128b4:       6c43            ldr     r3, [r0, #68]   @ 0x44
 80128b6:       6c43            ldr     r3, [r0, #68]   @ 0x44

Just doing a dummy Read back after the first store !  the second LDR will have the right store value.

Cheers,

STOne-32.

View solution in original post

4 REPLIES 4
liampwll
Associate II

Never mind, it turns out this is just another case of a key detail being buried in an obscure part of the reference manual:

Because MOE falling edge can be asynchronous, a resynchronization circuit has been inserted between the actual signal (acting on the outputs) and the synchronous control bit (accessed in the TIMx_BDTR register). It results in some delays between the asynchronous and the synchronous signals. In particular, if MOE is set to 1 whereas it was low, a delay must be inserted (dummy instruction) before reading it correctly. This is because the write acts on the asynchronous signal whereas the read reflects the synchronous signal.

- RM0440 Rev 8 28.3.18

However, this still seems to be wrong as a single DMB does not seem to be a long enough delay, so does anyone know what the actual required delay is?

STOne-32
ST Employee

Dear @liampwll ,

 

That register is on APB2 bus, interpretation of cycle is based on it’s own cycles . So if for example the AHBtoAPB2 ratio clock is 4 . One APB2 cycle means 4 AHB or CPU cycles etc. 
DMB is acting only at CPU Cortex / AHB cycle to wait till the Internal Cortex-M prefetch is flushed  and can not help to wait the APBs mapped registers thru the Bridges .  Do you know your AHB/APB2 configuration? And if inline with inserting dummy Reads after the STORE ? 
Let us know .

STOne-32

liampwll
Associate II

They're both /1 (HPRE = 0, PPRE = 0). The following works as expected rather than using a DMB, so something about DMB causes an issue even though it should cause at least a single cycle wait as far as I'm aware:

 

 80128ac:       6c43            ldr     r3, [r0, #68]   @ 0x44
 80128ae:       f443 4300       orr.w   r3, r3, #32768  @ 0x8000
 80128b2:       6443            str     r3, [r0, #68]   @ 0x44
 80128b4:       6c43            ldr     r3, [r0, #68]   @ 0x44
 80128b6:       6c43            ldr     r3, [r0, #68]   @ 0x44
 80128b8:       041b            lsls    r3, r3, #16

 

 

STOne-32
ST Employee

Hi @liampwll ,

That is the best workaround :

 80128b4:       6c43            ldr     r3, [r0, #68]   @ 0x44
 80128b6:       6c43            ldr     r3, [r0, #68]   @ 0x44

Just doing a dummy Read back after the first store !  the second LDR will have the right store value.

Cheers,

STOne-32.