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;