AT25SF641B: Flash Read always returning 0xFF

Hello, 

The AT25SF641B device I am having issues with is interfaced with a TMS320F28379D.

Please see C code below.  The code performs the flash operations as defined in the Operations[] array every 10ms (FlashTestStateMachine_Task() is called every 10ms.  This is verified by noticing u16FlashEraseCounter counts up to 2999 during a flash erase).

In essence, the program performs the following flash operations and then goes to the FLASH_TEST_COMPLETE_STATE.
1. enable flash writes (opcode = 0x06)

2. erase flash chip (opcode = 0x60)

3. Read the flash status (opcode = 0x05)

4. Write a byte to address 0x7FF000 (opcode = 0x02)

5 Disables flash writes (opcode = 0x04)

6 Reads the Status (opcode = 0x05)

7. Reads a byte from address 0x7FF00  (opcode = 0x03)

The Flash Status is always reading three zeros and the flash read is always reading 0xFF. 

What am I doing wrong?


Enable Flash Writes:

Flash Erase:

Flash Write (Zoomed out and then Zoomed in):

Flash Read (Zoomed out and then Zoomed in):



Read Status Bytes:

Read of Manufacturer and Device IDs

Read Status

Clock Frequency (1MHz)

#include "driverlib.h"
#include "device.h"
#include "board.h"
#include "FlashTestStateMachine.h"
#include "string.h"

Uint16 u16StartCommand = 0;

Uint16 u16ChipEraseStarted = 0;

Uint16 u16FlashEraseCounter = 0;

Uint16 u16FlashTestAddress24_16 = 0x7F;
Uint16 u16FlashTestAddress15_8 = 0xF0;
Uint16 u16FlashTestAddress7_0 = 00;

Uint16 FlashTestDataRead1 = 0;
Uint16 FlashTestDataRead2 = 0;
Uint16 FlashTestDataWrite = 0x68;

int16 s16TestPassed = 0;
Uint16 u16TestCompleted = 0;
Uint16 WriteStarted = 0;
Uint16 ReadStarted = 0;
Uint16 u16tempReadData1 = 0;
Uint16 u16tempReadData2 = 0;
Uint16 u16tempReadData3 = 0;
Uint16 u16tempReadData4 = 0;

Uint16 u16DummyByte;
Uint16 ManufacturerID = 0x00;
Uint16 DeviceID1= 0x00;
Uint16 DeviceID2= 0x00;

#define CHIP_SELECT_LOW     GPIO_writePin(McBSP_ChipSelectPinNumber,0)
#define CHIP_SELECT_HIGH    GPIO_writePin(McBSP_ChipSelectPinNumber,1)

extern Uint16 Tsk4msPeriodInMiliseconds;

#define FLASH_TEST_STATE_MACHINE_TASK_PERIOD   (((float)Tsk4msPeriodInMiliseconds)*0.001)
#define THIRTY_SECONDS  ((Uint16)(30.0/FLASH_TEST_STATE_MACHINE_TASK_PERIOD))

Uint16 flashWriteCounter = 0;

Uint16 Status1 = 0;
Uint16 Status2 = 0;
Uint16 Status3 = 0;

typedef enum
{
    FLASH_OPCODE_WRITE = 0x02,
    FLASH_OPCODE_READ = 0x03,
    FLASH_OPCODE_DISABLE_WRITES = 0x04,
    FLASH_OPCODE_READ_STATUS = 0x05,
    FLASH_OPCODE_ENABLE_WRITES = 0x06,
    FLASH_OPCODE_CHIP_ERASE = 0x60,
    FLASH_OPCODE_READ_MANUFACTURER_AND_DEVICE_IDS = 0x9F
} FLASH_OPCODES;

typedef enum
{
    FLASH_TEST_WAIT_TO_START_STATE,
    FLASH_TEST_ERASE_FLASH_CHIP_STATE,
    FLASH_TEST_READ_MANUFACTURER_ID,
    FLASH_TEST_WRITE_SINGLE_BYTE_STATE,
    FLASH_TEST_READ_SINGLE_BYTE_STATE,
    FLASH_TEST_COMPLETE_STATE,
    FLASH_TEST_READ_STATUS,
    FLASH_TEST_ENABLE_WRITES,
    FLASH_TEST_DISABLE_WRITES
} FLASH_TEST_STATEMACHINE_STATE;

FLASH_TEST_STATEMACHINE_STATE FlashTestState = FLASH_TEST_WAIT_TO_START_STATE;

FLASH_TEST_STATEMACHINE_STATE Operations[] =
{       FLASH_TEST_ENABLE_WRITES,
        FLASH_TEST_ERASE_FLASH_CHIP_STATE,
        FLASH_TEST_READ_STATUS,
        FLASH_TEST_WRITE_SINGLE_BYTE_STATE,
        FLASH_TEST_DISABLE_WRITES,
        FLASH_TEST_READ_STATUS,
        FLASH_TEST_READ_SINGLE_BYTE_STATE,
        FLASH_TEST_COMPLETE_STATE
};

#define MAX_DEBUG_INDEX  20
FLASH_TEST_STATEMACHINE_STATE FlashTestDebugData[MAX_DEBUG_INDEX];
Uint16 FlashTestDebugArrayIndex = 0;

Uint16 OperationSize = 0;

void FlashTestStateMachine_Init(void)
{
    OperationSize = sizeof(Operations)/sizeof(FLASH_TEST_STATEMACHINE_STATE);

    memset((void*)FlashTestDebugData,0,sizeof(FlashTestDebugData));
}


static BOOL FlashTestStateMachine(FLASH_TEST_STATEMACHINE_STATE FlashTestState)
{
    BOOL CompletedTask = FALSE;

    switch(FlashTestState)
    {
        case FLASH_TEST_READ_MANUFACTURER_ID:
            GPIO_writePin(McBSP_ChipSelectPinNumber,0);
            McBSP_transmit16BitDataBlocking(MCBSPB_BASE,FLASH_OPCODE_READ_MANUFACTURER_AND_DEVICE_IDS);
            McBSP_receive16BitDataBlocking(MCBSPB_BASE,&u16DummyByte);
            McBSP_transmit16BitDataBlocking(MCBSPB_BASE,0x00);
            McBSP_receive16BitDataBlocking(MCBSPB_BASE,&ManufacturerID);
            McBSP_transmit16BitDataBlocking(MCBSPB_BASE,0x00);
            McBSP_receive16BitDataBlocking(MCBSPB_BASE,&DeviceID1);
            McBSP_transmit16BitDataBlocking(MCBSPB_BASE,0x00);
            McBSP_receive16BitDataBlocking(MCBSPB_BASE,&DeviceID2);
            GPIO_writePin(McBSP_ChipSelectPinNumber,1);

            CompletedTask = TRUE;

            break;

        case FLASH_TEST_READ_STATUS:
            GPIO_writePin(McBSP_ChipSelectPinNumber,0);
            McBSP_transmit16BitDataBlocking(MCBSPB_BASE,FLASH_OPCODE_READ_STATUS);
            McBSP_receive16BitDataBlocking(MCBSPB_BASE,&u16DummyByte);
            McBSP_transmit16BitDataBlocking(MCBSPB_BASE,0x00);
            McBSP_receive16BitDataBlocking(MCBSPB_BASE,&Status1);
            McBSP_transmit16BitDataBlocking(MCBSPB_BASE,0x00);
            McBSP_receive16BitDataBlocking(MCBSPB_BASE,&Status2);
            McBSP_transmit16BitDataBlocking(MCBSPB_BASE,0x00);
            McBSP_receive16BitDataBlocking(MCBSPB_BASE,&Status3);
            GPIO_writePin(McBSP_ChipSelectPinNumber,1);

            CompletedTask = TRUE;

            break;

        case FLASH_TEST_ENABLE_WRITES:
            CHIP_SELECT_LOW;
            McBSP_transmit16BitDataBlocking(MCBSPB_BASE,FLASH_OPCODE_ENABLE_WRITES);
            McBSP_receive16BitDataBlocking(MCBSPB_BASE,&u16DummyByte);
            CHIP_SELECT_HIGH;

            CompletedTask = TRUE;

            break;

        case FLASH_TEST_ERASE_FLASH_CHIP_STATE:

            if (!u16ChipEraseStarted)
            {
                CHIP_SELECT_LOW;
                McBSP_transmit16BitDataBlocking(MCBSPB_BASE,FLASH_OPCODE_CHIP_ERASE);
                McBSP_receive16BitDataBlocking(MCBSPB_BASE,&u16DummyByte);
                CHIP_SELECT_HIGH;
                u16ChipEraseStarted = 1;
            }

            u16FlashEraseCounter++;

            //Wait 30 seconds
            if (u16FlashEraseCounter >= THIRTY_SECONDS)
            {

                CompletedTask = TRUE;
            }

            break;

        case FLASH_TEST_WRITE_SINGLE_BYTE_STATE:

            if (!WriteStarted)
            {
                WriteStarted = 1;
                CHIP_SELECT_LOW;
                McBSP_transmit16BitDataBlocking(MCBSPB_BASE,FLASH_OPCODE_WRITE);
                McBSP_receive16BitDataBlocking(MCBSPB_BASE,&u16DummyByte);
                McBSP_transmit16BitDataBlocking(MCBSPB_BASE,u16FlashTestAddress24_16);
                McBSP_receive16BitDataBlocking(MCBSPB_BASE,&u16DummyByte);
                McBSP_transmit16BitDataBlocking(MCBSPB_BASE,u16FlashTestAddress15_8);
                McBSP_receive16BitDataBlocking(MCBSPB_BASE,&u16DummyByte);
                McBSP_transmit16BitDataBlocking(MCBSPB_BASE,u16FlashTestAddress7_0);
                McBSP_receive16BitDataBlocking(MCBSPB_BASE,&u16DummyByte);
                McBSP_transmit16BitDataBlocking(MCBSPB_BASE,FlashTestDataWrite);
                McBSP_receive16BitDataBlocking(MCBSPB_BASE,&u16DummyByte);
                CHIP_SELECT_HIGH;

                CompletedTask = TRUE;
            }

            break;

        case FLASH_TEST_DISABLE_WRITES:
            CHIP_SELECT_LOW;
            McBSP_transmit16BitDataBlocking(MCBSPB_BASE,FLASH_OPCODE_DISABLE_WRITES);
            McBSP_receive16BitDataBlocking(MCBSPB_BASE,&u16DummyByte);
            CHIP_SELECT_HIGH;

            CompletedTask = TRUE;

            break;

        case FLASH_TEST_READ_SINGLE_BYTE_STATE:

            if (!ReadStarted)
            {
                ReadStarted = 1;
                CHIP_SELECT_LOW;
                McBSP_transmit16BitDataBlocking(MCBSPB_BASE,FLASH_OPCODE_READ);
                McBSP_receive16BitDataBlocking(MCBSPB_BASE,&u16DummyByte);
                McBSP_transmit16BitDataBlocking(MCBSPB_BASE,u16FlashTestAddress24_16);
                McBSP_receive16BitDataBlocking(MCBSPB_BASE,&u16DummyByte);
                McBSP_transmit16BitDataBlocking(MCBSPB_BASE,u16FlashTestAddress15_8);
                McBSP_receive16BitDataBlocking(MCBSPB_BASE,&u16DummyByte);
                McBSP_transmit16BitDataBlocking(MCBSPB_BASE,u16FlashTestAddress7_0);
                McBSP_receive16BitDataBlocking(MCBSPB_BASE,&u16DummyByte);
                McBSP_transmit16BitDataBlocking(MCBSPB_BASE,0x00);
                McBSP_receive16BitDataBlocking(MCBSPB_BASE,&FlashTestDataRead1);
                CHIP_SELECT_HIGH;
            }
            else
            {
                if (FlashTestDataRead1 == FlashTestDataWrite)
                {
                    s16TestPassed = 1;
                }
                else
                {
                    s16TestPassed = -1;
                }

                CompletedTask = TRUE;
            }

            break;

        case FLASH_TEST_COMPLETE_STATE:

            u16TestCompleted = 1;

            CompletedTask = TRUE;

            break;
    }

    return CompletedTask;
}

Uint16 OperationArrayIndex = 0;

void FlashTestStateMachine_Task(void)
{
    if (u16StartCommand)
    {
        if (OperationArrayIndex < OperationSize)
        {
            Uint16 CompletedTask;

            FlashTestState = Operations[OperationArrayIndex];
            CompletedTask = FlashTestStateMachine(FlashTestState);

            if (CompletedTask)
            {
                OperationArrayIndex++;
            }

            if (FlashTestDebugArrayIndex < MAX_DEBUG_INDEX)
            {
                FlashTestDebugData[FlashTestDebugArrayIndex] = FlashTestState;

                if (FlashTestState != FLASH_TEST_ERASE_FLASH_CHIP_STATE)
                {
                    FlashTestDebugArrayIndex++;
                }
            }
        }
        else
        {
            u16StartCommand = 0;
            OperationArrayIndex = 0;
        }
    }
}