Index: firmware/App/Modes/ModeStandby.c =================================================================== diff -u -r2823873d5790228595fb991e52e78e2fd0d5987c -rb887b4a2796de3b26be07619809f8f4146955867 --- firmware/App/Modes/ModeStandby.c (.../ModeStandby.c) (revision 2823873d5790228595fb991e52e78e2fd0d5987c) +++ firmware/App/Modes/ModeStandby.c (.../ModeStandby.c) (revision b887b4a2796de3b26be07619809f8f4146955867) @@ -1,6 +1,7 @@ #include // For memcpy and memset +#include "reg_system.h" #include "sys_core.h" // To disable RAM and Flash ECC #include "sys_mpu.h" // To disable MPU @@ -9,6 +10,7 @@ #include "ModeStandby.h" #include "NVDataMgmt.h" #include "OperationModes.h" +#include "SystemComm.h" #include "Timers.h" #include "Utilities.h" @@ -19,7 +21,7 @@ // ********** private definitions ********** -#define WAIT_FOR_UPDATE_FROM_UI_MS 2000 ///< Wait for update timeout in milliseconds. +#define WAIT_FOR_UPDATE_FROM_UI_MS 1000 ///< Wait for update timeout in milliseconds. // ********** private data ********** @@ -28,10 +30,13 @@ // ********** private function prototypes ********** static MODE_STANDBY_STATE_T handleStandbyModeCheckForUpdateState( void ); -static MODE_STANDBY_STATE_T handleStandbyModeCheckFWAndFPGAImages( void ); +static MODE_STANDBY_STATE_T handleStandbyModeCheckFWAndFPGAImagesState( void ); static MODE_STANDBY_STATE_T handleStandbyModeIdleState( void ); +static MODE_STANDBY_STATE_T handleStandbyModeCheckUpdatedImageStates( void ); +static MODE_STANDBY_STATE_T handleStandyModeResetBootloaderState( void ); static void jumpToApplication( void ); +static void resetBootloader( void ); /*********************************************************************//** * @brief @@ -81,13 +86,21 @@ break; case STANDBY_CHECK_FW_AND_FPGA_IMAGES_STATE: - standbyCurrentState = handleStandbyModeCheckFWAndFPGAImages(); + standbyCurrentState = handleStandbyModeCheckFWAndFPGAImagesState(); break; case STANDBY_IDLE_STATE: standbyCurrentState = handleStandbyModeIdleState(); break; + case STANDBY_CHECK_UPDATED_IMAGE_STATE: + standbyCurrentState = handleStandbyModeCheckUpdatedImageStates(); + break; + + case STANDBY_RESET_BOOTLOADER_STATE: + standbyCurrentState = handleStandyModeResetBootloaderState(); + break; + default: // Do nothing break; @@ -119,50 +132,54 @@ break; case UPDATE_CMD_VERIFY: - state = STANDBY_CHECK_FW_AND_FPGA_IMAGES_STATE; + state = STANDBY_CHECK_UPDATED_IMAGE_STATE; break; + case UPDATE_CMD_IDLE: + if ( TRUE == didTimeout( getLastBroadcastMessageTimeStampMS(), WAIT_FOR_UPDATE_FROM_UI_MS ) ) + { + state = STANDBY_CHECK_FW_AND_FPGA_IMAGES_STATE; + } + break; + default: // Do nothing break; } - if ( TRUE == didTimeout( getLastBroadcastMessageTimeStampMS(), WAIT_FOR_UPDATE_FROM_UI_MS ) ) - { - state = STANDBY_CHECK_FW_AND_FPGA_IMAGES_STATE; - } - return state; } /*********************************************************************//** * @brief - * The handleStandbyModeCheckFWAndFPGAImages function handles the standby + * The handleStandbyModeCheckFWAndFPGAImagesState function handles the standby * check firmware and FPGA images state. * This state checks the integrity of the firmware as well as the FPGA header * to make sure the images are valid. * @details \b Inputs: none * @details \b Outputs: none * @return next state of the standby mode state machine *************************************************************************/ -static MODE_STANDBY_STATE_T handleStandbyModeCheckFWAndFPGAImages( void ) +static MODE_STANDBY_STATE_T handleStandbyModeCheckFWAndFPGAImagesState( void ) { MODE_STANDBY_STATE_T state = STANDBY_IDLE_STATE; BOOL isFirmwareImageValid = FALSE; BOOL isFPGAImageValid = FALSE; + SW_UPDATE_CMD_T cmd = getSWUpdateCommandState(); + // TODO why a bad code passes the CRC? - // TODO send the results back (pass/fail) up to be sent to the cloud. if ( TRUE == isFWCRCTableValid() ) { isFirmwareImageValid = runFWIntegrityTest(); } - if ( TRUE == isFPGAIDValid() ) // TODO change the FPGA ID to Leahi. It is not right now to not jump + if ( TRUE == isFPGAIDValid() ) { isFPGAImageValid = TRUE; } // NOTE: If either of the images (firmware or FPGA) failed, go to the idle state until another update request is received + // If both images are good and no update was in progress, jump to firmware address if ( ( TRUE == isFirmwareImageValid ) && ( TRUE == isFPGAImageValid ) ) { // All good, jump to application @@ -192,9 +209,76 @@ /*********************************************************************//** * @brief + * The handleStandbyModeCheckUpdatedImageStates function handles the standby + * check the updated image state. + * This state checks the validity of the updated image that the update + * was in progress. + * @details \b Inputs: none + * @details \b Outputs: none + * @return next state of the standby mode state machine + *************************************************************************/ +static MODE_STANDBY_STATE_T handleStandbyModeCheckUpdatedImageStates( void ) +{ + SW_UPDATE_RESP_STATUS_T resp; + U32 calcCRC = 0; + MODE_STANDBY_STATE_T state = STANDBY_RESET_BOOTLOADER_STATE; + SW_UPDATE_DESINTATION_T dest = getSWUpdateDestination(); + ACK_NACK_STATUS_T ackStatus = ACK; + BOOL status = FALSE; + + switch( dest ) + { + case UPDATE_FPGA: + status = isFPGAFlashSuccessful(); + ackStatus = ( TRUE == status ? ACK : NACK ); + break; + + case UPDATE_FIRMWARE: + status = runFWIntegrityTest(); + ackStatus = ( TRUE == status ? ACK : NACK ); + break; + + default: + // Do nothing + break; + } + + // NOTE: FPGA is check in self configure + resp.msgID = getCurrentCmdMessageID(); + resp.msgAckNackStatus = ackStatus; + resp.spareSpace = 0; + resp.msgCRC = crc32( calcCRC, (U08*)&resp, sizeof( SW_UPDATE_RESP_STATUS_T ) - sizeof( U32 ) ); + + // If both firmware and FPGA results passed, send an ack otherwise send a nack + sendAckNackStatusFromBootloader( (U08*)&resp ); + + return state; +} + +/*********************************************************************//** + * @brief + * The handleStandyModeResetBootloaderState function handles the standby + * reset bootloader state. + * This state resets the bootloader and transitions to idle state. + * @details \b Inputs: none + * @details \b Outputs: none + * @return next state of the standby mode state machine + *************************************************************************/ +static MODE_STANDBY_STATE_T handleStandyModeResetBootloaderState( void ) +{ + MODE_STANDBY_STATE_T state = STANDBY_IDLE_STATE; + + // Reset the bootloader regardless of whether the update was successful or not + resetBootloader(); + + return state; +} + +/*********************************************************************//** + * @brief * The jumpToApplication function handles the jump to application commands. * This function, disables interrupts that were used in the bootloader and - * then it jumps to the fimrware start address. + * then it jumps to the firmware start address. * @details \b Inputs: none * @details \b Outputs: none * @return none @@ -217,5 +301,18 @@ while(1); } +/*********************************************************************//** + * @brief + * The resetBootloader function resets the bootloader by soft reseting the + * processor. + * @details \b Inputs: none + * @details \b Outputs: none + * @return none + *************************************************************************/ +static void resetBootloader( void ) +{ + systemREG1->SYSECR = (0x2) << 14; // Reset processor +} + /**@}*/