[nrf5340] Is there a way to set VREGHVOUT to 3.3V before mcuboot runs?

I want to implement FOTA Update for a nrf5340 based board by using nrfConnect SDK v2.9.0 with zephyr and mcuboot. The board has a MX25R6435F external flash (same as the nrf5340dk) which is powered by a LDO (3.3V). The nrf5340 is run in "High Voltage Mode" and powered by a Li-Ion battery. To read the external flash successfully the GPIO voltage of the nrf5340 has to be set to 3.3V by writing the UICR register.

This works as it should but a problem arises when I try to use the mcuboot bootloader with external flash configured (SB_CONFIG_PM_EXTERNAL_FLASH_MCUBOOT_SECONDARY=y). On boards that don't have the UICR configured correctly to 3.3V GPIO voltage, the bootloader won't be able to read the QSPI NOR flash and fail the boot process.

A solution would be to register a initialization function in mcuboot like:

SYS_INIT( earlyVREGHSet, PRE_KERNEL_1, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT );

My question is if there is a way to handle this problem without changing the mcuboot source in the nrfConnectSDK as I wouldn't like to maintain a fork.

Thanks in advance!

Parents
  • Hi Tarik,

    Your suggested way to do a pre kernel callback before mcuboot runs is a good way to do it in my opinion. But if you do not want to maintain a fork then you can do this in your custom board init function in  ncs\v2.9.0\bootloader\mcuboot\boot\zephyr\boards something like tihs

    void board_init(void)
    {
        // Check if VREGHVOUT is not set to 3.3V
        if ((NRF_UICR->VREGHVOUT & UICR_VREGHVOUT_VREGHVOUT_Msk) != UICR_VREGHVOUT_VREGHVOUT_Set6) {
            NRF_NVMC->CONFIG = NVMC_CONFIG_WEN_Wen;
            while (NRF_NVMC->READY == NVMC_READY_READY_Busy);
    
            NRF_UICR->VREGHVOUT = (NRF_UICR->VREGHVOUT & ~UICR_VREGHVOUT_VREGHVOUT_Msk)
                                | UICR_VREGHVOUT_VREGHVOUT_Set6;
    
            while (NRF_NVMC->READY == NVMC_READY_READY_Busy);
    
            NVIC_SystemReset();
        }
    }
    
    add this board file to your mcuboot\boot\zephyr CMakelists.txt file.

    Then it will be your project changes rather than trying to maintain a fork.

  • Thanks for the response. I wasn't aware that I could add source code to a custom board. This worked very well.

    If someone is interested: I ended up creating a board.c and a CMakeLists.txt in my custom board directory (something like ../boards/mycustomboard/ ):

    CMakeLists.txt

    # Compile custom board init when using CPUAPP
    if(CONFIG_BOARD_MYCUSTOMBOARD_NRF5340_CPUAPP OR CONFIG_BOARD_MYCUSTOMBOARD_NRF5340_CPUAPP_NS)
    zephyr_library()
    zephyr_library_sources(board.c)
    endif()

    board.c

    #include <nrf.h>
    #include <nrfx_nvmc.h>
    #include <zephyr/init.h>
    
    void board_init(void)
    {
        // Check if VREGHVOUT is not set to 3.3V
        if ((NRF_UICR->VREGHVOUT & UICR_VREGHVOUT_VREGHVOUT_Msk) != UICR_VREGHVOUT_VREGHVOUT_Set6) {
            NRF_NVMC->CONFIG = NVMC_CONFIG_WEN_Wen;
            while (NRF_NVMC->READY == NVMC_READY_READY_Busy);
    
            NRF_UICR->VREGHVOUT = (NRF_UICR->VREGHVOUT & ~UICR_VREGHVOUT_VREGHVOUT_Msk)
                                | UICR_VREGHVOUT_VREGHVOUT_Set6;
    
            while (NRF_NVMC->READY == NVMC_READY_READY_Busy);
    
            NVIC_SystemReset();
        }
    }
    SYS_INIT( board_init, PRE_KERNEL_1, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT );

    As mcuboot will use the boardfiles, board.c will be compiled and SYS_INIT() will be excecuted in PRE_KERNEL stage.

    I also found information here:

    https://academy.nordicsemi.com/courses/nrf-connect-sdk-intermediate/lessons/lesson-3-adding-custom-board-support/topic/creating-board-files/

Reply
  • Thanks for the response. I wasn't aware that I could add source code to a custom board. This worked very well.

    If someone is interested: I ended up creating a board.c and a CMakeLists.txt in my custom board directory (something like ../boards/mycustomboard/ ):

    CMakeLists.txt

    # Compile custom board init when using CPUAPP
    if(CONFIG_BOARD_MYCUSTOMBOARD_NRF5340_CPUAPP OR CONFIG_BOARD_MYCUSTOMBOARD_NRF5340_CPUAPP_NS)
    zephyr_library()
    zephyr_library_sources(board.c)
    endif()

    board.c

    #include <nrf.h>
    #include <nrfx_nvmc.h>
    #include <zephyr/init.h>
    
    void board_init(void)
    {
        // Check if VREGHVOUT is not set to 3.3V
        if ((NRF_UICR->VREGHVOUT & UICR_VREGHVOUT_VREGHVOUT_Msk) != UICR_VREGHVOUT_VREGHVOUT_Set6) {
            NRF_NVMC->CONFIG = NVMC_CONFIG_WEN_Wen;
            while (NRF_NVMC->READY == NVMC_READY_READY_Busy);
    
            NRF_UICR->VREGHVOUT = (NRF_UICR->VREGHVOUT & ~UICR_VREGHVOUT_VREGHVOUT_Msk)
                                | UICR_VREGHVOUT_VREGHVOUT_Set6;
    
            while (NRF_NVMC->READY == NVMC_READY_READY_Busy);
    
            NVIC_SystemReset();
        }
    }
    SYS_INIT( board_init, PRE_KERNEL_1, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT );

    As mcuboot will use the boardfiles, board.c will be compiled and SYS_INIT() will be excecuted in PRE_KERNEL stage.

    I also found information here:

    https://academy.nordicsemi.com/courses/nrf-connect-sdk-intermediate/lessons/lesson-3-adding-custom-board-support/topic/creating-board-files/

Children
No Data
Related