This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

NOR flash - validation failed

Working with the AT91SAM9260 controller from atmel, I get a lot of errors when I try to program the NOR flash AT49BV160 which is connected at NSC0.

The problem is, that I have no communication at NRD, NRW0 and NCS0, when I try to program the flash or turn on the power of this board (BMS pin is high during the reset).

During the programming via the jtag interface I get a lot of errors (validation failed). Erase and programming was successfull (said uvision).

Maybe someone of you working with this controller, could show me the right commands / settings (especially to configurate this flash).

thank you in advance - best regards

Stefan

Parents
  • Hello Stefan,

    It is logical that you get some action on pins when you try programming.

    I'm not really sure what is the problem now?

    Anyways it is strange to me that you are mentioning memcpy for copying code to NOR flash, NOR flash is programmed by entering instructions first and then entering data.
    For example for programming: M16(base_adr + 0x0AAA) = 0xAA; M16(base_adr + 0x1554) = 0x55; M16(base_adr + 0x0AAA) = 0xA0; M16(adr) = *((unsigned short *) buf);

    so you have to enter commands before every 16-bit value you write to NOR flas.

    So I don't see how you planed to do that with memcpy?

    Please, ask more (detailed) clear questions if you still have problems.

Reply
  • Hello Stefan,

    It is logical that you get some action on pins when you try programming.

    I'm not really sure what is the problem now?

    Anyways it is strange to me that you are mentioning memcpy for copying code to NOR flash, NOR flash is programmed by entering instructions first and then entering data.
    For example for programming: M16(base_adr + 0x0AAA) = 0xAA; M16(base_adr + 0x1554) = 0x55; M16(base_adr + 0x0AAA) = 0xA0; M16(adr) = *((unsigned short *) buf);

    so you have to enter commands before every 16-bit value you write to NOR flas.

    So I don't see how you planed to do that with memcpy?

    Please, ask more (detailed) clear questions if you still have problems.

Children
  • thanks for your answer. I tried to program a new algorithm for the flash memory.

    The memory flash doesn't provide an "chip erase" command (only a sector erase command) - could you tell me how is it possible to use the "erase-button" (Flash>Erase) in the uvision IDE to erase the whole memory flash? I think that this function will be called if I / you press the erase-button.

    int EraseChip (void) {
    
      // Start Chip Erase Command
    
      //return (Polling(base_adr));  // Wait until Erase completed
      return 0;
    }
    

    There's the datashheet of this memory flash: The command table is on page 15.
    www.atmel.com/.../doc3591.pdf

    best regards
    Stefan

  • If you do not have EraseChip function implemented in your flash algorithm (delete EraseChip function, do not leave it empty), ULINK driver will automatically call EraseSector command for each sector of the flash.

    Important things to define are in FlashDev.c and they are "Device Size in Bytes" and "Size and Address of Sectors". According to these 2 parameters ULINK driver knows how many times it has to call SectorErase command and with what address increments.

  • thanks for your answer. At the moment, when I press the erase-button (under Flash->Erase) -> nothing happens on the pins NCS0, NWE0.

    I deleted the EraseChip-Function. The sector-erase-chip function is:

    int EraseSector (unsigned long adr) {
    
      // Start Erase Sector Command
      M16(base_adr + 0x0AAA) = 0x20;
      M16(adr) = 0xD0;
    
      return (Polling(adr));       // Wait until Erase completed
    }
    

    Sector Erase/Confirm: 2 cycles Addr: XX (any addr) 20 (data) and the second cycle is SA(sector addr) and D0 (data).

    The polling-function: q3 is the VPP status and q7 determine if sector erase or Word Program is complete.

    int Polling (unsigned long adr) {
    
      unsigned int q7; //1: ready 0: busy
    
      fsr.v = M16(adr);
      q7 = fsr.b.q7;
      do {
        fsr.v = M16(adr);
        if (fsr.b.q7 == 1) return (0);  // Done
        q7 = fsr.b.q7;
        if (fsr.b.q3 == 1) break;        // VPP not high enough
      } while (fsr.b.q7 == 0);           // Check for Timeout
    
      fsr.v = M16(adr);
      q7 = fsr.b.q7;
      fsr.v = M16(adr);
      if (fsr.b.q7 == 1) return (0);    // Done
    
      //M16(adr) = 0xF0;                   // Reset Device
      return (1);                        // Failed
    }
    

    Under options-for-target->utlities I have a short init-file, where I start the clocks and program the three SMC controller registers. The clock function is directly from keil (and works).

    //Control Register: 16bit databus, NRD, NWE controlled
    _WDWORD(0xFFFFEC0C,0x00021003);
    
    //Cycle Register: NWE_Cycle - NRD_Cycle
    _WDWORD(0xFFFFEC08, 0x00070007);
    
    //Setup Register: NWE_Setup - NCS_WR_Setup - NRD_Setup - NCS_RD_Setup
    _WDWORD(0xFFFFEC00, 0x00000001);
    
    //Pulse Register: NWE_Pulse - NCS_WR_Pulse - NRD_Pulse - NCS_RD_Pulse
    _WDWORD(0xFFFFEC04, 0x07070703);
    

    I hope you could tell me what I'm doing wrong so that I have no signal output (on NCS0, NWE...) when I press the erase-button.

    best regards
    Stefan

  • here's my configuration from the FlashDev.c-file:

    struct FlashDevice const FlashDevice  =  {
       FLASH_DRV_VERS,             // Driver Version, do not modify!
       "AT49BV160 Flash",        // Device Name
       EXT16BIT,                   // Device Type
       0x000000,                   // Device Start Address
       0x200000,                   // Device Size in Bytes (2MB)
       1024,                       // Programming Page Size
       0,                          // Reserved, must be 0
       0xFF,                       // Initial Content of Erased Memory
       100,                        // Program Page Timeout 100 mSec
       1000,                       // Erase Sector Timeout 1000 mSec
    
    // Specify Size and Address of Sectors
       0x10000, 0x000000,          // Sector Size 64kB (31 Sectors)
       0x02000, 0x1F0000,          // Sector Size  8kB (8 Sectors)
       SECTOR_END
    };
    
    

    The flash memory is 2MB,. 1024 page size and the sector size is 64kB and 8kB....

    best regards
    Stefan

  • Hi Stefan,

    my guess is that you did not enable clocks for SMC (in PMC_PCER register).
    Anyways seems that pins and clocks are not fully configured.

  • Hi Milorad,

    there's no such clock (especially for the SMC controller).

    I disable the pio mode, select peripheral A and disable the pull-ups. And now the NCS0 signal and NRD signal goes low if I tried to erase the nor flash.

    // Specify Size and Address of Sectors
       0x10000, 0x000000,          // Sector Size 64kB (31 Sectors)
       0x02000, 0x1F0000,          // Sector Size  8kB (8 Sectors)
    

    Could you tell me the way I get the start addr from the sector 8kb (0x1F0000)? In the datasheet there's a table about the start and end of each sector. The last 64k sector ends at 0xF7FFF and the first 8k sector starts at F80000.

    How do I have to name the read function in the flash algorithm (FlashProg.c)? Because I have to write 0xFF (as command) to one addr.

    At the moment I see that somethings happens on the pins (ncs0, nrd and nwe) but the veryfication failed. I think that I'm not able to read out anything from the flash.

    Anyways seems that pins and clocks are not fully configured

    Here's the clock-enable-function:

    FUNC void Clock_Setup (void) {
    
        // Setup clock; XTAL      = 18.432000 MHz,
        //              PLLA      = 96.109714 MHz,
        //              Processor = 96.109714 MHz
        _WDWORD(PMC+   0x20, 0x0000FF01);   // CKGR_MOR: Enable main oscillator
        _sleep_(100);                       // Wait for stable Main Oscillator
        _WDWORD(PMC+   0x28, 0x20483F0E);   // CKGR_PLLAR: Configure PLL A
        _sleep_(100);                       // Wait for stable PLL A
        _WDWORD(PMC+   0x30, 0x00000000);   // PMC_MCKR: MDIV and PRES fields
        _sleep_(100);                       // Wait for Main Master Clock ready
        _WDWORD(PMC+   0x30, 0x00000002);   // PMC_MCKR: all fields
        _sleep_(100);                       // Wait for Main Master Clock ready
    }
    

    best regards
    Stefan

  • Hi Stefan,

    Your SectorErase fuction will be called with addresses of each sector correctly, so you do not need to worry about sector address.

    Why do you want to get sector address?

    As this is NOR flash you do not need to specify any Read function because processor should be able to directly read from NOR flash and it uses directly reading to verify what has been written.

    In other words you can not specify read function you could specify Verify function but in your case you do not need it as flash should be readable directly at its memory addresses.

    You could try this by entering debug and looking at flash memory addresses where your flash is mapped if you do not see what you have written then everything still does not function as expected.

    My guess is that you still do not write to flash correctly.

    Best regards, Milorad

  • My guess is that you still do not write to flash correctly.

    that's right. When I try to erase the whole flash memory then I get a signal on NCS0 and NRD; but when I try to download some code to the memory there's no activity on NWE or at the whole databus. Only at the address bus, NCS0 and NRD is an activity.

    The programming algorithm for the flash is:

    int ProgramPage (unsigned long adr, unsigned long sz, unsigned char *buf) {
      int i;
    
      for (i = 0; i < ((sz+1)/2); i++)  {
        // Start Program Command
        M16(base_adr + 0x15) = 0x10;
        M16(adr) = *((unsigned short *) buf);
        if (Polling(adr) != 0) return (1);
        buf += 2;
        adr += 2;
      }
      return (0);
    }
    

    Datasheet: Word-Program:
    Cycle 1: Addr=XX and Data 40/10 - I'm not sure what this means (40 / 10)? I tried to use 0x40 and 0x10 - but nothing has changed.

    Cycle 2: Addr=Addr and Data is Din

    I'm not sure, where there could be another error in my configuration.

    best regards
    Stefan

  • Hi Stefan,

    can you answer following questions:
    - do you have flash connected in 16-bit bus?
    - do you have !WP pin connected High?
    - did you connect A1 processor line to A0 on flash? (flash expects half word address on A0..A19, and this means that A1 which is first half word address on processor has to be connected to A0 on flash chip, and all other lines are shifted by one, meaning:

       proc  A1 -> flash  A0
       proc  A2 -> flash  A1
                ...
       proc A20 -> flash A19
    

    If answers to previous questions are yes can you then try this for SectorErase:

    int EraseSector (unsigned long adr) {
    
      // Start Erase Sector Command
      M16(adr) = 0x20;
      M16(adr) = 0xD0;
    
      return (Polling(adr));
    }
    

    Best regards, Milorad

  • - do you have flash connected in 16-bit bus?

    _WDWORD(0xFFFFEC0C,0x00021003);
    


    this is the mode register for the SMC controller (NCS0), where I selected 16bit databus mode, write operation controlled by NWE, read operation controlled by NRD, NWAIT disabled, TDF data float time = 2, standard read, page mode not enableda and TDF optimization disabled.

    If answers to previous questions are yes can you then try this for

    yes, the connections are correct (and as you described it in your last message).

    int EraseSector (unsigned long adr) {
    
      // Start Erase Sector Command
      M16(adr) = 0x20;
      M16(adr) = 0xD0;
    
      return (Polling(adr));
    }
    

    It's still the same problem -> no activity on NWE and the databus (0x20 and 0xD0), when I try to erase the chip. There's only a activity at NCS0, the addressbus and NRD. All control signals (NWE, NCS0 and NRD), as well as all address lines are connected direct to the memory.

    I have installed two bidirectional transceivers for the whole databus (between the controller and the flash memory). OE (transceiver) is always low active when the sdram (which is not connected at the moment) won't be active (-> so it's always low which is correct). And NRD is connected to control the T/R (transmit / receive) pin. If NRD is low then the information goes from the memory to the controller.

    www.fairchildsemi.com/.../74LVTH245.pdf

    That's my hardware wiring.

    best regards
    Stefan

  • Hi Stefan,

    can you try in initialization:

    _WDWORD(0xFFFFEC00,0x3F3F3F3F);
    _WDWORD(0xFFFFEC04,0x7F7F7F7F);
    _WDWORD(0xFFFFEC08,0x01FF01FF);
    _WDWORD(0xFFFFEC0C,0x000F1103);
    

    Did you see anything on NWR or NRD?

    Best regards, Milorad

  • When I try this configuration, then I see nothing on NRD, NCS0 and NWE... No signal at all.

    best regards
    Stefan

  • Hi Stefan,

    That setting I gave you should have setup communication for longest times and should have worked.

    Can you try another microcontroller (new chip)?

    I would suggest that you contact Atmel support directly and ask them for help about how to configure SMC for NOR Flash.

    Best regards, Milorad

  • thanks for your help. I will contact the support from atmel.

    By the way, when I try to erase the flash, I see an activity at the SDCS pin (NCS1 chip select configurated for the sdram)? And I don't program the sdram in the init-file. The same occurs when I use another NCS-pin.

    At the moment there's no sdram chip on the board.

    best regards
    Stefan

  • I changed the controller and know I am able to see some activity on all relative pins (WE, NRD and so on).

    The problem now is, that NRD, WE or CE pin goes only low at the beginning of each page; but within a page there's still no activity. From this it follows that'I have only at the addr - and data lines activity within each page. So a lot of the data, the controller sends to the flash, can't be stored in the flash because the CS and WE lines are both high.

    Dataline: |||||||||||| (activity)
    CS:       |     |    |
    NRD:      |     |    |
    
    

    best regards
    Stefan