Index: firmware/App/Services/FPGA.c =================================================================== diff -u -rab214e8ea52d8433b7cee58f5aaff49fc759310d -rf6fd9dfd1a30412e237ff45ebee44854f0e2d4b2 --- firmware/App/Services/FPGA.c (.../FPGA.c) (revision ab214e8ea52d8433b7cee58f5aaff49fc759310d) +++ firmware/App/Services/FPGA.c (.../FPGA.c) (revision f6fd9dfd1a30412e237ff45ebee44854f0e2d4b2) @@ -50,7 +50,6 @@ #define FPGA_READ_CMD_CODE 0x5A ///< FPGA read command code. #define FPGA_READ_CMD_ACK 0xAA ///< FPGA read command ACK code. #define FPGA_HEADER_START_ADDR 0x0000 ///< Start address for FPGA header data. -#define FPGA_WRITE_START_ADDR 0x000B ///< Start address for FPGA continuous priority writes. // TODO does this vary? #if BL_STACK_ID == 1 #define FPGA_FLASH_CONTROL_REG_ADDR 0x120E ///< FPGA flash control register address. @@ -64,22 +63,19 @@ #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 remvoe -#define FPGA_FIFO_COUNT_REG_ADDR 0x0902 ///< FPGA FIFO count register address. // TODO remvoe +#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_UPDATE_REGISTER_ADDR ( FPGA_WRITE_START_ADDR + 4 ) ///< FPGA update register address. -#define FPGA_UPDATE_REQUEST_INDEX ( FPGA_READ_RSP_HDR_LEN + 1 ) ///< FPGA update request index. // TODO Get this value from Noe, make sure the index is the same in all of the stacks -#define FPGA_FLASH_STATUS_INDEX ( FPGA_READ_RSP_HDR_LEN + 1 ) ///< FPGA flash status index. -#define FPGA_FIFO_COUNT_INDEX ( FPGA_READ_RSP_HDR_LEN + 1 ) ///< FPGA FIFO count index. +#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 UPDATE_REQUESTED_VALUE 1 ///< 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_ERASE_FIFO_CMD_OK ( 1 << 11 ) ///< FPGA erase FIFO command status ok value. -#define FPGA_FLASH_STATUS_OK ( 1 << 15 ) ///< FPGA flash status status ok value. - +#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 @@ -93,12 +89,21 @@ NUM_OF_FPGA_COMM_STATUS ///< Number of FPGA communication status. } FPGA_COMM_STATE_T; +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_T; + /// FPGA queue jobs enumeration typedef enum { FPGA_READ_HEADER = 0, ///< FPGA read header. - FPGA_READ_UPDATE_REG, // TODO remove? ///< FPGA read update request register. - FPGA_WRITE_UPDATE_REG, ///< FPGA write to update request register. + 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. @@ -119,14 +124,14 @@ NUM_OF_FPGA_STATES ///< Number of FPGA states. } FPGA_STATE_T; -#pragma pack(push,1) +//#pragma pack(push,1) /// FPGA queue job specification structure typedef struct { U16 fpgaJobAddress; ///< FPGA job address. U16 fpgaJobSize; ///< FPGA job size. + BOOL fpgaIsJobWrite; ///< FPGA boolean flag to indicate this is a write job or not. U08* fpgaWriteStartAddress; ///< FPGA write buffer start address. - U08 fpgaIsJobWrite; ///< FPGA boolean flag to indicate this is a write job or not. } FPGA_JOB_SPECS_T; /// FPGA jobs queue status structure @@ -156,14 +161,16 @@ /// FPGA flash status structure typedef struct { - BOOL hasUpdateRegsBeenRqstd; ///< Flag to indicate whether update registers request has been requested. - U16 fifoRemainingCount; ///< FIFO empty space remaining count. - BOOL isFIFOEraseOk; ///< Flag to indicate whether FIFO has been erased or not. - BOOL isFlashStatusOk; ///< Flag to indicate whether flash status is okay or not. - BOOL isFPGAFlashComplete; ///< Flag to indicate whether flash update has been completed. - U16 flashStatusBits; ///< Flash status. + 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 startTime; ///< Start time in milliseconds. + U32 startTimeMS; ///< Start time in milliseconds. } FPGA_FLASH_STATUS_T; /// Record structure for FPGA header read. @@ -174,7 +181,7 @@ 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) +//#pragma pack(pop) // ********** private data ********** @@ -192,47 +199,63 @@ static FPGA_HEADER_T fpgaHeader; ///< Record of last received FPGA header data. static FPGA_STATE_T fpgaState; ///< FPGA current state. -static U08 fpgaUpdateRegisterStatus; ///< FPGA update register status. +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 U32 TESTREMOVE = 0; // TODO remove -static U32 countRemove = 0; // TODO remove -static U08 tempACkStatus = 0; // TODO remove +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 +//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 +//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_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 ), 0, FALSE }, // FPGA_READ_HEADER - { FPGA_BULK_READ_START_ADDR, FPGA_MAX_READ_SIZE, 0, FALSE }, // TODO remove // FPGA_READ_UPDATE_REG - { FPGA_UPDATE_REGISTER_ADDR, sizeof( U16 ), (U08*)&DISABLE_UPDATE_REG_CMD, TRUE }, // FPGA_WRITE_UPDATE_REG + { FPGA_HEADER_START_ADDR, sizeof( FPGA_HEADER_T ), FALSE, (U08*)&DUMMY_ADDRESS1, }, // FPGA_READ_HEADER - { FPGA_FLASH_CONTROL_REG_ADDR, sizeof( U08 ), (U08*)&FPGA_RESET_FLASH_CMD, TRUE }, // FPGA_RESET_FLASH + { 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 ), (U08*)&FPGA_ERASE_FIFO_CMD, TRUE }, // FPGA_ERASE_FIFO - { FPGA_FLASH_CONTROL_REG_ADDR, sizeof( U08 ), (U08*)&FPGA_ENABLE_FLASH_CMD, TRUE }, // FPGA_ENABLE_FLASH - { FPGA_MULTI_BOOT_STATUS_ADDR, sizeof( FPGA_READ_REGS_T ), 0, FALSE }, // FPGA_READ_MULTI_BOOT_STATUS - { FPGA_FLASH_DATA_REG_ADDR, SW_UPDATE_FLASH_BUFFER_SIZE, fpgaDataToWriteBuffer, TRUE }, // FPGA_FLASH_WRITE_DATA - { FPGA_ICAP2_REG_ADDR, sizeof( U08 ), (U08*)&FPGA_SELF_CONFIG_CMD, TRUE } // FPGA_SELF_CONFIGURE + { 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_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 }; // ********** private function prototypes ********** static void initDMA( void ); static void consumeUnexpectedData( void ); -static void requestFlashRegistersStatus( void ); static void processFPGAFlashRegistersRead( void ); +static void processFPGAUpdateInitStatus( void ); static void setupDMAForReadResp( U32 bytes2Receive ); static void setupDMAForReadCmd( U32 bytes2Transmit ); @@ -249,6 +272,8 @@ static FPGA_JOBS_T peekFromQueue( void ); static BOOL isQueueFull( void ); +static void publishDataTemp( void ); + static FPGA_STATE_T handleFPGAIdleState( void ); static FPGA_STATE_T handleFPGAWriteToFPGAState( void ); @@ -266,24 +291,32 @@ *************************************************************************/ void initFPGA( void ) { - memset( &fpgaHeader, 0x0, sizeof( FPGA_HEADER_T ) ); - memset( &fpgaJobsQStatus, 0x0, sizeof( FPGA_JOBS_Q_STATUS_T ) ); - memset( &fpgaFlashStatus, 0x0, sizeof( FPGA_FLASH_STATUS_T ) ); + memset( &fpgaHeader, 0x0, sizeof( FPGA_HEADER_T ) ); + memset( &fpgaJobsQStatus, 0x0, sizeof( FPGA_JOBS_Q_STATUS_T ) ); + memset( &fpgaFlashStatus, 0x0, sizeof( FPGA_FLASH_STATUS_T ) ); + memset( &fpgaReadRegsStatus, 0x0, sizeof( FPGA_READ_REGS_T ) ); + memset( &fpgaDataToWriteBuffer, 0x0, SW_UPDATE_FLASH_BUFFER_SIZE ); // initialize fpga comm buffers memset( &fpgaWriteCmdBuffer, 0, FPGA_WRITE_CMD_BUFFER_LEN ); memset( &fpgaReadCmdBuffer, 0, FPGA_READ_CMD_BUFFER_LEN ); 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; + + tempPrevJob = 0; + tempPrevFlash = 0; + tempPrevFIFO = 0; + initDMA(); consumeUnexpectedData(); enqueue( FPGA_READ_HEADER ); enqueue( FPGA_READ_MULTI_BOOT_STATUS ); - - fpgaState = FPGA_IDLE_STATE; - fpgaUpdateRegisterStatus = 0; } /*********************************************************************//** @@ -295,19 +328,6 @@ *************************************************************************/ void execFPGA( void ) { - // TODO test code remove - U08 data[8]; - data[0] = GET_LSB_OF_WORD( getCurrentUpdateMessageID() ); - data[1] = GET_MSB_OF_WORD( getCurrentUpdateMessageID() ); - data[2] = GET_LSB_OF_WORD( fpgaFlashStatus.fifoRemainingCount ); - data[3] = GET_MSB_OF_WORD( fpgaFlashStatus.fifoRemainingCount ); - data[4] = GET_LSB_OF_WORD( fpgaFlashStatus.flashStatusBits ); - data[5] = GET_MSB_OF_WORD( fpgaFlashStatus.flashStatusBits ); - data[6] = fpgaJobsQStatus.fpgaCurrentJob; - data[7] = (U08)fpgaState; - broadcastDataTestRemove(data); - // TODO test code remove - switch( fpgaState ) { case FPGA_IDLE_STATE: @@ -334,6 +354,8 @@ // Do nothing break; } + + publishDataTemp(); } /*********************************************************************//** @@ -388,8 +410,10 @@ *************************************************************************/ BOOL isFPGAIDValid( void ) { - BOOL status = ( STACK_FPGA_ID[ BL_STACK_ID ] == fpgaHeader.fpgaId ? TRUE : FALSE ); + //BOOL status = ( STACK_FPGA_ID[ BL_STACK_ID ] == fpgaHeader.fpgaId ? TRUE : FALSE ); + BOOL status = FALSE; + return status; } @@ -403,7 +427,9 @@ *************************************************************************/ BOOL isFPGAFlashComplete( void ) { - return fpgaFlashStatus.isFPGAFlashComplete; + //return fpgaFlashStatus.isFPGAFlashComplete; // TODO clean this up + + return TRUE; } /*********************************************************************//** @@ -430,19 +456,34 @@ * job if the queue is not full. * @details \b Inputs: none * @details \b Outputs: fpgaDataLenToWrite, fpgaDataToWriteBuffer - * @return none + * @return TURE if the buffer was enqueued successfully otherwise, FALSE *************************************************************************/ -void signalFPGAToWriteToFlash( U08* data, U32 len ) +BOOL signalFPGAToWriteToFlash( U08* data, U32 len ) { - if ( FALSE == isQueueFull() ) + BOOL status = FALSE; + BOOL isFIFOReady = FALSE; + + // 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 enough number of bytes available in the FIFO for the next data (e.g. 256) + // 2. The flash status is okay + if ( ( fpgaFlashStatus.fpgaRemainingFIFOCountBytes > SW_UPDATE_FLASH_BUFFER_SIZE ) && + ( FPGA_FLASH_READY_FOR_UPDATE_STATUS == fpgaFlashStatus.fpgaReadyForDataStatus ) ) { - memset( fpgaDataToWriteBuffer, 0x0, SW_UPDATE_FLASH_BUFFER_SIZE ); + isFIFOReady = TRUE; + } + if ( ( FALSE == isQueueFull() ) && ( TRUE == isFIFOReady ) ) + { fpgaDataLenToWrite = len; - memcpy( fpgaDataToWriteBuffer, data, len ); + status = TRUE; + memset( &fpgaDataToWriteBuffer, 0x0, SW_UPDATE_FLASH_BUFFER_SIZE ); + memcpy( &fpgaDataToWriteBuffer, data, len ); enqueue( FPGA_FLASH_WRITE_DATA ); } + + return status; } /*********************************************************************//** @@ -584,83 +625,42 @@ /*********************************************************************//** * @brief - * The requestFlashRegistersStatus function requests the FPGA flash readings - * status. - * @details \b Inputs: none - * @details \b Outputs: fpgaReadCmdBuffer[], fpgaJobsQStatus, fpgaFlashStatus - * @return none - *************************************************************************/ -static void requestFlashRegistersStatus( void ) -{ - U16 jobAddress = JOBS_SPECS[ FPGA_READ_MULTI_BOOT_STATUS ].fpgaJobAddress; - U08 jobSize = JOBS_SPECS[ FPGA_READ_MULTI_BOOT_STATUS ].fpgaJobSize; - U16 crc = 0; - - // Construct read command to read 3 registers starting at address 0 - fpgaReadCmdBuffer[ 0 ] = FPGA_READ_CMD_CODE; - fpgaReadCmdBuffer[ 1 ] = GET_LSB_OF_WORD( jobAddress ); - fpgaReadCmdBuffer[ 2 ] = GET_MSB_OF_WORD( jobAddress ); -#if BL_STACK_ID == 1 - fpgaReadCmdBuffer[ 3 ] = GET_LSB_OF_WORD( jobSize ); - fpgaReadCmdBuffer[ 4 ] = GET_MSB_OF_WORD( jobSize ); -#else - fpgaReadCmdBuffer[ 3 ] = jobSize; -#endif - crc = crc16( fpgaReadCmdBuffer, FPGA_READ_CMD_HDR_LEN ); -#if BL_STACK_ID == 1 - fpgaReadCmdBuffer[ 5 ] = GET_MSB_OF_WORD( crc ); - fpgaReadCmdBuffer[ 6 ] = GET_LSB_OF_WORD( crc ); -#else - fpgaReadCmdBuffer[ 4 ] = GET_MSB_OF_WORD( crc ); - fpgaReadCmdBuffer[ 5 ] = GET_LSB_OF_WORD( crc ); -#endif - // Prep DMA for sending the read cmd and receiving the response - fpgaJobsQStatus.fpgaCommRead = FPGA_COMM_READ_IN_PROGRESS; - fpgaFlashStatus.hasUpdateRegsBeenRqstd = TRUE; - - setupDMAForReadResp( FPGA_READ_RSP_HDR_LEN + jobSize + sizeof( U16 ) ); - setupDMAForReadCmd( FPGA_READ_CMD_HDR_LEN + sizeof( U16 ) ); - startDMAReceiptOfReadResp(); - startDMAReadCmd(); -} - -/*********************************************************************//** - * @brief * The processFPGAFlashRegistersRead function processes the read flash readings. * @details \b Inputs: fpgaReadResponseBuffer[] * @details \b Outputs: fpgaFlashStatus * @return none *************************************************************************/ static void processFPGAFlashRegistersRead( void ) { - if ( FPGA_READ_CMD_ACK == fpgaReadResponseBuffer[ 0 ] ) + fpgaFlashStatus.fpgaRemainingFIFOCountBytes = FPGA_FIFO_SIZE_BYTES - ( fpgaReadRegsStatus.fifoCount & FPGA_FIFO_COUNT_MASK ); + fpgaFlashStatus.fpgaInitStatus = fpgaReadRegsStatus.flashStatus & FPGA_FLASH_INIT_STATUS; + fpgaFlashStatus.fpgaEraseStatus = fpgaReadRegsStatus.flashStatus & FPGA_FLASH_ERASE_STATUS; + fpgaFlashStatus.fpgaProgramImageStatus = fpgaReadRegsStatus.flashStatus & FPGA_FLASH_PROG_IMAGE_STATUS; + fpgaFlashStatus.fpgaReadyForDataStatus = fpgaReadRegsStatus.flashStatus & FPGA_FLASH_READY_FOR_UPDATE_STATUS; +} + +static void processFPGAUpdateInitStatus( void ) +{ + if ( TRUE == didTimeout( fpgaFlashStatus.startTimeMS, FPGA_INIT_STAGE_TIMEOUT_MS ) ) { - U32 rspSize = FPGA_READ_RSP_HDR_LEN + JOBS_SPECS[ fpgaJobsQStatus.fpgaCurrentJob ].fpgaJobSize; - U32 crcPos = rspSize; - U16 crc = MAKE_WORD_OF_BYTES( fpgaReadResponseBuffer[ crcPos ], fpgaReadResponseBuffer[ crcPos + 1 ] ); + BOOL initStatus = TRUE; + ACK_NACK_STATUS_T ackStatus = NACK; - // Does the FPGA response CRC check out? - if ( crc == crc16( fpgaReadResponseBuffer, rspSize ) ) - { - U16 flashStatus = MAKE_WORD_OF_BYTES( fpgaReadResponseBuffer[ FPGA_FLASH_STATUS_INDEX ], fpgaReadResponseBuffer[ FPGA_FLASH_STATUS_INDEX - 1 ] ); - U16 fifoStatus = MAKE_WORD_OF_BYTES( fpgaReadResponseBuffer[ FPGA_FLASH_STATUS_INDEX + sizeof( U16 ) ], - fpgaReadResponseBuffer[ FPGA_FLASH_STATUS_INDEX + sizeof( U16 ) - 1 ] ); + fpgaFlashStatus.fpgaUpdateStage = FPGA_UPDATE_STAGE_INIT; - fpgaFlashStatus.fifoRemainingCount = FPGA_FIFO_SIZE_BYTES - ( FPGA_FIFO_COUNT_MASK & fifoStatus ); - fpgaFlashStatus.hasUpdateRegsBeenRqstd = FALSE; - fpgaFlashStatus.flashStatusBits = flashStatus; - fpgaFlashStatus.isFlashStatusOk = FALSE; + initStatus &= ( FPGA_FLASH_INIT_STATUS == fpgaFlashStatus.fpgaInitStatus ? TRUE : FALSE ); + initStatus &= ( FPGA_FLASH_READY_FOR_UPDATE_STATUS == fpgaFlashStatus.fpgaReadyForDataStatus ? TRUE : FALSE ); + initStatus &= ( fpgaFlashStatus.fpgaRemainingFIFOCountBytes > SW_UPDATE_FLASH_BUFFER_SIZE ? TRUE : FALSE ); - if ( ( flashStatus & FPGA_ERASE_FIFO_CMD_OK ) == FPGA_ERASE_FIFO_CMD_OK ) - { - fpgaFlashStatus.isFIFOEraseOk = TRUE; - } - - if ( ( flashStatus & FPGA_FLASH_STATUS_OK ) == FPGA_FLASH_STATUS_OK ) - { - fpgaFlashStatus.isFlashStatusOk = TRUE; - } + if ( TRUE == initStatus ) + { + ackStatus = ACK; + fpgaFlashStatus.fpgaUpdateStage = FPGA_UPDATE_STAGE_UPDATE; } + + ackStatus = ( TRUE == initStatus ? ACK : NACK ); + + sendFPGAAckNackStatus( ackStatus, FALSE ); } } @@ -897,6 +897,29 @@ return isFull; } +static void publishDataTemp( void ) +{ + // TODO test code remove + //if ( ( tempPrevJob != fpgaJobsQStatus.fpgaCurrentJob ) || ( tempPrevFlash != fpgaReadRegsStatus.flashStatus ) || ( tempPrevFIFO != fpgaFlashStatus.fpgaRemainingFIFOCountBytes ) ) + { + 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[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; + } + // TODO test code remove +} + /*********************************************************************//** * @brief * The handleFPGAIdleState function handles the FPGA idle state. This state @@ -910,36 +933,51 @@ { FPGA_STATE_T state = FPGA_IDLE_STATE; + switch( fpgaFlashStatus.fpgaUpdateStage ) + { + 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 ); + } + if ( fpgaJobsQStatus.fpgaJobsQueueCount > 0 ) { BOOL isDequeueAllowed = TRUE; - 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.fifoRemainingCount < SW_UPDATE_FLASH_BUFFER_SIZE ) || - ( FALSE == fpgaFlashStatus.isFlashStatusOk ) || - ( FALSE == fpgaFlashStatus.isFIFOEraseOk ) ) - { - isDequeueAllowed = FALSE; - } - } + // 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; + // } + //} - 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; - } - } + // 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 ) { @@ -949,7 +987,6 @@ } } - //requestFlashRegistersStatus(); // TODO remove return state; } @@ -980,23 +1017,23 @@ { // Once self configure is sent the FPGA will be unresponsive so there will be no ack back // Signal FPGA is completed - state = FPGA_IDLE_STATE; - fpgaFlashStatus.isFPGAFlashComplete = TRUE; + 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; + memset( &fpgaWriteCmdBuffer, 0x0, FPGA_WRITE_CMD_BUFFER_LEN ); // TODO a better place for this memcpy( &fpgaWriteCmdBuffer[ FPGA_WRITE_CMD_HDR_LEN ], value2Write, jobSize ); // Construct bulk read command to read sensor data registers starting at address 8 fpgaWriteCmdBuffer[ 0 ] = FPGA_WRITE_CMD_CODE; fpgaWriteCmdBuffer[ 1 ] = GET_LSB_OF_WORD( jobAddress ); fpgaWriteCmdBuffer[ 2 ] = GET_MSB_OF_WORD( jobAddress ); #if BL_STACK_ID == 1 - fpgaWriteCmdBuffer[ 3 ] = GET_LSB_OF_WORD( jobSize % SW_UPDATE_FLASH_BUFFER_SIZE ); - fpgaWriteCmdBuffer[ 4 ] = GET_MSB_OF_WORD( jobSize % SW_UPDATE_FLASH_BUFFER_SIZE ); + fpgaWriteCmdBuffer[ 3 ] = GET_LSB_OF_WORD( jobSize ); + fpgaWriteCmdBuffer[ 4 ] = GET_MSB_OF_WORD( jobSize ); #else fpgaWriteCmdBuffer[ 3 ] = jobSize % SW_UPDATE_FLASH_BUFFER_SIZE; #endif @@ -1042,13 +1079,16 @@ // 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 ); - tempACkStatus = ACK; // TODO remove + sendFPGAAckNackStatus( ACK, TRUE ); + } - TESTREMOVE += fpgaDataLenToWrite;// TODO REMOVE - countRemove += 1;// TODO REMOVE + if ( FPGA_ENABLE_FLASH == fpgaJobsQStatus.fpgaCurrentJob ) + { + fpgaFlashStatus.fpgaUpdateStage = FPGA_UPDATE_STAGE_CHECK_UPDATE_INIT; + fpgaFlashStatus.startTimeMS = getMSTimerCount(); } // CRC passed @@ -1057,14 +1097,11 @@ else { // TODO error handling + BOOL test = FALSE; } } - - memset( fpgaWriteCmdBuffer, 0x0, FPGA_WRITE_CMD_BUFFER_LEN ); // TODO a better place for this } - //requestFlashRegistersStatus(); - return state; } @@ -1104,7 +1141,7 @@ // Prep DMA for sending the read cmd and receiving the response fpgaJobsQStatus.fpgaCommRead = FPGA_COMM_READ_IN_PROGRESS; - fpgaFlashStatus.startTime = getMSTimerCount(); + fpgaOperationStartTimeMS = getMSTimerCount(); setupDMAForReadResp( FPGA_READ_RSP_HDR_LEN + jobSize + sizeof( U16 ) ); setupDMAForReadCmd( FPGA_READ_CMD_HDR_LEN + sizeof( U16 ) ); @@ -1151,24 +1188,22 @@ case FPGA_READ_MULTI_BOOT_STATUS: memcpy( &fpgaReadRegsStatus, &fpgaReadResponseBuffer[ FPGA_READ_RSP_HDR_LEN ], jobSize ); + processFPGAFlashRegistersRead(); break; default: // Do nothing break; } - memset( fpgaReadResponseBuffer, 0x0, FPGA_READ_RSP_BUFFER_LEN ); - - enqueue( FPGA_READ_MULTI_BOOT_STATUS ); + memset( &fpgaReadResponseBuffer, 0x0, FPGA_READ_RSP_BUFFER_LEN ); state = FPGA_IDLE_STATE; } } } - if ( TRUE == didTimeout( fpgaFlashStatus.startTime, 100 ) ) + if ( TRUE == didTimeout( fpgaFlashStatus.startTimeMS, 100 ) ) { - // TODO a request multiboot here state = FPGA_IDLE_STATE; }