/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. * * The information contained herein is property of Nordic Semiconductor ASA. * Terms and conditions of usage are described in detail in NORDIC * SEMICONDUCTOR STANDARD SOFTWARE LICENSE AGREEMENT. * * Licensees are granted free, non-transferable use of the information. NO * WARRANTY of ANY KIND is provided. This heading must NOT be removed from * the file. * */ /**@file * * @defgroup ble_sdk_app_bootloader_main main.c * @{ * @ingroup dfu_bootloader_api * @brief Bootloader project main file. * * -# Receive start data packet. * -# Based on start packet, prepare NVM area to store received data. * -# Receive data packet. * -# Validate data packet. * -# Write Data packet to NVM. * -# If not finished - Wait for next packet. * -# Receive stop data packet. * -# Activate Image, boot application. * */ #include "dfu_transport.h" #include "bootloader.h" #include "bootloader_util.h" #include #include #include #include "nordic_common.h" #include "nrf.h" #include "nrf_soc.h" #include "app_error.h" #include "nrf_gpio.h" #include "ble.h" #include "nrf.h" #include "ble_hci.h" #include "app_scheduler.h" #include "app_timer_appsh.h" #include "nrf_error.h" #include "bsp.h" #include "softdevice_handler_appsh.h" #include "pstorage_platform.h" #include "nrf_mbr.h" #include "nrf_log.h" #include "uart.h" //zhou #include "flash.h" //zhou #include "nrf_delay.h" //zhou #if BUTTONS_NUMBER < 1 #error "Not enough buttons on board" #endif #if LEDS_NUMBER < 1 #error "Not enough LEDs on board" #endif #define IS_SRVC_CHANGED_CHARACT_PRESENT 1 /**< Include the service_changed characteristic. For DFU this should normally be the case. */ #define BOOTLOADER_BUTTON BSP_BUTTON_3 /**< Button used to enter SW update mode. */ #define UPDATE_IN_PROGRESS_LED BSP_LED_2 /**< Led used to indicate that DFU is active. */ #define APP_TIMER_PRESCALER 0 /**< Value of the RTC1 PRESCALER register. */ #define APP_TIMER_OP_QUEUE_SIZE 4 /**< Size of timer operation queues. */ #define SCHED_MAX_EVENT_DATA_SIZE MAX(APP_TIMER_SCHED_EVT_SIZE, 0) /**< Maximum size of scheduler events. */ #define SCHED_QUEUE_SIZE 20 /**< Maximum number of events in the scheduler queue. */ /**@brief Callback function for asserts in the SoftDevice. * * @details This function will be called in case of an assert in the SoftDevice. * * @warning This handler is an example only and does not fit a final product. You need to analyze * how your product is supposed to react in case of Assert. * @warning On assert from the SoftDevice, the system can only recover on reset. * * @param[in] line_num Line number of the failing ASSERT call. * @param[in] file_name File name of the failing ASSERT call. */ void assert_nrf_callback(uint16_t line_num, const uint8_t * p_file_name) { app_error_handler(0xDEADBEEF, line_num, p_file_name); } /**@brief Function for initialization of LEDs. */ //static void leds_init(void) //{ // nrf_gpio_range_cfg_output(LED_START, LED_STOP); // nrf_gpio_pins_set(LEDS_MASK); //} /**@brief Function for initializing the timer handler module (app_timer). */ static void timers_init(void) { // Initialize timer module, making it use the scheduler. APP_TIMER_APPSH_INIT(APP_TIMER_PRESCALER, APP_TIMER_OP_QUEUE_SIZE, true); } /**@brief Function for initializing the button module. */ //static void buttons_init(void) //{ // nrf_gpio_cfg_sense_input(BOOTLOADER_BUTTON, // BUTTON_PULL, // NRF_GPIO_PIN_SENSE_LOW); //} /**@brief Function for dispatching a BLE stack event to all modules with a BLE stack event handler. * * @details This function is called from the scheduler in the main loop after a BLE stack * event has been received. * * @param[in] p_ble_evt Bluetooth stack event. */ static void sys_evt_dispatch(uint32_t event) { pstorage_sys_event_handler(event); } /**@brief Function for initializing the BLE stack. * * @details Initializes the SoftDevice and the BLE event interrupt. * * @param[in] init_softdevice true if SoftDevice should be initialized. The SoftDevice must only * be initialized if a chip reset has occured. Soft reset from * application must not reinitialize the SoftDevice. */ static void ble_stack_init(bool init_softdevice) { uint32_t err_code; sd_mbr_command_t com = {SD_MBR_COMMAND_INIT_SD, }; nrf_clock_lf_cfg_t clock_lf_cfg = NRF_CLOCK_LFCLKSRC; if (init_softdevice) { err_code = sd_mbr_command(&com); APP_ERROR_CHECK(err_code); } err_code = sd_softdevice_vector_table_base_set(BOOTLOADER_REGION_START); APP_ERROR_CHECK(err_code); SOFTDEVICE_HANDLER_APPSH_INIT(&clock_lf_cfg, true); // Enable BLE stack. ble_enable_params_t ble_enable_params; // Only one connection as a central is used when performing dfu. err_code = softdevice_enable_get_default_config(1, 1, &ble_enable_params); APP_ERROR_CHECK(err_code); ble_enable_params.gatts_enable_params.service_changed = IS_SRVC_CHANGED_CHARACT_PRESENT; err_code = softdevice_enable(&ble_enable_params); APP_ERROR_CHECK(err_code); err_code = softdevice_sys_evt_handler_set(sys_evt_dispatch); APP_ERROR_CHECK(err_code); } /**@brief Function for event scheduler initialization. */ static void scheduler_init(void) { APP_SCHED_INIT(SCHED_MAX_EVENT_DATA_SIZE, SCHED_QUEUE_SIZE); } /**@brief Function for bootloader main entry. */ int main(void) { uint32_t err_code; bool dfu_start = false; bool app_reset = (NRF_POWER->GPREGRET == BOOTLOADER_DFU_START); bool app_gprs_reset = (NRF_POWER->GPREGRET == BOOTLOADER_DFU_GPRS_START); bool app_gprs_reset2 = ((*((uint8_t *)(DFU_APP_DATA_USER_START+40))) == BOOTLOADER_DFU_GPRS_START); if (app_reset) { NRF_POWER->GPREGRET = 0; } // else if(app_gprs_reset) // { // NRF_POWER->GPREGRET = 0; // } // leds_init(); // uart_init(); // This check ensures that the defined fields in the bootloader corresponds with actual // setting in the chip. APP_ERROR_CHECK_BOOL(*((uint32_t *)NRF_UICR_BOOT_START_ADDRESS) == BOOTLOADER_REGION_START); APP_ERROR_CHECK_BOOL(NRF_FICR->CODEPAGESIZE == CODE_PAGE_SIZE); // Initialize. timers_init(); //buttons_init(); // printf("BOOTLOADER START!app_gprs_reset is %d\r\n",app_gprs_reset); // nrf_delay_ms(200); // // if (*((uint32_t *)DFU_APP_DATA_USER_START) == EMPTY_FLASH_MASK) // { // //printf("BOOT filenum no value\r\n"); // nrf_delay_ms(200); // } // else // { // //printf("BOOT filenum is %d\r\n",*((uint32_t *)DFU_APP_DATA_USER_START)); // nrf_delay_ms(200); // } // if(app_gprs_reset && *((uint32_t *)DFU_APP_DATA_USER_START) != EMPTY_FLASH_MASK) // { // //uart_init(); // printf("BOOTLOADER GPRS UPGRADE!\r\n"); // nrf_delay_ms(200); // dfu_app_image_swap(); // nrf_delay_ms(4000); // bootloader_app_start(DFU_BANK_0_REGION_START); // //NVIC_SystemReset(); // } // if(app_gprs_reset) // { // //uart_init(); // printf("BOOTLOADER GPRS UPGRADE!\r\n"); // nrf_delay_ms(200); // dfu_app_image_swap(); // nrf_delay_ms(4000); // bootloader_app_start(DFU_BANK_0_REGION_START); // //NVIC_SystemReset(); // } (void)bootloader_init(); // if(app_gprs_reset) // { // //uart_init(); // printf("BOOTLOADER GPRS UPGRADE!\r\n"); // nrf_delay_ms(200); // dfu_app_image_swap(); // nrf_delay_ms(4000); // bootloader_app_start(DFU_BANK_0_REGION_START); // //NVIC_SystemReset(); // } if (bootloader_dfu_sd_in_progress()) { //nrf_gpio_pin_clear(UPDATE_IN_PROGRESS_LED); err_code = bootloader_dfu_sd_update_continue(); APP_ERROR_CHECK(err_code); ble_stack_init(!app_reset); scheduler_init(); err_code = bootloader_dfu_sd_update_finalize(); APP_ERROR_CHECK(err_code); // nrf_gpio_pin_set(UPDATE_IN_PROGRESS_LED); } else { // If stack is present then continue initialization of bootloader. ble_stack_init(!app_reset); scheduler_init(); // printf("stack start!\r\n"); } nrf_delay_ms(200); dfu_start = app_reset; //dfu_start |= ((nrf_gpio_pin_read(BOOTLOADER_BUTTON) == 0) ? true: false); if(app_gprs_reset || app_gprs_reset2) { //uart_init(); // printf("BOOTLOADER GPRS UPGRADE!\r\n"); // nrf_delay_ms(200); //flash_upgrade_op(); err_code = dfu_app_image_swap(); APP_ERROR_CHECK(err_code); nrf_delay_ms(4000); //NRF_POWER->GPREGRET = 0; sd_power_gpregret_clr(0xFF); bootloader_app_start(DFU_BANK_0_REGION_START); //NVIC_SystemReset(); } else if (dfu_start || (!bootloader_app_is_valid(DFU_BANK_0_REGION_START))) { // printf("ble upgrade start!\r\n"); //nrf_gpio_pin_clear(UPDATE_IN_PROGRESS_LED); // Initiate an update of the firmware. err_code = bootloader_dfu_start(); APP_ERROR_CHECK(err_code); //nrf_gpio_pin_set(UPDATE_IN_PROGRESS_LED); } if (bootloader_app_is_valid(DFU_BANK_0_REGION_START) && !bootloader_dfu_sd_in_progress()) { // Select a bank region to use as application region. // @note: Only applications running from DFU_BANK_0_REGION_START is supported. bootloader_app_start(DFU_BANK_0_REGION_START); } NVIC_SystemReset(); }