This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

TM4C129XNCZAD: SPI communication with W25Q128JV FLASH memory not working.

Part Number: TM4C129XNCZAD

Hello, I am trying to write to and read from W25Q128JV FLASH memory by Winbond. I have a simple code right now that is supposed to enable write operation and read back the value of status register 1, which has write enable status on bit-1. I am getting all 0s on the read even though the expected value is 0x02 for write enabled status. Any help would be appreciated since I am not sure if it is my write or read that is faulty.

Here is the code I have:

//Disable the SSI module to change the settings for Memory communication.
SSIDisable(SSI3_BASE);

//make sure the polarity and phase configuration is correct for Memory communication
SSIConfigSetExpClk(SSI3_BASE, ui32SysClock, SSI_FRF_MOTO_MODE_3, SSI_MODE_MASTER, 2000000 , 8);

//Enable the SSI module after settings change.
SSIEnable(SSI3_BASE);

GPIOPinWrite(PQ_SPI_PORT, PQ1_SPI_SS_MEMORY_PIN, 0x0);

//Send the data over SPI.
SSIDataPut(SSI3_BASE, 0x06 );
while(SSIBusy(SSI3_BASE)){

}
//Turn SS pin high to finish write enable.
GPIOPinWrite(PQ_SPI_PORT, PQ1_SPI_SS_MEMORY_PIN, PQ1_SPI_SS_MEMORY_PIN);

GPIOPinWrite(PQ_SPI_PORT, PQ1_SPI_SS_MEMORY_PIN, 0x0);

//Send the data over SPI.
SSIDataPut(SSI3_BASE, 0x05 );

SSIDataGet(SSI3_BASE, (uint32_t *) &Laser.Miscellaneous.Monitor.TECSupplyVoltage);
while(SSIBusy(SSI3_BASE)){

}

GPIOPinWrite(PQ_SPI_PORT, PQ1_SPI_SS_MEMORY_PIN, PQ1_SPI_SS_MEMORY_PIN);

Here is the SPI initialization code I have:

uint32_t ui32SysClock = SysCtlClockFreqSet((SYSCTL_XTAL_25MHZ |
                                            SYSCTL_OSC_MAIN |
                                            SYSCTL_USE_PLL |
                                            SYSCTL_CFG_VCO_240), 50000000);

//enable the pins used for SPI communication.
SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOQ);

while(!SysCtlPeripheralReady(SYSCTL_PERIPH_GPIOQ)){

}
//
// Configure the SS pin and communication pins as GPIO output pins.
//
GPIOPinTypeGPIOOutput(PQ_SPI_PORT, (PQ3_SPI_RX_PIN              |
                                    PQ1_SPI_SS_MEMORY_PIN       |
                                    PQ4_SPI_SS_DIGIPOT_PIN      |
                                    PQ5_SPI_SS_DAC_PIN));

//drive the clear pin high.
GPIOPinWrite(PQ_SPI_PORT, PQ3_SPI_RX_PIN, PQ3_SPI_RX_PIN);

//
// Enable the SSI3 peripheral
//
SysCtlPeripheralEnable(SYSCTL_PERIPH_SSI3);

while(!SysCtlPeripheralReady(SYSCTL_PERIPH_SSI3)){

}

GPIOPinConfigure(GPIO_PQ0_SSI3CLK);
GPIOPinConfigure(GPIO_PQ2_SSI3XDAT0);

GPIOPinTypeSSI(PQ_SPI_PORT, (   PQ0_SPI_CLK_PIN         |
                                PQ2_SPI_TX_PIN          ));

//
// Configure the SSI.
//
SSIConfigSetExpClk(SSI3_BASE, ui32SysClock, SSI_FRF_MOTO_MODE_3, SSI_MODE_MASTER, 2000000 , 12);

//
//Enable the SSI module
//
SSIEnable(SSI3_BASE);

//Set the SS pins to high to disable communication.
GPIOPinWrite(PQ_SPI_PORT, PQ1_SPI_SS_MEMORY_PIN, PQ1_SPI_SS_MEMORY_PIN);
GPIOPinWrite(PQ_SPI_PORT, PQ4_SPI_SS_DIGIPOT_PIN, PQ4_SPI_SS_DIGIPOT_PIN);
GPIOPinWrite(PQ_SPI_PORT, PQ5_SPI_SS_DAC_PIN, PQ5_SPI_SS_DAC_PIN);

SSIIntEnable(SSI3_BASE, SSI_TXFF);

Here is the write enable and read status register 1 instructions from the datasheet:

As far as I understand this device should work with either mode 0  or mode 3 SPI communication and I have tried both.

  • Hi,

      I'm confused that you setup SSI character length to 8 and 12 in two different places. Which one do you want? I will suggest you use a logic analyzer or a scope to see what is being written and read on the SPI interface. This will greatly help your debugging. I also see that you first assert the CS pin low and after the write, you de-assert CS pin high. You then assert the CS pin low again before the read and then de-assert the CS high again. However, looking at Figure 8a you attach for the timing diagram, the CS must be active during both write and read. This might be your problem as the flash memory may think that you terminated the command when CS goes high. 

  • The change in the character length is happening because I have multiple devices I communicate with over SPI and for some 12 is easier than 8. Me toggling the CS pin high is because, as far as I understand, for write enable to register to the status register I need to toggle the pin high afterwards, before doing any other instructions.

  • Hi,

      That is not what I see from your timing diagram. The CS is active low during instruction phase and data phase. In any case, you should use a logic analyzer to make sure your timing on the SPI bus is matching the figure. 

  • I found the issue, I was defining the RX pin as output because one of the devices need it to be driven high to function properly and never setting it back to SSI, changing the configuration based on the device being communicated with fixed it. Also I needed to call another SSIDataPut after sending the read command to make sure the clock is asserted for reading in data.