hi Dialog
if my code stored in QSPI flash, but I writed a BD address in OTP ROM by PLT, how to make ble stack use BD address in OTP ROM instead of the one in NVMS or defaultBLE_STATIC_ADDRESS? Moreover, how to read the BD address from OTP ROM? Is there any example code anout this case?
thanks
Nigel
Hi Nigel,
The BD Address in placed in specific address (0x07F8EA58) in the OPT header. Please try to read the OPT Header with the OTP tool from the SmartSnippets toolbox. In order to read the BD Address from the OTP Header you should follow the procedure below:
1. Add the LLD (low level drivers) of the OTP controller
#include "hw_otpc.h"
2. Add the function which reads from the OTP memory, named read_bd_address_from_otp(). The source code is below:
static bool read_bd_address_from_otp(uint32_t otp_cell_offset, uint8_t *bd_address, uint32_t *phy_otp_address) { uint32_t r_buf[2]; uint32_t num_words = 3; uint32_t *physical_otp_address; static uint8_t bd_address_otp_final[8]; bool is_correct = 0; physical_otp_address = hw_otpc_cell_to_mem(otp_cell_offset); phy_otp_address = physical_otp_address; hw_otpc_init(); is_correct = hw_otpc_fifo_read( (uint32_t *) r_buf, otp_cell_offset ,HW_OTPC_WORD_LOW, num_words, false ); hw_otpc_disable(); bd_address_otp_final[0] = (r_buf[0] >> 0 ); bd_address_otp_final[1] = (r_buf[0] >> 8 ); bd_address_otp_final[2] = (r_buf[0] >> 16 ); bd_address_otp_final[3] = (r_buf[0] >> 24 ); bd_address_otp_final[4] = (r_buf[1] >> 0 ); bd_address_otp_final[5] = (r_buf[1] >> 8 ); bd_address_otp_final[6] = (r_buf[1] >> 16 ); bd_address_otp_final[7] = (r_buf[1] >> 24 ); memcpy(bd_address, bd_address_otp_final, 8); return is_correct; }
3. Retrieve the BD address from the OTP memory
uint32_t *physical_otp_memory_cell; uint32_t cell_offset = 0x1D4B; static uint8_t bd_address_final[8]; bool read_success; /* Retrieve the BD address from the OTP memory */ read_success = read_bd_address_from_otp(cell_offset, bd_address_final, physical_otp_memory_cell); OS_ASSERT(read_success); static own_address_t user_bd_address = { .addr_type = PRIVATE_STATIC_ADDRESS, }; memcpy(user_bd_address.addr, bd_address_final, 6); // Set BD address to the preffered value. This function sets the BD address in inverse order. ble_gap_address_set(&user_bd_address, 0x00FF);
Thanks, PM_Dialog
hi Dialog,
My test based on your function seems not work for DA14681. Can you tell me why "cell_offset" is 0x1D4B ? and what is the relation with 0x07F8EA58 (BD address in OTP) ? I am curious that "physical_otp_address = hw_otpc_cell_to_mem(otp_cell_offset)", however, physical_otp_address = 0x7F80000 + (cell_offset << 3) in hw_otpc_cell_to_mem( ). It will not be 0x07F8EA58.
Hi nigelyang,
param [in] otp_cell_offset :The offset of the OTP cell. The formula to calculate the physical memory address is (0x7F80000 + (otp_cell_offset << 3)). E.g. the offset 0x1D4B corresponds to 0x7F8EA58 physical address (location of the BD address)
param [in] bd_address : The cell's contents in chunks of 1 byte
param [in] phy_otp_address : The physical address of the OTP memory cell (for verification purposes)
param [out] : True if the read request has been successfully performed, false otherwise
As I mentioned in my precious answer, the BD Address in placed in specific address (0x07F8EA58) in the OPT header. Did you read the OPT Header with the OTP tool from the SmartSnippets toolbox. Is the BD Address located into 0x07F8EA58? Otherwise, in which OTP address is located?
Hi Dialog,
I found my problem comes from using cm_sys_clk_set(sysclk_PLL48) for systme clock setting. I got the correct BD address of OTP after changing by cm_sys_clk_set(sysclk_XTAL16M); One more question, what is correct way to read OTP BD address if using cm_sys_clk_set(sysclk_PLL48) ?
Yes, you should read the BD Address with the same way. If you change the clock to PLL are you able to access the OPT Header from the toolbox and read the contains? If you found the previous answers useful please mark one of them as “accepted”.
Is this still the best method for loading the BD Address from OTP? Has this been worked on at all since this post? It's interesting the OTP has a memory location dedicated to the BD Address, and that the PLT has a built in option for writing the BD Address to OTP, but the SDK (1.0.14) has no functions for reading in and using the BD Address from OTP.
Update: As of right now, there is no method in the most recent SDK (1.0.14) for reading the BD Address from OTP and using it.
You have to add a function yourself that does the operations as noted above.
Just an update: Doing the Secureboot initial flash procedure BREAKS this OTP read functionality as described above.
Update: This was probably associated with the other FLASH and partition table issues. Direct pointer access to OTP worked even with the broken partition table.