5. Burning the Firmware

Before successfully downloading custom Firmware to DA1469x devices which use a different than the default QSPI Flash as booting source, three things must be done.

  1. The firmware loader has to be built with proper modifications to target the custom QSPI Flash.

  2. The firmware itself must be built using the new driver as described in the previous chapter.

  3. The Flash Configurations used to generate the proper Product Header must be changed to target the custom QSPI Flash.

5.1. Downloading Tools

SmartSnippetsStudio™ is using host application cli_programmer to successfully download binaries into DA1469x device’s Flash or RAM. cli_programmer project can be found under {SDK_root}/utilities/cli_programmer.

5.1.1. Host Side

  • cli_programmer is a project included in the SDK which allows the user to use command line instructions to program/read/erase the QSPI Flash amongst other things. When built as a static version, it includes as part of its binary, the dependency projects uartboot and libprogrammer. When it is built in its dynamic version, its dependency projects are also built separately as a binary file(uartboot.bin) and a dll library (libprogrammer.dll).

  • libprogrammer implements all the functions that cli_programmer calls as well as several sanity checks. Additionally it utilizes the UART or the GDB server to send the data and the commands over to or receive the responses from a connected DA1469x Device. libprogrammer consists the link between the User Interface and the Device Firmware.

5.1.2. Device Side

  • uartboot is a second stage bootloader running on the device. It is usually downloaded by cli_programmer or the SmartSnippetsToolbox™ equivalent. This second stage bootloader implements all the functionality relevant to receiving commands and data from the Host PC and responding back, as well as all the functions that access the QSPI Flash. This part of the ecosystem is the one that needs to be rebuilt every time a new driver is included.

Note

uartboot also needs to be rebuilt everytime the partition table needs to be stored in a new location. By default the partition_table address used is 0x3FF000 as dictated in {sdk_root}/sdk/bsp/config/4M/partition_table.h. Please note that if a QSPI Flash of lower capacity than 32MBits is used, the default address might exceed the Flash’ boundaries which will cause it to wrap around, potentially overwriting mandatory data elements (e.g. Interrupt Vector) or firmware parts. Thus, it is imperative that the correct partition table address is used based on the QSPI Flash’ size or client’s custom needs.

5.1.3. Rebuilding the Tools

Import into the workspace, projects cli_programmer, libprogrammer and uartboot along with python_scripts.

Project uartboot’s config file custom_config.h has to be modified to be able to identify the custom QSPIC Flash device connected. Please refer to the previous chapter on how to make a driver visible to a firmware and then rebuild the project as DA1469x-00-Release.

Next, cli_programmer also needs to be recompiled as DA1469x-00_Release_static_ version. This will automatically build project libprogrammer as well and will incorporate it along with uartboot into the cli_programmer binary.

5.2. Burning the Firmware

The process of burning the custom firmware to the new flash will create or update any pre-existing Product Headers. Part of the information of a valid Product Header is taken from flash_configurations.xml file which can be found under {SDK_root}/utilities/python_scripts/qspi/. This file contains entries for different QSPI Flash devices. Since the QSPI Flash used is a custom one, a new entry has to be created for it.

5.2.1. Adding an Entry

Add the following configuration entry…

<configuration name="Adesto AT25SL321">
   <flash_size>0x400000</flash_size>
   <flash_burstcmda_reg_value>0xa8a000eb</flash_burstcmda_reg_value>
   <flash_burstcmdb_reg_value>0x00000066</flash_burstcmdb_reg_value>
   <flash_write_config_command>0x31 0x02 0x07</flash_write_config_command>
</configuration>

This configuration entry is used to produce a firmware’s product header and contains information on how to initialize the QSPI Flash.

configuration name: This value is an identifier that helps the developer distinguish which QSPI Flash device’s configuration entry this is.

flash_size: This value is the capacity of the QSPI Flash in bytes in hexadecimal. In the case of 32Mbit Adesto AT25SL321 0x400000 corresponds to 4MBytes.

flash_burstcmda_reg_value: This is the value that QSPIC_BURSTCMDA_REG register should take so the Flash can operate properly. For more information, please consult DA1469x Datasheet Table 247 page 343/743.

flash_burstcmdb_reg_value: This is the value that QSPIC_BURSTCMDB_REG register should take so the Flash can operate properly. For more information, please consult DA1469x Datasheet Table 248 page 344/743.

Note

The easiest way to receive the values of flash_burstcmda_reg_value and flash_burstcmdb_reg_value is after Debug version of uartboot is built to detect the new QSPI Flash device, begin a debug RAM_DA1469x session. There, once the device has been successfully identified and the breakpoint in main() is reached, check EmbSys Registers for the values of QSPIC_BURSTCMDA_REG and QSPIC_BURSTCMDB_REG values.

QSPIC_BURSTCMDA_REG and QSPIC_BURSTCMDB_REG.

Figure 1 QSPIC_BURSTCMDA_REG and QSPIC_BURSTCMDB_REG.

flash_write_config_command: The last field is a single instruction sent through Single SPI mode to the QSPI Flash and is used for initialization when a custom Firmware boots. It can be disected as shown in the image below…

Flash Configurations XML Entry.

Figure 2 Flash Configurations XML Entry.

The first byte is the instruction opcode sent in Single SPI mode. (0x31 - Write Status Register 2 in this example)

The last byte always represents the pipe delay and is not sent over to the QSPI Flash.

All other bytes are sent in sequence after the instruction opcode. Usually here the desired values of the Status Register Bytes are being passed, often setting Quad Enable bit amongst others.

In this particular example “flash_write_config_command” sends a Write Status Register command with value 0x02 -> b0_0000_0010. This value corresponds to a set Quad Enable bit which resides in bit position 1 of Status Register’s second byte. Every other volatile bit of the second byte of Status Register (a.k.a. Status Register 2 in this example) will be set to 0. After 0x02 is sent, the instruction is terminated with the CE# returning to high state while the pipe delay is 0x07.

Warning

It is only possible to send one command to the device through the configuration entry. The CE# signal will only go high right after the previous to last byte is sent.

5.2.2. Activating the Custom Configuration Entry

The final step is switching Flash Configuration and burning the custom Firmware to the QSPI Flash.

In the External Tools dropdown icon of SmartSnippetsStudio™ working environment, pick “program_qspi_config”.

QSPI Flash Configuration Change prompt windows.

Figure 3 QSPI Flash Configuration Change prompt windows.

  1. If this is not the first time that a firmware is burned in the current SmartSnippetsStudio™ installation, a window will appear, showing the current configuration prompting the user to either Keep or Change.

  2. Next, the user will be asked what is the Dialog Device being used. Pick DA1469x

  3. Following that, comes a window that prompts the user to pick the QSPI Flash being used. Pick the one with the same name as configuration name field of the xml configuration entry added. (Adesto AT25SL321 for this example)

  4. Finally, for active_fw_image_address and update_fw_image_address it is advised to use the default values 0x2000.

Once the configuration is finished, any program_qspi_ variant should be able to program the custom QSPI Flash without errors. Reseting the DA1469x device should now boot the custom firmware.