I want to store some board info (serial number etc.) in OTP during board production. I managed to program OTP[189] trough J-Link commander. Now I want to read it back in the application.
My first attempt was to read the address:
reg = *((uint32_t *)0x00FF83FC);
This results in a bus fault. Reading trough earlier topics on this subject I suspect the OTP can only be read by secure code? All earlier topics mention the secure partition manager, which is now deprecated (using SDK 2.1.0).
I tried to convert to TF-M, using the following code:
static uint32_t secure_read_word(intptr_t ptr) { uint32_t err = 0; uint32_t val; enum tfm_platform_err_t plt_err; plt_err = tfm_platform_mem_read(&val, ptr, 4, &err); if (plt_err != TFM_PLATFORM_ERR_SUCCESS || err != 0) { printk("tfm_..._mem_read failed: plt_err: 0x%x, err: 0x%x\n", plt_err, err); return -1; } return val; } uint32_t read_otp(void) { uint32_t val = secure_read_word((intptr_t)&NRF_UICR_S->OTP[189]);// *((uint32_t *)0x00FF83FC); if(val == 0xFFFFFFFF) { return SERIAL_NUMBER_DEFAULT; } return val; }
But this always gives the default serial, and the following line in the console:
tfm_..._mem_read failed: plt_err: 0x2, err: 0xffffffff
I guess I need to add the address to some whitelisted addresses that the non-secure code can read?