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: Store data in Flash

Other Parts Discussed in Thread: CC2541

Hi All:

    The CC2541 is a peripheral, it send sensor data to the Phone which is a central.

    When the CC2541 doesn't connect with the phone, it will collect data from sensor and save them in flash.  the CC2541 will send the saved data to the phone as long as they are connected.

     I learn that there is only 1KB~2KB space that can be used by osal_snv_write. I chose the CC2541 with 256KB Flash, and the .map file after compile shows that only about 130KB memory used. Could I use the left space (nearly 100KB) to store data.

      If I have more than 50KB data to store, Should I have to save them into the external Flash ?  Could I use the left flash in CC2541?

Thanks a lot !

  • Hello Yunlong,

    As far as I understood, yes it it possible to use the flash memory to store additional data. Through osal_snv_write you can store up to 3KB of data. If you need more space you should consider using HalFlashWrite to access the free space from flash memory. However, I tried a lot to do that by reading several posts in this forum, but with no luck. Can someone more expert make it clear for us ?

    Thnx.

    F.

  • Check this thread: http://e2e.ti.com/support/wireless_connectivity/f/156/p/279926/977092.aspx#977092 

  • Hello Peter and thank you for responding, 

    I checked what you proposed and also this explanation provided by you (http://e2e.ti.com/support/wireless_connectivity/f/538/p/324669/1130899.aspx) which is really helpful. However, I have concluded to the following: 

    1) Using osal_snv_read and osal_snv_write didn't work for me.

    #define BLE_NVID_TEST 0x80
    static uint32 iWrite = 0xcafe;
    static uint32 iRead = 0x0;
    VOID osal_snv_write(BLE_NVID_TEST, sizeof( uint32 ), &iWrite );
    VOID osal_snv_read( BLE_NVID_TEST, sizeof( uint32 ), &iRead );

    Do I missing something there ? I thought that that should be the easy way ;)

    2) Alternative, using HalFlashEraseHalFlashReadHalFlashRead I got better results but still with some problems. 

    HalFlashErase seems that does not work as expected. In my understanding, HalFlashErase takes as argument the page number i.e. 112 to declare which page to erase, but nothing happened.

    Instead of HallFlashErase I used the following code that worked fine

    unsigned char erase_page_num = 112; /* page number to erase, here: flash page #112 */
    /* Erase one flash page */
    EA = 0; /* disable interrupts */
    while (FCTL & 0x80); /* poll FCTL.BUSY and wait until flash controller is ready */
    FADDRH = erase_page_num << 1; /* select the flash page via FADDRH[7:1] bits */
    FCTL |= 0x01; /* set FCTL.ERASE bit to start page erase */
    while (FCTL & 0x80); /* wait until flash write has completed (~20 ms) */
    EA = 1; /* enable interrupts */

    which really erases page #112 (verified by reading the memory through smart RF Flash programmer)

    uint8 data[]={0xfa, 0xce, 0xb0, 0x0c, 0xca, 0xfe, 0xba, 0xbe};
    
    HalFlashWrite(0xE400, data, 2);
    while(FCTL&0x80); // make sure that write operation is completed

    and HalFlashWrite writes data at bank #7. 

    I tried 

    HalFlashRead(erase_page_num, 0, temp, 4);     

    but it never returns and I can not figure out why. Do you have any idea what I'm a doing wrong ? Is there any alternative approach to read data from flash ? 

    Thank you

  • For your first question, check the OSAL API guide, chapter 10. IDs 0x61-0x80 are reserved for security. You need to use an ID in the range 0x401 -0xFFF for app data.

    For your second questions, I assume a reading the User's Guide and the comments in the stack will help you with hal function usage.

    Never underestimate the power of reading.

  • Hello Peter, 

    Searching the forum I had found that IDs should be in the range 0x80 - 0xFF. Anyway, I tried also the values you proposed but the problem remains. 

    For the HalFlashRead() I couldn't find the way to read data. Writing data works fine, but unfortunately I can not get any data bank. Any help will be appreciated. 

    F.

  • Ah, You're right. I was reading the NV chapter. the SNV range is 0x80-0xFE.Shows what I know

    Anyways your snv code works.  I copied your code character for character into a clean SimpleBLEPeripheral project from the V1.4 stack. I put your code in at the start SimpleBLEPeripheral_Init(). I also had to #include "osal_snv.h"

    The code I copied 

    #define BLE_NVID_TEST 0x80
    static uint32 iWrite = 0xcafe;
    static uint32 iRead = 0x0;
    VOID osal_snv_write(BLE_NVID_TEST, sizeof( uint32 ), &iWrite );
    VOID osal_snv_read( BLE_NVID_TEST, sizeof( uint32 ), &iRead );

    It worked perfectly

    As far as halFlash Erase is concerned, try inserting the line while(FCTL & 0x80);  This should force the core to wait for the flash erase to finish.

    Your hal flash write address is E400. This is the word address. The actual address is 0x39000. This is on page 114, but you are reading from page 112. 112 actual address starts at 0x38000 through 0x387fff (2048 bytes).

  • I 'm testing the code on a modified version of SimpleBLECentral. I don't think that it differs a lot from SimpleBLEPeripheral - - the osal_snv.h is already included. The only difference is that the code is not called within SimpleBLECentral_Init but from another function. I'll test it from SimpleBLECentral_Init() and I 'll let you know. 

    Now, regarding HalFlashRead, I assume that we write on 0x79000 which leads to the 7*0x8000 + 0x9000 - 0x8000 (according to a previous post). This leads to the 0xE400 and I verified the data when reading through SmartRF Flash Programmer (hex file dump). I thought that this belongs to page 112, however I tried what you proposed (114) but still does not work :(

    uint8 buf[] = { 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC };
    
    HalFlashWrite(0xE400, simpleBLEDevList[search].addr, 2); // This works fine!
    
    HalFlashRead(114, 0, &buf, 2); // 112 before your post
    HalFlashWrite(0xE404, buf, 2);

    When reading from SmartRF I 'm finding the 0xCCCCCCCC value @ 0xE404.

     

     

    What do you think ? 

  • Hi, 

    Anybody could please tell me why the cc2541 flash application address range is only 3KB as  cc2541 has the 256KB storage flash?

  • Hi Ankit,

    The discussion here is about dedicated flash part for storing data during run time. The 256KB flash includes the complete software solution (BLE protocol stack, application, profiles, drivers etc.). 

    Best Regards

    Joakim

  • Hi Joakim,

                    Thank you for reply. I have one more question to ask & that is if i want to store data which requires more than 20 KB flash in my application then how i store that much of data into flash. As i gone through the OSAL_API.pdf it stated that in non volatile memory system there is only 3KB (0x0401 - 0x0FFF) of flash is used for application space.Why it is ?.  According to memory map of simplebleperipheral application the program memory required is approx. 120k  then how can use the remaining flash for my application?

  • Hi Ankit,

    The flash space dedicated for storing values in flash from the application is kept minimal in order to fit more code. If you have free space, feel free to modify the linker file to dedicate more flash for the SNV.

    Best Regards

    Joakim

  • Hi Joakim,

    I don't understand the memory map  explained in cc2541 user guide. I only see the two flash memory bank of 64 KB i.e. one for CODE & the other for XDATA memory which totals only 128 KB but cc2541 has 256 kb flash. Where is the remaining flash map. How exactly the memory map is? Will you please tell me how i can use my 30 KB data into the flash? & also the how to  change the linker file to dedicate more flash for the snv?. Thanks