9 Replies Latest reply on Jul 2, 2019 3:01 AM by ApurvaS_36

    regarding calculatin of sectors for erase  before page write of normal and secured regions S25FL-L 128/256

    vivc_4156156

      Hi

         My page program nd sector erase functions are done . To erase the sectors before page write any rfefrences for calculation for the same.

      if it is there It would be helpful. some thing like this ive done is this correct

       

       

       

       

      void spi_flash_secure_region_program (uint16_t address, uint8_t *p_data_bytes, uint16_t size)
      {
      static uint16_t number_of_pages, size_of_data, last_data_block_size, counter;

      int i = 0;

      uint16_t startSctrAddr = address & 0x0000FFFF;
      uint16_t stopSctrAddr = (address + size) & 0x0000FFFF;

      int numSctrs = 1;

      if (startSctrAddr != stopSctrAddr)  // Data to be written over sector boundary?
      numSctrs += 1;

      for (i = 0; i < numSctrs; i++)
      {
        spi_flash_secure_region_erase(startSctrAddr + (i * FLASH_SECURE_REGION_SIZE_4K)); // FLASH_SECURE_REGION_SIZE_4K = 0x400
      }

      size_of_data = size;

      if(size_of_data <= 1024)
      {
        if (size_of_data % 256)
        {
         number_of_pages = (size_of_data / 256) + 1;
         last_data_block_size = size_of_data % 256;
        }
        else
        {
         number_of_pages = (size_of_data / 256);
         last_data_block_size = 256;
        }

        address &= 0x0000FFFF; // address must be aligned to 256 byte !

        for ( counter = 0; counter < number_of_pages - 1; counter++ )
        {
         spi_flash_secure_region_page_program ((address + 256*counter) ,(p_data_bytes +256*counter), 256);
        }
        // last page
        spi_flash_secure_region_page_program ((address + 256*(number_of_pages - 1)) ,(p_data_bytes +256*(number_of_pages - 1)), last_data_block_size);
      }

      }

       

      void spi_flash_program (uint32_t address, uint8_t *p_data_bytes, uint32_t size)
      {
      static uint32_t number_of_pages, size_of_data, last_data_block_size, counter;
      int i = 0;

      uint32_t startSctrAddr = address & 0xff000;
      uint32_t stopSctrAddr = (address + size) & 0xff000;

      int numSctrs = 1;

      if (startSctrAddr != stopSctrAddr)  // Data to be written over sector boundary?
      numSctrs += 1;

      for (i = 0; i < numSctrs; i++)
      {
          spi_flash_sector_erase(startSctrAddr + (i * FLASH_SCTR_SIZE_4K)); // FLASH_SCTR_SIZE_4K - 0x1000
      }

      size_of_data = size;

      if (size_of_data % 256)
      {
        number_of_pages = (size_of_data / 256) + 1;
        last_data_block_size = size_of_data % 256;
      }
      else
      {
        number_of_pages = (size_of_data / 256);
        last_data_block_size = 256;
      }


      address &= 0x00FFFF00; // address must be aligned to 256 byte !

       

      for ( counter = 0; counter < number_of_pages - 1; counter++ )
      {
        spi_flash_page_program ((address + 256*counter) ,(p_data_bytes +256*counter), 256);
      }
      // last page
      spi_flash_page_program ((address + 256*(number_of_pages - 1)) ,(p_data_bytes +256*(number_of_pages - 1)), last_data_block_size);

      }

       

      void spi_flash_sector_erase(uint32_t address)
      {
      uint8_t status, dummy_var;
      uint8_t addr0, addr1, addr2,addr3;
      (void)(dummy_var);
      addr0 = (uint8_t) (address & 0x000000FF);
      addr1 = (uint8_t) ((address & 0x0000FF00) >> 8);
      addr2 = (uint8_t) ((address & 0x00FF0000) >> 16);
      addr3 = (uint8_t) ((address & 0xFF000000) >> 24);

      ALLOW_TRANSFER; // if previous command has set EOQ

      PUSH_ENQ(WREN);   // write enable command (must be done before every write !!!)
      WAIT_UNTIL_RxFIFO_IS_NOT_EMPTY;
      POP(dummy_var);

      ALLOW_TRANSFER; // from this point all following write to PUSHR will be sent

      PUSH(SE); // Sector erase command
      WAIT_UNTIL_RxFIFO_IS_NOT_EMPTY;
      POP(dummy_var); // discard one RxFIFO item

      PUSH(addr3); // most-significant byte of address
      WAIT_UNTIL_RxFIFO_IS_NOT_EMPTY;
      POP(dummy_var);

      PUSH(addr2); // most-significant byte of address
      WAIT_UNTIL_RxFIFO_IS_NOT_EMPTY;
      POP(dummy_var);

      PUSH(addr1); // middle byte of address
      WAIT_UNTIL_RxFIFO_IS_NOT_EMPTY;
      POP(dummy_var);

      PUSH_ENQ(addr0); // least-significant byte of address
      WAIT_UNTIL_RxFIFO_IS_NOT_EMPTY;
      POP(dummy_var);

      do
      {
        status = spi_flash_read_status_register();
      }
      while (status & WIP); // wait here until bulk erase is done
      }

      void spi_flash_secure_region_erase(uint16_t address)
      {
      uint8_t status, dummy_var;
      uint8_t addr0, addr1, addr2,addr3;
      (void)(dummy_var);
      addr0 = (uint8_t) (address & 0x000000FF);
      addr1 = (uint8_t) ((address & 0x0000FF00) >> 8);
      addr2 = 0;

      ALLOW_TRANSFER; // if previous command has set EOQ

      PUSH_ENQ(WREN);   // write enable command (must be done before every write !!!)
      WAIT_UNTIL_RxFIFO_IS_NOT_EMPTY;
      POP(dummy_var);

      ALLOW_TRANSFER; // from this point all following write to PUSHR will be sent

      PUSH(SECRE); // Secured region erase command
      WAIT_UNTIL_RxFIFO_IS_NOT_EMPTY;
      POP(dummy_var); // discard one RxFIFO item

      PUSH(addr2); // most-significant byte of address
      WAIT_UNTIL_RxFIFO_IS_NOT_EMPTY;
      POP(dummy_var);

      PUSH(addr1); // middle byte of address
      WAIT_UNTIL_RxFIFO_IS_NOT_EMPTY;
      POP(dummy_var);

      PUSH_ENQ(addr0); // least-significant byte of address
      WAIT_UNTIL_RxFIFO_IS_NOT_EMPTY;
      POP(dummy_var);

      do
      {
        status = spi_flash_read_status_register();
      }
      while (status & WIP); // wait here until sector erase is done
      }

       

       

        • 1. Re: regarding calculatin of sectors for erase  before page write of normal and secured regions S25FL-L 128/256
          ApurvaS_36

          Hi Vignesh,

           

          Thank you for contacting Cypress.

          I need a little more clarification regarding your question. As far as I can understand you have a specific number of bytes of data and the 'size' variable is denoting the number of bytes of data. You want to check how many sectors will this data span to, so that before you perform the page program operation, you can erase those many sectors accordingly. Please correct me if I am wrong.

           

          For calculating the number of sectors required to be erased, one method could be to divide the data size with the size of one sector (4KB). If the obtained value is a float then round it off till the next integer value. In the function provided by you the maximum value that numSctrs can go till is 2, but there might be cases when size of data will be huge and it might span up till more than two sectors.

           

          In case of secure region erase, since the Security Region is just 1024 bytes, that is the maximum area that you can erase.

           

          Hope this helps.

           

          Regards,

          Apurva

          • 2. Re: regarding calculatin of sectors for erase  before page write of normal and secured regions S25FL-L 128/256
            vivc_4156156

            I need a little more clarification regarding your question. As far as I can understand you have a specific number of bytes of data and the 'size' variable is denoting the number of bytes of data. You want to check how many sectors will this data span to, so that before you perform the page program operation, you can erase those many sectors accordingly. Please correct me if I am wrong.

             

            ----  Yes Absolutely that is what I require

             

            For calculating the number of sectors required to be erased, one method could be to divide the data size with the size of one sector (4KB). If the obtained value is a float then round it off till the next integer value. In the function provided by you the maximum value that numSctrs can go till is 2, but there might be cases when size of data will be huge and it might span up till more than two sectors.

             

            --- yes I found that I had made a mistake

             

            In case of secure region erase, since the Security Region is just 1024 bytes, that is the maximum area that you can erase.

             

            if that is the case maximum of four sectors can be erased . correct me if I'm wrong . So divide that by 1024 incase of secure region and divide by 4096 in case of normal region

             

            for example if I have to write a page from address 20000 for a size of 40 bytes then I have to divide 40 / 4096

            and it ll result in a value of 0. am I right is this correct.

             

            and what should be done in case of a boundary considering one page is 256 bytes but its written over a boundary.

             

            can u pl guide me on these 2 scenarios. sector erase and page program seem to work separately.

            if I properly could conceive this I think I can integrate both.

             

            Thanks In Advance,

            Vignesh.V

            • 3. Re: regarding calculatin of sectors for erase  before page write of normal and secured regions S25FL-L 128/256
              ApurvaS_36

              Hi Vignesh,

               

              if that is the case maximum of four sectors can be erased . correct me if I'm wrong . So divide that by 1024 incase of secure region and divide by 4096 in case of normal region

              >>The Security Region comprises of 1024 bytes which are divided into four groups of 256 bytes each. The address mapping for the Security Region is provided on page 24 Section 6.5 Security region Address Space of the datasheet (https://www.cypress.com/file/316171/download ). The Security Region Erase SECRE (44h) command is capable of erasing each 256 byte block of security region separately. In order to figure out how many blocks of security region needs to be erased, the data size should be divided by 256. If the value obtained is a float it should be rounded up till the next integer.

              >>In case of normal region since Sector Erase (20h) command erases one 4KB sector at once, the data size should be divided by 4096. If the value obtained is a float it should be rounded up till the next integer.

               

              for example if I have to write a page from address 20000 for a size of 40 bytes then I have to divide 40 / 4096 and it ll result in a value of 0. am I right is this correct.

              >>40/4096 will give you 0.009765 and it should be rounded off to the next integer that is 1. So you should be erasing one sector which starts from address (say) 20000.

               

              and what should be done in case of a boundary considering one page is 256 bytes but its written over a boundary.

              >>In case of programming over a boundary if both pages fall in the same sector, one sector should be erased, else if both pages are in different sector, both sectors should be erased.

               

              >>All the above calculations are based on the assumption that programming will starts at the starting address of any sector.

               

              Regards,

              Apurva

              • 4. Re: regarding calculatin of sectors for erase  before page write of normal and secured regions S25FL-L 128/256
                vivc_4156156

                Hi,

                   Thanks . I have worked on and I tested as per ur suggestion. also I tested the functions separately I mean erase the sector separately and then re program the sector with different set of values.

                 

                For secure region erase the erase seems to happen cuz I able to read the buffer values as 255 after erase.

                and the value seems to be programmed after the erase.

                 

                1. For normal main flash array erase its not  happening as expected as all the read values after the erase doesn't seem to be 255

                and the status value read RDSR seems to be 2

                 

                do

                {

                  status = spi_flash_read_status_register();

                }

                while (status & WIP); // wait here until bulk erase is done

                 

                status returns as 2 for other which are working it returns as 0. If I do a chip erase then its getting erased.

                 

                2. For secure region where erase seems to work correctly I'm seeing a issue

                 

                 

                wrtflashBufsecr1[10] = {15,20,25,30,35,40,45,50,55,60};

                 

                uint8_t readflashbufsecr1[10];

                 

                uint8_t readbuf1[10];

                 

                spi_flash_secure_region_program(0x100,wrtflashBufsecr1,sizeof(wrtflashBufsecr1));

                 

                spi_flash_secure_region_read_data(0x100,readflashbufsecr1,sizeof(readflashbufsecr1));

                int loopCountRead;
                for(loopCountRead = 0; loopCountRead < sizeof(readflashbufsecr1); loopCountRead++)
                {
                char resultantflashreg3[50] = {0};
                sprintf(resultantflashreg3,"flash address read value = %d\r\n",readflashbufsecr1[loopCountRead]);
                }

                 

                if I read the first 10 values I get the first value as 255 the other values get written  omitting the last value

                for eg 255 ,15,20,25,30,35,40,45,50,55

                 

                if I read the first 11 values I get the first value as 255 the other values get written

                for eg 255 ,15,20,25,30,35,40,45,50,55,60

                why this could happen a shift of one array .? Any suggestions on these two issues would be appreciated.

                 

                Regards,

                Vignesh.V

                 

                 

                 

                 

                 

                • 5. Re: regarding calculatin of sectors for erase  before page write of normal and secured regions S25FL-L 128/256
                  ApurvaS_36

                  Hi Vignesh,

                   

                  For a better understanding of the problem could you please provide us the waveforms for both the erase operations and your full code.

                   

                  Regards,

                  Apurva

                  • 6. Re: regarding calculatin of sectors for erase  before page write of normal and secured regions S25FL-L 128/256
                    vivc_4156156

                    Hi,

                        Due to some reasons I m not able to give the entire project but I'm sharing the SPI interface file which is the point of discussion.

                    Unfortunately there are no test points for to get it effectively probed and as its to be taken out from the chip's pin directly at the moment unable to give you the waveform.

                     

                    Kindly let me know how to share because I'm not able to find any attach file here. I need to attach 2 text files

                     

                    Regards,

                    Vignesh.V

                    • 7. Re: regarding calculatin of sectors for erase  before page write of normal and secured regions S25FL-L 128/256
                      ApurvaS_36

                      Hi Vignesh,

                       

                      While typing your reply, you will see a "Use advanced editor" option at the top right corner of the message box. Click on it, and it will reload the message box. Upon reloading, you will find an "Attach" option at the bottom right corner of the box. You can attach files from there.

                       

                      Regards,

                      Apurva

                      • 9. Re: regarding calculatin of sectors for erase  before page write of normal and secured regions S25FL-L 128/256
                        ApurvaS_36

                        Hi Vignesh,

                         

                        Upon going through your code, I noticed that -

                         

                        • You are using 4 bytes of address inside spi_flash_sector_erase(uint32_t address) function. In order to be able to use 4 bytes of address with SE (20h) command you need to set the CR2V[0] bit to 1, else the device will ignore the SE command and erase operation will not happen.
                        • While calculating the number of sectors to be erased, you should also consider the case when num_of_sector = size / 4096 will come out to be a floating number which is greater than one (say 2.5). For that case also num_of_sector variable will have to be incremented by one, else num_of_sector will take the value as 2 and erase only 2 sectors.
                        • The values that you are reading from the secure region are actually correct. If you go to page 37 of the datasheet (https://www.cypress.com/file/316171/download ), you will find the table for latency code cycles. For security region read, 8 dummy cycles are required. Hence, for the first byte of data that if being read (255), the flash is not driving the SO. The flash starts driving the SO line after the completion of 8 dummy cycles. Hence the output obtained is an expected behavior of flash.

                         

                        Regards,

                        Apurva