3. Non-Volatile Memory Storage

This section analyzes the way the SDK handles the Non-Volatile Memory Storage. The DA1468x SDK defines a set of storage classification rules that allow proper storage handling and budget estimation. For each storage type, a dedicated region is mapped in the flash memory which can be identified by a unique ID. Table 2 explains the available partition IDs, defined in /sdk/adapters/partition_def.h. The exact memory mapping depends on the flash memory model (size, sector size) and needs to be specified at compile time. The SDK provides a few ready-to-use partition tables that can be found under /sdk/config. By default, the 1M model is enabled and perfectly fits in the ProDK QSPI Winbond W25Q80EW 8-Mbit flash memory (1 Mbyte with sectors of 4 kB). For more information on the used Flash, read its Datasheet. Other partition tables for different sized flash memories (on a custom board) can be selected by declaring the appropriate macro in /config/custom_config_qspi.h.

Table 2 NVMS Partition IDs
Tag ID Description
NVMS_FIRMWARE_PART This entry is used during a non-SUOTA/SUOTA enabled application. When in a non-SUOTA application, this entry contains the current application firmware version, whereas in a SUOTA application, it contains the bootloader that manages the firmware update process.
NVMS_PARAM_PART This entry is used during a non-SUOTA/SUOTA enabled application for storing BLE related information (for example, the BD address of the device).
NVMS_BIN_PART This entry is used during a non-SUOTA enabled application for storing binaries.
NVMS_LOG_PART This entry is used during a non-SUOTA/SUOTA enabled application for logging events or values.
NVMS_GENERIC_PART This entry is used during a non-SUOTA/SUOTA enabled application for storing generic data such as bonding data. This is the only area marked as VES (Virtual EEPROM).
NVMS_PLATFORM_PARAMS_PART This entry is used during a SUOTA enabled application for storing platform-specific information.
NVMS_PARTITION_TABLE This entry is used during a non-SUOTA/SUOTA enabled application and contains information on the partition table used.
NVMS_FW_EXEC_PART This entry is used during a SUOTA enabled application and contains the current application firmware version.
NVMS_FW_UPDATE_PART This entry is used during a SUOTA enabled application and contains the new updated firmware version.
NVMS_PRODUCT_HEADER_PART This entry is used during a SUOTA enabled application and contains information on the target device.
NVMS_IMAGE_HEADER_PART This entry is used during a SUOTA enabled application and contains information on the software version.

The partition layout significantly differs between a SUOTA enabled build and a non-SUOTA enabled build, as depicted in Fig. 8.

'Flash memory partition layouts'

Fig. 8 Partition Layout for a non-SUOTA (left) and SUOTA (right) Enabled Application

3.1. Creating Custom Partition Tables

This section describes the steps required to successfully alter a partition table. It utilizes the default 1M flash memory model for a non-SUOTA enabled application and slightly modifies it. It splits the default NVMS_BIN_PART into three equal-sized areas. To do this, the SDK provides some macros in /sdk/adapters/include/flash_partitions.h.

'Configuring the MCP4822 DAC Slave Device'

Fig. 9 Modifying the 1M Model Partition Table

Warning

  1. The size of a partition entry should be multiple of sector size, 4 kB in our case (this is device-specific information).
  2. The first declared entry should always be the place where the firmware dwells. The minimum allowable size is 128 kB and it should be 64 kB aligned. Keep in mind that, the DA1468x platforms has a read-only cache controller. That is, cache will not be updated when a cacheable area is re-written.
  3. It is recommended not to change the default location of the NVMS_PARTITION_TABLE. However, if you do change the location, the starting address should be declared in /sdk/adapters/include/flash_partitions.h, using the PARTITION_TABLE_ADDR macro.

  1. Establish a connection between the target device and your PC through the USB2(DBG) port of the motherboard.
  2. Import a non-SUOTA demonstration example, for example, the freertos_retarget found in the SDK of the DA1468x family of devices.

Note

It is essential to import the folder named scripts to perform various operations such as building, debugging, downloading.

  1. In the target application, create a new folder as well as a header file under sdk/config/ directive. It should look like this:
'Creating a Custom Partition Table'

Fig. 10 Creating a Custom Partition Table

  1. In the newly created header file (My_Custom_1M.h) add the following code to define the new partition scheme:
/*
 * General form of the PARTITION2 (start, size, id, flags)
 *
 * \[start]  The physical start address of the partition entry in Flash
 * \[size]   The size of the partition entry in bytes. Since the underlying flash consists of
 *           4K sectors, a partition entry should be multiple of 4 kBytes (0x1000)
 *
 * \[id]     A value from the [nvms_partition_id_t] enumerator or a custom one.
 * \[flags]  Indicates the permission attributes. Valid values are:
 *
 *           0, PARTITION_FLAG_READ_ONLY, PARTITION_FLAG_VES
 */

PARTITION2( 0x000000 , 0x07F000 , NVMS_FIRMWARE_PART        , 0 )
PARTITION2( 0x07F000 , 0x001000 , NVMS_PARTITION_TABLE      , PARTITION_FLAG_READ_ONLY )
PARTITION2( 0x080000 , 0x010000 , NVMS_PARAM_PART           , 0 )
PARTITION2( 0x090000 , 0x010000 , NVMS_BIN_PART             , 0 )
PARTITION2( 0x0A0000 , 0x010000 , NVMS_CUSTOM_ENTRY_ONE     , 0 )
PARTITION2( 0x0B0000 , 0x010000 , NVMS_CUSTOM_ENTRY_TWO     , 0 )
PARTITION2( 0x0C0000 , 0x020000 , NVMS_LOG_PART             , 0 )
PARTITION2( 0x0E0000 , 0x020000 , NVMS_GENERIC_PART         , PARTITION_FLAG_VES )
  1. Modify the nvms_partition_id_t enumerator, located in sdk/adapters/include/partition_def.h to add new IDs for the newly defined entries. A possible modification is illustrated below:
/**
 * \brief NVMS Partition IDs
 */
typedef enum {
        NVMS_FIRMWARE_PART              = 1,
        NVMS_PARAM_PART                 = 2,
        NVMS_BIN_PART                   = 3,
        NVMS_LOG_PART                   = 4,
        NVMS_GENERIC_PART               = 5,
        NVMS_PLATFORM_PARAMS_PART       = 15,
        NVMS_PARTITION_TABLE            = 16,
        NVMS_FW_EXEC_PART               = 17,
        NVMS_FW_UPDATE_PART             = 18,
        NVMS_PRODUCT_HEADER_PART        = 19,
        NVMS_IMAGE_HEADER_PART          = 20,

        /*
         * New IDs for the newly defined entries!
         */
        NVMS_CUSTOM_ENTRY_ONE           = 21,
        NVMS_CUSTOM_ENTRY_TWO           = 22,
} nvms_partition_id_t;
  1. Modify the /sdk/adapters/include/partition_table.h header file to include another condition for selecting the new partition scheme. It should look like this:
#if defined(USE_PARTITION_TABLE_2MB)
#include <2M/partition_table.h>
#elif defined(USE_PARTITION_TABLE_2MB_WITH_SUOTA)
#include <2M/suota/partition_table.h>
#elif defined(USE_PARTITION_TABLE_512K)
#include <512K/partition_table.h>
#elif defined(USE_PARTITION_TABLE_512K_WITH_SUOTA)
#include <512K/suota/partition_table.h>
#elif defined(USE_PARTITION_TABLE_1MB_WITH_SUOTA)
#include <1M/suota/partition_table.h>
#elif defined(USE_MY_CUSTOM_PARTITION_TABLE)
#include <My_Custom_1M/My_Custom_1M.h>
#else
#include <1M/partition_table.h>
#endif
  1. In custom_config_qspi.h header file add the macro for selecting the new partition scheme.
#define USE_MY_CUSTOM_PARTITION_TABLE
  1. Erase the whole flash memory contents either via the serial port or jtag interface. The following uses the second option.
    1. Run the script to erase the flash through jtag.
'Flash Erase Script #1'

Fig. 11 Select the Flash Erase Script

  1. In the Console window at the bottom of the IDE, enter y and then press Enter. Wait for the process to complete.
'Flash Erase Script #2'

Fig. 12 Erase the Flash

Warning

When changing a partition table, it is essential to erase the old one in order for the new one to be taken into consideration.

  1. Build the project either in Debug_QSPI or Release_QSPI mode and burn the generated image to the chip.

3.1.1. Verifying with the SmartSnippets Toolbox

  1. Open a new instance of the SmartSnippets Toolbox and switch to the QSPI Partition Table window (1).
'Configuring the SmartSnippets Toolbox #1'

Fig. 13 SmartSnippets Toolbox - Display the Partition Table Area

  1. In the Partition Table area, click Connect (2). A rotating cursor is displayed waiting for the connected device to reset.

  2. Press button K2 on the DevKit to reset the device.

  3. Wait for the cursor to stop rotating and click Read (3).

    All the partition entries are displayed. The custom defined entries will be displayed as Unknown areas since their corresponding IDs are not recognized by the SmartSnippets Toolbox.

'SmartSnippets Toolbox, Partition Table Area*'

Fig. 14 SmartSnippets Toolbox, Partition Table Area

Note

If the new partition table is not shown or updated, unplug and then plug the USB cable from the USB2(DBG) port of the motherboard, wait for the device to connect and then execute the steps 1 – 4 again.

3.2. NVPARAM Flash Partition Entry

The SDK provides an additional layer for accessing the NVMS_PARAM_PART partition entry. The internal structure is declared in /sdk/adapters/include/platform_nvparam.h and consists of thirteen fields (all starting with TAG_BLE_PLATFORM_). Each field value includes an additional byte which indicates its validity. This value must be set to 0x00 to be considered valid. The SmartSnippets SDK also provides a script for burning the predefined structure in flash memory. All the preferred values should be declared in platform_nvparam_values.h. This file is not used in a regular build. Instead, it will be used when the program_qspi_nvparam_win script is explicitly used.

  1. Using the previous non-SUOTA sample code, in /sdk/adapters/include/platform_nvparam_values.h, declare the preferred values including their validity flags. For this demonstration, let’s modify the value for the BD address field:
//                                                                  ,-- parameter value
//                                                                  |                            ,-- 'validity' flag
//                                                                  V                            V
NVPARAM_PARAM_VALUE( TAG_BLE_PLATFORM_BD_ADDRESS, uint8_t,  0x01, 0x02, 0x03, 0x04, 0x05, 0x06,  0x00)

Note

During a BLE application, if this field is valid, the BLE manager will bypass any default or user-defined BD address with this one.

  1. Run the script to populate the NVMS_PARAM_PART partition entry with the defined structure.
'NVPARAM script'

Fig. 15 Script for Writing the NVMS_PARAM_PART Partition Entry

  1. Open a new instance of the SmartSnippets Toolbox and switch to the QSPI NVPARAMS window (1).
'SmartSnippets Toolbox, NVPARAM Area*'

Fig. 16 SmartSnippets Toolbox - Display the NVPARAMS Area

  1. In the QSPI NVPARAMS area, click Connect (located at the bottom). A rotating cursor is displayed waiting for the connected device to reset.
  2. Press button K2 on the DevKit to reset the device.
  3. When the cursor stops rotating, click Read (located at the bottom).
'SmartSnippets Toolbox, NVPARAM Area*'

Fig. 17 SmartSnippets Toolbox, NVPARAMS Area