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.

CC2640R2F: Using NVS drivers in ProjectZero

Part Number: CC2640R2F
Other Parts Discussed in Thread: BLE-STACK

Hello,

I am working on a small weather station project where I will be collecting samples from at least four different sensors at five minute intervals. I was able write samples from four ADC sensors into non-volatile storage, then read them back in an empty project. My problem is that when trying to use the NVS drivers in ProjectZero, my board will freeze up in the ProjectZero_init() function when NVS_init() is called.My configuration for NVS in Board.h and CC2640R2_LAUNCHXL.c seem to be the same in both projects, so I am not sure what the problem is.

I would like to be able to use about 16 KB of storage so I can leave my device to collect data for several days (ideally up to a week) at a time, which seemed very possible from the NVS example project. Is this too much space to ask for with only 128KB of flash for ProjectZero code and data? Is there an alternative to the NVS drivers I have missed? 

Thanks,

Matt

  • Hi Matt,

    Can you provide a bit more information so that we can best assist?
    What exactly are the steps to reproduce your issue, what files did you change, what steps need to be done? Ideally provide a minimum list of steps to show the condition using a stock project_zero app on a LaunchPad.

    NVS is recommended for accessing the NV of the device. If you are willing to share some space with the pairing and bonding keys, you can use osal_snv APIs to store your information (see BLE-Stack User's Guide for more information).

    Alternatively you can create a separate NVS region for your configuration data.
  • Hello Sean,

    Sorry for the vagueness of my initial post. I'll list the steps I took to add NVS to a stock project_zero.

    First  I made sure to include the driver, and initialize a handle, attrs, and params objects near the top of project_zero.c

    #include <ti/drivers/NVS.h>
    
    // NVS handle, params, and attrs objects
    NVS_Handle nvsHandle;
    NVS_Attrs regionAttrs;
    NVS_Params nvsParams;

    Next I added the NVS config structures into the CC2640R2_LAUNCHXL.c file so that I had a region of the flash reserved for NVS

    /*
     *  =============================== NVS ===============================
     */
    #include <ti/drivers/NVS.h>
    #include <ti/drivers/nvs/NVSSPI25X.h>
    #include <ti/drivers/nvs/NVSCC26XX.h>
    
    #define NVS_REGIONS_BASE 0x1B000
    #define SECTORSIZE       0x1000
    #define REGIONSIZE       (SECTORSIZE * 4)
    #define VERIFYBUFSIZE    64
    
    static uint8_t verifyBuf[VERIFYBUFSIZE];
    
    /*
     * Reserve flash sectors for NVS driver use by placing an uninitialized byte
     * array at the desired flash address.
     */
    #if defined(__TI_COMPILER_VERSION__)
    
    /*
     * Place uninitialized array at NVS_REGIONS_BASE
     */
    #pragma LOCATION(flashBuf, NVS_REGIONS_BASE);
    #pragma NOINIT(flashBuf);
    static char flashBuf[REGIONSIZE];
    
    #elif defined(__IAR_SYSTEMS_ICC__)
    
    /*
     * Place uninitialized array at NVS_REGIONS_BASE
     */
    __no_init static char flashBuf[REGIONSIZE] @ NVS_REGIONS_BASE;
    
    #elif defined(__GNUC__)
    
    /*
     * Place the flash buffers in the .nvs section created in the gcc linker file.
     * The .nvs section enforces alignment on a sector boundary but may
     * be placed anywhere in flash memory.  If desired the .nvs section can be set
     * to a fixed address by changing the following in the gcc linker file:
     *
     * .nvs (FIXED_FLASH_ADDR) (NOLOAD) : AT (FIXED_FLASH_ADDR) {
     *      *(.nvs)
     * } > REGION_TEXT
     */
    __attribute__ ((section (".nvs")))
    static char flashBuf[REGIONSIZE];
    
    #endif
    
    /* Allocate objects for NVS and NVS SPI */
    NVSCC26XX_Object nvsCC26xxObjects[1];
    NVSSPI25X_Object nvsSPI25XObjects[1];
    
    /* Hardware attributes for NVS */
    const NVSCC26XX_HWAttrs nvsCC26xxHWAttrs[1] = {
        {
            .regionBase = (void *)flashBuf,
            .regionSize = REGIONSIZE,
        },
    };
    
    /* Hardware attributes for NVS SPI */
    const NVSSPI25X_HWAttrs nvsSPI25XHWAttrs[1] = {
        {
            .regionBaseOffset = 0,
            .regionSize = REGIONSIZE,
            .sectorSize = SECTORSIZE,
            .verifyBuf = verifyBuf,
            .verifyBufSize = VERIFYBUFSIZE,
            .spiHandle = NULL,
            .spiIndex = 0,
            .spiBitRate = 4000000,
            .spiCsnGpioIndex = CC2640R2_LAUNCHXL_GPIO_SPI_FLASH_CS,
        },
    };
    
    /* NVS Region index 0 and 1 refer to NVS and NVS SPI respectively */
    const NVS_Config NVS_config[CC2640R2_LAUNCHXL_NVSCOUNT] = {
        {
            .fxnTablePtr = &NVSCC26XX_fxnTable,
            .object = &nvsCC26xxObjects[0],
            .hwAttrs = &nvsCC26xxHWAttrs[0],
        },
        {
            .fxnTablePtr = &NVSSPI25X_fxnTable,
            .object = &nvsSPI25XObjects[0],
            .hwAttrs = &nvsSPI25XHWAttrs[0],
        },
    };
    
    const uint_least8_t NVS_count = CC2640R2_LAUNCHXL_NVSCOUNT;

    I also made sure to add the define statements for the NVS region name mapping in Board.h

    #define Board_NVS0              CC2640R2_LAUNCHXL_NVSCC26XX0
    #define Board_NVS1              CC2640R2_LAUNCHXL_NVSSPI25X0

    After adding this code I have no problems with building or debugging, but adding NVS_init() into the ProjectZero_init() function causes my device to not advertise at all. This setup for the NVS is the same as what I used in my empty project, at it also seems to be the same in the stock nvs example project. Let me know if this is enough information to help.

  • Hi Matt,

    Thanks for the information. I apologize for the long response delay. I have looked into your issue and have been able to reproduce it.
    Looking into the cause, I have found that it is because the NVS sectors are interfering with the placement of the SNV sectors (which the BLE-Stack uses for pairing and bonding information). The SNV sectors cannot be relocated unless FEATURE_OAD is defined in the stack project's preprocessor symbols.

    I am able to confirm that after adding that symbol to the stack project and rebuilding, the device is able to advertise.

    I have updated the known issues page here:
    processors.wiki.ti.com/.../CC2640R2_Porting_Projects
  •  Hi,

    I'm also facing the same issue. How to add FEATURE_OAD in the stack project's preprocessor symbols. I had done as shown in above image but still its hanging.

    Regards,

    Vijay Rakesh

  • Vijay ,

    Open that same window for the project titled project_zero_cc2640r2lp_stack_library, add the FEATURE_OAD symbol there.

    In summary right click on project_zero_cc2640r2lp_stack_library --> properties --> ARM Compiler --> Predefined Symbols --> FEATURE_OAD

    Then rebuild the project and load it.
  • Hi Sean,

    Thanks for the reply, It's working.

    Regards,
    Vijay Rakesh
  • Hi Sean,

    Does NVS_erase and NVS_write calls will effect the scan response data? After those operations scan response data is not advertising.

    Regards,
    Vijay Rakesh.
  • Hi Vijay,

    Have you attached a debugger and checked the state of the device after these calls or single stepped through them?
  • Hi Sean,

    I had attached the debugger but i cant find anything, After receiving data i'm storing in to NVS and updating to advertisement data (Local Name) and it starts the advertising the updated Local Name but the scan response data is disappeared (shown in screenshots).

      

    Regards,

    Vijay Rakesh

  • This solved my issues, thank you!