My device doesn't goes into DFU with new hardware, with old hardware its completely working fine

The first mage is old hardware, the second one is new hardware,
all the other functionality works fine with both the hardware but when I want to firmware update the new hardware does not goes into DFU Bootloader mode,
where old hardware firmware update works perfectly with the same firmware.

Old hardware have Skylab SKB501 module nrf52840_XAA REV2
new hardware have nrf52840_XAA REV3

Pin configuration code for new hardware:

#define MAX_ROW_PIN 10
#define MAX_COL_PIN 4
#define ROW_1   NRF_GPIO_PIN_MAP(0, 18)
#define ROW_2   NRF_GPIO_PIN_MAP(0, 17)
#define ROW_3   NRF_GPIO_PIN_MAP(0, 14)
#define ROW_4   NRF_GPIO_PIN_MAP(0, 13)
#define ROW_5   NRF_GPIO_PIN_MAP(0, 12)
#define ROW_6   NRF_GPIO_PIN_MAP(0, 11)
#define ROW_7   NRF_GPIO_PIN_MAP(1, 9)
#define ROW_8   NRF_GPIO_PIN_MAP(1, 8)
#define ROW_9   NRF_GPIO_PIN_MAP(0, 8)
#define ROW_10  NRF_GPIO_PIN_MAP(0, 7)

#define COL_1    NRF_GPIO_PIN_MAP(0, 21)
#define COL_2    NRF_GPIO_PIN_MAP(0, 22)
#define COL_3    NRF_GPIO_PIN_MAP(0, 23)
#define COL_4    NRF_GPIO_PIN_MAP(0, 24)

uint32_t row_pins[MAX_ROW_PIN] = {ROW_1,ROW_2,ROW_3,ROW_4,ROW_5,ROW_6,ROW_7,ROW_8,ROW_9,ROW_10};
uint32_t col_pins[MAX_COL_PIN] = {COL_1,COL_2,COL_3,COL_4};

uint64_t get_key_number() {
    uint64_t key_bitmap = 0;

    for (uint8_t i = 0; i < MAX_COL_PIN; i++) {
        nrf_drv_gpiote_in_event_disable(col_pins[i]);
    }

    for (uint8_t i = 0; i < MAX_ROW_PIN; i++) {
        for (uint8_t j = 0; j < MAX_ROW_PIN; j++) {
            if (i != j) {
                nrf_gpio_pin_clear(row_pins[j]);
            }
        }

        for (uint8_t j = 0; j < MAX_COL_PIN; j++) {
            if (nrf_gpio_pin_read(col_pins[j]) == 1) {
                uint8_t key_number = (i * MAX_COL_PIN) + j;
                set_bit(&key_bitmap, key_number);
                // ilumi_log("%d, %d, key number: %d\r\n", i + 1, j + 1, key_number);
            }
        }

        for (uint8_t j = 0; j < MAX_ROW_PIN; j++) {
            nrf_gpio_pin_set(row_pins[j]);
        }
    }

    for (uint8_t i = 0; i < MAX_COL_PIN; i++) {
        nrf_drv_gpiote_in_event_enable(col_pins[i], true);
    }

    return key_bitmap;
}

// GPIOTE event handler
void gpiote_event_handler(nrf_drv_gpiote_pin_t pin, nrf_gpiote_polarity_t action) {
    // Wake up the system from sleep mode
    CRITICAL_REGION_ENTER();
    if(action == NRF_GPIOTE_POLARITY_LOTOHI){
        if (nrf_gpio_pin_read(pin)) {
            start_gpio_read_timer();
        }
    }
    CRITICAL_REGION_EXIT();
}
/** A function to initialize the GPIOs
**/
void ilumi_initialize_pins(void)
{
    nrf_gpio_cfg_output(RED_LED);

    nrf_gpio_pin_clear(RED_LED);
    // Initialize GPIOTE driver
    ret_code_t err_code = nrf_drv_gpiote_init();
    APP_ERROR_CHECK(err_code);

    // Configure columns for sensing with pull-down resistors
    nrf_drv_gpiote_in_config_t in_config = NRFX_GPIOTE_CONFIG_IN_SENSE_LOTOHI(true);
    in_config.pull = NRF_GPIO_PIN_NOPULL;

    // Configure each column pin to generate an interrupt on state change
    for (int i = 0; i < MAX_COL_PIN; i++) {
        err_code = nrf_drv_gpiote_in_init(col_pins[i], &in_config, gpiote_event_handler);
        APP_ERROR_CHECK(err_code);
        nrf_drv_gpiote_in_event_enable(col_pins[i], true);
    }

    // Configure row pins as outputs
    for (int i = 0; i < sizeof(row_pins) / sizeof(row_pins[0]); i++) {
        nrf_gpio_cfg_output(row_pins[i]);
        nrf_gpio_pin_set(row_pins[i]);
    }

    // Configure column pins as inputs with no pull resistors (external pull-down)
    for (int i = 0; i < MAX_COL_PIN; i++) {
        nrf_gpio_cfg_input(col_pins[i], NRF_GPIO_PIN_NOPULL);
    }
}

void gpio_read_timer_event_handler(void * p_context){
    CRITICAL_REGION_ENTER();
    force_to_sleep = false;
    if(!commission_data.is_commissioned){
            wake_device_from_sleep=true;
        goto EXIT_READ_KEY;
    }
    if(commission_data.is_commissioned && ilumi_adv_stop_timer_running()){
        goto EXIT_READ_KEY;
    }
    key_status |= get_key_number();
    if(get_bit(key_status,0)){
        clear_bit(&key_status,0);
        isResetKeyPressed = true;
        start_long_press_timer();
    }else if(get_bit(key_status,3)){
        clear_bit(&key_status,3);
        isRebootKeyPressed = true;
        start_long_press_timer();
    }else{
        start_key_process_timer();
    }
    // ilumi_log("KEY : 0x%" PRIx64 "\r\n",key_status);
EXIT_READ_KEY:
    CRITICAL_REGION_EXIT();
}

void create_gpio_read_timer(void)
{
    ret_code_t ret = app_timer_create(&gpio_read_timer, APP_TIMER_MODE_SINGLE_SHOT, gpio_read_timer_event_handler);
	if(ret != NRF_SUCCESS)
		ilumi_debug("Failed to Create GPIO Read Timer, error %d\r\n", ret);
}

void start_gpio_read_timer(void)
{
    stop_gpio_read_timer();
	ret_code_t ret = app_timer_start(gpio_read_timer, APP_TIMER_TICKS(50), NULL);
	if(ret != NRF_SUCCESS)
		ilumi_debug("Failed to Start GPIO Read Timer, error %d\r\n", ret);
}

void stop_gpio_read_timer(void)
{
	ret_code_t ret = app_timer_stop(gpio_read_timer);

	if(ret != NRF_SUCCESS)
		ilumi_debug("Failed to stop the long press timer. error %d\r\n", ret);
}
 

Pin configuration for old hardware:

#define RED_LED     ((uint32_t)26)  //ACTIVE_LOW
#define GREEN_LED   ((uint32_t)27)  //ACTIVE_LOW
#define USER_SW_3   ((uint32_t)28)  //ACTIVE_LOW   
#define USER_SW_6   ((uint32_t)29)  //ACTIVE_LOW
#define USER_SW_2   ((uint32_t)30)  //ACTIVE_LOW
#define USER_SW_4   ((uint32_t)31)  //ACTIVE_LOW
#define USER_SW_1   ((uint32_t)2)   //ACTIVE_LOW
#define USER_SW_5   ((uint32_t)3)   //ACTIVE_LOW
#define  USER_SW (uint32_t[]){USER_SW_1,USER_SW_2,USER_SW_3,USER_SW_4,USER_SW_5,USER_SW_6}

uint8_t long_press_timer_active_flag = 0x00;
uint8_t long_press_time_counter = 0x00; 			// increments every second

bool is_sw1_pressed = false,is_sw2_pressed =false;

void ilumi_button_event_handler(uint8_t pin_no, uint8_t button_action){
    force_to_sleep = false;
    if(!commission_data.is_commissioned){
        if(button_action == APP_BUTTON_PUSH){
            wake_device_from_sleep=true;
        }
        return;
    }
    if(commission_data.is_commissioned && ilumi_adv_stop_timer_running())
        return;    

    switch(pin_no){
        case USER_SW_1:
        if(button_action == APP_BUTTON_PUSH){
            is_sw1_pressed = true;
            start_long_press_timer();
        }else{
            is_sw1_pressed = false;
            if(long_press_timer_active_flag)
                stop_long_press_timer(); 
            if(is_device_waking_up==true || user_sw_reset_flag==1){
                is_device_waking_up = false;
                break;
            }                
            sw_action.sw1_action = 1;
        }
        break;

        case USER_SW_2:
        if(button_action == APP_BUTTON_PUSH){
            is_sw2_pressed = true;
            if(is_sw1_pressed){
                start_long_press_timer();
            }            
        }else{
            is_sw2_pressed = false;
            if(long_press_timer_active_flag)
                stop_long_press_timer(); 
            if(user_sw_reset_flag==1)
                break;                 
            sw_action.sw2_action = 1;               
        }
        break;   

        case USER_SW_3:
        if(button_action == APP_BUTTON_PUSH){
            sw_action.sw3_action = 1;                      
        }
        break;
        
        case USER_SW_4:
        if(button_action == APP_BUTTON_PUSH){
            sw_action.sw4_action = 1;                       
        }
        break;  

        case USER_SW_5:
        if(button_action == APP_BUTTON_PUSH){
            sw_action.sw5_action = 1;                        
        }
        break;
        
        case USER_SW_6:
        if(button_action == APP_BUTTON_PUSH){
            sw_action.sw6_action = 1;                        
        }
        break;          
    }
}

/** A function to initialize the GPIOs
**/
void ilumi_initialize_pins(void)
{
    nrf_gpio_cfg_output(RED_LED);
    nrf_gpio_cfg_output(GREEN_LED);

    nrf_gpio_pin_set(RED_LED);
    nrf_gpio_pin_set(GREEN_LED);

    static app_button_cfg_t button[6] = {
        {
            USER_SW_1,
            APP_BUTTON_ACTIVE_HIGH,
            NRF_GPIO_PIN_NOPULL,
            ilumi_button_event_handler
        },
        {
            USER_SW_2,
            APP_BUTTON_ACTIVE_HIGH,
            NRF_GPIO_PIN_NOPULL,
            ilumi_button_event_handler,
        },
        {
            USER_SW_3,
            APP_BUTTON_ACTIVE_HIGH,
            NRF_GPIO_PIN_NOPULL,
            ilumi_button_event_handler,
        },
        {
            USER_SW_4,
            APP_BUTTON_ACTIVE_HIGH,
            NRF_GPIO_PIN_NOPULL,
            ilumi_button_event_handler,
        },
        {
            USER_SW_5,
            APP_BUTTON_ACTIVE_HIGH,
            NRF_GPIO_PIN_NOPULL,
            ilumi_button_event_handler,
        },
        {
            USER_SW_6,
            APP_BUTTON_ACTIVE_HIGH,
            NRF_GPIO_PIN_NOPULL,
            ilumi_button_event_handler,
        }

    };

    APP_ERROR_CHECK(app_button_init(&button[0], 6, APP_TIMER_TICKS(50)));
    APP_ERROR_CHECK(app_button_enable());  
}


My device goes into DFU bootloader with which is perfectly working fine with old hardware
        
        //On receiving following command over BLE
        case CONFIG_ENTER_BOOTLOADER:

        sd_power_gpregret_set(0, 0xB1);


        ilumi_log("starting bootloder...\r\n");
        nrf_delay_ms(1000);

        sd_nvic_SystemReset();   // reset system to enter in bootloader

        break;

  • Hello,

    What SDK version are you using?

    It may be that you need to update the MDK for the latest revision of the chip. If not, you may miss a bunch of included workarounds for erratas. So if possible, you should port the entire application and bootloader to SDK17.1.0, but if that is too much work, you can try to only update the MDK from the latest SDK. The MDK in SDK17.1.0 is found in SDK\modules\nrfx\mdk.

    Best regards,

    Edvin

  • Hi Edvin,

    I am already using SDK V17.1.0. So how can I update the MDK can you please let me know the steps.


  • does above affect the dfu operations?

    i have read it in errata

  • I don't think it does, since the bootloader doesn't really check the resetreason. It uses another register (GPREGRET) to check whether it should enter DFU mode or not.

    Can you please try to use the debug version of the bootloader found in:

    SDK\examples\dfu\secure_bootloader\pca10056_s140_ble_debug, instead of your "normal" bootloader, and then monitor the RTT logs. What does the log say?

    Best regards,

    Edvin

  • 00> <info> app: Inside main
    00> 
    00> <debug> app: In nrf_bootloader_init
    00> 
    00> <debug> nrf_dfu_settings: Calling nrf_dfu_settings_init()...
    00> 
    00> <debug> nrf_dfu_flash: Initializing nrf_fstorage_nvmc backend.
    00> 
    00> <warning> nrf_dfu_settings: Resetting bootloader settings since neither the settings page nor the backup are valid (CRC error).
    00> 
    00> <debug> nrf_dfu_settings: Writing settings...
    00> 
    00> <debug> nrf_dfu_settings: Erasing old settings at: 0x000FF000
    00> 
    00> <debug> nrf_dfu_flash: nrf_fstorage_erase(addr=0x0x000FF000, len=1 pages), queue usage: 0
    00> 
    00> <debug> nrf_dfu_flash: Flash erase success: addr=0x000FF000, pending 0
    00> 
    00> <debug> nrf_dfu_flash: nrf_fstorage_write(addr=0x000FF000, src=0x2000AB38, len=896 bytes), queue usage: 1
    00> 
    00> <debug> nrf_dfu_flash: Flash write success: addr=0x000FF000, pending 0
    00> 
    00> <info> nrf_dfu_settings: Backing up settings page to address 0xFE000.
    00> 
    00> <debug> nrf_dfu_settings: Writing settings...
    00> 
    00> <debug> nrf_dfu_settings: Erasing old settings at: 0x000FE000
    00> 
    00> <debug> nrf_dfu_flash: nrf_fstorage_erase(addr=0x0x000FE000, len=1 pages), queue usage: 1
    00> 
    00> <debug> nrf_dfu_flash: Flash erase success: addr=0x000FE000, pending 0
    00> 
    00> <debug> nrf_dfu_flash: nrf_fstorage_write(addr=0x000FE000, src=0x2000A7B8, len=896 bytes), queue usage: 1
    00> 
    00> <debug> nrf_dfu_flash: Flash write success: addr=0x000FE000, pending 0
    00> 
    00> <debug> app: Enter nrf_bootloader_fw_activate
    00> 
    00> <info> app: No firmware to activate.
    00> 
    00> <info> app: Boot validation failed. No valid app to boot.
    00> 
    00> <debug> app: DFU mode because app is not valid.
    00> 
    00> <info> nrf_bootloader_wdt: WDT is not enabled
    00> 
    00> <debug> app: in weak nrf_dfu_init_user
    00> 
    00> <debug> app: timer_stop (0x2000599C)
    00> 
    00> <debug> app: timer_activate (0x2000599C)
    00> 
    00> <info> app: Entering DFU mode.
    00> 
    00> <error> app: Received a fault! id: 0x00004002, pc: 0x00000000, info: 0x2003FFA8

    I have attached the DFU logs, can you please check and let me know the issue.

Related