Hello,
We have an NRF52840 based custom design board where the peripherals run on 3.3v. I based my code on a combination of ble_app_uart and ble_app_buttonless_dfu examples. It has been working great so far. However, recently we designed a new board where we want to use DCDC regulator both for the chip and the peripherals.
From what I can gather, what I need to do in my code is:
NRF_POWER->DCDCEN = 1; NRF_POWER->DCDCEN0 = 1;
Also, to change the output voltage from REG0 regulator stage, I also need to write 0xFFFFFFFD to NRF_UICR->REGOUT0 register. I did some research on the forums and it seems that writing to UICR registers isn't trivial if you have a bootloader since uicr_bootloader_start_address, and uicr_mbr_params_page are also kept on UICR. So, I decided to modify the bootloader to change the UICR REGOUT0 register with a compile time constant. I listed the changes I made to the bootloader below:
-Added uicr_config.h and included it in main.c
-Defined REGOUT0 3v3 value as a constant like below:
const uint32_t REGOUT0 __attribute__((section(".uicr_regout0"))) = 0xFFFFFFFD;
-Modified flash_placement.xml:
<MemorySegment name="UICR" start="0x10001000" size="0x308" fill="0xff"> <ProgramSection alignment="4" keep="yes" load="no" name=".uicr_fill" fill="0xff" size="0x1" /> <ProgramSection alignment="4" keep="Yes" load="Yes" name=".uicr_regout0" start="0x10001304" size="4"/> </MemorySegment> <MemorySegment name="uicr_bootloader_start_address" start="0x10001014" size="0x4"> <ProgramSection alignment="4" keep="Yes" load="Yes" name=".uicr_bootloader_start_address" address_symbol="__start_uicr_bootloader_start_address" end_symbol="__stop_uicr_bootloader_start_address" start = "0x10001014" size="0x4" /> </MemorySegment> <MemorySegment name="uicr_mbr_params_page" start="0x10001018" size="0x4"> <ProgramSection alignment="4" keep="Yes" load="Yes" name=".uicr_mbr_params_page" address_symbol="__start_uicr_mbr_params_page" end_symbol="__stop_uicr_mbr_params_page" start = "0x10001018" size="0x4" /> </MemorySegment>
-Modified Project Options->Linker->Memory Segments to
FLASH RX 0x0 0x100000;RAM1 RWX 0x20000000 0x40000;mbr_params_page RX 0x000FE000 0x1000;bootloader_settings_page RX 0x000FF000 0x1000;uicr_bootloader_start_address RX 0x10001014 0x4;uicr_mbr_params_page RX 0x10001018 0x4;UICR RWX 0x10001000 0x308
When I read the REGOUT0, uicr_bootloader_start_address, and uicr_mbr_params_page after flashing with:
nrfjprog --memrd 0x10001304 --w 32 --n 32 nrfjprog --memrd 0x10001014 --w 32 --n 32 nrfjprog --memrd 0x10001018 --w 32 --n 32
all three look correct, so I assume I'm not doing something wrong while writing them. However, if I flash this bootloader, my app, softdevice and a bootloader settings page using Segger Embedded Studio (bootloader, settings and the softdevice are correctly selected as additional load files in Project Options->Loader), the device gets stuck in bootloader as it starts advertising as DfuTarg. I generate the settings with this command:
nrfutil settings generate --family NRF52840 --application app.hex --application-version 0 --bootloader-version 0 --bl-settings-version 2 settings.hex
I am using SDK v17, hence the settings version 2. However, when run this command to read the bootloader settings in the flash with:
nrfjprog --readcode read.hex nrfutil settings display read.hex
I'm getting this message:
Unknown Bootloader DFU settings version: 4294967295
Other than that, the settings look normal to me. Even if I perform a proper DFU with nRF Toolbox, the device doesn't boot my app and is stuck in bootloader.
The question became much longer than I anticipated, but I wanted to share everything I did with you so that maybe you can spot my mistakes.
In summary, I would like to have these functionalities:
-Buttonless DFU
-DCDC REG0 output to be 3.3V
Can you please help?
Kind Regards,
Onur Gules.