EmberStatus halLaunchStandaloneBootloader(uint8_t mode) { if(BOOTLOADER_BASE_TYPE(halBootloaderAddressTable.bootloaderType) == BL_TYPE_STANDALONE) { // should never return if(mode == STANDALONE_BOOTLOADER_NORMAL_MODE) { // Version 0x0106 is where OTA bootloader support was added and the // RESET_BOOTLOADER_OTAVALID reset type was introduced. if(halBootloaderAddressTable.baseTable.version < 0x0106) { halInternalSysReset(RESET_BOOTLOADER_BOOTLOAD); } else { tokTypeStackCalData calData; // Convert channel number to index (bootloader only uses index). uint8_t channelIndex = emGetPhyRadioChannel() - 11; halCommonGetIndexedToken(&calData, TOKEN_STACK_CAL_DATA, channelIndex); halResetInfo.boot.panId = PAN_ID_REG; halResetInfo.boot.radioChannel = channelIndex; halResetInfo.boot.radioPower = emGetPhyRadioPower(); halResetInfo.boot.radioLnaCal = calData.lna; // ota parameters valid bootloader reset halInternalSysReset(RESET_BOOTLOADER_OTAVALID); } } else if(mode == STANDALONE_BOOTLOADER_RECOVERY_MODE) { // standard bootloader reset halInternalSysReset(RESET_BOOTLOADER_BOOTLOAD); } } return EMBER_ERR_FATAL; }
// The Simulated EEPROM Callback function. void halSimEepromCallback(EmberStatus status) { switch (status) { case EMBER_SIM_EEPROM_ERASE_PAGE_GREEN: //SimEE is asking for one page to be erased. #ifdef EMBER_STACK_COBRA HalUARTRestrain(); // temporarily hold off serial input from host #endif halSimEepromErasePage(); break; case EMBER_SIM_EEPROM_ERASE_PAGE_RED: case EMBER_SIM_EEPROM_FULL: { //SimEE says we're out of room! Erase all pages now or data //currently being written will be dropped. bool erasedSome = false; #ifdef EMBER_STACK_COBRA HalUARTRestrain(); // temporarily hold off serial input from host #endif while(halSimEepromErasePage()) { erasedSome = true; } if(erasedSome) { break; } //If nothing got erased, then we have a situation where page //rotation is stuck because live tokens still exist in the //page we want to erase. In this case we must do a repair to //get all live tokens into one virtual page. [BugzId:14392] //Fall into... } case EMBER_ERR_FLASH_WRITE_INHIBITED: case EMBER_ERR_FLASH_VERIFY_FAILED: { //Something went wrong while writing a token. There is stale data and the //token the app expected to write did not get written. Also there may //now be "stray" data written in the flash that could inhibit future token //writes. To deal with stray/stale data, we must repair the Simulated //EEPROM. Because the expected token write failed and will not be retried, //it is best to reset the chip and let normal boot sequences take over. //Since halInternalSimEeRepair() could potentially result in another write //failure, we use a simple semaphore to prevent recursion. static bool repairActive = false; if(!repairActive) { repairActive = true; halInternalSimEeRepair(false); switch (status) { case EMBER_SIM_EEPROM_FULL: //Don't reboot - return to let SimEE code retry the token write //[BugzId:14392] break; case EMBER_ERR_FLASH_VERIFY_FAILED: #if defined (CORTEXM3) halInternalSysReset(RESET_FLASH_VERIFY); #elif defined (EMBER_STACK_COBRA) halInternalSystemReset(RESET_FLASH); #else assert(0); #endif break; case EMBER_ERR_FLASH_WRITE_INHIBITED: #if defined (CORTEXM3) halInternalSysReset(RESET_FLASH_INHIBIT); #elif defined (EMBER_STACK_COBRA) halInternalSystemReset(RESET_FLASH); #else assert(0); #endif break; default: assert(0); break; } repairActive = false; } break; } case EMBER_SIM_EEPROM_REPAIRING: // While there's nothing for an app to do when the SimEE is going to // repair itself (SimEE has to be fully functional for the rest of the // system to work), alert the application to the fact that repairing // is occuring. There are debugging scenarios where an app might want // to know that repairing is happening; such as monitoring frequency. // NOTE: Common situations will trigger an expected repair, such as // using an erased chip or changing token definitions. break; default: // this condition indicates an unexpected problem. assert(0); break; } }
void halReboot(void) { halInternalSysReset(RESET_SOFTWARE_REBOOT); }