2023-08-06 08:21 AM
[This is a reconstruction of a thread I've started on Apr 7, 2017, but got lost in the two forum software transitions since then.]
CRC unit is reset by writing CRC_CR.RESET to 1.
If immediately after this data are written into CRC_DR by the processor (i.e. the two writes are in consecutive str instructions), the written data are ignored and CRC_DR reads 0xFFFFFFFF.
Apparently, the guard time promised for DR writes does not apply to this sequence, and the CRC reset takes some time, so that DR writes within a certain number of cycles from CR writes are ignored.
ST, please specify exactly this time.
Thanks,
Jan Waclawek
-------
{waclawek.jan} {Jan 30, 2018 10:27 AM}
As this came up again, dug out some experimental results:
{
register uint32_t tmp1, tmp2;
__asm volatile(
"movs %[t1], #1" "\n\t"
"ldr %[t2], [%[p2], #48]" "\n\t"
"orr %[t2], #4096 " "\n\t"
"str %[t2], [%[p2], #48]" "\n\t"
#if(0)
"ldr %[t2], [%[p2], #48]" "\n\t"
#elif(1)
"dsb" "\n\t"
#else
"nop" "\n\t"
"nop" "\n\t"
#endif
"str %[t1], [%[p]]" "\n\t"
"movs %[t2], #0 " "\n\t"
"nop" "\n\t"
"nop" "\n\t"
"str %[t1], [%[p], #8]" "\n\t"
#if(1)
"dsb" "\n\t"
#else
"nop" "\n\t"
"nop" "\n\t"
#endif
"str %[t2], [%[p]]" "\n\t"
"nop" "\n\t"
"nop" "\n\t"
"str %[t1], [%[p], #8]" "\n\t"
"ldr %[t1], [%[p], #8]" "\n\t"
"str %[t2], [%[p]]" "\n\t"
"nop" "\n\t"
"nop" "\n\t"
:[t1] "=&r" (tmp1)
,[t2] "=&r" (tmp2)
:[p] "r" (CRC)
,[p2] "r" (RCC)
);
}
// conclusion:
// - one nop is not enough, two are needed
// - one dsb is enough instead of nops
// - the loadback is not enough, it required the same two nops after it
// - the same applies for the write-RCC_AHB1ENR--to--write-CRC_DR delay, one nop is not enough
Enjoy.
JW
----
{Tilen MAJERLE} [Employee] @ {waclawek.jan} on {Feb 8, 2018 2:08 PM}
Hello Jan,
You have to wait for reset bit to go back to 0 before you can start using CRC peripheral again.
{[pastedImage_1.png] -- I don't have this image saved, but I'm pretty sure it was this snapshot from the manual:
}
Please check last statement.
Best reegards,
Tilen
------
{waclawek.jan} @ {Tilen MAJERLE} on {Feb 8, 2018 2:13 PM}
Hi Tilen,
Thanks for the explanation. I'll sure try.
However, the last sentence says, that the reset bit is automatically cleared by hardware, not that I have to wait for it to get cleared.
If there is such a claim in the RM, can you please direct me to it.
Thanks,
Jan
----
{waclawek.jan} @ {Tilen MAJERLE} on {Feb 8, 2018 2:24 PM}
Also, none of the "libraries" appear to do this - they just write the reset bit in CRC->CR and then start to churn in data, without checking whether the reset bit had been cleared.
I looked into Cube/HAL - it's the usual mess I am not willing to delve into, but I could not find any *read* of CRC->CR. Same for Cube/LL. Both from CubeF4 v1.18. Same in 'F4 SPL v1.8
I even went to a very popular site with miscellaneous STM32 libraries and checked there... ;)
Jan
-----
{Tilen MAJERLE} [Employee] {Feb 8, 2018 2:47 PM}
Hello Jan,
none of the examples are writing data just after reset write and that's the reason why the issue was not seen. There are at least 2 cycles of "nothing" before actual write is performed. This is as well something you found in your example that waiting for 2 __NOP works ok.
I agree with you, anyway. RM is confused and I will check this.
FYI, thanks for advertisement I need somebody to maintain the web.
Best regards,
Tilen
------
{waclawek.jan} @ {Tilen MAJERLE} on {Feb 8, 2018 2:41 PM}
Tilen,
> none of the examples are writing data just after reset write.
Sorry, but this is - and sorry for the expression - ********.
The examples are all written in C, i.e. unless you have volatile access between the write to CR and DR - which is not in your example and there's no guarantee for that in none of the "libraries" - you have ABSOLUTELY NO control over the exact timing of the instructions.
That in one particular setting of one particular compiler it will insert some instructions, is COMPLETELY IRRELEVANT.
Guess how did I come to examine this at all? Do you think I write extensive assembly code?
JW
[EDIT] heh the forum censored the word... male cow manure, I meant.
2023-08-06 08:27 AM
The presented asm is messy, sorry for that, it's the crude result of several experiments. The gist is, though, that reset followed immediately by data write fails. This thread contains a description of real-world scenario with quite normal C program which compiled to such sequence - the point is, if the first datum is already loaded in some register for whatever reason, the compiler does not hesitate to store it to the CRC data register immediately after the reset.
JW
JW