Hi, I'm semi experienced with STM32, have been doing a lot of things, hate the broken documentation, but have been living with that.
This is totally new to me:
I'm trying the simplest thing ever, basic SPI, set as master, chip select managed by myself. Transmit works, clocking works, RXNE interrupt comes as supposed, but data register always reads as zero!
Done a lot of debugging, and reduced the issue to the minimal, super simple code:
CPU: STM32F205VFT6
Clock config: SYSCLK at 120MHz, SPIs running at 30 MHz, but potential issues related to clock ruled out by running from 8MHz HSI divided down to 4MHz for SPI.
GPIO, clock enable init:
RCC->AHB1ENR |= 0b111111111 /* PORTA to PORTI */;
RCC->APB1ENR |= 1UL<<18 /*USART3*/ | 1UL<<14 /*SPI2*/;
RCC->APB2ENR |= 1UL<<12 /*SPI1*/;
GPIOA->AFR[0] |= 5UL<<20 | 5UL<<24 | 5UL<<28; // SPI1 alternate functions.
GPIOB->AFR[1] |= 5UL<<20 | 5UL<<24 | 5UL<<28; // SPI2 alternate functions.
// SPI1 and SPI2 MOSI, MISO, SCK as Alternate Functions:
// 15141312111009080706050403020100
// | | | | | | | | | | | | | | | |
GPIOA->MODER = 0b01000000000000001010100100000000;
GPIOB->MODER = 0b10101000000000000000000000000000;
SPI2 (works PERFECTLY):
SPI2->CR1 = 1UL<<9 /*Software slave management*/ | 1UL<<8 /*SSI must be high*/ | 0b010UL<<3 /*div 8*/ | 1UL<<2 /*master*/;
SPI2->CR1 |= 1UL<<6; // Enable SPI
while(1)
{
SPI2->DR = 123; // Send 123
while(!(SPI2->SR & 1)) ; // Wait for RXNE
buf = o_str_append(buf, " data read=");
buf = o_utoa32(SPI2->DR, buf);
buf = o_str_append(buf, "\r\n");
usart_print(buffer);
}
Short MISO&MOSI: prints "123". Short MISO to Vcc: prints 255. Short MISO to GND: prints 0. As expected!
Then, SPI1, which should be identical. Replace SPI2 registers with SPI1, exact same code. Always prints 0, regardless of the actual input pin state!
I have debugged the IO pin structure by configuring the MISO pin as general purpose input instead of alternate function, and copy its value (in a while(1) loop) to a random output pin, which I scope. The input pin works just fine, the output pin follows the input pin logic level.
There is not much left I can do, so I'm at loss here. Next I'm going to assume that the chip is broken in a very interesting way, and going to desolder it for replacement. But I'm experienced enough to know that sometimes it just happens that a clear "hardware issue" is, after all, some random configuration bit in a wrong way, something that some other experienced person can catch in a few seconds.