Index: firmware/App/Services/FPGA.c =================================================================== diff -u -r3a0dc476f0f42bb7ebadc7d6109a0b5b6581cce4 -r0595b4b31cef5980bc589ff7ce39a4e97bc81d8d --- firmware/App/Services/FPGA.c (.../FPGA.c) (revision 3a0dc476f0f42bb7ebadc7d6109a0b5b6581cce4) +++ firmware/App/Services/FPGA.c (.../FPGA.c) (revision 0595b4b31cef5980bc589ff7ce39a4e97bc81d8d) @@ -12,9 +12,10 @@ #include "Comm.h" #include "FPGA.h" +#include "Timers.h" #include "Utilities.h" -#define QUEUE_MAX_SIZE 10 ///< Max queue size. +#define QUEUE_MAX_SIZE 20 ///< Max queue size. #define FPGA_PAGE_SIZE 256 ///< FPGA register pages are 256 bytes. #define FPGA_MAX_READ_SIZE ( FPGA_PAGE_SIZE - 1 ) #define FPGA_WRITE_CMD_BUFFER_LEN ( FPGA_PAGE_SIZE + 8 ) ///< FPGA write command buffer byte length. @@ -46,9 +47,14 @@ #define FPGA_READ_CMD_HDR_LEN 4 ///< FPGA read command header byte length. #define FPGA_READ_RSP_HDR_LEN 3 ///< FPGA read command response header byte length. #define FPGA_UPDATE_REQUEST_INDEX ( FPGA_READ_RSP_HDR_LEN + 1 ) // 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 ) +#define FPGA_FIFO_COUNT_INDEX ( FPGA_READ_RSP_HDR_LEN + 1 ) #define UPDATE_REQUESTED_VALUE 1 +#define FPGA_FIFO_SIZE_BYTES 1024 +#define FPGA_FIFO_COUNT_MASK 0x03FF + #define FPGA_ERASE_FIFO_CMD_OK ( 1 << 11 ) #define FPGA_FLASH_STATUS_OK ( 1 << 15 ) @@ -88,15 +94,6 @@ NUM_OF_FPGA_STATES } FPGA_STATE_T; -typedef enum -{ - FPGA_UPDATE_NOT_STARTED = 0, - FPGA_UPDATE_INITIALIZE_FLASH, - FPGA_UPDATE_FLASH_IN_PROG, - FPGA_UPDATE_FINISH_FLASH, - NUM_OF_FPGA_FLASH_STATE, -} FPGA_FLASH_STATE_T; // TODO remove? - #pragma pack(push,1) typedef struct { @@ -120,8 +117,7 @@ typedef struct { BOOL isFlashErased; - BOOL isFlashReady; - U16 FIFOCount; + FPGA_FLASH_STATE_T fpgaFlashState; U32 startTime; } FPGA_FLASH_STATUS_T; @@ -152,7 +148,10 @@ static FPGA_STATE_T fpgaState; static U08 fpgaUpdateRegisterStatus; static FPGA_JOBS_Q_STATUS_T fpgaJobsQStatus; +static FPGA_FLASH_STATUS_T fpgaFlashStatus; +static U32 TESTTIMEREMOVE; + static const U08 STACK_FPGA_ID[ NUM_OF_FW_STACKS ] = { 0x5A, 0x61, 0xFF }; // TODO update with the real FPGA IDs static const U16 DISABLE_UPDATE_REG_CMD = 5; // TODO what is this value? 0? static const U08 FPGA_RESET_FLASH_CMD = 0x01; @@ -170,13 +169,16 @@ { FPGA_FLASH_STATUS_REG_ADDR, sizeof( U16 ), 0, FALSE }, // FPGA_CHECK_ERASE_FIFO_STATUS { FPGA_FLASH_STATUS_REG_ADDR, sizeof( U16 ), 0, FALSE }, // FPGA_CHECK_FLASH_READY_STATUS { FPGA_FIFO_COUNT_REG_ADDR, sizeof( U16 ), 0, FALSE }, // FPGA_CHECK_FIFO_COUNT - { FPGA_FLASH_DATA_REG_ADDR, SW_UPDATE_FLASH_BUFFER_SIZE, fpgaWriteCmdBuffer, TRUE }, // FPGA_FLASH_UPDATE_DATA + { FPGA_FLASH_DATA_REG_ADDR, SW_UPDATE_FLASH_BUFFER_SIZE, fpgaWriteCmdBuffer, TRUE }, // FPGA_FLASH_WRITE_DATA { FPGA_ICAP2_REG_ADDR, sizeof( U08 ), (U08*)&FPGA_SELF_CONFIG_CMD, TRUE } // FPGA_SELF_CONFIGURE }; static void initDMA( void ); static void consumeUnexpectedData( void ); -static void processFPGAReceivedData( void ); +static BOOL processFPGAReceivedData( void ); +static BOOL isFPGAEraseFlashStatusOk( void ); +static BOOL isFPGAFlashStatusOk( void ); +static BOOL isFPGAFIFOStatusOk( void ); static void setupDMAForReadResp( U32 bytes2Receive ); static void setupDMAForReadCmd( U32 bytes2Transmit ); @@ -203,6 +205,7 @@ { memset( &fpgaHeader, 0x0, sizeof( FPGA_HEADER_T ) ); memset( &fpgaJobsQStatus, 0x0, sizeof( FPGA_JOBS_Q_STATUS_T ) ); + memset( &fpgaFlashStatus, 0x0, sizeof( FPGA_FLASH_STATUS_T ) ); initDMA(); consumeUnexpectedData(); @@ -279,6 +282,38 @@ return status; } +FPGA_FLASH_STATE_T getFPGAFlashState( void ) +{ + return fpgaFlashStatus.fpgaFlashState; +} + + +void signalFPGAToPrepareForUpdate( void ) +{ + enqueue( FPGA_RESET_FLASH ); + enqueue( FPGA_ERASE_FIFO ); + enqueue( FPGA_ENABLE_FLASH ); + enqueue( FPGA_CHECK_ERASE_FIFO_STATUS ); +} + +void signalFPGAToWriteToFlash( U08* data, U32 len ) +{ + enqueue( FPGA_CHECK_FLASH_READY_STATUS ); + enqueue( FPGA_CHECK_FIFO_COUNT ); + enqueue( FPGA_FLASH_WRITE_DATA ); + enqueue( FPGA_CHECK_FIFO_COUNT ); // TODO remove for testing only + enqueue( FPGA_CHECK_FIFO_COUNT ); // TODO remove for testing only + enqueue( FPGA_CHECK_FIFO_COUNT ); // TODO remove for testing only + enqueue( FPGA_CHECK_FIFO_COUNT ); // TODO remove for testing only + enqueue( FPGA_CHECK_FIFO_COUNT ); // TODO remove for testing only + + memcpy( fpgaWriteCmdBuffer, data, len ); + + fpgaFlashStatus.fpgaFlashState = FPGA_UPDATE_BUSY; +} + +// ********** private functions ********** + static void initDMA( void ) { // Enable interrupt notifications for FPGA serial port @@ -381,8 +416,10 @@ } } -static void processFPGAReceivedData( void ) +static BOOL processFPGAReceivedData( void ) { + BOOL status = TRUE; + // Capture the read values switch( fpgaJobsQStatus.fpgaCurrentJob ) { @@ -395,21 +432,77 @@ break; case FPGA_CHECK_ERASE_FIFO_STATUS: + status = isFPGAEraseFlashStatusOk(); break; case FPGA_CHECK_FLASH_READY_STATUS: + status = isFPGAFlashStatusOk(); break; case FPGA_CHECK_FIFO_COUNT: + status = isFPGAFIFOStatusOk(); break; default: // Do nothing break; } + + return status; } +static BOOL isFPGAEraseFlashStatusOk( void ) +{ + U08 jobSize = JOBS_SPECS[ fpgaJobsQStatus.fpgaCurrentJob ].fpgaJobSize; + U16 flashStatus = 0; + BOOL eraseStatus = FALSE; + memcpy( &flashStatus, &fpgaReadResponseBuffer[ FPGA_FLASH_STATUS_INDEX ], jobSize ); + + if ( ( flashStatus & FPGA_ERASE_FIFO_CMD_OK ) == FPGA_ERASE_FIFO_CMD_OK ) + { + fpgaFlashStatus.fpgaFlashState = FPGA_UPDATE_READY; + eraseStatus = TRUE; + } + + return eraseStatus; +} + +static BOOL isFPGAFlashStatusOk( void ) +{ + U16 flashStatus = 0; + BOOL flashStatusOk = FALSE; + + flashStatus = MAKE_WORD_OF_BYTES( fpgaReadResponseBuffer[ FPGA_FLASH_STATUS_INDEX ], + fpgaReadResponseBuffer[ FPGA_FLASH_STATUS_INDEX - 1 ] ); + + if ( ( flashStatus & FPGA_FLASH_STATUS_OK ) == FPGA_FLASH_STATUS_OK ) + { + fpgaFlashStatus.fpgaFlashState = FPGA_UPDATE_READY; + flashStatusOk = TRUE; + } + + return flashStatusOk; +} + +static BOOL isFPGAFIFOStatusOk( void ) +{ + U16 remFIFOCount = 0; + BOOL isStatusOk = FALSE; + + remFIFOCount = FPGA_FIFO_COUNT_MASK & MAKE_WORD_OF_BYTES( fpgaReadResponseBuffer[ FPGA_FLASH_STATUS_INDEX ], + fpgaReadResponseBuffer[ FPGA_FLASH_STATUS_INDEX - 1 ] ); + remFIFOCount = FPGA_FIFO_SIZE_BYTES - remFIFOCount; + + if ( remFIFOCount >= SW_UPDATE_FLASH_BUFFER_SIZE ) + { + isStatusOk = TRUE; + //fpgaFlashStatus.fpgaFlashState = + } + + return isStatusOk; +} + static void setupDMAForReadResp( U32 bytes2Receive ) { // Verify # of bytes does not exceed buffer length @@ -593,6 +686,8 @@ startDMAReceiptOfWriteResp(); startDMAWriteCmd(); + TESTTIMEREMOVE = getMSTimerCount(); + return state; } @@ -612,14 +707,21 @@ // Does the FPGA response CRC checkout? if ( crc == crc16( fpgaWriteResponseBuffer, rspSize ) ) { - // CRC failed - state = FPGA_IDLE_STATE; + if ( TRUE == didTimeout( TESTTIMEREMOVE, 3000) ) + { + // CRC passed + state = FPGA_IDLE_STATE; + memset( fpgaWriteCmdBuffer, 0x0, FPGA_WRITE_CMD_BUFFER_LEN ); // TODO remove + + } } else { // TODO error handling } } + + // memset( fpgaWriteCmdBuffer, 0x0, FPGA_WRITE_CMD_BUFFER_LEN ); // TODO a better place for this } return state; @@ -660,17 +762,18 @@ { if ( FPGA_READ_CMD_ACK == fpgaReadResponseBuffer[ 0 ] ) { - U32 rspSize = FPGA_READ_RSP_HDR_LEN + FPGA_MAX_READ_SIZE; + 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 ] ); // Does the FPGA response CRC check out? if ( crc == crc16( fpgaReadResponseBuffer, rspSize ) ) { - processFPGAReceivedData(); + BOOL status = processFPGAReceivedData(); - fpgaJobsQStatus.fpgaCommRead = FPGA_COMM_IDLE; - state = FPGA_IDLE_STATE; + memset( fpgaReadResponseBuffer, 0x0, FPGA_READ_RSP_BUFFER_LEN ); + + state = ( TRUE == status ? FPGA_IDLE_STATE : FPGA_READ_FROM_FPGA_STATE ); // TODO have a limit } } }