This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

CC2541: How to use internal flash memory (basic read-write-erase operations)?

Part Number: CC2541


Hi,

I need some help with HalFlashRead / Write / Erase functions.

I'm trying to write and readback some small amount of data.

After read I get only 0xFF, I suppose, I'm reading from wrong address.

Here is part of code:

uint8 send_buf[10] = {0x01, 0x02, 0x03, 0x04, 0x05,0x06, 0x07, 0x08, 0x09, 0x10};
uint8 get_buf[10] = {0}; // inits as zeros

void main(void)
{
   //------------------- HAL PROTOTYPES
   //void HalFlashErase(uint8 pg);
   //HalFlashWrite(uint16 addr, uint8 *buf, uint16 cnt);
   //HalFlashRead(uint8 pg, uint16 offset, uint8 *buf, uint16 cnt);
   
   //lets say I need to write to page #4 (which is located at address 0x2000)
   
   uint8 pageNum = 4;
   uint16 pageAddr = 0x2000;
   HalFlashErase(pageNum);
   HalFlashWrite(pageAddr, send_buf, 10);
   
   //readback
   uint16 offset = 0; // as I understand, this should be non-zero when I'm trying read something at middle of page
   HalFlashRead(pageNum, offset, get_buf, 10);

  // and get_buf is filled with 0xFF
}

Please advice about what am I missing. 

  • Hello,

    Please add the following before and after each erase/write operations:

    halIntState_t cs;
    
    HAL_ENTER_CRITICAL_SECTION(cs);
    
    erase()
    
    HAL_EXIT_CRITICAL_SECTION(cs);
    
    HAL_ENTER_CRITICAL_SECTION(cs);
    
    write()
    
    HAL_EXIT_CRITICAL_SECTION(cs);

    Regards,

    AB

  • Hello,

    I have tried to do it, but still all 0xFF:

  • Am I set correct values for addres, page and offset?

    Not sure how to check write operation, maybe it has been written to some other place?

    UPDATE.

    I have update about HalFlashWrite:

    #define PAGE_SIZE_INTERNAL   2048
    #define TEST_BUF_SIZE        32
    #define WRITE_WORD_SIZE      4
    
    uint8 send_buff[TEST_BUF_SIZE] = {0x01, 0x02, 0x03, 0x04, 0x05,0x06, 0x07, 0x08, 0x09, 0x10};
    uint8 get_buff[TEST_BUF_SIZE] = {0}; // inits as zeros
    
    uint8 debug_buff[PAGE_SIZE_INTERNAL] = {0}; // readback entire page here
    
    void main(void)
    {
       halIntState_t cs;
      
       uint8  pageNum = 0x04; // page #4
       uint16 pageAddr = (PAGE_SIZE_INTERNAL * pageNum) / WRITE_WORD_SIZE; 
       uint16 offset = 0x0000; 
       
       HAL_ENTER_CRITICAL_SECTION(cs);
       HalFlashErase(pageNum);
       while( FCTL & 0x80 ); // wait for erase to complete  
       HAL_EXIT_CRITICAL_SECTION(cs);
       
       
       HAL_ENTER_CRITICAL_SECTION(cs);
       HalFlashWrite(pageAddr, send_buff, (TEST_BUF_SIZE / 4));
       HAL_EXIT_CRITICAL_SECTION(cs);
       
       //readback
       HalFlashRead(pageNum, offset, get_buff, TEST_BUF_SIZE);
    
       // test all pages for 0x01, 0x02 ... 0x10 values
       for (uint8 i = 0; i < 128; i++)
       {
          pageNum = i;
          HAL_ENTER_CRITICAL_SECTION(cs);
          HalFlashRead(pageNum, offset, debug_buff, 2048);
          HAL_EXIT_CRITICAL_SECTION(cs);
       }
      
       while(1);
    }

    but still, I'm getting all 0xFF:

    Furthermore, I have read all other pages.

    I have located my 0x01, 0x02 ... 0x10 sequence only at pageNum = 0.

    I'm pretty sure this is firmware page, not the data I have written...

    Please advice what am I missing.

  • Do you use BLE Stack? If so, I suggest you to use osal_nv_read and osal_nv_write to read and write internal flash.
  • no, I dont use it.

    Also I tried SWRC257 (CC2541_43_44_45_Peripherals_Software_Examples), but there are only dma examples in flash section.
  • Can you try changing the page number or offset that you write to and see if the result is the same?
    Also, from your calculations on the pagenum on line 118, it looks like you are writing to address 0x00000800. This is in fact page 0, page 4 starts on address 0x00004000. You can better check the flash by using the our flash programmer tool, and see the whole flash and even write to it. Please check and confirm that you are writing to the address you are sending in the write command using our tool.

    Regards,
    AB
  • Hi,

    Thanks for update.

    I'm writing to program-write address 0x0800, not physical, as it described in HalFlashWrite function:

    /**************************************************************************************************
     * @fn          HalFlashWrite
     *
     * @brief       This function writes 'cnt' bytes to the internal flash.
     *
     * input parameters
     *
     * @param       addr - Valid HAL flash write address: actual addr / 4 and quad-aligned.
     * @param       buf - Valid buffer space at least as big as 'cnt' X 4.
     * @param       cnt - Number of 4-byte blocks to write.
     *
     * output parameters
     *
     * None.
     *
     * @return      None.
     **************************************************************************************************
     */
    void HalFlashWrite(uint16 addr, uint8 *buf, uint16 cnt)

    As I understand, this address should be (physical address / 4).

    So, it comes out that physical address is  (2048 * 4) .

    And write address is (2048 * 4 / 4) = 2048 = 0x0800

    "page 4 starts on address 0x00004000"

    Please explain how it is calculated? I'm totaly confused, since user manual http://www.ti.com/lit/ug/swru191f/swru191f.pdf at parapraph 6.1 says that page size is 2048kB (I have 256kB cc2541).

    So page #4 should have physical address 2048*4 = 8192 = 0x2000 , isn't?

    I have checked internal flash by SmartRF Flash Programer (read flash into hex file), all data after address ~0x00170 is empty (0xFFs)

     

  • Hello,

    You are correct in what you are saying, I confused your device with another one.
    Have you taken a loot at the osal_NVS drivers?

    Regards,
    AB
  • After all, I have written data, when initialized dma at channel 0...
    I think this moment is pretty not obvious, since I haven't find any remarks about this and just had to roam in attempts to find out reason.