Skip to main content
Kuikui
Associate III
February 20, 2011
Question

How to properly reset SPI

  • February 20, 2011
  • 17 replies
  • 3335 views
Posted on February 20, 2011 at 19:06

How to properly reset SPI

#spi2-usart3
This topic has been closed for replies.

17 replies

Tesla DeLorean
Guru
May 17, 2011
Posted on May 17, 2011 at 14:25

Well here are a couple of thoughts.

Look carefully at what you initialize in each partition.

Try calling/starting the second partition at earlier times from within the first. Do a binary search to figure out what differs.

Look at enabled interrupts, vector address (0x200 boundary)  and service routines, perhaps you are firing an unhandled interrupt.

Add in debug/diagnostic code to dump out peripheral and clock settings. Start with clock and reset registers.

Dump out large portions of the register maps in hex, compare them between the two partitions, use fc/comp to spot differences.

Tips, Buy me a coffee, or three.. PayPal Venmo (See Profile) Up vote any posts that you find helpful, it shows what's working..
Kuikui
KuikuiAuthor
Associate III
May 17, 2011
Posted on May 17, 2011 at 14:25

I tried to add SPI_DeInit(..); followed by SPI_Init(...) , but the result is still the same.

I'm stuck... I can't get why the SCK is clocking where as MOSI stays +3V...

And I don't understand why if I have only 1 partition, everything's fine ....

For debugging, I changed the MOSI pin to GPIO function, and I managed to make it go low and high levels. When configured as AF PP, nothing happens during clocks...

Does anyone has already seen this ?

I'm stuck :\

Kuikui
KuikuiAuthor
Associate III
May 17, 2011
Posted on May 17, 2011 at 14:25

Here is a few code.

 do

 {

  /* Checkup memory */

    FlashID = sFLASH_ReadID();

           

  table[0] = SPI2->CR1;

  table[1] = SPI2->CR2;

  table[2] = SPI2->SR;

  table[3] = RCC->APB1ENR;

  table[4] = RCC->APB2ENR;

  table[5] = RCC->AHBENR;

  table[6] = GPIOB->ODR;

  } while (FlashID != sFLASH_M25P64_ID );

This is how I proceed :

1° Power-up and flash the code

2° It works ( FlashID == M25P64_ID ) ... Reset with IAR => it works ... Reset, reset reset => it works, it works, it works. Reflash => it works.

3° Jump to partition 2

4° Reboot (with IAR)

5° Code does not work ( FlashID = 0x00, no SPI clock, table is exactly the same as when it was working )

6° Then I reboot (with IAR) again, and again, and again ... still doesn't work..

8° Okay, so let's reflash the code !

9° After a reflash ... doesn't work .... no clock, no SPI

10° Reflash, reflash, and reflash ... doesn't work ....

Finally ... power-off and power-up ... and now it works.

Believe me or not, the ONLY way to make it work is to make a power-reboot ... I've never seen such a situation ...

The ''log'' table is exactly the same when it's working or not.

What other register should I look at ??

What could that much mess-up the SPI ??

Why when I reset the µC with JTAG it still doesn't work ??

Kuikui
KuikuiAuthor
Associate III
May 17, 2011
Posted on May 17, 2011 at 14:25

Another test..

Only 1 partition now.

First boot => it works.

I reset the board with the RST pin => doesn't work anymore ...

Maybe having a sleep would help ...

Tesla DeLorean
Guru
May 17, 2011
Posted on May 17, 2011 at 14:25

Does the SPI Flash device have a reset pin? Are you leaving it in an invalid state?

Tips, Buy me a coffee, or three.. PayPal Venmo (See Profile) Up vote any posts that you find helpful, it shows what's working..
sima2
Associate III
May 17, 2011
Posted on May 17, 2011 at 14:25

Are you using any interrupts in the bootloader? You must turn off all enabled interrupts in the bootloader before jumping to the application.

Have you forgotten to relocate the interrupt vector table in the application?

For example: NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x8200);

Kuikui
KuikuiAuthor
Associate III
May 17, 2011
Posted on May 17, 2011 at 14:25

I've checked the ISR's, and now I'm on only one partition.

I think the issue is how I setup the SPI.

I'll post the code later.

Tesla DeLorean
Guru
May 17, 2011
Posted on May 17, 2011 at 14:25

Get some small code example that demonstrates this failure.

If it's not coming out the pins then you need to look at the GPIO settings, and confirm that the SPI2 is not remapped. Perhaps it's clashing with USART3 or TIM1. Check clocks on/off for those, or remap them elsewhere if appropriate. If the SPI clock is not present, consider if it is pending the TX register being loaded by DMA or a write.

The reset for SPI2 (host side) is RCC->APB1RST bit 14

Dump all the RCC, GPIOB, SPI2 and AFIO registers in hex, and paste them in forum.

Does it behave differently if NOT attached to a debugger?

Tips, Buy me a coffee, or three.. PayPal Venmo (See Profile) Up vote any posts that you find helpful, it shows what's working..
Kuikui
KuikuiAuthor
Associate III
May 17, 2011
Posted on May 17, 2011 at 14:25

I thought about it, but even if the SPI device would mess-up, the SPI host should still send clocks and data on MOSI.

Kuikui
KuikuiAuthor
Associate III
May 17, 2011
Posted on May 17, 2011 at 14:25

After hours of tests, I think I found the cause... But not sure yet.

It seems like SPI2 ( dunno about the others ) does not like to be powered-down at any ''random'' time.

Without debugger, after the first power-up, it works. And if I ''play'' with the reset button ( pin RST ), sometimes it's still working ... and sometimes it's not. And when it's not, it's not .... until you make another ''lucky'' reset where it will work back.

Same thing with entering low power mode with       PWR_EnterSTOPMode(PWR_Regulator_LowPower, PWR_STOPEntry_WFI);

When you enter stop mode, APB1 and APB2 are no more clocked, and if you're unlucky and did it at a time the SPI(2) doesn't want, then you won't be able to re-enable SPI after waking up from stop mode.

When I say ''it's not working'', I mean : or the SCK doesn't clock, either SCK clocks but MOSI freezed at level 1.

Before an SPI send :

RCC->CR = 0x03035883

RCC->CFGR = 0x0051BD0A

RCC->CIR = 0

RCC->APB2/1RSTR = 0

RCC->AHBENR = 0x00000015

RCC->APB2ENR = 0x0000421D

RCC->APB1ENR = 0x18C04000

RCC->BDCR = 0x00008103

RCC->CSR = 0x0C000000

GPIOB->CRH = 0xBBB3EE42

GPIOB->IDR = 0x0000B654

GPIOB->ODR = 0x00001050

GPIOB->LKCR = 0x00000000

SPI2->CR1 = 0x0000034F

SPI2->CR2 = 0

SPI2->SR = 2

SPI2->CRCPR = 7

AFIO->EVCR = 0

AFIO->MAPR = 0

AFIO->EXTICR1 = 0

AFIO->EXTICR2 = 0x00002000

AFIO->EXTICR3 = 0x00002020

AFIO->EXTICR4 = 0

Result is here : http://img225.imageshack.us/i/failsb.jpg/

Whereas executed code is :

    retry = 0;

    SPI_CS_LOW();

    cmd = sFLASH_CMD_RDSR;

    while (!(SPI2->SR & SPI_I2S_FLAG_TXE));

    SPI2->DR = cmd;

    while (!(SPI2->SR & SPI_I2S_FLAG_RXNE));

    cmd = SPI2->DR;

  

    do

    {

      data = sFLASH_DUMMY_BYTE;

      while (!(SPI2->SR & SPI_I2S_FLAG_TXE));

      SPI2->DR = data;

      while (!(SPI2->SR & SPI_I2S_FLAG_RXNE));

      data = SPI2->DR;

      retry++;

    } while ((data & sFLASH_WIP_FLAG) == SET && retry < 101);

    SPI_CS_HIGH();

ASM is below , sent values are 0x05 and 0xA5 ( not 0xFF )

    retry = 0;

 

    0x8003ebe: 0x2000         MOVS      r0, #0

 

    0x8003ec0: 0x0004         MOVS      r4, r0

 

    SPI_CS_LOW();

 

    0x8003ec2: 0x483b         LDR.N     r0, ??DataTable3_3 [0x8003fb0] ; GPIOB_BRR

 

    0x8003ec4: 0xf44f 0x5180  MOV.W     r1, #4096               ; 0x1000

 

    0x8003ec8: 0x6001         STR       r1, [r0]

 

    cmd = sFLASH_CMD_RDSR;

 

    0x8003eca: 0x2005         MOVS      r0, #5

 

    0x8003ecc: 0xf8ad 0x0006  STRH.W    r0, [sp, #0x6]

 

    while (!(SPI2->SR & SPI_I2S_FLAG_TXE));

 

??Flash_WaitForWriteEnd_2:

 

    0x8003ed0: 0x4838         LDR.N     r0, ??DataTable3_4 [0x8003fb4] ; SPI2_SR

 

    0x8003ed2: 0x8800         LDRH      r0, [r0]

 

    0x8003ed4: 0x0780         LSLS      r0, r0, #30

 

    0x8003ed6: 0xd5fb         BPL.N     ??Flash_WaitForWriteEnd_2 ; 0x8003ed0

 

    SPI2->DR = cmd;

 

    0x8003ed8: 0x4837         LDR.N     r0, ??DataTable3_5 [0x8003fb8] ; SPI2_DR

 

    0x8003eda: 0xf8bd 0x1006  LDRH.W    r1, [sp, #0x6]

 

    0x8003ede: 0x8001         STRH      r1, [r0]

 

    while (!(SPI2->SR & SPI_I2S_FLAG_RXNE));

 

??Flash_WaitForWriteEnd_3:

 

    0x8003ee0: 0x4834         LDR.N     r0, ??DataTable3_4 [0x8003fb4] ; SPI2_SR

 

    0x8003ee2: 0x8800         LDRH      r0, [r0]

 

    0x8003ee4: 0x07c0         LSLS      r0, r0, #31

 

    0x8003ee6: 0xd5fb         BPL.N     ??Flash_WaitForWriteEnd_3 ; 0x8003ee0

 

    cmd = SPI2->DR;

 

    0x8003ee8: 0x4833         LDR.N     r0, ??DataTable3_5 [0x8003fb8] ; SPI2_DR

 

    0x8003eea: 0x8800         LDRH      r0, [r0]

 

    0x8003eec: 0xf8ad 0x0006  STRH.W    r0, [sp, #0x6]

 

      data = sFLASH_DUMMY_BYTE;

 

??Flash_WaitForWriteEnd_4:

 

    0x8003ef0: 0x20a5         MOVS      r0, #165                ; 0xa5

 

    0x8003ef2: 0xf8ad 0x0004  STRH.W    r0, [sp, #0x4]

 

      while (!(SPI2->SR & SPI_I2S_FLAG_TXE));

 

??Flash_WaitForWriteEnd_5:

And, after some fails ... I got one working ... : http://img842.imageshack.us/i/works.jpg/