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

UICR via armgcc

I need to set REGOUT0 to 3v3 for a custom board. What's the best way to do this using the armgcc toolchain? Right now, I'm setting the value first thing in my main:

int main(void) {

    NRF_UICR_Type *uicr = NRF_UICR;
    uicr = &((NRF_UICR_Type){ .REGOUT0 = UICR_REGOUT0_VOUT_3V3 });
    ...

Is there a way to bake the values into the hex file, itself, without futzing with linker scripts?

 
  • Hi,

    You can set this in code in a toolchain independent way like this (taken from <nRF5 SDK 16.0.0>\components\boards\boards.c):

    /**
     * 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();
        }
    }
    #endif
    

    Just modify it to set 3.3 V instead. As you can see, it does not erase the UICR page, and only writes to REGOUT0 if it has the default value (what it will have after a full chip erases), but that is sensible in most cases.

    There are other ways to do this as well, as you can see for instance by looking at how the bootloader starts address is written to UICR. This approach has the advantage that it does not add to the code size, and only adds the UICR value to the .hex file. However, it is toolchain-dependent and less obvious. If you want to use this approach, you can see how uicr_bootloader_start_address is used in <SDK16>\examples\dfu\secure_bootloader\pca10100_s140_ble\armgcc\secure_bootloader_gcc_nrf52.ld, and how it is used in <SDK16>\components\libraries\bootloader\nrf_bootloader_info.c.

Related