Interesting bug in SPI. Send 14 bits instead of 8 + BSY flag. (STM32L010K8) [solved]
I used SPI. 8 bit. HCLK / PCLK1 / PCLK2 is 1 MHz from HSI. I've run the standard code many times:
SPI->CR1 = 0;
SPI->CR1 = (0x7 << 3) | (1u << 2);
SPI->CR2 = (1 << 2); // Without OVR.
SPI->CR1 |= 1 << 6; // Enable.It worked. Many launches after that, I started getting BSY flag after line 4. If I then execute this line:
SPI->DR = 0;I get this in a boolean analyzer:
I was doing RCC RESET SPI. I turned SPI on and off in RCC ENABLE. It did not help. If after that I send 0xFF, then I received 0b00000011 in the logic analyzer. If I further sent 0x00, I received 0b11111100. Etc. I got an offset of 6 bits. All submissions were further shifted by 6 bits.
I came up with a solution:
SPI->CR1 = 0;
SPI->CR1 = (0x7 << 3) | (1u << 2) ;
SPI->CR2 = (1 << 2) ;
// Dirty hack to enable.
*((volatile uint8_t*)&SPI->DR) = 0x00;
SPI->CR1 |= 1 << 6; // Enable.
for (volatile int i = 0; i < 10; i++) // For start transaction.
;
while (SPI->SR & (1 << 7))
;
volatile uint8_t buf = (uint8_t)SPI->DR;
buf = (uint8_t)SPI->DR;
buf = (uint8_t)SPI->SR;
buf = (uint8_t)SPI->DR;
(void)buf;This makes one transaction. 14 bit. But after that, all data is sent without offset.
However, there is a better solution. To get rid of the error completely, you need to disconnect the power from the microcontroller for 10 minutes. After that, the problem disappears. Initialization from document starts working immediately.
I think inside the SPI there is a bit counter. This counter may not be reset via RCC_RESET. Also EN set and reset.
Please check this in your VHDL / Verilog / SystemVerilog / other language source code.
It took me 3 hours to discover this.