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.

LAUNCHXL-CC26X2R1: Read and Write variables into NV-RAM

Part Number: LAUNCHXL-CC26X2R1
Other Parts Discussed in Thread: CC2630, CC2650, Z-STACK

Hi TI team,

I want to read and write the value of variables into NVRAM. Do you have any API that I can use and provide some example code to me for reference?

Thank you very much

  • You can try to use zclport_readNV/zclport_writeNV
  • Hi YK,
    What range of id - NV ID and subId - NV ID can I use for the function of zclport_readNV/ zclport_writeNV?
    Do you have some example code of zclport_writeNV and zclport_readNV for me to reference?
    Thanks
  • If I am correct, NV ID range is between 0x0280 to 0x02FF and you can keep subId - NV ID as 0.
  • Hi YK,
    I found you mentioned the range of NV ID is reserved for APS Link Key Table entries in the file of zcomdef.h
    // NV Items Reserved for APS Link Key Table entries
    // 0x0201 - 0x02FF
    #define ZCD_NV_APS_LINK_KEY_DATA_START 0x0201 // APS key data
    #define ZCD_NV_APS_LINK_KEY_DATA_END 0x02FF

    I wonder whether I can still use the range of 0x0280 to 0x02FF or not??

    Another question:
    Does the data will be erased(data will disappear) when I call the function of bdb_resetLocalAction if I use the function of zclport_writeNV to write a data?

    Thanks
  • I think I give you the information on CC2650/CC2630. For CC2652/CC1352, it should be 0x0401 -0x0FFF. No, those custom NV ID won't be erase after you call bdb_resetLocalAction.
  • Hi YK,
    Do I have way to erase this NV ID or I just can use the function of zclport_writeNV to write the initial value for my data??
    Thanks
  • You can can usezclport_writeNV to write the initial value for your data.
  • Hi YK,
    I used below code to init,write and read a nvram after I pressed a button. But it seems did not work. I outputted the result of reading nvram and the value was not correct. Do I miss somethings?

    I also checked the status of init(NV_ITEM_UNINIT  0x09) ,write(NV_ITEM_UNINIT  0x09) and read(SUCCESS  0x00). 


    /*read/write nvram*/
    uint8 join_result;
    uint16_t customNvID=0x0402;;
    //join_result=0x01;

    uint8 result_read;
    zclport_initializeNVItem(customNvID,0,1,(void*)&join_result);

    //printf("result_init=%02x\n",result_init);
    //fflush(stdout);

    join_result=0x00;
    zclport_writeNV(customNvID, 0, 0, 1, (void*)&join_result);
    //printf("result_write=%02x\n",result_write);
    //fflush(stdout);

    uint8 temp_value;
    result_read=zclport_readNV(customNvID, 0, 0, 1, (void*)&temp_value);
    printf("result_read=%02x temp_value=%02x\n",result_read,temp_value);
    fflush(stdout);

    Thanks

  • What's the return code of your zclport_writeNV and zclport_readNV?
  • Hi YK,
    The return code of zclport_writeNV is NV_ITEM_UNINIT(0x09) and zclport_readNV is SUCCESS(0x00)

    It seems I did not write successfully.

    Thanks

  • Try to call zclport_initializeNVItem before you use it.
  • Hi YK,
    I already called it. You can refer to my code. I need to call init function every times that I want to use the read/write??

    Or I need to put the function of zclport_initializeNVItem into init APP?

    static void zclSampleSw_processKey(uint8 keysPressed)
    {

    if(keysPressed == KEY_RIGHT)
    {


    /*read/write nvram*/
    uint8 join_result;
    uint16_t customNvID=0x0402;;
    //join_result=0x01;

    uint8 result_init;
    uint8 result_write;
    uint8 result_read;
    result_init=zclport_initializeNVItem(customNvID,0,1,(void*)&join_result);

    printf("result_init=%02x\n",result_init);
    fflush(stdout);

    join_result=0x00;
    result_write=zclport_writeNV(customNvID, 0, 0, 1, (void*)&join_result);
    printf("result_write=%02x\n",result_write);
    fflush(stdout);

    uint8 temp_value;
    result_read=zclport_readNV(customNvID, 0, 0, 1, (void*)&temp_value);
    printf("temp_value=%02x result_read=%02x\n",temp_value,result_read);
    fflush(stdout);
    }
    }
    Thanks

  • Can you try to use 0x0303 instead of 0x0402 as NV ID to test and see if it works?
  • Hi YK,
    I tried to use the 0x0303 instead of 0x0402 and it works.
    But why? I should be able to using the 0x0402 in the range of 0x0402~0x0FFF
    Thanks
  • I suspect the comments in source codes are wrong but I am sure 0x0303 is in correct range. I just want to confirm this so I ask you to test it. Will need TI employee to help on providing correct range.

    Do you know correct NV ID range reseved for application usage?
  • Hi YK,
    Noted.

    Hi Ryan Brown1,
    Could you help to provide the correct NV ID range that was reserved for application?

    And Do we have any API that I can use to unset a NV ID?

    Do I have any way can unset all NV ID to default on reference board(CC2652)? I tired to pressed the reset button on the reference board of CC2652 to reset NV ID that I already write some data but it did not work.


    Thanks

  • Hi YK, Lawrence,

    Each NV item is 8 bytes long (four words) so 0x400 items is 8 kB (or two pages) of flash memory which is all that is allocated by default in hal_board_cfg.h.  Please try increasing HAL_NV_PAGE_CNT if you would like to access NV item space above 0x400.  As for clearing NV items on reset:

    zstack_sysResetReq_t resetReq; 
    restReq.newNwkState = true;
    (void)Zstackapi_sysResetReq(zclSampleLight_Entity, &resetReq);
    

    This should perform a factory reset so long as newNwkState is set to true.  Here is a link to the Z-Stack API guide as well although we do recognize that there are some APIs missing which we are currently working to address:

    Regards,

    Ryan

  • if we don’t increase HAL_NV_PAGE_CNT, which range of NV ID is reserved for application?
  • Hi Ryan,

    Besides, the YK's problems. I want to ask one more question.

    What's the differences between the function of bdb_resetLocalAction() and the API of Zstackapi_sysResetReq?

    I know the the function of bdb_resetLocalAction only can reset the setting of zigbee.

    The API of Zstackapi_sysResetReq can reset(cleaning) the setting of zigbee and NV Items or it only can reset(cleaning) the setting of NV items??

    Thanks

  • bdb_resetLocalAction() provides application interface to perform BDB Reset to FN. Zstackapi_sysResetReq is Z-Stack API to send a System Reset Request through the iCall dispatcher to the ZStack Thread.
  • Hi YK,
    I wonder whether the Zstackapi_sysResetReq can reset the Zigbee's setting and NV items?

    It seems cannot reset the NV items Iin my testing.
    Thanks

  • Zstackapi_sysResetReq can aso clear netowrk information in NV.
  • Hi YK,
    How about other NV items that I modify it by myself not networking information such as 0x0303(NV ID)?

    It seems cannot reset other NV items that are not networking information in my testing.
    Thanks

  • I suppose you can use those are not defined NV ID in zcomdef.h.
  • Hi Ryan,
    The API of Zstackapi_sysResetReq can reset the setting of zigbee's information in the NV items.
    But I could not use this API to reset some NV items(not zigbee's information) that I modified it by myself.
    Do we have any API to reset or delete these NV items?
    Thanks
  • You can use the following code to clear netowrk information with Zstackapi_sysResetReq

    zstack_sysResetReq_t restReq;
    restReq.newNwkState = true;
    Zstackapi_sysResetReq(zswEntity, &restReq);
  • Hi YK
    I know I can use the API of Zstackapi_sysResetReq to clear netowrk information(Zigbee).
    But I want to clean the NV items(not network information) that are modified by myself via zclport_writeNV.
    I want to know whether there are any APIs that I can use for this purpose.
    Thanks
  • There is no such API to clear your custom NV ID. You have to use zclport_writeNV to do it by yourself.
  • Hi YK,
    Well Noted.
    Thanks
  • Hi YK,

    Although not innately "reserved for application", NV IDs 0x330 through 0x3FF are unused and can be considered.

    Regards,
    Ryan
  • Thanks Ryan. I would like to know is this range reserved for application and won’t be used by Z-Stack core? I would suggest you to list this in next released document.
  • Hi YK,

    If you look at zcomdef.h there is ca comment that says:

    // NV Items Reserved for applications (user applications)
    // 0x0401 – 0x0FFF

    My recommendation is to use this range of reserved NV items even if for example 0x0303 is not used now, this Item could be used in future versions of the stack for new features for example, so there is no guarantee that for items outside the range of 0x0401 – 0x0FFF to be available in the future.

  • Does this mean we have to increasing HAL_NV_PAGE_CNT? If so, do you plan to increasing HAL_NV_PAGE_CNT by default in next Z-Stack release and add this in document?
  • No, just take care of use NV items from 0x0401 – 0x0FFF to avoid issues with reserved items fro the stack in the future.
  • but Lawrence had tested 0x0401 and it didn’t work. That’s why I suggest him to use 0x0303 instead of 0x0401 and suggested to ncreasing HAL_NV_PAGE_CNT if we want to use 0x0401. Are you sure we don’t have to ncreasing HAL_NV_PAGE_CNT if we want to use 0x0401?
  • Hi YK,

    I was looking to the example code and is writen in a wrong way, take a look to zclGeneral_AddScene() in zcl_port.c, zclSceneNVID is equal to ZCL_PORT_SCENE_TABLE_NV_ID and the value is defined in zcl_port.h as 0x0001. The zclport NV api saves items in a different way as before since now you have two ID's that gives the location of an NV item.

    From zcl_port.h:

    /** Default ZCL Scene Table NV Item ID */
    #define ZCL_PORT_SCENE_TABLE_NV_ID 0x0001
    /** Default ZCL Proxy Table NV Item ID */
    #define ZCL_PORT_PROXY_TABLE_NV_ID 0x0002
    /** Default ZCL Sink Table NV Item ID */
    #define ZCL_PORT_SINK_TABLE_NV_ID 0x0003

    The code that works is this:

    #define CUSTOM_NV_ID   0x0004
    
    static void zclSampleSw_processKey(uint8 keysPressed)
    {
      if(keysPressed == KEY_RIGHT)
      {
        /*read/write nvram*/
        uint8 join_result;
        uint16_t customNvID = CUSTOM_NV_ID;
        //join_result=0x01;
    
        uint8 result_init;
        uint8 result_write;
        uint8 result_read;
        result_init=zclport_initializeNVItem(customNvID,0,1,(void*)&join_result);
    
        printf("result_init=%02x\n",result_init);
        fflush(stdout);
    
        join_result=0x00;
        result_write=zclport_writeNV(customNvID, 0, 0, 1, (void*)&join_result);
        printf("result_write=%02x\n",result_write);
        fflush(stdout);
    
        uint8 temp_value;
        result_read=zclport_readNV(customNvID, 0, 0, 1, (void*)&temp_value);
        printf("temp_value=%02x result_read=%02x\n",temp_value,result_read);
        fflush(stdout);
      }
    }
    

  • Do you mean we can use custom NV ID after 0x0004~ in application when you use API zclport_writeNV and zclport_readNV? Can you confirm this?
  • Yes, you can also take a look to Green power proxy table in gp_ProxyTblInit(), this function is in gp_proxy.c, there the proxy table is initialized with ZCL_PORT_PROXY_TABLE_NV_ID as NV id with a number of elements equal to GPP_MAX_PROXY_TABLE_ENTRIES, this means that the "subId" will start from 0 to GPP_MAX_PROXY_TABLE_ENTRIES.

    uint8 gp_ProxyTblInit( uint8 resetTable )
    {
      uint8 i;
      uint8 status;
      uint8 emptyEntry[PROXY_TBL_LEN];
      
      gp_ResetProxyTblEntry( emptyEntry );
      
      for ( i = 0; i < GPP_MAX_PROXY_TABLE_ENTRIES ; i++ )
      {
        status = zclport_initializeNVItem( ZCL_PORT_PROXY_TABLE_NV_ID, ( ZCD_NV_PROXY_TABLE_START + i ),
                                          PROXY_TBL_LEN,
                                          emptyEntry );
        
        if ( ( status != SUCCESS ) && ( status != NV_ITEM_UNINIT ) )
        {
          return status;
        }
        else if ( ( status == SUCCESS ) && ( resetTable == TRUE ) )
        {
          status = zclport_writeNV( ZCL_PORT_PROXY_TABLE_NV_ID, ( ZCD_NV_PROXY_TABLE_START + i ),
                                    0,
                                    PROXY_TBL_LEN,
                                    emptyEntry );
        }
      }
      return status;
    }

  • Thanks for elaboration. Since this is one of frequently asking question, I would like to suggest you to put this into the documents of next Z-Stack release.
  • Hi YK,
    I want to double confirm it.
    According to Jose Maria Alvarez, we can directly use the value of 0x0004 and after it if I use API zclport_writeNV and zclport_readNV.
    And It also will not affect other Zigbee's NV items? Am I right?
    Thanks
  • Yes, that's confirmed by Jose.
  • Hi YK and Jose,
    Well Noted.
    Thanks
  • Hi YK,

    I will find a suitable place with which to address this inside our documentation but it is mentioned in Section 9.6.3 of the Z-Stack Overview section of the User's Guide.  One should be able to reference the doorlockcontroller examples for a use-case scenario of implementing custom NV items into their application.  The maximum values for this NV id's are defined in nvoctp.c:

    // Maximum ID parameters - must be coordinated with header compression,
    // Increasing these limits requires modification of the readHdr() function
    #define NVOCTP_MAXSYSID   0x003F  //  6 bits
    #define NVOCTP_MAXITEMID  0x03FF  // 10 bits
    #define NVOCTP_MAXSUBID   0x03FF  // 10 bits
    #define NVOCTP_MAXLEN     0x03FF  // 10 bits

    Regards, Ryan

  • I had read Section 9.6.3 of the Z-Stack Overview section of the User's Guide but there is no specific descriptions for user to know exact safe NV ID range for user application and that's why I suggest you to document it more clearly and specifically.