Author Topic: spi flash test failed  (Read 9052 times)

Offline neil

  • Sr. Member
  • ****
  • Posts: 427
    • View Profile
spi flash test failed
« on: September 16, 2008, 09:57:17 PM »
Hi Mark,
  When checking the new SP8 project the fnTestSPIFLASH(..) returned 'FLASH TEST FAILED' . Looking at the code it failed on the code :
     fnWriteBytesFlash(TEST_DEVICE, test_buffer1, SPI_FLASH_PAGE_LENGTH);
    fnGetParsFile(TEST_DEVICE, test_buffer2, SPI_FLASH_PAGE_LENGTH);


To test the spi chip (only 1 on my board, dont have demo or eval) I added the following in the M52233X.c file:

void WriteToPage(unsigned long ulPageNumberOffset, volatile unsigned char *ucData)
{   
   fnSPI_command(WRITE_BUFFER_1, ulPageNumberOffset, ucData,SPI_FLASH_PAGE_LENGTH);
   fnSPI_command(ERASE_PROG_FROM_BUFFER_1, ulPageNumberOffset, ucData,SPI_FLASH_PAGE_LENGTH);
}

void ReadFromPage(unsigned long ulPageNumberOffset, volatile unsigned char *ucData)
{   
   fnSPI_command(CONTINUOUS_ARRAY_READ, ulPageNumberOffset << 9, ucData,SPI_FLASH_PAGE_LENGTH);
}

and within the fnTestSPIFLASH(..) I replaced the   fnWriteBytesFlash(..)and  fnGetParsFile(..) with:
    WriteToPage(2,test_buffer1) ;
   ReadFromPage(2,test_buffer2);

And worked fine.

Any ideas what can be the problem?

Neil

Offline mark

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 3167
    • View Profile
    • uTasker
Re: spi flash test failed
« Reply #1 on: September 17, 2008, 11:14:25 AM »
Hi Neil

I just tested this in the simulator and it didn't show an error.

Are you sure that the setup matches your FLASH chip/size?
In app_hw_m5223x.h the device type can be chosen:

  //#define SPI_FLASH_AT45DB011                                          // {31} define the ATMEL type used here
  //#define SPI_FLASH_AT45DB021
  //#define SPI_FLASH_AT45DB041
    #define SPI_FLASH_AT45DB081
  //#define SPI_FLASH_AT45DB161
  //#define SPI_FLASH_AT45DB321
  //#define SPI_FLASH_AT45DB642


Depending on the types there are differences in the page sizes. Could this explain something?


Another idea is that your FLASH already had some data in it (not blank) since the test will fail this case (if you force it to jump to the delete part it would then be OK afterward). The difference between the routine that you have used (which works) and the standard write/reads is that you have used the command ERASE_PROG_FROM_BUFFER_1, which takes a bit longer due to the fact that it first erases the page and then writes the buffer to it (this will also work if the page was not deleted beforehand). The SPI FLASH driver uses PROG_FROM_BUFFER_1, which will not first erase (it is thus also faster), but it assumes that no bits in the memory are already programmed with '0', that need to be set to '1'. Normal use of the file system ensures this to be the case but the quick test function fnTestSPIFLASH() doesn't. A non-blank chip can this fail - in fact I originally thought that all new chips were delivered fully erased but I think that I also had the case that a fresh one had data in it so I first had to delete it for the test to be successful.

Last note: make sure that this test is turned off when working with the real project otherwise it trashes the first page in SPI FLASH...

Regards

Mark


Regards

Mark

Offline neil

  • Sr. Member
  • ****
  • Posts: 427
    • View Profile
Re: spi flash test failed
« Reply #2 on: September 17, 2008, 11:47:28 AM »
Hi Mike,
  I placed the command fnEraseFlashSector(TEST_DEVICE, 0); in front of the fnWriteBytesFlash(TEST_DEVICE, test_buffer1, SPI_FLASH_PAGE_LENGTH); command, and worked fine. 


I have set the utasker up so the parameter block is in Flash, and file system in SPI memory, I setup the following:

#define FLASH_FILE_SYSTEM
#define PARAMETER_BLOCK_START 0x3f000                            // {34} FLASH location at 2 parameter blocks short of end of internal FLASH
#define uFILE_START 0x40000                                      // immediately after internal FLASH

So does the command fnGetParsFile(..) read from the internal flash?

Thanks
Neil

Offline mark

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 3167
    • View Profile
    • uTasker
Re: spi flash test failed
« Reply #3 on: September 17, 2008, 01:14:47 PM »
Hi Neil

I think that you forgot to mention that you also set SPI_FILE_SYSTEM.

This positions the parameter block(s) in FLASH (assuming you have 256k of FLASH! - some Coldfire types have less). Therefore all parameter system accesses are internal (you won't see any QSPI activity).

If you however use the file system (eg. browse to the board using a WebBrowser) you will see that QSPI used for this since the file system starts in SPI FLASH. [Note that it is possible to also start the file system internal FLASH and end it in external SPI FLASH, although this probably doesn't make much sense to actually do].

This is also easy to verify using the uTasker simulator. When the parameters are retrieved the routine fnGetParsFile() is called and detects that the address is in internal FLASH and thus performs a simple uMemcpy(). When it retrieves a file for the WebServer it also uses this routine but detects that the memory is external - then it collects the data via QSPI.

Regards

Mark

Offline neil

  • Sr. Member
  • ****
  • Posts: 427
    • View Profile
Re: spi flash test failed
« Reply #4 on: November 10, 2008, 04:07:50 PM »
Hi Mark,

I am using 1 externel SPI ATMEL EEPROM, which I want to use for firmware upgrade, and also use the rest of EEPROM (after 256k for firmware) for my filesystem (set SPI_FILE_SYSTEM).

I am using the WriteToPage() as speed is not an issue while simply uploading the new firmware.

I done the following (and the test failed)..

     unsigned char test_buffer1[SPI_FLASH_PAGE_LENGTH];
     unsigned char test_buffer2[SPI_FLASH_PAGE_LENGTH];

    uMemset(test_buffer1, 0x55, SPI_FLASH_PAGE_LENGTH);
    uMemset(test_buffer2, 0x00, SPI_FLASH_PAGE_LENGTH);

    WriteToPage(445,test_buffer1) ;  //0x55 written to page 445
   ReadFromPage(445,test_buffer2); //read page 445 to test buffer 2

   if (!(uMemcmp(test_buffer1, test_buffer2, SPI_FLASH_PAGE_LENGTH)))
    fnWrite(SerialPortID, (unsigned char*)"OKAY", 4);    // success
   else
     fnWrite(SerialPortID, (unsigned char*)"FAILED", 5);    // failed


Any idea why this would happen (The fnTestSPIFLASH(..)) works fine?

Thanks
Neil


Offline mark

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 3167
    • View Profile
    • uTasker
Re: spi flash test failed
« Reply #5 on: November 10, 2008, 06:55:53 PM »
Hi Neil

I just put your code in the project (after the fnTestSPIFLASH() test) and tested in the simulator. The simulator didn't see any problem with it.

Note that the command ERASE_PROG_FROM_BUFFER_1 is not actually used in the project so i don't have great experience with it, therefore I looked a bit closer at the way that the ERASE_PROG_FROM_BUFFER_1 is actually handled in the driver routine and whether the SPI FLASH command was really being simulated correctly, and found the following:

after sending the ERASE_PROG_FROM_BUFFER_1 command correctly to the chip, the routine was then sending extra data, whereas I would have expected it to leave the driver routine and negating the CS. Then I noticed that this is due to the fact that following command there is data specified:
   fnSPI_command(ERASE_PROG_FROM_BUFFER_1, ulPageNumberOffset, ucData,SPI_FLASH_PAGE_LENGTH);

Removing the data (the command doesn't actually have any data)
   fnSPI_command(ERASE_PROG_FROM_BUFFER_1, ulPageNumberOffset, 0,0);

and stepping through the routine it looked to be good.

This shows that the simulator wasn't disturbed by these unexpected data bytes but I don't known what the real chip thinks of them... I would try this change to see if it solves the difficulty.

regards

Mark








Offline neil

  • Sr. Member
  • ****
  • Posts: 427
    • View Profile
Re: spi flash test failed
« Reply #6 on: November 10, 2008, 07:45:24 PM »
Hi Mark,
  That helped thanks. But.. I done the following:

Wrote to page 1, and read it to compare  which was fine.
Wrote to page 2, and read it to compare, and found that in the read buffer, an extra 0 was added at the start of the read in buffer.

test_buffer2 was transmitted via serial through my windows application, so I could see what was sent.

     uMemset(test_buffer1, 0x42, SPI_FLASH_PAGE_LENGTH);
     WriteToPage(PageNumber,test_buffer2) ;
     ReadFromPage(PageNumber,test_buffer1);   <--- second time carried read in and extra 0 added at start,

    for(Loop=0;Loop<264;Loop++)  //could have used uCompare, but wanted to note the position the problem was at.
    if(test_buffer2[Loop]!=test_buffer1[Loop])
      ;
   

test_buffer2 =  0,0,178,23 
test_buffer1 =  0,0,0,178,23

Regards
Neil

Offline mark

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 3167
    • View Profile
    • uTasker
Re: spi flash test failed
« Reply #7 on: November 10, 2008, 08:39:42 PM »
Hi Neil

I don't understand exactly how you are testing in this case. Can you show the complete test code?

regards

Mark

Offline neil

  • Sr. Member
  • ****
  • Posts: 427
    • View Profile
Re: spi flash test failed
« Reply #8 on: November 10, 2008, 09:46:28 PM »
Hi Mark,
  I have a procedure that sends 264 bytes at time (and a small header), which is saved within the eeprom (spi) for updating the firmware. Everytime a block of data is read in to the processor (at the moment by serial), it is saved to a page number (which is specified in header). The code is as follows:

  void SavePage(int PageNo,unsigned char *data)
 {
  unsigned char test_buffer1[SPI_FLASH_PAGE_LENGTH],test_buffer2[SPI_FLASH_PAGE_LENGTH];   
  int Loop;
 
  for(Loop=0;Loop<264;Loop++) //used for testing, will simply use passed block
       test_buffer2[Loop]=data[Loop];
 
     uMemset(test_buffer1, 0x42, SPI_FLASH_PAGE_LENGTH); //set block 1 to known state
 
    WriteToPage(PageNumber,test_buffer2) ; //write to memory
    ReadFromPage(PageNumber,test_buffer1); //read back into buffer 1

   for(Loop=0;Loop<264;Loop++)
    if(test_buffer2[Loop]!=test_buffer1[Loop])
    {
       //error here on second time called..
    }
}

Now the 1st time the procedure is called (with page Number 0) works fine, the second time called is when the error appears.

The second time the function  is called, test_buffer2 holds the below, and when read back into buffer1 , an extra 0 is read in at beginning.

test_buffer2 =  0,0,178,23
test_buffer1 =  0,0,0,178,23

Regards
Neil

Offline neil

  • Sr. Member
  • ****
  • Posts: 427
    • View Profile
Re: spi flash test failed
« Reply #9 on: November 11, 2008, 09:17:40 AM »
Hi Mark,
  There is something strange going on, I think its my side, nothing to do with utasker. I am looking more into it to see whats going on.

Regards
Neil

Offline neil

  • Sr. Member
  • ****
  • Posts: 427
    • View Profile
Re: spi flash test failed
« Reply #10 on: November 11, 2008, 02:19:08 PM »
Hi Mark,
  Im still having a problem with this. I have altered the fnTestSPIFLASH(..) to replicate this. Im using the WriteToPage(..) and ReadFromPage(..) described previously.  The below code produces an error starting from Page 1. But if I remove the    test_buffer1[0]=0;   test_buffer1[1]=0;   test_buffer1[2]=0;   test_buffer1[3]=178; Then all works okay.

Regards
Neil
 


unsigned char test_buffer1[SPI_FLASH_PAGE_LENGTH];
unsigned char test_buffer2[SPI_FLASH_PAGE_LENGTH];
int Loop,Loop1;
unsigned long Page=0;
char Tmp;

for(Loop=0;Loop<10;Loop++)
{
     uMemset(test_buffer1, 0x00, SPI_FLASH_PAGE_LENGTH);
     uMemset(test_buffer2, 0x11, SPI_FLASH_PAGE_LENGTH);
    test_buffer1[0]=0;
    test_buffer1[1]=0;
    test_buffer1[2]=0;
    test_buffer1[3]=178;
 
     WriteToPage(Page,test_buffer1) ;
     ReadFromPage(Page++,test_buffer2);
     
     Tmp=0;
    for(Loop1=0;Loop1<264;Loop1++)
     if(test_buffer2[Loop1]!=test_buffer1[Loop1])
     {
       sprintf(Check,"Error Page=%ld\r\n",Page-1);
       fnDebugMsg(Check);
       Tmp=1;
       break;
     }
   
    if(!Tmp)
    {
      sprintf(Check,"OK Page=%ld\r\n",Page-1);
     fnDebugMsg(Check);
      
    }     
}

Offline mark

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 3167
    • View Profile
    • uTasker
Re: spi flash test failed
« Reply #11 on: November 11, 2008, 03:32:40 PM »
Hi Neil

I could reproduce this in the simulator and it turns out that it is the following.

void WriteToPage(unsigned long ulPageNumberOffset, volatile unsigned char *ucData)
{  
   fnSPI_command(WRITE_BUFFER_1, ulPageNumberOffset, ucData,SPI_FLASH_PAGE_LENGTH);
   fnSPI_command(ERASE_PROG_FROM_BUFFER_1, ulPageNumberOffset, 0,0);
}


The command WRITE_BUFFER_1 takes an offset in the buffer as parameter and not a page number. This means that when you incremented the page it was correctly deleting the page in the ERASE_PROG_FROM_BUFFER_1 but it was introducing an offset in the WRITE_BUFFER_1. The buffer was therefore being written from address 1 and not from the start. Further incrementing the page was increasing the shift each time.

The ReadFromPage() reads always from the start of the buffer. The compare showed subsequently that the read buffer was one byte shifted. This was not noticed when accessing the first page and is also not noticed when the content of the buffer is always the same value at each location.

The correction that you need is:
   fnSPI_command(WRITE_BUFFER_1, 0, ucData,SPI_FLASH_PAGE_LENGTH);

seeing as you are only reading complete pages.

Final note:
in ReadFromPage() the page shift required depends on the page size in the physical SPI FLASH.
fnSPI_command(CONTINUOUS_ARRAY_READ, ulPageNumberOffset << 9, ucData,SPI_FLASH_PAGE_LENGTH); is correct for types with 264 byte buffer but needs shifts of 10 or 11 should you change to bigger types with 528 or even 1056 byte pages.


Regards

Mark
« Last Edit: November 11, 2008, 04:08:52 PM by mark »

Offline neil

  • Sr. Member
  • ****
  • Posts: 427
    • View Profile
Re: spi flash test failed
« Reply #12 on: November 11, 2008, 04:04:27 PM »
Hi Mark,
  Thanks very much, I was that busy looking at the rest of the code, I overlooked this  :'( 


Neil