Index: firmware/App/Common.h =================================================================== diff -u -rf6fd9dfd1a30412e237ff45ebee44854f0e2d4b2 -r621896c8a4cc9204a12a7243ccef729c37e50c52 --- firmware/App/Common.h (.../Common.h) (revision f6fd9dfd1a30412e237ff45ebee44854f0e2d4b2) +++ firmware/App/Common.h (.../Common.h) (revision 621896c8a4cc9204a12a7243ccef729c37e50c52) @@ -136,7 +136,7 @@ UPDATE_CMD_START = 0, ///< Update command start. UPDATE_CMD_ABORT, ///< Update command abort. UPDATE_CMD_VERIFY, ///< Update command verify. - UPDATE_CMD_RESYNC, ///< Update command resync. + UPDATE_CMD_CONFIG_FPGA, ///< Update command configure FPGA. UPDATE_CMD_IDLE, ///< Update command idle. NUM_OF_UPDATE_CMDS ///< Number of update commands. } SW_UPDATE_CMD_T; Index: firmware/App/Modes/ModeStandby.c =================================================================== diff -u -rab214e8ea52d8433b7cee58f5aaff49fc759310d -r621896c8a4cc9204a12a7243ccef729c37e50c52 --- firmware/App/Modes/ModeStandby.c (.../ModeStandby.c) (revision ab214e8ea52d8433b7cee58f5aaff49fc759310d) +++ firmware/App/Modes/ModeStandby.c (.../ModeStandby.c) (revision 621896c8a4cc9204a12a7243ccef729c37e50c52) @@ -69,7 +69,7 @@ U32 execStandbyMode( void ) { // If the bootloader is in standby mode and update request is received at any time, request a transition to update mode - if ( ( UPDATE_CMD_START == getSWUpdateCommandState() ) || ( TRUE == hasUpdateBeenRequested() ) ) + if ( UPDATE_CMD_START == getSWUpdateCommandState() ) { requestNewOperationMode( MODE_UPDATE ); } Index: firmware/App/Services/Download.c =================================================================== diff -u -rf6fd9dfd1a30412e237ff45ebee44854f0e2d4b2 -r621896c8a4cc9204a12a7243ccef729c37e50c52 --- firmware/App/Services/Download.c (.../Download.c) (revision f6fd9dfd1a30412e237ff45ebee44854f0e2d4b2) +++ firmware/App/Services/Download.c (.../Download.c) (revision 621896c8a4cc9204a12a7243ccef729c37e50c52) @@ -236,16 +236,31 @@ SWUpdateSpecs.dest = (SW_UPDATE_DESINTATION_T)SWUpdateCmdStatus.destination; ackStatus = ACK; - if ( UPDATE_FPGA == SWUpdateSpecs.dest ) // TODO once verify command is received for FPGA, make sure the prepare signal is not sent again + if ( UPDATE_FPGA == SWUpdateSpecs.dest ) { - // If the update destination is FPGA, signal FPGA to prepare for the update. - signalFPGAToPrepareForUpdate(); + switch ( SWUpdateSpecs.cmd ) + { + case UPDATE_CMD_START: + // If the update destination is FPGA, signal FPGA to prepare for the update. + signalFPGAToPrepareForUpdate(); + break; + + case UPDATE_CMD_CONFIG_FPGA: + // Signal FPGA to self configure after the update is finished. + signalFPGAToSelfConfigure(); + break; + + default: + // Do nothing for the rest of the commands + break; + } } } if ( SWUpdateSpecs.dest != UPDATE_FPGA ) { - // Send the result of the command received + // Send the result of the command received for firmware. + // FPGA is delayed and it takes a while to prepare it so ack is not sent immediately prepareAndSendBootLoaderResponseMessage( msgID, ackStatus ); } @@ -309,13 +324,19 @@ case UPDATE_FPGA: ackStatus = handleFPGAUpdate(); // For FPGA update, do not send the ack status immediately since the jobs are queued + // For consistency we still receive the ack status but it is not sent. break; default: // Do nothing break; } } + else + { + // CRC did not pass send a nack + prepareAndSendBootLoaderResponseMessage( msgID, ackStatus ); + } } } @@ -423,34 +444,27 @@ ACK_NACK_STATUS_T ackStatus = NACK; BOOL status = FALSE; -//#define SW_UPDATE_FINAL_MSG_INDEX 0xFFFF // TODO: Remove. NOTE: once FPGA is ready investigate and remove 0xFFFF + fpgaPayloadLengthBytes = SWUpdateRCVStatus.updatePayloadLen; + REMOVETHEVAR += fpgaPayloadLengthBytes; - //if ( SWUpdateRCVStatus.updatePayloadLen != SW_UPDATE_FINAL_MSG_INDEX ) // TODO remove - //{ - fpgaPayloadLengthBytes = SWUpdateRCVStatus.updatePayloadLen; - REMOVETHEVAR += fpgaPayloadLengthBytes; + status = signalFPGAToWriteToFlash( SWUpdateRCVStatus.SWUpdateBuffer, fpgaPayloadLengthBytes ); - status = signalFPGAToWriteToFlash( SWUpdateRCVStatus.SWUpdateBuffer, fpgaPayloadLengthBytes ); - - if ( fpgaPayloadLengthBytes < SW_UPDATE_FLASH_BUFFER_SIZE ) - { - // TODO this should be a command and not the last buffer because what if the last payload is 256 bytes? - signalFPGAToSelfConfigure(); - } - - if ( TRUE == status ) - { - // The update payload has been enqueued successfully, clear the buffers - SW_UPDATE_CAN_MAIL_BOX_T thisStackMailBox = RECEIVE_MSG_ID[ BL_STACK_ID ][ FW_STACKS_RCV_MAIL_BOX_INDEX ]; - - clearCommBuffer( thisStackMailBox ); - //clearSWUpdateBuffer(); // TODO remove? - } - //} - //else + // TODO remove this code + //if ( fpgaPayloadLengthBytes < SW_UPDATE_FLASH_BUFFER_SIZE ) //{ - // prepareAndSendBootLoaderResponseMessage( SWUpdateRCVStatus.msgID, ACK ); + // // TODO this should be a command and not the last buffer because what if the last payload is 256 bytes? + // signalFPGAToSelfConfigure(); //} + if ( TRUE == status ) + { + // The update payload has been enqueued successfully, clear the raw buffer but keep the receive buffer since the enqueue + // to write to the FPGA buffer is delayed until the FPGA is ready and there is enough bytes available in the FIFO. + // The receive buffer is cleared once the write to FPGA is scheduled. + SW_UPDATE_CAN_MAIL_BOX_T thisStackMailBox = RECEIVE_MSG_ID[ BL_STACK_ID ][ FW_STACKS_RCV_MAIL_BOX_INDEX ]; + + clearCommBuffer( thisStackMailBox ); + } + return ackStatus; } Index: firmware/App/Services/FPGA.c =================================================================== diff -u -rf6fd9dfd1a30412e237ff45ebee44854f0e2d4b2 -r621896c8a4cc9204a12a7243ccef729c37e50c52 --- firmware/App/Services/FPGA.c (.../FPGA.c) (revision f6fd9dfd1a30412e237ff45ebee44854f0e2d4b2) +++ firmware/App/Services/FPGA.c (.../FPGA.c) (revision 621896c8a4cc9204a12a7243ccef729c37e50c52) @@ -54,28 +54,18 @@ #if BL_STACK_ID == 1 #define FPGA_FLASH_CONTROL_REG_ADDR 0x120E ///< FPGA flash control register address. #define FPGA_MULTI_BOOT_STATUS_ADDR 0x1200 ///< FPGA multi boot status register address. -#define FPGA_ICAP2_REG_ADDR 0x1209 ///< FPGA ICAP 2 command register address. +#define FPGA_ICAPE2_REG_ADDR 0x1209 ///< FPGA ICAPE 2 command register address. #define FPGA_FLASH_DATA_REG_ADDR 0x1400 ///< FPGA flash data register address. #else #define FPGA_FLASH_CONTROL_REG_ADDR 0x090E ///< FPGA flash control register address. #define FPGA_MULTI_BOOT_STATUS_ADDR 0x0900 ///< FPGA multi boot status register address. -#define FPGA_ICAP2_REG_ADDR 0x0909 ///< FPGA ICAP 2 command register address. +#define FPGA_ICAPE2_REG_ADDR 0x0909 ///< FPGA ICAPE 2 command register address. #define FPGA_FLASH_DATA_REG_ADDR 0x0A00 ///< FPGA flash data register address. #endif -#define FPGA_FLASH_STATUS_REG_ADDR 0x0900 ///< FPGA flash status register address. // TODO remove -#define FPGA_FIFO_COUNT_REG_ADDR 0x0902 ///< FPGA FIFO count register address. // TODO remove - -#define FPGA_WRITE_START_ADDR 0x000B ///< Start address for FPGA continuous priority writes. // TODO remove -#define FPGA_UPDATE_REGISTER_ADDR ( FPGA_WRITE_START_ADDR + 4 ) ///< FPGA update register address. // TODO remove since FFU will broadcast -#define FPGA_UPDATE_REQUEST_INDEX ( FPGA_READ_RSP_HDR_LEN + 1 ) ///< FPGA update request index. // TODO remove -#define FPGA_FLASH_STATUS_INDEX ( FPGA_READ_RSP_HDR_LEN + 1 ) ///< FPGA flash status index. // TODO remove -#define FPGA_FIFO_COUNT_INDEX ( FPGA_READ_RSP_HDR_LEN + 1 ) ///< FPGA FIFO count index. // TODO remove -#define UPDATE_REQUESTED_VALUE 1 // TODO remove FFU will broadcast ///< The value that indicates and update has been requested. - #define FPGA_FIFO_SIZE_BYTES 1024 ///< FPGA FIFO size in bytes. #define FPGA_FIFO_COUNT_MASK 0x03FF ///< FPGA FIFO count in FIFO mask. -#define FPGA_INIT_STAGE_TIMEOUT_MS 6000 ///< FPGA initialization stage timeout in milliseconds. +#define FPGA_INIT_STAGE_TIMEOUT_MS 6000 ///< FPGA initialization stage timeout in milliseconds. #define FPGA_PRE_SELF_CONFIG_TIMEOUT_MS 10000 ///< FPGA pre self configure timeout in milliseconds. /// FPGA communication status enumeration @@ -89,21 +79,21 @@ NUM_OF_FPGA_COMM_STATUS ///< Number of FPGA communication status. } FPGA_COMM_STATE_T; +/// FPGA update stage typedef enum { - FPGA_UPDATE_STAGE_INIT = 0, - FPGA_UPDATE_STAGE_CHECK_UPDATE_INIT, - FPGA_UPDATE_STAGE_UPDATE, - FPGA_UPDATE_STAGE_SELF_CONFIGURE, - NUM_OF_FPGA_UPDATE_STAGES + FPGA_UPDATE_STAGE_INIT = 0, ///< FPGA update stage init. + FPGA_UPDATE_STAGE_CHECK_UPDATE_INIT, ///< FPGA update stage check update init. + FPGA_UPDATE_STAGE_UPDATE, ///< FPGA update stage update. + FPGA_UPDATE_STAGE_PREPARE_FOR_SELF_CONFIGURE, ///< FPGA update stage prepare for self configure. + FPGA_UPDATE_STAGE_SELF_CONFIGURE, ///< FPGA update stage self configure. + NUM_OF_FPGA_UPDATE_STAGES ///< Number of FPGA update stages. } FPGA_UPDATE_STAGE_T; /// FPGA queue jobs enumeration typedef enum { FPGA_READ_HEADER = 0, ///< FPGA read header. - FPGA_READ_UPDATE_REG, // TODO remove related to using FPGA as communication but FFU will broadcast ///< FPGA read update request register. - FPGA_WRITE_UPDATE_REG, // TODO remove related to using FPGA as communication but FFU will broadcast ///< FPGA write to update request register. FPGA_RESET_FLASH, ///< FPGA reset flash. FPGA_ERASE_FIFO, ///< FPGA erase FIFO. FPGA_ENABLE_FLASH, ///< FPGA enable flash. @@ -124,7 +114,6 @@ NUM_OF_FPGA_STATES ///< Number of FPGA states. } FPGA_STATE_T; -//#pragma pack(push,1) /// FPGA queue job specification structure typedef struct { @@ -151,26 +140,25 @@ { U16 flashStatus; ///< FPGA flash status. U16 fifoCount; ///< FPGA FIFO count. - U32 icape2DataIn; ///< FPGA ICAPE2 datain. + U32 icape2DataIn; ///< FPGA ICAPE2 data in. U08 icape2Address; ///< FPGA ICAPE2 address. U08 icape2Cmd; ///< FPGA ICAPE2 command. - U32 icape2DataOut; ///< FPGA ICAPE2 dataout. + U32 icape2DataOut; ///< FPGA ICAPE2 data out. U08 flashIntCtrlReg; ///< FPGA flash interface control register. } FPGA_READ_REGS_T; /// FPGA flash status structure typedef struct { - U16 fpgaRemainingFIFOCountBytes; ///< Remaining FIFO size in bytes. - U16 fpgaInitStatus; - U16 fpgaCheckIDStatus; - U16 fpgaEraseStatus; - U16 fpgaProgramImageStatus; - U16 fpgaReadyForDataStatus; - FPGA_UPDATE_STAGE_T fpgaUpdateStage; - - U32 preSelfConfigureStartTimeMS; ///< Pre self configure start time in milliseconds. - U32 startTimeMS; ///< Start time in milliseconds. + U16 fpgaRemainingFIFOCountBytes; ///< FPGA remaining FIFO size in bytes. + U16 fpgaInitStatus; ///< FPGA initialization status. + U16 fpgaCheckIDStatus; ///< FPGA check ID status. + U16 fpgaEraseStatus; ///< FPGA erase status. + U16 fpgaProgramImageStatus; ///< FPGA program image status. + U16 fpgaReadyForDataStatus; ///< FPGA ready for data status. + FPGA_UPDATE_STAGE_T fpgaUpdateStage; ///< FPGA update stage. + U32 fpgaUpdateCmdStartTimeMS; ///< FPGA update related command time in milliseconds. + U32 fpgaReadWriteOpsStartTimeMS; ///< FPGA read/write operations start time in milliseconds. } FPGA_FLASH_STATUS_T; /// Record structure for FPGA header read. @@ -181,7 +169,6 @@ U08 fpgaRevMajor; ///< Reg 2. FPGA revision (major) being reported. U08 fpgaRevLab; ///< Reg 3. FPGA revision (lab) being reported. } FPGA_HEADER_T; // Read only on FPGA -//#pragma pack(pop) // ********** private data ********** @@ -199,55 +186,40 @@ static FPGA_HEADER_T fpgaHeader; ///< Record of last received FPGA header data. static FPGA_STATE_T fpgaState; ///< FPGA current state. -static U08 fpgaUpdateRegisterStatus; // TODO remove FFU will broadcast ///< FPGA update register status. static FPGA_JOBS_Q_STATUS_T fpgaJobsQStatus; ///< FPGA jobs queue status. static FPGA_FLASH_STATUS_T fpgaFlashStatus; ///< FPGA flash status. static FPGA_READ_REGS_T fpgaReadRegsStatus; ///< FGPA read registers status. -static U32 fpgaOperationStartTimeMS; ///< FPGA operation start time in milliseconds (read/write). static U08 fpgaDataToWriteBuffer[ SW_UPDATE_FLASH_BUFFER_SIZE ]; ///< FPGA data to write to FPGA flash buffer. static U32 fpgaDataLenToWrite; ///< FPGA data length to write to FPGA. static U08 tempPrevJob; static U16 tempPrevFlash; static U16 tempPrevFIFO; -/// FPGA stack ID for TD, DD -//static const U08 STACK_FPGA_ID[ NUM_OF_FW_STACKS ] = { 0x5A, 0x61 }; // TODO update with the real FPGA IDs // TODO remove -// TODO what is this value? 0? -//static const U16 DISABLE_UPDATE_REG_CMD = 5; ///< FPGA disable update register command. // TODO remove FFU will broadcast +static const U08 FPGA_RESET_FLASH_CMD = 0x01; ///< FPGA reset flash command. +static const U08 FPGA_ERASE_FIFO_CMD = 0x08; ///< FPGA erase FIFO command. +static const U08 FPGA_ENABLE_FLASH_CMD = 0x00; ///< FPGA enable flash command. +static const U08 FPGA_SELF_CONFIG_CMD = 0x03; ///< FPGA self configure command. +static const U08 DUMMY_WRITE_ADDR_IN_READ_STRUCT = 0xFF; ///< FPGA dummy variable for the pointer in the write address. +static const U32 FPGA_FLASH_INIT_STATUS = ( 1 << 8 ); ///< FPGA flash initialize status bit value. +static const U32 FPGA_FLASH_ERASE_STATUS = ( 1 << 11 ); ///< FPGA flash erase status bit value. +static const U32 FPGA_FLASH_PROG_IMAGE_STATUS = ( 1 << 12 ); ///< FPGA flash program image ok status bit value. +static const U32 FPGA_FLASH_READY_FOR_UPDATE_STATUS = ( 1 << 15 ); ///< FPGA flash ready for update status bit value. -static const U08 FPGA_RESET_FLASH_CMD = 0x01; ///< FPGA reset flash command. -static const U08 FPGA_ERASE_FIFO_CMD = 0x08; ///< FPGA erase FIFO command. -static const U08 FPGA_ENABLE_FLASH_CMD = 0x00; ///< FPGA enable flash command. -static const U08 FPGA_SELF_CONFIG_CMD = 0x03; ///< FPGA self configure command. - -static const U08 DUMMY_ADDRESS1 = 0x03; -static const U08 DUMMY_ADDRESS2 = 0x03; -static const U08 DUMMY_ADDRESS3 = 0x03; -static const U08 DUMMY_ADDRESS4 = 0x03; - -static const U32 FPGA_FLASH_INIT_STATUS = ( 1 << 8 ); -static const U32 FPGA_FLASH_ERASE_STATUS = ( 1 << 11 ); -static const U32 FPGA_FLASH_PROG_IMAGE_STATUS = ( 1 << 12 ); -static const U32 FPGA_FLASH_READY_FOR_UPDATE_STATUS = ( 1 << 15 ); - /// FPGA jobs specifications. static const FPGA_JOB_SPECS_T JOBS_SPECS[ NUM_OF_FPGA_JOBS ] = { - { FPGA_HEADER_START_ADDR, sizeof( FPGA_HEADER_T ), FALSE, (U08*)&DUMMY_ADDRESS1, }, // FPGA_READ_HEADER + { FPGA_HEADER_START_ADDR, sizeof( FPGA_HEADER_T ), FALSE, (U08*)&DUMMY_WRITE_ADDR_IN_READ_STRUCT, }, // FPGA_READ_HEADER - { FPGA_BULK_READ_START_ADDR, FPGA_MAX_READ_SIZE, FALSE, (U08*)&DUMMY_ADDRESS1, }, // TODO remove with the enum at the top // FPGA_READ_UPDATE_REG - { FPGA_UPDATE_REGISTER_ADDR, sizeof( U16 ), TRUE , (U08*)&DUMMY_ADDRESS1, }, // TODO remove // FPGA_WRITE_UPDATE_REG + { FPGA_FLASH_CONTROL_REG_ADDR, sizeof( U08 ), TRUE , (U08*)&FPGA_RESET_FLASH_CMD, }, // FPGA_RESET_FLASH - { FPGA_FLASH_CONTROL_REG_ADDR, sizeof( U08 ), TRUE , (U08*)&FPGA_RESET_FLASH_CMD, }, // FPGA_RESET_FLASH + { FPGA_FLASH_CONTROL_REG_ADDR, sizeof( U08 ), TRUE , (U08*)&FPGA_ERASE_FIFO_CMD, }, // FPGA_ERASE_FIFO + { FPGA_FLASH_CONTROL_REG_ADDR, sizeof( U08 ), TRUE , (U08*)&FPGA_ENABLE_FLASH_CMD, }, // FPGA_ENABLE_FLASH - { FPGA_FLASH_CONTROL_REG_ADDR, sizeof( U08 ), TRUE , (U08*)&FPGA_ERASE_FIFO_CMD, }, // FPGA_ERASE_FIFO - { FPGA_FLASH_CONTROL_REG_ADDR, sizeof( U08 ), TRUE , (U08*)&FPGA_ENABLE_FLASH_CMD, }, // FPGA_ENABLE_FLASH + { FPGA_MULTI_BOOT_STATUS_ADDR, sizeof( FPGA_READ_REGS_T ), FALSE, (U08*)&DUMMY_WRITE_ADDR_IN_READ_STRUCT, }, // FPGA_READ_MULTI_BOOT_STATUS - { FPGA_MULTI_BOOT_STATUS_ADDR, sizeof( FPGA_READ_REGS_T ), FALSE, (U08*)&DUMMY_ADDRESS1, }, // FPGA_READ_MULTI_BOOT_STATUS - - { FPGA_FLASH_DATA_REG_ADDR, SW_UPDATE_FLASH_BUFFER_SIZE, TRUE , (U08*)&fpgaDataToWriteBuffer, }, // FPGA_FLASH_WRITE_DATA - { FPGA_ICAP2_REG_ADDR, sizeof( U08 ), TRUE , (U08*)&FPGA_SELF_CONFIG_CMD, } // FPGA_SELF_CONFIGURE + { FPGA_FLASH_DATA_REG_ADDR, SW_UPDATE_FLASH_BUFFER_SIZE, TRUE , (U08*)&fpgaDataToWriteBuffer, }, // FPGA_FLASH_WRITE_DATA + { FPGA_ICAPE2_REG_ADDR, sizeof( U08 ), TRUE , (U08*)&FPGA_SELF_CONFIG_CMD, } // FPGA_SELF_CONFIGURE }; // ********** private function prototypes ********** @@ -256,6 +228,7 @@ static void consumeUnexpectedData( void ); static void processFPGAFlashRegistersRead( void ); static void processFPGAUpdateInitStatus( void ); +static void processFPGAPrepareForSelfConfigureStatus( void ); static void setupDMAForReadResp( U32 bytes2Receive ); static void setupDMAForReadCmd( U32 bytes2Transmit ); @@ -269,7 +242,6 @@ static void resetFPGACommFlags( void ); static void enqueue( FPGA_JOBS_T job ); static void dequeue( void ); -static FPGA_JOBS_T peekFromQueue( void ); static BOOL isQueueFull( void ); static void publishDataTemp( void ); @@ -303,15 +275,9 @@ memset( &fpgaWriteResponseBuffer, 0, FPGA_WRITE_RSP_BUFFER_LEN ); memset( &fpgaReadResponseBuffer, 0, FPGA_READ_RSP_BUFFER_LEN ); - fpgaState = FPGA_IDLE_STATE; - fpgaUpdateRegisterStatus = 0; - fpgaOperationStartTimeMS = 0; - fpgaDataLenToWrite = 0; + fpgaState = FPGA_IDLE_STATE; + fpgaDataLenToWrite = 0; - tempPrevJob = 0; - tempPrevFlash = 0; - tempPrevFIFO = 0; - initDMA(); consumeUnexpectedData(); @@ -381,28 +347,6 @@ /*********************************************************************//** * @brief - * The hasUpdateBeenRequested function checks whether an update has been - * requested through the FPGA read registers. - * @details \b Inputs: fpgaState, fpgaUpdateRegisterStatus - * @details \b Outputs: fpgaUpdateRegisterStatus - * @return TRUE if an update has been requested otherwise, FALSE - *************************************************************************/ -BOOL hasUpdateBeenRequested( void ) -{ - BOOL status = FALSE; - - if ( ( FPGA_IDLE_STATE == fpgaState ) && ( UPDATE_REQUESTED_VALUE == fpgaUpdateRegisterStatus ) ) - { - status = TRUE; - fpgaUpdateRegisterStatus = 0; - enqueue( FPGA_WRITE_UPDATE_REG ); - } - - return status; -} - -/*********************************************************************//** - * @brief * The isFPGAIDValid function checks whether the FPGA header is valid. * @details \b Inputs: fpgaHeader * @details \b Outputs: none @@ -496,11 +440,10 @@ *************************************************************************/ void signalFPGAToSelfConfigure( void ) { - if ( FALSE == isQueueFull() ) + if ( FPGA_UPDATE_STAGE_UPDATE == fpgaFlashStatus.fpgaUpdateStage ) { - fpgaFlashStatus.preSelfConfigureStartTimeMS = getMSTimerCount(); - - enqueue( FPGA_SELF_CONFIGURE ); + fpgaFlashStatus.fpgaUpdateStage = FPGA_UPDATE_STAGE_PREPARE_FOR_SELF_CONFIGURE; + fpgaFlashStatus.fpgaUpdateCmdStartTimeMS = getMSTimerCount(); } } @@ -639,11 +582,20 @@ fpgaFlashStatus.fpgaReadyForDataStatus = fpgaReadRegsStatus.flashStatus & FPGA_FLASH_READY_FOR_UPDATE_STATUS; } +/*********************************************************************//** + * @brief + * The processFPGAUpdateInitStatus function processes the FPGA init status. + * This function checks the flash status bits after the specified time delay + * to make sure the FPGA is ready for an update. + * @details \b Inputs: fpgaFlashStatus + * @details \b Outputs: fpgaFlashStatus + * @return none + *************************************************************************/ static void processFPGAUpdateInitStatus( void ) { - if ( TRUE == didTimeout( fpgaFlashStatus.startTimeMS, FPGA_INIT_STAGE_TIMEOUT_MS ) ) + if ( TRUE == didTimeout( fpgaFlashStatus.fpgaUpdateCmdStartTimeMS, FPGA_INIT_STAGE_TIMEOUT_MS ) ) { - BOOL initStatus = TRUE; + BOOL initStatus = TRUE; ACK_NACK_STATUS_T ackStatus = NACK; fpgaFlashStatus.fpgaUpdateStage = FPGA_UPDATE_STAGE_INIT; @@ -666,6 +618,27 @@ /*********************************************************************//** * @brief + * The processFPGAPrepareForSelfConfigureStatus function prepares the FPGA + * to program the uploaded image. It queues the self configure command after + * the specified time delay. + * @details \b Inputs: fpgaFlashStatus + * @details \b Outputs: fpgaFlashStatus + * @return none + *************************************************************************/ +static void processFPGAPrepareForSelfConfigureStatus( void ) +{ + if ( TRUE == didTimeout( fpgaFlashStatus.fpgaUpdateCmdStartTimeMS, FPGA_PRE_SELF_CONFIG_TIMEOUT_MS ) ) + { + if ( FALSE == isQueueFull() ) + { + fpgaFlashStatus.fpgaUpdateStage = FPGA_UPDATE_STAGE_SELF_CONFIGURE; + enqueue( FPGA_SELF_CONFIGURE ); + } + } +} + +/*********************************************************************//** + * @brief * The setupDMAForReadResp function sets the expected byte count for the * next DMA read command response from the FPGA. * @details \b Inputs: none @@ -861,25 +834,6 @@ /*********************************************************************//** * @brief - * The peekFromQueue function just reports what is the next job in the queue. - * This function does not do the actual dequeue. This function is thread - * safe. Prior to peeking into the next job, the IRQ interrupt is stopped. - * @details \b Inputs: fpgaJobsQStatus - * @details \b Outputs: none - * @return the next job that is in the queue - *************************************************************************/ -static FPGA_JOBS_T peekFromQueue( void ) -{ - _disable_IRQ(); - U08 frontIndex = fpgaJobsQStatus.fpgaJobFrontIndex; - FPGA_JOBS_T nextJob = (FPGA_JOBS_T)fpgaJobsQStatus.fpgaJobsQueue[ frontIndex ]; - _enable_IRQ(); - - return nextJob; -} - -/*********************************************************************//** - * @brief * The isQueueFull function checks whether the queue is full or not. * @details \b Inputs: fpgaJobsQStatus * @details \b Outputs: none @@ -905,17 +859,17 @@ U08 data[8]; data[0] = GET_MSB_OF_WORD( getCurrentUpdateMessageID() ); data[1] = GET_LSB_OF_WORD( getCurrentUpdateMessageID() ); - data[2] = GET_MSB_OF_WORD( fpgaFlashStatus.fpgaRemainingFIFOCountBytes ); - data[3] = GET_LSB_OF_WORD( fpgaFlashStatus.fpgaRemainingFIFOCountBytes ); + data[2] = GET_MSB_OF_WORD( fpgaReadRegsStatus.fifoCount ); + data[3] = GET_LSB_OF_WORD( fpgaReadRegsStatus.fifoCount ); data[4] = GET_MSB_OF_WORD( fpgaReadRegsStatus.flashStatus ); data[5] = GET_LSB_OF_WORD( fpgaReadRegsStatus.flashStatus ); data[6] = fpgaJobsQStatus.fpgaCurrentJob; data[7] = (U08)fpgaState; broadcastDataTestRemove(data); - //tempPrevJob = fpgaJobsQStatus.fpgaCurrentJob; - //tempPrevFlash = fpgaReadRegsStatus.flashStatus; - //tempPrevFIFO = fpgaFlashStatus.fpgaRemainingFIFOCountBytes; + tempPrevJob = fpgaJobsQStatus.fpgaCurrentJob; + tempPrevFlash = fpgaReadRegsStatus.flashStatus; + tempPrevFIFO = fpgaFlashStatus.fpgaRemainingFIFOCountBytes; } // TODO test code remove } @@ -938,56 +892,30 @@ case FPGA_UPDATE_STAGE_CHECK_UPDATE_INIT: processFPGAUpdateInitStatus(); break; - } - if ( FALSE == isQueueFull() ) - { - // If queue is not full enqueue a multi-boot status read - enqueue( FPGA_READ_MULTI_BOOT_STATUS ); + case FPGA_UPDATE_STAGE_PREPARE_FOR_SELF_CONFIGURE: + processFPGAPrepareForSelfConfigureStatus(); + break; + + default: + // Do nothing for the rest of the commands + break; } + fpgaFlashStatus.fpgaReadWriteOpsStartTimeMS = getMSTimerCount(); + if ( fpgaJobsQStatus.fpgaJobsQueueCount > 0 ) { - BOOL isDequeueAllowed = TRUE; - - // TODO remove - //if ( FPGA_FLASH_WRITE_DATA == peekFromQueue() ) - //{ - // // Check if the next job in the queue is a flash write. - // // If there is a flash write, only dequeue it if: - // // 1. There are at least 256 bytes available in the FIFO - // // 2. The flash status is okay - // // 3. The FIFO erase is okay - // if ( ( fpgaFlashStatus.fpgaRemainingFIFOCountBytes < SW_UPDATE_FLASH_BUFFER_SIZE ) || - // ( FALSE == fpgaFlashStatus.isFlashStatusOk ) || - // ( FALSE == fpgaFlashStatus.isFIFOEraseOk ) ) - // { - // isDequeueAllowed = FALSE; - // } - //} - - // TODO remove - //if ( FPGA_SELF_CONFIGURE == peekFromQueue() ) - //{ - // // Check if the next job in the queue is the self configure. Then make sure: - // // 1. The delay has timed out - // // 2. The flash status is okay - // if ( ( FALSE == didTimeout( fpgaFlashStatus.preSelfConfigureStartTimeMS, FPGA_PRE_SELF_CONFIG_TIMEOUT_MS ) ) || - // ( FALSE == fpgaFlashStatus.isFlashStatusOk ) ) - // { - // isDequeueAllowed = FALSE; - // } - //} - - if ( TRUE == isDequeueAllowed ) - { - dequeue(); - // After dequeue based on the job specs transition to either write or read states - state = ( FALSE == JOBS_SPECS[ fpgaJobsQStatus.fpgaCurrentJob ].fpgaIsJobWrite ? FPGA_READ_FROM_FPGA_STATE : FPGA_WRITE_TO_FPGA_STATE ); - } + dequeue(); + // After dequeue based on the job specs transition to either write or read states + state = ( FALSE == JOBS_SPECS[ fpgaJobsQStatus.fpgaCurrentJob ].fpgaIsJobWrite ? FPGA_READ_FROM_FPGA_STATE : FPGA_WRITE_TO_FPGA_STATE ); } + else + { + // There is nothing in the queue so schedule a read to read all the registers. + state = FPGA_READ_FROM_FPGA_STATE; + } - return state; } @@ -1006,8 +934,11 @@ U16 crc = 0; U16 jobAddress = JOBS_SPECS[ fpgaJobsQStatus.fpgaCurrentJob ].fpgaJobAddress; U16 jobSize = JOBS_SPECS[ fpgaJobsQStatus.fpgaCurrentJob ].fpgaJobSize; + U08* value2Write = JOBS_SPECS[ fpgaJobsQStatus.fpgaCurrentJob ].fpgaWriteStartAddress; + U16 firstCRCIndex = 0; + U16 secondCRCIndex = 0; - if ( ( fpgaDataLenToWrite != SW_UPDATE_FLASH_BUFFER_SIZE ) && ( FPGA_FLASH_WRITE_DATA == fpgaJobsQStatus.fpgaCurrentJob ) ) + if ( FPGA_FLASH_WRITE_DATA == fpgaJobsQStatus.fpgaCurrentJob ) { // Set the write length from the buffer length provided jobSize = (U16)fpgaDataLenToWrite; @@ -1020,11 +951,10 @@ state = FPGA_IDLE_STATE; } - U08* value2Write = JOBS_SPECS[ fpgaJobsQStatus.fpgaCurrentJob ].fpgaWriteStartAddress; - U16 firstCRCIndex = FPGA_WRITE_CMD_HDR_LEN + jobSize; - U16 secondCRCIndex = FPGA_WRITE_CMD_HDR_LEN + jobSize + 1; + firstCRCIndex = FPGA_WRITE_CMD_HDR_LEN + jobSize; + secondCRCIndex = FPGA_WRITE_CMD_HDR_LEN + jobSize + 1; - memset( &fpgaWriteCmdBuffer, 0x0, FPGA_WRITE_CMD_BUFFER_LEN ); // TODO a better place for this + memset( &fpgaWriteCmdBuffer, 0x0, FPGA_WRITE_CMD_BUFFER_LEN ); memcpy( &fpgaWriteCmdBuffer[ FPGA_WRITE_CMD_HDR_LEN ], value2Write, jobSize ); // Construct bulk read command to read sensor data registers starting at address 8 @@ -1072,33 +1002,30 @@ if ( FPGA_WRITE_CMD_ACK == fpgaWriteResponseBuffer[ 0 ] ) { // Message is an ack - check CRC - U32 rspSize = FPGA_READ_RSP_HDR_LEN; - U32 crcPos = rspSize; - U16 crc = MAKE_WORD_OF_BYTES( fpgaWriteResponseBuffer[ crcPos ], fpgaWriteResponseBuffer[ crcPos + 1 ] ); + ACK_NACK_STATUS_T ackStatus = NACK; + U32 rspSize = FPGA_READ_RSP_HDR_LEN; + U32 crcPos = rspSize; + U16 crc = MAKE_WORD_OF_BYTES( fpgaWriteResponseBuffer[ crcPos ], fpgaWriteResponseBuffer[ crcPos + 1 ] ); // Does the FPGA response CRC checkout? if ( crc == crc16( fpgaWriteResponseBuffer, rspSize ) ) { - // TODO switch case or a function here if ( FPGA_FLASH_WRITE_DATA == fpgaJobsQStatus.fpgaCurrentJob ) { - sendFPGAAckNackStatus( ACK, TRUE ); + ackStatus = ACK; } if ( FPGA_ENABLE_FLASH == fpgaJobsQStatus.fpgaCurrentJob ) { - fpgaFlashStatus.fpgaUpdateStage = FPGA_UPDATE_STAGE_CHECK_UPDATE_INIT; - fpgaFlashStatus.startTimeMS = getMSTimerCount(); + fpgaFlashStatus.fpgaUpdateStage = FPGA_UPDATE_STAGE_CHECK_UPDATE_INIT; + fpgaFlashStatus.fpgaUpdateCmdStartTimeMS = getMSTimerCount(); } // CRC passed state = FPGA_IDLE_STATE; } - else - { - // TODO error handling - BOOL test = FALSE; - } + + sendFPGAAckNackStatus( ackStatus, TRUE ); } } @@ -1116,8 +1043,9 @@ { FPGA_STATE_T state = FPGA_RCV_READ_RESP_FROM_FPGA_STATE; U16 crc = 0; - U16 jobAddress = JOBS_SPECS[ fpgaJobsQStatus.fpgaCurrentJob ].fpgaJobAddress; - U08 jobSize = JOBS_SPECS[ fpgaJobsQStatus.fpgaCurrentJob ].fpgaJobSize; + U08 currentJob = ( FPGA_READ_HEADER == fpgaJobsQStatus.fpgaCurrentJob ? fpgaJobsQStatus.fpgaCurrentJob : FPGA_READ_MULTI_BOOT_STATUS ); + U16 jobAddress = JOBS_SPECS[ currentJob ].fpgaJobAddress; + U08 jobSize = JOBS_SPECS[ currentJob ].fpgaJobSize; // Construct read command to read 3 registers starting at address 0 fpgaReadCmdBuffer[ 0 ] = FPGA_READ_CMD_CODE; @@ -1141,7 +1069,6 @@ // Prep DMA for sending the read cmd and receiving the response fpgaJobsQStatus.fpgaCommRead = FPGA_COMM_READ_IN_PROGRESS; - fpgaOperationStartTimeMS = getMSTimerCount(); setupDMAForReadResp( FPGA_READ_RSP_HDR_LEN + jobSize + sizeof( U16 ) ); setupDMAForReadCmd( FPGA_READ_CMD_HDR_LEN + sizeof( U16 ) ); @@ -1156,36 +1083,33 @@ * The handleFPGAReceiveReadRespFromFPGAState function handles the FPGA * read response from FPGA. * @details \b Inputs: fpgaJobsQStatus, fpgaReadResponseBuffer[] - * @details \b Outputs: fpgaReadResponseBuffer[], fpgaHeader, - * fpgaUpdateRegisterStatus + * @details \b Outputs: fpgaReadResponseBuffer[], fpgaHeader * @return next state of the FPGA state machine *************************************************************************/ static FPGA_STATE_T handleFPGAReceiveReadRespFromFPGAState( void ) { FPGA_STATE_T state = FPGA_RCV_READ_RESP_FROM_FPGA_STATE; + U08 currentJob = ( FPGA_READ_HEADER == fpgaJobsQStatus.fpgaCurrentJob ? fpgaJobsQStatus.fpgaCurrentJob : FPGA_READ_MULTI_BOOT_STATUS ); + U16 jobSize = JOBS_SPECS[ currentJob ].fpgaJobSize; if ( FPGA_COMM_READ_RESP_RECEIVED == fpgaJobsQStatus.fpgaCommRead ) { if ( FPGA_READ_CMD_ACK == fpgaReadResponseBuffer[ 0 ] ) { - U16 jobSize = JOBS_SPECS[ fpgaJobsQStatus.fpgaCurrentJob ].fpgaJobSize; - U32 rspSize = FPGA_READ_RSP_HDR_LEN + jobSize; - U32 crcPos = rspSize; - U16 crc = MAKE_WORD_OF_BYTES( fpgaReadResponseBuffer[ crcPos ], fpgaReadResponseBuffer[ crcPos + 1 ] ); + // If we are here for a read + U32 rspSize = FPGA_READ_RSP_HDR_LEN + jobSize; + U32 crcPos = rspSize; + U16 crc = MAKE_WORD_OF_BYTES( fpgaReadResponseBuffer[ crcPos ], fpgaReadResponseBuffer[ crcPos + 1 ] ); // Does the FPGA response CRC check out? if ( crc == crc16( fpgaReadResponseBuffer, rspSize ) ) { - switch( fpgaJobsQStatus.fpgaCurrentJob ) + switch( currentJob ) { case FPGA_READ_HEADER: memcpy( &fpgaHeader, &fpgaReadResponseBuffer[ FPGA_READ_RSP_HDR_LEN ], jobSize ); break; - case FPGA_READ_UPDATE_REG: - fpgaUpdateRegisterStatus = fpgaReadResponseBuffer[ FPGA_UPDATE_REQUEST_INDEX ]; - break; - case FPGA_READ_MULTI_BOOT_STATUS: memcpy( &fpgaReadRegsStatus, &fpgaReadResponseBuffer[ FPGA_READ_RSP_HDR_LEN ], jobSize ); processFPGAFlashRegistersRead(); @@ -1202,8 +1126,11 @@ } } - if ( TRUE == didTimeout( fpgaFlashStatus.startTimeMS, 100 ) ) + if ( TRUE == didTimeout( fpgaFlashStatus.fpgaReadWriteOpsStartTimeMS, 40 ) ) { + memset( &fpgaReadResponseBuffer, 0x0, FPGA_READ_RSP_BUFFER_LEN ); + memcpy( &fpgaReadRegsStatus, &fpgaReadResponseBuffer[ FPGA_READ_RSP_HDR_LEN ], jobSize ); + processFPGAFlashRegistersRead(); state = FPGA_IDLE_STATE; } Index: firmware/App/Services/FPGA.h =================================================================== diff -u -rf6fd9dfd1a30412e237ff45ebee44854f0e2d4b2 -r621896c8a4cc9204a12a7243ccef729c37e50c52 --- firmware/App/Services/FPGA.h (.../FPGA.h) (revision f6fd9dfd1a30412e237ff45ebee44854f0e2d4b2) +++ firmware/App/Services/FPGA.h (.../FPGA.h) (revision 621896c8a4cc9204a12a7243ccef729c37e50c52) @@ -28,7 +28,6 @@ void signalFPGAReceiptCompleted( void ); -BOOL hasUpdateBeenRequested( void ); BOOL isFPGAIDValid( void ); BOOL isFPGAFlashComplete( void );