0
\$\begingroup\$

I am working with SPI on STM32F429 to write data on MX25V1006F flash memory. I am not using cubeMX library.

My problem is that it works for a while and then suddenly it doesn't work. I have replaced MCU several times but I faced same problem again and again. When checking the internal protection diode on SPI pins (0.8V or short), the measurements are different from good MCU SPI pins (~0.6V). Could it be hardware problem or software problem. I am connecting the MOSI and MISO pins directly to flash MISO and MOSI pins respectively with no resistors in between. Could this be the reason for SPI pins dying out ?

As I understand SPI pins doesn't need pull up. By referring to internet sources, I connected MISO pins with 3.3K pull up but there is no change.

I reduced SPI data speed but I get same problem.

I checked the waveforms on SPI, and there is no waveform at all on one STM32F429 MCU and only SCK waveform with no MOSI change on another STM32F429 MCU. I suspect this is a hardware problem but I am unable to trace it. In my board, there is no other codes or functions conflicting in SPI1 (PortB 3,4,5)

Here is my SPI schematic: STM32F429 SPI part

Connection to Flash Here is my SPI code

void SPI_Flash_Port_Init(void) 
{ 
    SPI_InitTypeDef SPI_InitStruct; 
    GPIO_InitTypeDef GPIO_InitStructure;

    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE); 

    // spi1 cs setting
    GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_OUT;
    GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
    GPIO_InitStructure.GPIO_PuPd  = GPIO_PuPd_UP;

    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;       GPIO_Init(GPIOB,  &GPIO_InitStructure);     // Name: EX_IO1 -> CS
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;      GPIO_Init(GPIOB,  &GPIO_InitStructure);     // I2C2_SDA -> Flash WP, HOLD

    // spi1 miso, mosi, sck setting
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1,ENABLE);    // APB2CLK = 84Mhz, APB2Timer = 168Mhz

    GPIO_PinAFConfig(SPI1_SCL_Port,  GPIO_PinSource3, GPIO_AF_SPI1);
    GPIO_PinAFConfig(SPI1_MISO_Port, GPIO_PinSource4, GPIO_AF_SPI1);
    GPIO_PinAFConfig(SPI1_MOSI_Port, GPIO_PinSource5, GPIO_AF_SPI1);

    GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_AF;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
    GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
    GPIO_InitStructure.GPIO_PuPd  = GPIO_PuPd_UP;
  
    GPIO_InitStructure.GPIO_Pin = SPI1_SCL_Pin;     GPIO_Init(SPI1_SCL_Port,  &GPIO_InitStructure);
    GPIO_InitStructure.GPIO_Pin = SPI1_MISO_Pin;    GPIO_Init(SPI1_MISO_Port, &GPIO_InitStructure);
    GPIO_InitStructure.GPIO_Pin = SPI1_MOSI_Pin;    GPIO_Init(SPI1_MOSI_Port, &GPIO_InitStructure);


    SPI_I2S_DeInit(SPI1);
    SPI_InitStruct.SPI_Direction = SPI_Direction_2Lines_FullDuplex; 
    SPI_InitStruct.SPI_Mode = SPI_Mode_Master; 
    SPI_InitStruct.SPI_DataSize = SPI_DataSize_8b;     
    SPI_InitStruct.SPI_CPOL = SPI_CPOL_Low;     
    SPI_InitStruct.SPI_CPHA = SPI_CPHA_1Edge;
    SPI_InitStruct.SPI_NSS = SPI_NSS_Soft; 
    SPI_InitStruct.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_256;
    // SPI_BaudRatePrescaler_2    // clk = 84 /   2  =  42.0 Mhz
    // SPI_BaudRatePrescaler_4    // clk = 84 /   4  =  21.0 Mhz
    // SPI_BaudRatePrescaler_8    // clk = 84 /   8  =  10.5 Mhz
    // SPI_BaudRatePrescaler_16   // clk = 84 /  16  =   5.2 Mhz
    // SPI_BaudRatePrescaler_32   // clk = 84 /  32  =   2.6 Mhz
    // SPI_BaudRatePrescaler_64   // clk = 84 /  64  =   1.3 Mhz
    // SPI_BaudRatePrescaler_128  // clk = 84 / 128  =   0.6 Mhz
    // SPI_BaudRatePrescaler_256  // clk = 84 / 256  =   0.3 Mhz  
    SPI_InitStruct.SPI_FirstBit = SPI_FirstBit_MSB; 
    SPI_InitStruct.SPI_CRCPolynomial = 7; 

    SPI_Init(SPI1, &SPI_InitStruct);

    SPI_Cmd(SPI1, ENABLE); 

    EX_IO1(1);   // CS high
    GPIO_SetBits(IIC2_SDA_Port, IIC2_SDA_Pin);  // WP/Hold always high
}

void Flash_Spi_SendByte(unsigned char byte_value)
{
        while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE)  == RESET){};  SPI_I2S_SendData(SPI1,byte_value);  
        while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE) == RESET){};  SPI_I2S_ReceiveData(SPI1);  // Dummy rx
}

void Flash_Spi_ReadByte(unsigned int byte_count)
{
    unsigned int i;
    
    for(i = 0; i < byte_count; i++)
    {  
        Delay_us(5);
        SPI_Buffer[i] = 0;
        while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE)  == RESET){};  SPI_I2S_SendData(SPI1,0);   //dummy tx
        while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE) == RESET){};  SPI_Buffer[i] =     SPI_I2S_ReceiveData(SPI1);
    }
}

#define EX_IO1(x)    x ? GPIO_SetBits(GPIOB, GPIO_Pin_8) : GPIO_ResetBits(GPIOB, GPIO_Pin_8)

void Flash_Spi_CS(uint8_t value)
{
    Delay_us(5);
    EX_IO1(value);
    Delay_us(5);
}

uint8_t Flash_Spi_ID_READ(unsigned char byte_count) // read a byte 
{ 
    Flash_Spi_CS(0);   // CS = 0
    Flash_Spi_SendByte(FLASH_CMD_RDID);
    Delay_us(10);
    Flash_Spi_ReadByte(byte_count);  
    Flash_Spi_CS(1);   // CS = 1
    
    //Uart1_Printf("Chip ID READ\n");   
    return true;
}
\$\endgroup\$
5
  • 1
    \$\begingroup\$ Since you suspect that there's a hardware problem it would be a good idea to show your schematic too. \$\endgroup\$ – brhans Jan 11 at 13:12
  • \$\begingroup\$ I have added SPI part schematic \$\endgroup\$ – sujan_014 Jan 11 at 13:32
  • 3
    \$\begingroup\$ That's not helpful... Where is the SPI device you're talking to? What other connections are there to the SPI bus? What other connecters are made to the SPI device? Are there appropriate decoupling caps? etc, etc ... \$\endgroup\$ – brhans Jan 11 at 14:02
  • \$\begingroup\$ When you say "suddenly it doesn't work", what do you mean? Does it stop working until you reset the MCU or does it stop working forever? \$\endgroup\$ – jwh20 Jan 11 at 14:07
  • 3
    \$\begingroup\$ According to the schematic, you have connected MISO to MOSI and vice versa. That cannot possibly work. And both the master's MOSI and the slave's MISO would concurrently drive the same line causing electrical problems. \$\endgroup\$ – Codo Jan 11 at 14:11
1
\$\begingroup\$

TLDR: Connect MISO to MISO on both (STM32f429 and Flash) sides and MOSI to MOSI. This make communication with flash working and resolve your issue.

Based on your description and schematics, You probably burned pins because you have connected MISO (Master In Slave Out) to MOSI (Master Out Slave In) and vice versa. You connected Slave Output with Master Output so both device outputs at the same wire.

Imagine that your MCU outputs logical 1 (this is 3.3V so you can imagine it as connecting VCC to wire on MCU side) and Flash optputs logical 0 (this is 0V so you can imagine it as you connect GND to wire on Flash side) at the same time. Think a little bit. What happens when you directly connect VCC and GND using wire? Short circuit.

When you do that, current flowing by pins and wire will increase. It overflow pretty small current limit of GPIO pin of your MCU (for STM32F429 port current limit is 25mA in both directions of flowing, for MX25V1006F I did not found this limit in datasheet, but expect similar limit). Both MCU and Flash probably survive higher current for some limited amount of time (but it is not garantuated!) but if you running that setup longer, tight wires connecting pins with die inside chip or some transistors probably burns after some time.

Note that you mention only mallfuction of STM32, but you probably similarly burned pins of Flash Memory.

\$\endgroup\$
2
  • 1
    \$\begingroup\$ This is probably not the explanation, not only because such conflict rarely causes damage, but because it is inconsistent with the report of it having worked for a while before failure. \$\endgroup\$ – Chris Stratton Jan 12 at 15:07
  • \$\begingroup\$ It definitely shouldn't work at all with MISO connected to MOSI and vice versa, and I agree that it's unlikely that it would cause damage. But I do find it strange that OP repeated this error both in the text and schematic; either OP was incorrect about it ever working (i.e. fooled by their debugger), or OP repeated a schematic mistake in their text that is not present in the actual circuit implementation. I'm more inclined to believe the first (and probably that the STM32 and flash memory are, in reality, fine too). \$\endgroup\$ – Ocanath Jan 12 at 15:32

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.