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

The green LED LD1 (LED1) will not light up when adapting ble_blinky_c for nRF52840 dongle.

Sorry in advance for the length and possible irrelevance of some of what I have written here Disappointed

So I am trying to figure out how the ble software works. I have the ble_app_blinky as server and which has a definition for working with pca10059 the board for the nrf52840 dongle board and am adapting the ble_app_blinky_c  as client. This only has a defined board pca10056 for the nRF52840 mk board (which I do not yet have, but have now purchased as it is going to be very difficult to develop with just a dongle...) The code builds fine, no errors (now that I have a set of defines for VS Code that seem to work) and I can flash soft device and application or separately as required.

The apps work, except...

On the ble_blinky_c I think the green led 1 LD1 which has the value 0 in the code won't come on. It should come on I think at startup whilst waiting to connect to the other board (that does come on green whilst advertising) I have swapped the boards round to check that the green led (LD1) does come on on both boards, so not a hardware fault.) I noticed that there is a very brief flash of LD1 though it looks red? Not enough voltage????

I just want to be able to light LD1.

I did try to chase the code - but it's spaghetti and with no debugger I'm not getting anywhere, but I did want to show I tried...

I also tried using a low level line of code in main.c that could light the LD2 led colours, but not the LD1.

I tried doing this by just doing

    //bsp_board_leds_on();  
    //nrf_gpio_pin_clear(0);
    
    bsp_board_led_on(0);
    //nrf_gpio_pin_set(0);
    nrf_delay_ms(3000);
after the inits.
Will work for    bsp_board_led_on(1);  //and 2,3 (red, green, blue)
 
Thinking that perhaps one of the intialise routines has done something I put the led on code after leds_init(), but no joy

    log_init();

    leds_init();

    bsp_board_led_on(0);
    nrf_delay_ms(3000);

I suspect that the LD1 is not getting configured/Initialised properly, but surely that common code is fine?

Is there something in the code that works fine for the pca10056 board, but screws things up in pca10059?

The rest of this post is probably irrelevant, but here is my trace through

main.c: --> 

leds_init(); -->
bsp_board_init(BSP_INIT_LEDS); -->
boards.h-->
#define BSP_INIT_LEDS    (1 << 0)
boards.c-->  (I don't think I have a board with the DFU trigger (yet) so I ignored that code as did VS Code? (how) Another define I should be aware of?
    #if LEDS_NUMBER > 0
    if (init_flags & BSP_INIT_LEDS)
    {
        bsp_board_leds_init();
    }
    #endif //LEDS_NUMBER > 0
//then an interesting bit of code
static void bsp_board_leds_init(void)
{
    #if defined(BOARD_PCA10059)
    // If nRF52 USB Dongle is powered from USB (high voltage mode),
    // GPIO output voltage is set to 1.8 V by default, which is not
    // enough to turn on green and blue LEDs. Therefore, GPIO voltage
    // needs to be increased to 3.0 V by configuring the UICR register.
    if (NRF_POWER->MAINREGSTATUS &
       (POWER_MAINREGSTATUS_MAINREGSTATUS_High << POWER_MAINREGSTATUS_MAINREGSTATUS_Pos))
    {
        gpio_output_voltage_setup();
    }
    #endif

    uint32_t i;
    for (i = 0i < LEDS_NUMBER; ++i)
    {
        nrf_gpio_cfg_output(m_board_led_list[i]);
    }
    bsp_board_leds_off();
}
I'm assuming this gets set as I can turn on all the leds for LD2 (red green blue)
This line seems to be key:
 gpio_output_voltage_setup();
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
but I can't believe this doesn't work???
also there is
nrf_gpio_cfg_output(m_board_led_list[i]);
m_board_led_list is an array of the following (I don't understand this pattern.)
LEDS_LIST is an array of the 4 leds
#define LED1_G         NRF_GPIO_PIN_MAP(0,6)
#define LED2_R         NRF_GPIO_PIN_MAP(0,8)
#define LED2_G         NRF_GPIO_PIN_MAP(1,9)
#define LED2_B         NRF_GPIO_PIN_MAP(0,12)
These look fine according to the dongle documentation (and I know this board works for the ble_app_blinky app or just plain blinky)
Still in boards.c, call this function for each led
nrf_gpio_cfg_output() --> nrf_gpio.h
Calls 
__STATIC_INLINE void nrf_gpio_cfg_output(uint32_t pin_number)
{
    nrf_gpio_cfg(
        pin_number,
        NRF_GPIO_PIN_DIR_OUTPUT,
        NRF_GPIO_PIN_INPUT_DISCONNECT,
        NRF_GPIO_PIN_NOPULL,
        NRF_GPIO_PIN_S0S1,
        NRF_GPIO_PIN_NOSENSE);
}
calls 
__STATIC_INLINE void nrf_gpio_cfg(
    uint32_t             pin_number,
    nrf_gpio_pin_dir_t   dir,
    nrf_gpio_pin_input_t input,
    nrf_gpio_pin_pull_t  pull,
    nrf_gpio_pin_drive_t drive,
    nrf_gpio_pin_sense_t sense)
{
    NRF_GPIO_Type * reg = nrf_gpio_pin_port_decode(&pin_number);

    reg->PIN_CNF[pin_number] = ((uint32_t)dir << GPIO_PIN_CNF_DIR_Pos)
                               | ((uint32_t)input << GPIO_PIN_CNF_INPUT_Pos)
                               | ((uint32_t)pull << GPIO_PIN_CNF_PULL_Pos)
                               | ((uint32_t)drive << GPIO_PIN_CNF_DRIVE_Pos)
                               | ((uint32_t)sense << GPIO_PIN_CNF_SENSE_Pos);
}
The nrfgpio_pin_port_decode calls
__STATIC_INLINE NRF_GPIO_Type * nrf_gpio_pin_port_decode(uint32_t * p_pin)
{
    NRFX_ASSERT(nrf_gpio_pin_present_check(*p_pin));
#if (GPIO_COUNT == 1)
    return NRF_P0;
#else
    if (*p_pin < P0_PIN_NUM)
    {
        return NRF_P0;
    }
    else
    {
        *p_pin = *p_pin & 0x1F;
        return NRF_P1;
    }
#endif
and this started going into the hal (hardware abstraction layer?) and at this point I almost lost the will to live.
So I tried an alternative approach, though I suspect that if the LEDs are not initialised properly all bets are off
I noted this routine
bsp_board_leds_off();
I figured there was also one for bsp_boards_leds_on();
and there is in boards,c
It calls 
bsp_board_led_on(i); for each led 0 to 3
This calls 
ASSERT(led_idx < LEDS_NUMBER);
nrf_gpio_pin_write(m_board_led_list[led_idx], LEDS_ACTIVE_STATE ? 1 : 0);
I have no idea what ASSERT does?
but the nrf_gpio_pin_write looks interesting  (LEDS_ACTIVE_STATE is 0 i.e. to light a led take the pin low
This then leads to 
nrf_gpio_pin_clear(pin_number); 
This calls in nrf_gpio.h
__STATIC_INLINE void nrf_gpio_pin_clear(uint32_t pin_number)
{
    NRF_GPIO_Type * reg = nrf_gpio_pin_port_decode(&pin_number);

    nrf_gpio_port_out_clear(reg1UL << pin_number);
}
I'm assuming that pin_number is simply a 0,1,2 or 3 
and then I started to get lost as I think this is now getting into actual hardware manipulation.
However, basically I did this to ask how the hell are we supposed to work with the dongle if it doesn't have a debugger and what sort of twisted genius? developed all this crud just to light a led!!!!
Parents Reply Children
Related