Beware that this post is related to an SDK in maintenance mode
More Info: Consider nRF Connect SDK for new designs

nRF52840 Dongle Set REGOUT0 for 3V3 VDD OUT

Looking to permanently change UICR REGOUT0 to 5 for 3V3 on VDDOUT from dongle, to power a small Pulse Oximeter. Then using nRF Connect SDK and Zephyr, get Bluetooth GATT services and I2C(TWI) up and running.

Questions:
1. To change REGOUT0 for 3.3V using SES and nRF SDK. Do we need to connect the nRF52840 Dongle via nRF52840 DK Debug Out in order to change the UICR?
2. Can Zephyr make changes to the UICR?
3. Using nRF Connect and Zephyr. Where might there be code resetting REGOUT0 to 4 (3V)?

Any advice welcome. Many thanks,  Andy

---------------------------
Following the nRF5 SDK guides > Getting Started > nRF52840 Dongle Programming Tutorial. 27 Nov 2018
https://devzone.nordicsemi.com/guides/short-range-guides/b/getting-started/posts/nrf52840-dongle-programming-tutorial  Adapting firmware to set REGOUT0 properly.

⦿ Ways in which we have tried to change REGOUT0 to 5:

1_))
Guide says: “The firmware must set REGOUT0 to 3 V in order to allow it to be debugged from a DK. This is handled by the BSP if it is used with board correctly set to pca10059 by defining BOARD_PCA10059, and the firmware calls bsp_board_init().”

a. We opened ../nRF5_SDK_17.1.0_ddde560/examples/peripheral/blinky/pca10059/mbr/ses/blinky_pca10059_mbr.emProject in Segger Embedded Studio.

b(1). Edited Board Definition > boards.c line 114 
     from (UICR_REGOUT0_VOUT_3V0 << UICR_REGOUT0_VOUT_Pos);
     to (UICR_REGOUT0_VOUT_3V3 << UICR_REGOUT0_VOUT_Pos);

b(2). We also tried editing line 108 if ((NRF_UICR->REGOUT0 & UICR_REGOUT0_VOUT_Msk) ==
    from (UICR_REGOUT0_VOUT_DEFAULT << UICR_REGOUT0_VOUT_Pos))
    to (UICR_REGOUT0_VOUT_3V0 << UICR_REGOUT0_VOUT_Pos))

c. In the Programmer. Plug dongle into USB port and push SW2 RESET.  Add file ../nRF5_SDK_17.1.0_ddde560/examples/peripheral/blinky/pca10059/mbr/ses/Output/Release/Exe/blink_pca10059_mbr.hex

We know the code and development path works in general. If the firmware does not fall into the 'if' statement in boards.c that changes REGOUT0, then the LEDs turn on and off as expected.

Problem:
If the code NRF_NVMC->CONFIG NRF_UICR->REGOUT0 etc in the 'if' statement is hit. The nRF52840 dongle does not do anything.  Subsequently, writing some firmware to read the value of REGOUT0 and getting an LED to blink that number confirms REGOUT0 is still set to 4 and VDDOUT is still at 3V

Next Step: We have a cable assembly and surface mount header on order to connect P1 on the nRF52840 Dongle (SWDIO & CLK) to nRF52840 Development kit p19 Debug Out.

2_))
Guide says: “If the BSP is not used, you should instead do the same thing directly by calling this code as early as possible in your firmware to set the REGOUT0 register if need:” Then there is a <code snippet> 

a. We opened up VS Code with nRF Connect Extension v2021.12.137 and using Zephyr…

b. Create a new application from sample - zephyr/samples/basic/brinky

c. Add Build Configuration > Board nrf52840dongle_nrf52840

d. Just under: void main(void) {   we added <code snippet> from Programming Tutorial. 
       i. Edited code snippet a bit to say if REGOUT0 = 4 then change REGOUT0 to 5 along with the required masking and bit shifting.
       ii. Commented out all other code for blinking an LED.

e. Looked in file: build > zephyr > zephyr.lst 
       i. We see our code to change REGOUT0 to UICR_REGOUT0_VOUT_3V3
       ii. Also saw #if NRF_POWER_HAS_MAINREGSTATUS looking to change NRF_UICR->REGOUT0 = UICR_REGOUT0_VOUT_3V0 which is a bit disconcerting.

f. We have also tried CONFIG_SOC_FLASH_NRF_UICR=y in pro.conf

g. In the Programmer. Plug dongle into USB port and push SW2 RESET.  Add file ../blinky*/build/zephyr/zephyr.hex

Problem:
REGOUT0 is still set to 4 and VDDOUT is still at 3V

Next Step: We are to find out where there is code for the nRF52840 dongle and Zephyr with the potential to just keep overwriting REGOUT0 to 4 (3V). To see if we can change the code locally so REGOUT0 = 5. Also find out if UICR can be changed using Zephyr.

---------------------------

Notes:

nRF52840 dongle sometimes referred to as PCA10059
nRF52840 Product Specification v1.7 https://infocenter.nordicsemi.com/pdf/nRF52840_PS_v1.7.pdf
nRF52840 Dongle Hardware files https://www.nordicsemi.com/-/media/Software-and-other-downloads/Dev-Kits/nRF52840-Dongle/nRF52840-USB-Dongle---Hardware-files-2_0_0.zip
UICR User Information Configuration Registers
GATT Generic Attribute Profile
TWI Two-Wire Interface


nRF52840 Dongle Hardware files > PCA10059_Schematic_And_PCB.pdf shows L4 10μH coil between DCCH and VDD. Alludes to nRF52840 Product Specification v1.7 page 67 Figure 18: High Voltage mode DC/DC for REG0 and REG1 enabled.


Currant mA:
We are trying to get the Analog Devices / maxim integrated MAXREFDES117# Hearth-Rate and Pulse-Oximetry Monitor working. LED1 and 2 at 7mA, Pilot LED 0mA = pull of about 15mA
nRF52840 Product Specification v1.7 page 84. nRF52840 REG0 stage External current draw allowed in High voltage mode when radio output power is lower than or equal to 4dBM = 25mA.

Without any changes to:
nRF52840 Dongle - nRF6936 version 1.2.0 2020.11  We were measuring 3.3v on VDD Out with not enough current to power MAXREFDES117# properly. *However, we did get this working for a short time.
nRF52840 Dongle - nRF6829 version 2.0.0 2021.19. We are measuring 3.0v on VDD Out with not enough current to power MAXREFDES117# properly.


Noteworthy Code:
NRF_POWER->DCDCEN0 = 1;
NRF_POWER->DCDCEN = 0;

Ref table:
REGOUT0 = 4 for 3V0
REGOUT0 = 5 for 3V3
REGOUT0 = 7 for Default

IDE:

nRF Connect for Desktop.
Programmer v2.2.0

Toolchain Manager v0.10.3:
     > VS Code with nRF Connect Extension v2021.12.137 using Zephyr
     > Segger Embedded Studio V.5.68 with nRF5 SDK v17.1.0

  • Hi,

    1. To change REGOUT0 for 3.3V using SES and nRF SDK. Do we need to connect the nRF52840 Dongle via nRF52840 DK Debug Out in order to change the UICR?

    You can write to the UICR from firmware even though you cannot erase it, so as this involves flipping more bits from 1 to 0 it is possible. But you cannot revert back without a debugger.

    2. Can Zephyr make changes to the UICR?

    You can flip bits from 1 to 0 regardless of using any RTOS or bare metal as long as that is not explicitly prevented. For (instance you cannot do it while a SoftDevice is active). Therefore it makes sense to do any changes in the UICR early. You can see how REGOUT0 is set for the dongle in zephyr/boards/arm/nrf52840dongle_nrf52840/board.c and this is where you would want to make changes.

    3. Using nRF Connect and Zephyr. Where might there be code resetting REGOUT0 to 4 (3V)?

    To flip bits from 0 to 1 you need to do a page erase of the UICR, and that must be done from a debugger.

  • Many thanks for your reply Einar. 



    Questions: 


    Might nRF52840 Dongles be shipping to customers with REGOUT0 already set to 3V0 already? 

    Therefore, new dongles no longer having to run the code to change REGOUT0 from Default to 3V0? 

    Might there be a problem ‘adapting firmware to set REGOUT0 properly’* that has not been realised?   


    Is the nRF52840 Dongle capable of producing 3.3V on VDD OUT?

    We made changes to zephyr/boards/arm/nrf52840dongle_nrf52840/board.c as you proposed.

 

    Unfortunately, there is no easy access to board.c file by building the developer environment using nRF Connect for Desktop > Toolchain Manager > VS Code with nRFConnect for VS Code > Create a new application from sample ‘zephyr/samples/basic/blinky



    Instead, we created a Zephyr developer environment using https://docs.zephyrproject.org/latest/getting_started/index.html and GNU Arm Embedded Toolchain https://developer.arm.com/tools-and-software/open-source-software/developer-tools/gnu-toolchain/gnu-rm/downloads

    new path ../zephyrproject/zephyr/boards/arm/nrf52840dongle_nrf52840/board.c



    -> Steps to reproduce:


                Show REGOUT0 already at 3V on new dongle.

    1. Open folder ../zephyrproject/zephyr in MS Code
    2. Open ../zephyrproject/zephyr/boards/arm/nrf52840dongle_nrf52840/board.c
    3. Change line 31 to (UICR_REGOUT0_VOUT_3V3 << UICR_REGOUT0_VOUT_Pos); So if the new board REGOUT0 is set to Default the voltage should change to 3V3.
    4. Open a terminal window at zephyr % and run % 

              west build -p auto -b nrf52840dongle_nrf52840 samples/basic/blinky
    5. Check file ../zephyrproject/build/zephyr/zephyr.lst See ref to UICR_REGOUT0_VOUT_3V3 on line 3060
6. Check file ../zephyrproject/build/zephyr/zephyr.hex (~44KB) is present and Date Modified is current. 

    6. Undo seal and take new nRF52840 Dongle (nRF6829 2.0.0 2021.19).
    7. Insert NEW DONGLE into USB. Red LED starts flashing ready for writing.
    8. Measure voltage between GND and VDD OUT. (Measured 3.021 Volts)

    9. Start up nRF Connect for Desktop > Programmer
    10. Select Open DFU Bootloader
    11. Add file ../zephyrproject/zephyr/build/zephyr/zephyr.hex
    12. Click ‘Write’
    13. Log reports Uploading image through SDFU: 100%, All dfu images have been written to the target device,
    14. - And green LED starts blinking on the nRF52840 Dongle.
    15. Measure voltage between GND and VDD OUT. (Measured 3.02 Volts)

       
      Try to change REGOUT0 to 3V3 early in board.c and have code in if statement run.

    16. Open ../zephyrproject/zephyr/boards/arm/nrf52840dongle_nrf52840/board.c
    17. Change code in board.c around line 22, so if REGOUT0 is not equal != to UICR_REGOUT0_VOUT_3V3 run the code to change REGOUT0 to 3V3
    18. Run the following again from the terminal window %

                 west build -p auto -b nrf52840dongle_nrf52840 samples/basic/blinky
    19. Check file ../zephyrproject/zephyr/build/zephyr/zephyr.lst 

          See ref to UICR_REGOUT0_VOUT_3V3 in the if statement on line 3039

          See ref to UICR_REGOUT0_VOUT_3V3 on line 3060
    20. Check file ../zephyrproject/zephyr/build/zephyr/zephyr.hex (~44KB) is present and Date Modified is latest.
    21. Start up nRF Connect for Desktop > Programmer
    22. Select Open DFU Bootloader
    23. Add file ../zephyrproject/zephyr/build/zephyr/zephyr.hex
    24. Click ‘Write’
    25. Log reports Uploading image through SDFU: 100%, All dfu images have been written to the target device.
    26. - NO blinking green LED
    27. Measure voltage between GND and VDD OUT. (Measured 3.02 Volts)


      Revert code so if statement in board.c is not run:

    28. In board.c Undo code change in the if statement only. So it’s back to if REGOUT0 = UICR_REGOUT0_VOUT_DEFAULT (with _Msk and _pos)
    29. Repeat steps 4,5,6,10,11,12,13,14 to reprogram dongle.
    30. - And green LED starts blinking on the nRF52840 Dongle.
    31. Measure voltage between GND and VDD OUT. (Measured 3.01 Volts)


    * Ref: Programming Tutorial: devzone.nordicsemi.com/.../nrf52840-dongle-programming-tutorial

  • Hi,

    Emerson Warwick said:
    Might nRF52840 Dongles be shipping to customers with REGOUT0 already set to 3V0 already?

    Yes, that is the case.

    Emerson Warwick said:
    Therefore, new dongles no longer having to run the code to change REGOUT0 from Default to 3V0?

    Yes, that is true. However, the code is present in the bootloader that ships with the dongle, though it only does work once as it checks the existing UICR content from <nRF5 SDK>\components\boards\boards.c:

    #if defined(BOARD_PCA10059)
    /**
     * Function for configuring UICR_REGOUT0 register
     * to set GPIO output voltage to 3.0V.
     */
    static void gpio_output_voltage_setup(void)
    {
        // Configure UICR_REGOUT0 register only if it is set to default value.
        if ((NRF_UICR->REGOUT0 & UICR_REGOUT0_VOUT_Msk) ==
            (UICR_REGOUT0_VOUT_DEFAULT << UICR_REGOUT0_VOUT_Pos))
        {
            NRF_NVMC->CONFIG = NVMC_CONFIG_WEN_Wen;
            while (NRF_NVMC->READY == NVMC_READY_READY_Busy){}
    
            NRF_UICR->REGOUT0 = (NRF_UICR->REGOUT0 & ~((uint32_t)UICR_REGOUT0_VOUT_Msk)) |
                                (UICR_REGOUT0_VOUT_3V0 << UICR_REGOUT0_VOUT_Pos);
    
            NRF_NVMC->CONFIG = NVMC_CONFIG_WEN_Ren;
            while (NRF_NVMC->READY == NVMC_READY_READY_Busy){}
    
            // System reset is needed to update UICR registers.
            NVIC_SystemReset();
        }
    }

    The above is more or less equivalent with the code you find in <nRF Connect SDK>\zephyr\boards\arm\nrf52840dongle_nrf52840\board.c.

    Emerson Warwick said:
    Might there be a problem ‘adapting firmware to set REGOUT0 properly’* that has not been realised?

    There should not be, but you will need to use a debugger and should avoid using the default bootloader in this case as it will constantly write to UICR on every reset if set to something other than 3V. Can you elaborate?

    Emerson Warwick said:
    Is the nRF52840 Dongle capable of producing 3.3V on VDD OUT?

    I do not see any reasons that should not work with regards to the HW.

    Emerson Warwick said:
    Unfortunately, there is no easy access to board.c file by building the developer environment using nRF Connect for Desktop > Toolchain Manager > VS Code with nRFConnect for VS Code > Create a new application from sample ‘zephyr/samples/basic/blink

    The dirty way would be to edit this file in place, which you can do for easy testing as you have described below. This will also work when using the toolchain manager. The "proper" way would probably be to make your own board, where you could simply copy the whole nrf52840dongle_nrf52840 folder into your project and make the required adjustment(s). See Custom boards.

    Emerson Warwick said:
    Steps to reproduce

    This approach looks good. However, I see now that this will not work though, and can never work with this approach, so my previous answer was incorrect. Specifically I remembered the values of REGOUT0 wrongly. From the documentation:

    When the dongle is shipped, REGOUT0 will be 0x4 which is "100", and to change this to 3V3 you need to make it 0x5 which is "101". This involves changing a '0' to a '1' and that can only be done with a page erase, not a writing. So unfortunately this can only be done using a debugger.

Related