Spansion EMC NOR Flash on LPC1788

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Spansion EMC NOR Flash on LPC1788

1,306 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by pcproa on Thu Sep 27 11:19:02 MST 2012
Hello,

I am having a problem with the External NOR Flash on the EMC of my LPC1788
The NOR Flash I’m using is a Spansion S29GL064N90TFI040. The Datasheet can be seen here
http://www.spansion.com/Support/Datasheets/S29GL-N_01.pdf
I’ve also attached a quick picture of the Timings to this post.

I began the project with the NORFlashDemo of lpc177x_8x_cmsis_120831 as seen here
http://sw.lpcware.com/?p=lpc177x_8x.git&a=blob&h=20f0151fba0f6bee45473f342a103e90ba848a55&hb=5032933...

When I loaded the example in Keil, the device was not able to read the NOR Flash ID. I found that if I turned off the Shift Control Bit it would actually read the NOR Flash ID

LPC_SC->SCS &= ~(1 << 0);

Later on I changed it in the file “system_LPC177x_8x.c” so it would clear the bit on startup. I then modified the expected NOR ID so it would verify and proceed to the next step.

I then found that the device would fall into the delay loop where it would attempt to Toggle Bit at the end of the first write. It would ToggleBitCheck for 5 to 10 minutes, then finally move onto verification and fail since nothing was actually written. I decided to turn on the EMC Buffer right before the NORFlashErase

EMC_StaMemConfigB(0, EMC_CFG_BUF_ENABLED);

And it would finally seemingly do the writes and move onto Verification without exhausting the ToggleBitCheck Timeout loop. That’s where I began playing with the timing for the next 3 days. Sometimes it seems to write once or twice or every few write cycles. Sometimes the value at the addresses in the verification look comes back as 0xFFFF, and sometimes 0x0000. But for the most part, I’m pretty much stuck. My modified demo code is attached below

My NORFlashInit sequence is here, which also shows the timing for the Spansion NOR Flash:

<code>
void NORFLASHInit( void )
{
    TIM_TIMERCFG_Type TIM_ConfigStruct;
    EMC_STATIC_MEM_Config_Type config;

    /**************************************************************************
    * Initialize EMC for NOR FLASH
    **************************************************************************/
    config.CSn = 0;
    config.AddressMirror = 0;
    config.ByteLane = 1;
    config.DataWidth = 16;

    config.ExtendedWait = 0; // 1 or 0 for yes or no
    config.PageMode = 1; // 1 or 0 for yes or no

    config.WaitWEn = 0x3;
    config.WaitOEn = 0x3;
    config.WaitWr = 0xA;
    config.WaitPage = 0x8;
    config.WaitRd = 0x5;
    config.WaitTurn = 0x7;
    StaticMem_Init(&config);

    // init timer
    TIM_ConfigStruct.PrescaleOption = TIM_PRESCALE_USVAL;
    TIM_ConfigStruct.PrescaleValue  = 1;

        // Set configuration for Tim_config and Tim_MatchConfig
    TIM_Init(LPC_TIM0, TIM_TIMER_MODE,&TIM_ConfigStruct);
    TIM_Waitms(1000);

    //delay time
    TIM_Waitms(100);

    return;
}
</code>

And this is my actual Static Mem Init

<code>
/*********************************************************************//**
* @brief         Initialize external static memory
* @param[in]    pConfig    Configuration
* @return         EMC_FUNC_OK/EMC_FUNC_INVALID_PARAM/EMC_FUNC_ERR
**********************************************************************/
EMC_FUNC_CODE StaticMem_Init(EMC_STATIC_MEM_Config_Type* pConfig)
{
    uint32_t i;
    EMC_FUNC_CODE ret = EMC_FUNC_OK;
    /* Pin configuration:
    * P4.30 - /EMC_CS0
    * P4.31 - /EMC_CS1
    * P2.14 - /EMC_CS2
    * P2.15 - /EMC_CS3
    *
    *
    * P3.0-P3.31 - EMC_D[0-31]
    * P4.0-P4.23 - EMC_A[0-23]
    * P5.0-P5.1  - EMC_A[24-25]
    *
    * P4.24 - /EMC_OE
    * P4.25 - /EMC_WE
    *

    */
    //PINSEL_ConfigPin(2,14,1);
    //PINSEL_ConfigPin(2,15,1);

    for(i = 0; i < 32; i++)
    {
        PINSEL_ConfigPin(3,i,1);
        if (i == 22 || i == 23 || i == 31)
{}
else
PINSEL_ConfigPin(4,i,1);
    }
    //PINSEL_ConfigPin(5,0,1);
    //PINSEL_ConfigPin(5,1,1);

    // Power On
    ret |= EMC_PwrOn();

    // Configuration
    if(pConfig->AddressMirror)
    {
        LPC_EMC->Control |= EMC_Control_M;
    }

     ret |= EMC_StaMemConfigMW(pConfig->CSn,pConfig->DataWidth);
   
    if(pConfig->PageMode)
         ret |= EMC_StaMemConfigPM(pConfig->CSn,EMC_CFG_PM_ASYNC_ENABLE);
    else
         ret |= EMC_StaMemConfigPM(pConfig->CSn,EMC_CFG_PM_DISABLE);

    if(pConfig->ByteLane)
         ret |= EMC_StaMemConfigPB(pConfig->CSn, EMC_CFG_BYTELAND_READ_BITSLOW);
    else
         ret |= EMC_StaMemConfigPB(pConfig->CSn, EMC_CFG_BYTELAND_READ_BITSHIGH);

    if(pConfig->ExtendedWait)
{
        ret |= EMC_StaMemConfigEW(pConfig->CSn,EMC_CFG_EW_ENABLED);
EMC_StaticExtendedWait(EMC_StaticExtendedWait_EXTENDEDWAIT(4));
}
    else
        ret |= EMC_StaMemConfigEW(pConfig->CSn,EMC_CFG_EW_DISABLED);

    // Timing
     ret |= EMC_SetStaMemoryParameter(pConfig->CSn,EMC_STA_MEM_WAITWEN, pConfig->WaitWEn);
     ret |= EMC_SetStaMemoryParameter(pConfig->CSn,EMC_STA_MEM_WAITOEN, pConfig->WaitOEn);
     ret |= EMC_SetStaMemoryParameter(pConfig->CSn,EMC_STA_MEM_WAITRD, pConfig->WaitRd);
     ret |= EMC_SetStaMemoryParameter(pConfig->CSn,EMC_STA_MEM_WAITPAGE, pConfig->WaitPage);
     ret |= EMC_SetStaMemoryParameter(pConfig->CSn,EMC_STA_MEM_WAITWR, pConfig->WaitWr);
     ret |= EMC_SetStaMemoryParameter(pConfig->CSn,EMC_STA_MEM_WAITTURN, pConfig->WaitTurn);


    return ret;
}
</code>

Keep in mind, I am sharing the bus with a 128MBit SDRAM chip that isn’t initialized. I wanted to get the NOR Flash going separate of the SDRAM. I’m also attaching a picture of the schematic. The SDRAM currently works without the NOR Flash being initialized. I do successful reads to get the ChipID of the NOR Flash, and it seems like reading the different addresses is fine. I think the issue might be with my write’s and/or chip erase.

Does anyone have any thoughts on this? I’ve been searching the internet for a while on a definitive guide to setting NOR Flash timing but can’t find anything. I’ve also been looking how to use EMCCAL to determine at run time how the latency should be adjusted but I can’t find much info out there either.

Here is the output on USART0 from when I run this example

<collapse>
********************************************************************************

Hello NXP Semiconductors
EMC NORFLASH example
         - MCU: LPC177x_8x
         - Core: Cortex-M3
         - UART Comunication: 115200 bps
Write and verify data with on-board NOR FLASH
********************************************************************************


Init NOR Flash...
Read NOR Flash ID...
Erase entire NOR Flash...
Write a block of 2K data to NOR Flash...
Verify data...
  0 - 0xAA55 Good1 -- 0xFFFF Fail2
  2 - 0xFFFF Fail1 -- 0xFFFF Fail2
  4 - 0xFFFF Fail1 -- 0xFFFF Fail2
  6 - 0xFFFF Fail1 -- 0xFFFF Fail2
  8 - 0xFFFF Fail1 -- 0xFFFF Fail2
10 - 0xFFFF Fail1 -- 0xFFFF Fail2
12 - 0xFFFF Fail1 -- 0xFFFF Fail2
14 - 0xFFFF Fail1 -- 0xFFFF Fail2
16 - 0xFFFF Fail1 -- 0xFFFF Fail2
18 - 0xFFFF Fail1 -- 0xFFFF Fail2
20 - 0xFFFF Fail1 -- 0xFFFF Fail2
22 - 0xFFFF Fail1 -- 0xFFFF Fail2
24 - 0xFFFF Fail1 -- 0xFFFF Fail2
26 - 0xFFFF Fail1 -- 0xFFFF Fail2
28 - 0xFFFF Fail1 -- 0xFFFF Fail2
30 - 0xFFFF Fail1 -- 0xFFFF Fail2
32 - 0xFFFF Fail1 -- 0xFFFF Fail2
34 - 0xFFFF Fail1 -- 0xFFFF Fail2
36 - 0xFFFF Fail1 -- 0xFFFF Fail2
38 - 0xFFFF Fail1 -- 0xFFFF Fail2
40 - 0xFFFF Fail1 -- 0xFFFF Fail2
42 - 0xFFFF Fail1 -- 0xFFFF Fail2
44 - 0xFFFF Fail1 -- 0xFFFF Fail2
46 - 0xFFFF Fail1 -- 0xFFFF Fail2
48 - 0xFFFF Fail1 -- 0xFFFF Fail2
50 - 0xFFFF Fail1 -- 0xFFFF Fail2
52 - 0xFFFF Fail1 -- 0xFFFF Fail2
54 - 0xFFFF Fail1 -- 0xFFFF Fail2
56 - 0xFFFF Fail1 -- 0xFFFF Fail2
58 - 0xFFFF Fail1 -- 0xFFFF Fail2
60 - 0xFFFF Fail1 -- 0xFFFF Fail2
62 - 0xFFFF Fail1 -- 0xFFFF Fail2
Testing Complete!
</collapse>

Original Attachment has been moved to: Emc_NorFlashDemo.c.zip

Labels (1)
0 Kudos
7 Replies

800 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by hadi987 on Sun Sep 15 09:12:03 MST 2013
Hi.
i have a problem like pcproa, I am using the same memory and LPC in my project.and all of my data is 0xFFFF ,
i am grateful if some body can help me

0 Kudos

800 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by crudo on Thu Nov 29 04:45:43 MST 2012
Hello. I am using the same memory and LPC in my project. Can you share the source code files that you fixed to work rightly. Thank you.

Best regards,
Ricardo Crudo.
0 Kudos

800 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by DF9DQ on Thu Sep 27 20:36:19 MST 2012
Hi Patrick,

I'm glad to hear that!
Thank you very much for letting us know the solution!

Regards,
Rolf
0 Kudos

800 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by pcproa on Thu Sep 27 17:59:00 MST 2012
Hey Rolf,

On your first response to my Original Post, you questioned the use of the buffer that I added. When I responded to that I started thinking about it as well. I immediately removed the line to turn on the buffer and started playing with the rest of the code. I removed every section of code and started doing each step one by one.

With the buffer off, I found that the Datasheet recommended Erase time of 128 seconds had to completely pass after I sent the command to Erase. If I tried to write to the chip before the Erase time transpired, it would Toggle Bit on the first write till the Flash completed the previous action. Once the action is complete, it would write everything correctly.

The CMSIS Example didn't have enough of a delay after the Erase command and I was wrong to assume it would work correctly with just a few changes to the EMC latencies. What made it worse is that after data had been written to an address on the NOR Flash, a second attempt to write the same address would allow it to run into the same long ToggleBit loop giving the impression that it is still faulty. I know you can't write to Flash twice unless you Erase and re-write, but I've never experienced a nearly infinite delay if you try to write over an address that was already written.

Early on, I became fixated on what made it seemingly work, that I didn't realize enabling the buffer action was actually a step in the wrong direction. Thank you very much for all the help, it now works flawlessly and reliably.

To follow up with the last thing you mentioned about the commands of 2AA/555 vs. 2AAA/5555, that was one of the first things I looked at a few days ago. I found that the SST39VF3201 Datasheet also says the commands are 2AA/555 and I didn't understand why the CMSIS examples had the extra repeat nibble of the nibble right before it. However, I did try both command formats and they both produced the same results on this chip. In other words, in this case, 2AA/555 seems to be the same as 2AAA/5555

Again, than you very much for the help Rolf. You managed to wipe out 3 days of frustration.

Best Regards,

Patrick
0 Kudos

800 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by DF9DQ on Thu Sep 27 14:32:26 MST 2012
Hi,

Have you adapted the NXP sample code (for the SST39VF3201) to your Spansion flash? As far as I can see, they differ in the addresses used for commands: 2AA/555 vs. 2AAA/5555.
I'm just asking because I've overlooked that several times myself before...

Regards,
Rolf
0 Kudos

800 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by pcproa on Thu Sep 27 14:12:35 MST 2012
Makes sense, but it just won't budge past the PROGRAM_TIMEOUT loop while it's trying to ToggleBit if the buffer is off.
Secondly, once in a while it seems to write something to the flash with the buffer on. I believe this is the case because I can complete a write cycle, turn it off for a few hours, turn it on and go straight to a read cycle, and it will show what was last written.
0 Kudos

800 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by DF9DQ on Thu Sep 27 13:57:53 MST 2012
Hi,

I would have expected that you cannot program the NOR flash if the buffers ar on. This is because if you read many times from the same address, the result will be taken from the buffers, and no physical read cycle will be initiated. In that case you are unable to detect toggling (of DQ7 or so).

Regards,
Rolf
0 Kudos