Author Topic: STM32: SPI master data register reads zero  (Read 5239 times)

0 Members and 1 Guest are viewing this topic.

Online SiwastajaTopic starter

  • Super Contributor
  • ***
  • Posts: 8166
  • Country: fi
STM32: SPI master data register reads zero
« on: March 24, 2017, 09:36:06 am »
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:
Code: [Select]
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):

Code: [Select]
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.
 

Offline Jeroen3

  • Super Contributor
  • ***
  • Posts: 4078
  • Country: nl
  • Embedded Engineer
    • jeroen3.nl
Re: STM32: SPI master data register reads zero
« Reply #1 on: March 24, 2017, 01:09:02 pm »
Code: [Select]
GPIOA->AFR[0] |= 5UL<<20 | 5UL<<24 | 5UL<<28; // SPI1 alternate functions.
GPIOB->AFR[1] |= 5UL<<20 | 5UL<<24 | 5UL<<28; // SPI2 alternate functions.
These lines are identical.
Yet, SPI1 on PA is on 5/6/7 and PB they are at 3/4/5. (clk/in/out)
The alternative on PB is shared with SWD.
 

Online SiwastajaTopic starter

  • Super Contributor
  • ***
  • Posts: 8166
  • Country: fi
Re: STM32: SPI master data register reads zero
« Reply #2 on: March 24, 2017, 01:44:45 pm »
Code: [Select]
GPIOA->AFR[0] .....
GPIOB->AFR[1] .....
These lines are identical.
Nope!

Quote
Yet, SPI1 on PA is on 5/6/7 and PB they are at 3/4/5. (clk/in/out)
The alternative on PB is shared with SWD.

I fail to see any issue here. SPI1 is on PA5,6,7, exactly like configured (GPIOA -> AFRL bits 31 downto 20).

Alternative for SPI1 in PB indeed is shared with SWD, but since I don't use the PB alternative for SPI1, it shouldn't matter. Or maybe it does, even when not connected!? This is one thing more to consider.
 

Offline Jeroen3

  • Super Contributor
  • ***
  • Posts: 4078
  • Country: nl
  • Embedded Engineer
    • jeroen3.nl
Re: STM32: SPI master data register reads zero
« Reply #3 on: March 24, 2017, 02:55:39 pm »
Oeps, I missed that. So you're setting SPI2 for PB13/14/15 then and SPI1 for PA5/6/7, ok.

Looks like your code matches the readable spi basic version I posted on this forum earlier.
Code: [Select]
SPI2->CR1 |= (4<<SPI_CR1_BR_Pos);   // Prescaler APB1 (36 Mhz) / 32
SPI2->CR1 |= SPI_CR1_SSM;           // Software chip select
SPI2->CR1 |= SPI_CR1_SSI;
SPI2->CR1 |= SPI_CR1_MSTR | SPI_CR1_SPE;

However, I do not set MISO to AF. But a 103 has a slightly different gpio system than a 205.

Did you try to force reset before inializing?
Code: [Select]
  __HAL_RCC_SPI2_FORCE_RESET();
  __NOP();
  __HAL_RCC_SPI2_RELEASE_RESET();
  __NOP();
Otherwise I can only suggest you try to replace the chip.
« Last Edit: March 24, 2017, 03:04:53 pm by Jeroen3 »
 

Online SiwastajaTopic starter

  • Super Contributor
  • ***
  • Posts: 8166
  • Country: fi
Re: STM32: SPI master data register reads zero
« Reply #4 on: March 24, 2017, 04:38:52 pm »
Thanks for ideas,

However, I do not set MISO to AF. But a 103 has a slightly different gpio system than a 205.

This is really weird. On all STM32's I've used, IO pin is set to AF mode all digital peripherals, also for inputs. I verified this from the F205 reference manual, but I tested this just in case, but nope.


Quote
Did you try to force reset before inializing?

Just tried. Not helping.

As a third thing, I tested moving the configuration of MSTR and SPE bits in the same read-modify-write, as you have in your code. No effect.

Either the chip is toasted in a very interesting way (not affecting the first IO structure, but inner logic), or there is some subtle difference between SPI1 and SPI2, or their routing to the IO using the AF mux. I don't suspect a clocking issue, because SPI1 emits the SCLK just right, and the slaves connected work just as expected - also, the RX complete interrupt comes as expected, only the data is null, so I am suspecting:
A) data signal somewhere between the IO cell, the AF mux, and then the SPI shift register, is broken.
B) Transfer operation from the shift register to the DR is broken
C) DR read operation to the CPU bus is broken
D) There is some very interesting issue that goes and resets the DR just before I read it. I even tested this out by running a while(1) loop quickly comparing DR if it is nonzero and setting a LED - the LED never came up, so this explanation is unlikely.

Thanks anyways, those were genuinely good ideas to try out. I have been trying random things for more than 10 hours of work time now. This is not the first time some trivial thing in STM32 is costing a huge amount of development time. Even in cases where it has been due to a bug caused by myself, the time spent has escalated due to broken documentation (too much trial and error everywhere). And, too many of the issues have been, after all, clear errors either on silicon or in documentation - not even covered in errata. I don't like that - I can accept myself making mistakes and banging my head on the wall, but repeated chip documentation / silicon mistakes are not ok.
« Last Edit: March 24, 2017, 04:40:53 pm by Siwastaja »
 

Offline Jeroen3

  • Super Contributor
  • ***
  • Posts: 4078
  • Country: nl
  • Embedded Engineer
    • jeroen3.nl
Re: STM32: SPI master data register reads zero
« Reply #5 on: March 24, 2017, 07:30:35 pm »
Spi1 has i2s capability. Does this work?
 

Online SiwastajaTopic starter

  • Super Contributor
  • ***
  • Posts: 8166
  • Country: fi
Re: STM32: SPI master data register reads zero
« Reply #6 on: March 26, 2017, 06:10:15 pm »
I had missed an obvious thing to try out:

So I changed SPI1 mapping to PB3,4,5, and yes, it does work there!

So this test verified that the issue is not within the SPI1 peripheral, but near the PA6 AF mux, since the PB4 -> AFmux -> SPI1 chain works, and since PA6 works as standard input, but PA6 -> AFmux -> SPI1 only gives zero.

So, I changed the chip. Problem solved. So it was broken, after all... Should have done it in the first place! OTOH, often when I think I have a case of internally broken chip, it is due to some code bug from myself, that's why I'm not eager to spend my time in changing the chip since it seldom helps. But this case was different!

I have seen broken IO cell structures, but haven't seen a broken internal signal just like this before! This is slightly disturbing, because I took at least basic ESD precautions, etc, soldering profile was OK, there hasn't been overvoltage kind of incidents during the development. So I really hope it's something I did, instead of a quality problem at ST...
 
The following users thanked this post: thm_w

Offline Jeroen3

  • Super Contributor
  • ***
  • Posts: 4078
  • Country: nl
  • Embedded Engineer
    • jeroen3.nl
Re: STM32: SPI master data register reads zero
« Reply #7 on: March 26, 2017, 07:54:58 pm »
Well, electronics can break. It's a just bad timing it breaks on your development platform. Which causes you to question yourself even more.

So I really hope it's something I did, instead of a quality problem at ST...
One broken chip on a dev board is not a quality problem.
Ten broken chips in production batch is a quality problem.
« Last Edit: March 26, 2017, 07:56:39 pm by Jeroen3 »
 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf