This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

Changing REGOUT0 value to 3v3 in a DFU enabled software

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.

Parents
  • Hello,

    It's not clear how data in the UICR could be impacting the settings page, it's not even in the same address range. As a test, and if you haven tried already, could you please try program the settings page after everything else has been programmed and see if it gives the same result?  You can use the following command to just load the settings file: "nrfjprog --program settings.hex --sectorease"

    Kind regards,

    Vidar

Reply
  • Hello,

    It's not clear how data in the UICR could be impacting the settings page, it's not even in the same address range. As a test, and if you haven tried already, could you please try program the settings page after everything else has been programmed and see if it gives the same result?  You can use the following command to just load the settings file: "nrfjprog --program settings.hex --sectorease"

    Kind regards,

    Vidar

Children
  • Hi Vidar,

    Thanks for your answer. I tried flashing everything one by one with nrfjprog.

    -Started with the bootloader first:

    nrfjprog --program softdevice.hex --chiperase --verify
    
    Parsing hex file.
    Erasing user available code and UICR flash areas.
    Applying system reset.
    Checking that the area to write is not protected.
    Programming device.
    Verifying programming.
    Verified OK.
    

    -Bootloader second:

    nrfjprog --program bl.hex --sectorerase --verify
    Parsing hex file.
    Erasing page at address 0xF1000.
    Erasing page at address 0xF2000.
    Erasing page at address 0xF3000.
    Erasing page at address 0xF4000.
    Erasing page at address 0xF5000.
    Erasing page at address 0xF6000.
    Erasing page at address 0xF7000.
    Erasing page at address 0xF8000.
    Erasing page at address 0xF9000.
    Erasing page at address 0xFA000.
    Erasing page at address 0xFB000.
    Erasing page at address 0xFC000.
    WARNING: A UICR write operation has been requested but UICR has not been
    WARNING: erased. Please verify that the result is correct.
    Applying system reset.
    Checking that the area to write is not protected.
    Programming device.
    Verifying programming.
    Verified OK.

    -my app next:

    nrfjprog --program app.hex --sectorerase --verify
    Parsing hex file.
    Erasing page at address 0x27000.
    Erasing page at address 0x28000.
    Erasing page at address 0x29000.
    Erasing page at address 0x2A000.
    Erasing page at address 0x2B000.
    Erasing page at address 0x2C000.
    Erasing page at address 0x2D000.
    Erasing page at address 0x2E000.
    Erasing page at address 0x2F000.
    Erasing page at address 0x30000.
    Erasing page at address 0x31000.
    Erasing page at address 0x32000.
    Erasing page at address 0x33000.
    Erasing page at address 0x34000.
    Erasing page at address 0x35000.
    Erasing page at address 0x36000.
    Erasing page at address 0x37000.
    Erasing page at address 0x38000.
    Erasing page at address 0x39000.
    Erasing page at address 0x3A000.
    Erasing page at address 0x3B000.
    Erasing page at address 0x3C000.
    Erasing page at address 0x3D000.
    Erasing page at address 0x3E000.
    Erasing page at address 0x3F000.
    Erasing page at address 0x40000.
    Erasing page at address 0x41000.
    Erasing page at address 0x42000.
    Erasing page at address 0x43000.
    Erasing page at address 0x44000.
    Erasing page at address 0x45000.
    Erasing page at address 0x46000.
    Erasing page at address 0x47000.
    Applying system reset.
    Checking that the area to write is not protected.
    Programming device.
    Verifying programming.
    Verified OK.

    -And finally the settings:

    nrfjprog --program settings.hex --sectorerase --verify
    Parsing hex file.
    Erasing page at address 0xFE000.
    Erasing page at address 0xFF000.
    Applying system reset.
    Checking that the area to write is not protected.
    Programming device.
    Verifying programming.
    Verified OK.

    I then reset the device with nrfjprog --reset, but the device is still stuck in bootloader.

    Any thoughts?

    Kind Regards,

    Onur Gules

  • Hi Onur,

    Thanks for testing. Is it possible that this may be unrelated to change you did to set the UICR regulator setting, or have you verified that it still works if you rever the change? Either way, I think you need to debug the bootloader project to find out why the bootloader will not start the application. First step may be to see if nrf_bootloader.c:dfu_enter_check() returns true instead of false which would make the  bootloader fall back to DFU mode.

    Kind regards,

    Vidar

  • Hi Vidar,

    I tried reverting the changes I made to flash_placement.xml, linker->memory segments and I also am not including uicr_config.h now in main.c. The device works normally now, although with incorrect voltage. So, it's probably the changes I made to uicr is messing up the bootloader. 

    I also debugged the bootloader project and dfu_enter_check() returns false as it should.  You can find the debug logs I got below:

    <debug> nrf_dfu_req_handler: Whole firmware image received. Postvalidating.
    <debug> nrf_dfu_validation: Hash verification. start address: 0x27000, size: 0x20428
    <debug> nrf_dfu_validation: Invalidating old application in bank 0.
    <debug> nrf_dfu_settings: Writing settings...
    <debug> nrf_dfu_settings: Erasing old settings at: 0x000FF000
    <debug> nrf_dfu_flash: nrf_fstorage_erase(addr=0x0x000FF000, len=1 pages), queue usage: 1
    <debug> nrf_dfu_flash: nrf_fstorage_write(addr=0x000FF000, src=0x2000A6E4, len=896 bytes), queue usage: 2
    <info> nrf_dfu_settings: Backing up settings page to address 0xFE000.
    <debug> nrf_dfu_settings: Writing settings...
    <debug> nrf_dfu_settings: Erasing old settings at: 0x000FE000
    <debug> nrf_dfu_flash: nrf_fstorage_erase(addr=0x0x000FE000, len=1 pages), queue usage: 3
    <debug> nrf_dfu_flash: nrf_fstorage_write(addr=0x000FE000, src=0x2000A364, len=896 bytes), queue usage: 4
    <debug> nrf_dfu_req_handler: Request handling complete. Result: 0x1
    <debug> nrf_dfu_flash: Flash erase success: addr=0x000FF000, pending 4
    <debug> nrf_dfu_flash: Flash erase success: addr=0x000FE000, pending 2
    <debug> nrf_dfu_flash: Flash write success: addr=0x000FE000, pending 1
    <debug> nrf_dfu_req_handler: All flash ash ash ash ash ash ash ash ash ash ash ash ash ash ash ash ash ash ash ash ash ash ash ash ash

    Edit: I debugged the bootloader by performing a DFU with the same app that normally works without DFU. I changed the debug logs from yesterday as I was debugging the bootloader incorrectly.

    Kind Regards,

    Onur Gules.

  • Hi Onur,

    It's interesting that it works as soon as you revert the change. To verify it if the relagulator setting is indeed the culprit, maybe you can try to set it directly with nrfjprog?

    e.g.

    nrfjprog --memwr 0x10001304 --val 5

    nrfjprog --reset

    Another post with some similiar observations (still unresolved) https://devzone.nordicsemi.com/f/nordic-q-a/74471/ota-failing-when-gpio-high-voltage-mode-3-3-v

    Kind regards,

    Vidar

  • Hi Vidar,

    I tried setting it directly with nrfjprog as you described. The device works fine before setting REGOUT0 to 5, and is stuck in bootloader after.

    I also found this thread:

    https://devzone.nordicsemi.com/f/nordic-q-a/73814/regout0-set-to-3-3v-fail-buttonless-dfu

    Not sure how, but their problem was related to their hardware. I have one more board so I'll see if I can make that one work.

    Kind regards,

    Onur.

Related