Hello,

I'm implementing the FSMC interface to Microchip SST39VF401C NOR Flash and ran into an issue with reading the manufacturer's ID.  My NOR Flash is mapped to FSMC_Bank1_NORSRAM2 and the low 16 address and data lines are multiplexed.  After the FSMC configuration, I send the 3 byte command and attempting to read the MFR ID, I always get the last byte that I sent.  For instance, I write:

    //  Issue the Software Product ID code to SST39VF401C
    *sysAddress(0x555) = 0x00AA;  // write data 0x00AA to device addr 0x555
    *sysAddress(0x2AA) = 0x0055;  // write data 0x0055 to device addr 0x2AA
    *sysAddress(0x555) = 0x0090;  // write data 0x0090 to device addr 0x555

    Delay_150_Nano_Seconds();

    // Read the product ID from SST39VF401C
    mfr_id  = *sysAddress(0x0000);   // get 0x90
    dev_id  = *sysAddress(0x0001);   // get 0x90

Can this symptom lead to a cause that someone already experienced?  I only have a 2 channel scope and was able to see that NADV, CS2, NOE, and NWE are behaving correctly according to Figure 445 and 446 on RM0090.  My FSMC configuration is listed below:

typedef unsigned char  BYTE;  // BYTE is 8-bit in length
typedef unsigned short  WORD;  // WORD is 16-bit in length, ARM
typedef unsigned int  Uint32;  // Uint32 is 32-bit in length, ARM

#define system_base   ((U32)0x64000000)
#define sysAddress(offset) ((volatile WORD *)(system_base + (((WORD)offset)<<1))) //For ARM CPU
#define MAX_TIMEOUT   0x07FFFFFF   // A ceiling constant used by Check_Toggle_

WORD mfr_id;
WORD dev_id;

void ExtFlash_Init(void)
{
 FSMC_NORSRAMInitTypeDef  FSMC_NORSRAMInitStructure;
 FSMC_NORSRAMTimingInitTypeDef  p;
 GPIO_InitTypeDef GPIO_InitStructure;
 
 RCC_AHB3PeriphClockCmd(RCC_AHB3Periph_FSMC, ENABLE);

 RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB | RCC_AHB1Periph_GPIOD | RCC_AHB1Periph_GPIOE | RCC_AHB1Periph_GPIOG, ENABLE);

 // address lines
 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_8 | GPIO_Pin_9 | GPIO_Pin_10 |
       GPIO_Pin_11 | GPIO_Pin_12 | GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15;
 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
 GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
 GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
 GPIO_PinAFConfig(GPIOD, GPIO_PinSource0, GPIO_AF_FSMC);
 GPIO_PinAFConfig(GPIOD, GPIO_PinSource1, GPIO_AF_FSMC);
 GPIO_PinAFConfig(GPIOD, GPIO_PinSource8, GPIO_AF_FSMC);
 GPIO_PinAFConfig(GPIOD, GPIO_PinSource9, GPIO_AF_FSMC);
 GPIO_PinAFConfig(GPIOD, GPIO_PinSource10, GPIO_AF_FSMC);
 GPIO_PinAFConfig(GPIOD, GPIO_PinSource11, GPIO_AF_FSMC);
 GPIO_PinAFConfig(GPIOD, GPIO_PinSource12, GPIO_AF_FSMC);
 GPIO_PinAFConfig(GPIOD, GPIO_PinSource13, GPIO_AF_FSMC);
 GPIO_PinAFConfig(GPIOD, GPIO_PinSource14, GPIO_AF_FSMC);
 GPIO_PinAFConfig(GPIOD, GPIO_PinSource15, GPIO_AF_FSMC);
 GPIO_Init(GPIOD, &GPIO_InitStructure);

 // address lines (continue)
 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3 | GPIO_Pin_7 | GPIO_Pin_8 | GPIO_Pin_9 | GPIO_Pin_10 |
       GPIO_Pin_11 | GPIO_Pin_12 | GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15;
 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
 GPIO_PinAFConfig(GPIOE, GPIO_PinSource3, GPIO_AF_FSMC);
 GPIO_PinAFConfig(GPIOE, GPIO_PinSource7, GPIO_AF_FSMC);
 GPIO_PinAFConfig(GPIOE, GPIO_PinSource8, GPIO_AF_FSMC);
 GPIO_PinAFConfig(GPIOE, GPIO_PinSource9, GPIO_AF_FSMC);
 GPIO_PinAFConfig(GPIOE, GPIO_PinSource10, GPIO_AF_FSMC);
 GPIO_PinAFConfig(GPIOE, GPIO_PinSource11, GPIO_AF_FSMC);
 GPIO_PinAFConfig(GPIOE, GPIO_PinSource12, GPIO_AF_FSMC);
 GPIO_PinAFConfig(GPIOE, GPIO_PinSource13, GPIO_AF_FSMC);
 GPIO_PinAFConfig(GPIOE, GPIO_PinSource14, GPIO_AF_FSMC);
 GPIO_PinAFConfig(GPIOE, GPIO_PinSource15, GPIO_AF_FSMC);
 GPIO_Init(GPIOE, &GPIO_InitStructure);

 /* External memory OE (#4 for reading from flash) and WE (#5 for writing to flash) */
 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4 | GPIO_Pin_5;
 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
 GPIO_PinAFConfig(GPIOD, GPIO_PinSource4, GPIO_AF_FSMC);
 GPIO_PinAFConfig(GPIOD, GPIO_PinSource5, GPIO_AF_FSMC);
 GPIO_Init(GPIOD, &GPIO_InitStructure);

 /* External memory CS2 (for selecting the flash part to interact) */
 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
 GPIO_PinAFConfig(GPIOG, GPIO_PinSource9, GPIO_AF_FSMC);
 GPIO_Init(GPIOG, &GPIO_InitStructure);

 // NADV pin
 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7;
 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
 GPIO_PinAFConfig(GPIOB, GPIO_PinSource7, GPIO_AF_FSMC);
 GPIO_Init(GPIOB, &GPIO_InitStructure);

 /* External memory WAIT (to get status from the flash part) */
 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;
 GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
 GPIO_Init(GPIOD, &GPIO_InitStructure);

 /*-- FSMC Configuration ----------------------------------------------------*/
 p.FSMC_AddressSetupTime = 0x0f;   // 0 to 15 (table 215 p1529) <= 2 or NADV won't pulse
 p.FSMC_AddressHoldTime = 0x04;   // 1 to 15 (table 215 p1529)
 p.FSMC_DataSetupTime = 0x2f;   // 1 to 256 (table 215 p1529) <= 5 gives last write; seq otherwise
 p.FSMC_BusTurnAroundDuration = 0x01; // 0 to 15 (table 215 p1529)
 p.FSMC_CLKDivision = 0x00;    // don't care (p.1548)
 p.FSMC_DataLatency = 0x00;    // don't care (p.1548)
 p.FSMC_AccessMode = 0x00;    // don't care (p.1560) only used during EXTMOD

 // configured according to p1547
 FSMC_NORSRAMInitStructure.FSMC_Bank = FSMC_Bank1_NORSRAM2;
 FSMC_NORSRAMInitStructure.FSMC_WriteBurst = FSMC_WriteBurst_Disable;      // disable or 0
 FSMC_NORSRAMInitStructure.FSMC_AsynchronousWait = FSMC_AsynchronousWait_Disable;   // if if memory supports it; otherwise 0
 FSMC_NORSRAMInitStructure.FSMC_ExtendedMode = FSMC_ExtendedMode_Disable;     // disable or 0
 FSMC_NORSRAMInitStructure.FSMC_WaitSignal = FSMC_WaitSignal_Disable;      // disable or 0
 FSMC_NORSRAMInitStructure.FSMC_WriteOperation = FSMC_WriteOperation_Enable;     // as needed?
 FSMC_NORSRAMInitStructure.FSMC_WaitSignalActive = FSMC_WaitSignalActive_BeforeWaitState; // don't care
 FSMC_NORSRAMInitStructure.FSMC_WrapMode = FSMC_WrapMode_Disable;       // disable or 0
 FSMC_NORSRAMInitStructure.FSMC_WaitSignalPolarity = FSMC_WaitSignalPolarity_Low;   // meaningful only if AsynchronousWait is 1
 FSMC_NORSRAMInitStructure.FSMC_BurstAccessMode = FSMC_BurstAccessMode_Disable;    // disable or 0
 FSMC_NORSRAMInitStructure.FSMC_MemoryDataWidth = FSMC_MemoryDataWidth_16b;     // as needed
 FSMC_NORSRAMInitStructure.FSMC_MemoryType = FSMC_MemoryType_NOR;       // 0x2 (NOR Flash memory)
 FSMC_NORSRAMInitStructure.FSMC_DataAddressMux = FSMC_DataAddressMux_Enable;     // enable or 1
 FSMC_NORSRAMInitStructure.FSMC_ReadWriteTimingStruct = &p;
 FSMC_NORSRAMInitStructure.FSMC_WriteTimingStruct = &p;

 FSMC_NORSRAMInit(&FSMC_NORSRAMInitStructure);

 /*!< Enable FSMC Bank1_NOR Bank */
 FSMC_NORSRAMCmd(FSMC_Bank1_NORSRAM2, ENABLE);
}

void ExtFlash_Verify(void)
{
    //  Issue the Software Product ID code to SST39VF401C
    *sysAddress(0x555) = 0x00AA;  // write data 0x00AA to device addr 0x555
    *sysAddress(0x2AA) = 0x0055;  // write data 0x0055 to device addr 0x2AA
    *sysAddress(0x555) = 0x0090;  // write data 0x0090 to device addr 0x555

    Delay_150_Nano_Seconds();

    // Read the product ID from SST39VF401C
    mfr_id  = *sysAddress(0x0000);   // get first ID byte
    dev_id  = *sysAddress(0x0001);   // get second ID byte

    // Issue the Software Product ID Exit code, thus returning the
    // SST39VF401C to the normal operation.
    *sysAddress(0x555) = 0x00AA;  // write data 0x00AA to device addr 0x555
    *sysAddress(0x2AA) = 0x0055;  // write data 0x0055 to device addr 0x2AA
    *sysAddress(0x555) = 0x00F0;  // write data 0x00F0 to device addr 0x555
 
    Delay_150_Nano_Seconds();
}