AnsweredAssumed Answered

STM32F205 SPI data register always zero, as master

Question asked by Alhonen.Antti on Mar 24, 2017
Latest reply on Mar 26, 2017 by Alhonen.Antti

Hi, I'm semi experienced with STM32, have been doing a lot of things. This issue 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! The issue is only with SPI1; SPI2 (in different pins) works with exact same code!

 

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.

 

This is the bare minimum initialization:

 

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;

 

Perfectly working code on SPI2:

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 pins for loopback: prints "123". Short MISO to Vcc: prints 255. Short MISO to GND: prints 0. As expected!

 

Then, the same code for SPI1, which should be identical. Replace SPI2 registers with SPI1, exact same code. Always prints 0, regardless of the actual input pin state!

 

I've verified the physical MISO (PA6) pin voltage.

 

I have debugged the IO pin structure by configuring the MISO pin as general purpose input instead of alternate function, and simply copy its value (in a while(1) loop) to a unrelated 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. I hope it's the case.

 

Thanks for help!

Outcomes