int Spark_Finish_Firmware_Update(FileTransfer::Descriptor& file, uint32_t flags, void* reserved) { SPARK_FLASH_UPDATE = 0; TimingFlashUpdateTimeout = 0; //DEBUG("update finished flags=%d store=%d", flags, file.store); if (flags & 1) { // update successful if (file.store==FileTransfer::Store::FIRMWARE) { hal_update_complete_t result = HAL_FLASH_End(NULL); system_notify_event(firmware_update, result!=HAL_UPDATE_ERROR ? firmware_update_complete : firmware_update_failed, &file); // always restart for now if (true || result==HAL_UPDATE_APPLIED_PENDING_RESTART) { system_pending_shutdown(); } } } else { system_notify_event(firmware_update, firmware_update_failed, &file); } RGB.control(false); return 0; }
int Spark_Finish_Firmware_Update(FileTransfer::Descriptor& file, uint32_t flags, void* reserved) { SPARK_FLASH_UPDATE = 0; TimingFlashUpdateTimeout = 0; //serial_dump("update finished flags=%d store=%d", flags, file.store); if (flags & 1) { // update successful if (file.store==FileTransfer::Store::FIRMWARE) { hal_update_complete_t result = HAL_FLASH_End(NULL); system_notify_event(firmware_update, result!=HAL_UPDATE_ERROR ? firmware_update_complete : firmware_update_failed, &file); // todo - talk with application and see if now is a good time to reset // if update not applied, do we need to reset? HAL_Core_System_Reset(); } } else { system_notify_event(firmware_update, firmware_update_failed, &file); } RGB.control(false); return 0; }
// this is called on multiple threads - ideally need a mutex void HAL_Notify_Button_State(uint8_t button, uint8_t pressed) { if (button==0) { if (pressed) { wasListeningOnButtonPress = network.listening(); buttonPushed = HAL_Timer_Get_Milli_Seconds(); if (!wasListeningOnButtonPress) // start of button press { system_notify_event(button_status, 0); } } else { int release_time = HAL_Timer_Get_Milli_Seconds(); uint16_t duration = release_time-buttonPushed; if (!network.listening()) { system_notify_event(button_status, duration); handle_button_click(duration, release_time); } buttonPushed = 0; if (duration>3000 && duration<8000 && wasListeningOnButtonPress && network.listening()) network.listen(true); } } }
int Spark_Prepare_For_Firmware_Update(FileTransfer::Descriptor& file, uint32_t flags, void* reserved) { if (file.store==FileTransfer::Store::FIRMWARE) { // address is relative to the OTA region. Normally will be 0. file.file_address = HAL_OTA_FlashAddress() + file.chunk_address; // chunk_size 0 indicates defaults. if (file.chunk_size==0) { file.chunk_size = HAL_OTA_ChunkSize(); file.file_length = HAL_OTA_FlashLength(); } } int result = 0; if (flags & 1) { // only check address } else { RGB.control(true); RGB.color(RGB_COLOR_MAGENTA); SPARK_FLASH_UPDATE = 1; TimingFlashUpdateTimeout = 0; system_notify_event(firmware_update, firmware_update_begin, &file); HAL_FLASH_Begin(file.file_address, file.file_length, NULL); } return result; }
void system_pending_shutdown() { uint8_t was_set = false; system_get_flag(SYSTEM_FLAG_RESET_PENDING, &was_set, nullptr); if (!was_set) { system_set_flag(SYSTEM_FLAG_RESET_PENDING, 1, nullptr); system_notify_event(reset_pending); } }
int Spark_Prepare_For_Firmware_Update(FileTransfer::Descriptor& file, uint32_t flags, void* reserved) { if (file.store==FileTransfer::Store::FIRMWARE) { // address is relative to the OTA region. Normally will be 0. file.file_address = HAL_OTA_FlashAddress() + file.chunk_address; // chunk_size 0 indicates defaults. if (file.chunk_size==0) { file.chunk_size = HAL_OTA_ChunkSize(); file.file_length = HAL_OTA_FlashLength(); } } int result = 0; if (flags & 1) { // only check address } else { uint32_t start = HAL_Timer_Milliseconds(); system_set_flag(SYSTEM_FLAG_OTA_UPDATE_PENDING, 1, nullptr); volatile bool flag = false; system_notify_event(firmware_update_pending, 0, nullptr, set_flag, (void*)&flag); System.waitCondition([&flag]{return flag;}, timeRemaining(start, 30000)); system_set_flag(SYSTEM_FLAG_OTA_UPDATE_PENDING, 0, nullptr); if (System.updatesEnabled()) // application event is handled asynchronously { RGB.control(true); RGB.color(RGB_COLOR_MAGENTA); SPARK_FLASH_UPDATE = 1; TimingFlashUpdateTimeout = 0; system_notify_event(firmware_update, firmware_update_begin, &file); HAL_FLASH_Begin(file.file_address, file.file_length, NULL); } else { result = 1; // updates disabled } } return result; }
int Spark_Save_Firmware_Chunk(FileTransfer::Descriptor& file, const uint8_t* chunk, void* reserved) { TimingFlashUpdateTimeout = 0; int result = -1; system_notify_event(firmware_update, firmware_update_progress, &file); if (file.store==FileTransfer::Store::FIRMWARE) { result = HAL_FLASH_Update(chunk, file.chunk_address, file.chunk_size, NULL); LED_Toggle(LED_RGB); } return result; }
void system_shutdown_if_needed() { static bool in_shutdown = false; if (canShutdown() && !in_shutdown) { in_shutdown = true; system_notify_event(reset, 0, nullptr, system_shutdown_if_enabled); #if PLATFORM_THREADING // timeout for 30 seconds. Keep the system thread pumping queue messages and the background task running system_tick_t start = millis(); while (canShutdown() && (millis()-start)<30000) { // todo - find a more enapsulated way for the SystemThread to take care of re-entranly // doing work. spark_process(); SystemThread.process(); } in_shutdown = false; system_shutdown_if_enabled(); #endif } }