cancel
Showing results for 
Search instead for 
Did you mean: 

STM32F205 SPI data register always zero, as master

Antti Alhonen
Associate
Posted on March 24, 2017 at 17:58

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 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!

#spi #stm32f205 #data-register

1 ACCEPTED SOLUTION

Accepted Solutions
Antti Alhonen
Associate
Posted on March 26, 2017 at 20:15

This is solved.

When I moved the SPI1 mapping to the PB3,4,5 alternative, it worked, so I found out that the issue must be between the SPI1 peripheral and the IO cell, since both are verified working separately. So I went on and just changed the chip, something I should have done in the first place. It's just that it's very rare that an assumed chip problem is actually a chip problem, especially since I followed basic ESD precautions and did not have overvoltage etc. issues during the development. After changing the chip, everything works as expected. This is slightly disturbing - I hope it's some unnoticed mishandling from my part, weirdly not affecting the IO cell, but inner logic; instead of a quality control issue at ST.

Thanks for the hints, anyway!

View solution in original post

2 REPLIES 2
Posted on March 25, 2017 at 00:46

Looks good at the first glance.

A few things to try (some of them you might have tried already):

  • cut code to ABSOLUTE MINIMUM. No printf, no usart. Have a debugger? Just observe memory (don't fall into the 'reading SPI registers by debugger changes the status bits' pitfall)
  • check clock/data comes out off the desired pins (SCK/MOSI). Use a higher-than-lowest OSPEEDR setting for SCK.
  • read out and double check the actual values from GPIO and SPI registers. All of them I mean. Setting inadvertently a different-than-expected pin as MISO might result in the observed behaviour too.
  • try deliberately a different set of SPI pins

Style advice: use the symbols from the default header as constants, instead of  mgic numbers.

JW

Antti Alhonen
Associate
Posted on March 26, 2017 at 20:15

This is solved.

When I moved the SPI1 mapping to the PB3,4,5 alternative, it worked, so I found out that the issue must be between the SPI1 peripheral and the IO cell, since both are verified working separately. So I went on and just changed the chip, something I should have done in the first place. It's just that it's very rare that an assumed chip problem is actually a chip problem, especially since I followed basic ESD precautions and did not have overvoltage etc. issues during the development. After changing the chip, everything works as expected. This is slightly disturbing - I hope it's some unnoticed mishandling from my part, weirdly not affecting the IO cell, but inner logic; instead of a quality control issue at ST.

Thanks for the hints, anyway!