Index: firmware/App/Common.h =================================================================== diff -u -r84f337383202622f14cd6148e26bab8f68333847 -rf100557efc2f7916054a63bbafb187d8017914d0 --- firmware/App/Common.h (.../Common.h) (revision 84f337383202622f14cd6148e26bab8f68333847) +++ firmware/App/Common.h (.../Common.h) (revision f100557efc2f7916054a63bbafb187d8017914d0) @@ -11,6 +11,9 @@ #define FIRMWARE_START_ADDRESS 0x00010000 #define FIRMWARE_CRC_TABLE_ADDRESS 0x10020 ///< The starting address of CRC table for firmware image. #define SW_UPDATE_FLASH_BUFFER_SIZE 128 +#define MASK_OFF_MSB 0x00FF ///< Bits to mask off the most significant byte of a 2-byte word +#define MASK_OFF_LSB 0xFF00 ///< Bits to mask off the least significant byte of a 2-byte word +#define SHIFT_8_BITS_FOR_BYTE_SHIFT 8 ///< Number of bits to shift in order to shift a byte // **** Types **** Index: firmware/App/Modes/ModeStandby.c =================================================================== diff -u -r84f337383202622f14cd6148e26bab8f68333847 -rf100557efc2f7916054a63bbafb187d8017914d0 --- firmware/App/Modes/ModeStandby.c (.../ModeStandby.c) (revision 84f337383202622f14cd6148e26bab8f68333847) +++ firmware/App/Modes/ModeStandby.c (.../ModeStandby.c) (revision f100557efc2f7916054a63bbafb187d8017914d0) @@ -5,7 +5,8 @@ * Author: fw */ -#include "string.h" // for memset +#include // For memcpy and memset + #include "sys_core.h" // To disable RAM and Flash ECC #include "sys_mpu.h" // To disable MPU @@ -151,7 +152,6 @@ { U32 jumpAddress = (U32)FIRMWARE_START_ADDRESS; - // TODO uncomment // Disable various memory protections _coreDisableRamEcc_(); _coreDisableFlashEcc_(); Index: firmware/App/Services/CommBuffers.c =================================================================== diff -u -r9af6fc3e5afc442a877bd5e23ecfa6872a3ad5a4 -rf100557efc2f7916054a63bbafb187d8017914d0 --- firmware/App/Services/CommBuffers.c (.../CommBuffers.c) (revision 9af6fc3e5afc442a877bd5e23ecfa6872a3ad5a4) +++ firmware/App/Services/CommBuffers.c (.../CommBuffers.c) (revision f100557efc2f7916054a63bbafb187d8017914d0) @@ -5,7 +5,8 @@ * Author: fw */ -#include "string.h" // For memcpy +#include // For memcpy + #include "can.h" #include "CommBuffers.h" Index: firmware/App/Services/FPGA.c =================================================================== diff -u --- firmware/App/Services/FPGA.c (revision 0) +++ firmware/App/Services/FPGA.c (revision f100557efc2f7916054a63bbafb187d8017914d0) @@ -0,0 +1,417 @@ +/* + * FPGA.c + * + * Created on: Aug 15, 2024 + * Author: fw + */ + +#include // For memcpy and memset + +#include "sci.h" +#include "sys_dma.h" + +#include "FPGA.h" +#include "Utilities.h" + +#define FPGA_PAGE_SIZE 256 ///< FPGA register pages are 256 bytes. +#define FPGA_EXPECTED_ID 0x5A ///< Expected ID for HD FPGA. +#define FPGA_WRITE_CMD_BUFFER_LEN ( FPGA_PAGE_SIZE + 8 ) ///< FPGA write command buffer byte length. +#define FPGA_READ_CMD_BUFFER_LEN 8 ///< FPGA read command buffer byte length. +#define FPGA_WRITE_RSP_BUFFER_LEN 8 ///< FPGA write command response buffer byte length. +#define FPGA_READ_RSP_BUFFER_LEN ( FPGA_PAGE_SIZE + 8 ) ///< FPGA read command response buffer byte length. + +#define SCI2_RECEIVE_DMA_REQUEST 28 ///< Serial port 2 receive DMA request line. +#define SCI2_TRANSMIT_DMA_REQUEST 29 ///< Serial port 2 transmit DMA request line. + +#define GET_LSB_OF_WORD(w) ((U08)((w) & MASK_OFF_MSB)) ///< Macro returns the least signficant byte of a 2-byte word +#define GET_MSB_OF_WORD(w) ((U08)(((w) >> SHIFT_8_BITS_FOR_BYTE_SHIFT) & MASK_OFF_MSB)) ///< Macro returns the most signficant byte of a 2-byte word +#define MAKE_WORD_OF_BYTES(h, l) ((((U16)(h) << SHIFT_8_BITS_FOR_BYTE_SHIFT) & MASK_OFF_LSB) | ((U16)(l) & MASK_OFF_MSB)) ///< Macro merges two bytes into a 2-byte word + +#define FPGA_READ_CMD_CODE 0x5A ///< FPGA read command code. +#define FPGA_HEADER_START_ADDR 0x0000 ///< Start address for FPGA header data. +#define FPGA_READ_CMD_ACK 0xAA ///< FPGA read command ACK code. +#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 SCI_DMA_TRANSMIT_INT 0x00010000 ///< Bit mask for setting/clearing serial DMA transmit interrupts. +#define SCI_DMA_RECEIVE_INT 0x00060000 ///< Bit mask for setting/clearing serial DMA receive interrupts. + +typedef enum +{ + FPGA_COMM_IDLE = 0, + FPGA_COMM_READ_IN_PROGRESS, + FPGA_COMM_READ_RESP_RECEIVED, + FPGA_COMM_WRITE_IN_PROGRESS, + FPGA_COMM_WRITE_RESP_RECEIVED, + NUM_OF_FPGA_COMM_STATUS +} FPGA_COMM_STATE_T; + +typedef enum +{ + FPGA_START_STATE = 0, + FPGA_RQST_HEADER_STATE, + FPGA_RCV_HEADER_STATE, + FPGA_WRITE_TO_FPGA_STATE, + FPGA_READ_FROM_FPGA_STATE, + FPGA_IDLE_STATE, + NUM_OF_FPGA_STATES +} FPGA_STATE_T; + +typedef struct +{ + FPGA_COMM_STATE_T fpgaCommRead; + FPGA_COMM_STATE_T fpgaCommWrite; +} FPGA_COMM_STATUS_T; +// FPGA Sensors Record +#pragma pack(push,1) +/// Record structure for FPGA header read. +typedef struct +{ + U08 fpgaId; ///< Reg 0. FPGA ID code. Checked against expected value at power up to verify basic FPGA communication and operation. + U08 fpgaRev; ///< Reg 1. FPGA revision (minor) being reported. + U08 fpgaRevMajor; ///< Reg 2. FPGA revision (major) being reported. + U08 fpgaRevLab; ///< Reg 3. FPGA revision (lab) being reported. + U16 fpgaStatus; ///< Reg 4. FPGA status register. +} FPGA_HEADER_T; // Read only on FPGA +#pragma pack(pop) + +// FPGA comm buffers +static U08 fpgaWriteCmdBuffer[ FPGA_WRITE_CMD_BUFFER_LEN ]; ///< FPGA write command buffer. Holds the next FPGA write command to be transmitted. +static U08 fpgaReadCmdBuffer[ FPGA_READ_CMD_BUFFER_LEN ]; ///< FPGA read command buffer. Holds the next FPGA read command to be transmitted. +static U08 fpgaWriteResponseBuffer[ FPGA_WRITE_RSP_BUFFER_LEN ]; ///< FPGA write command response buffer. Memory reserved to capture the response to the last FPGA write command. +static U08 fpgaReadResponseBuffer[ FPGA_READ_RSP_BUFFER_LEN ]; ///< FPGA read command response buffer. Memory reserved to capture the response to the last FPGA read command. + +// DMA control records +static g_dmaCTRL fpgaDMAWriteControlRecord; ///< DMA record for controlling a DMA write command transmission from buffer. +static g_dmaCTRL fpgaDMAWriteRespControlRecord; ///< DMA record for controlling a DMA write command reception to buffer. +static g_dmaCTRL fpgaDMAReadControlRecord; ///< DMA record for controlling a DMA read command transmission from buffer. +static g_dmaCTRL fpgaDMAReadRespControlRecord; ///< DMA record for controlling a DMA read command reception to buffer. + +static FPGA_HEADER_T fpgaHeader; ///< Record of last received FPGA header data. +static FPGA_STATE_T fpgaState; +static FPGA_COMM_STATUS_T fpgaCommStatus; + + +static void initDMA( void ); +static void consumeUnexpectedData( void ); +static void setSCI2DMAReceiveInterrupt( void ); +static void setSCI2DMATransmitInterrupt( void ); +static void setupDMAForReadResp( U32 bytes2Receive ); +static void setupDMAForReadCmd( U32 bytes2Transmit ); +static void startDMAReceiptOfReadResp( void ); +static void startDMAReadCmd( void ); +static void resetFPGACommFlags( void ); + +static FPGA_STATE_T handleFPGARequestHeaderState( void ); +static FPGA_STATE_T handleFPGARecieveHeaderState( void ); +static FPGA_STATE_T handleFPGAWriteToFPGAState( void ); +static FPGA_STATE_T handleFPGAReadFromFPGAState( void ); +static FPGA_STATE_T handleFPGAIdleState( void ); + + +void initFPGA( void ) +{ + memset( &fpgaHeader, 0x0, sizeof( FPGA_HEADER_T ) ); + + initDMA(); + consumeUnexpectedData(); + resetFPGACommFlags(); + + fpgaState = FPGA_START_STATE; +} + +void execFPGA( void ) +{ + switch( fpgaState ) + { + case FPGA_START_STATE: + fpgaState = FPGA_RQST_HEADER_STATE; // TODO this needs to be changed read from FPGA state to first see if there is an update or not. This is for test + break; + + case FPGA_RQST_HEADER_STATE: + fpgaState = handleFPGARequestHeaderState(); + break; + + case FPGA_RCV_HEADER_STATE: + fpgaState = handleFPGARecieveHeaderState(); + break; + + case FPGA_WRITE_TO_FPGA_STATE: + fpgaState = handleFPGAWriteToFPGAState(); + break; + + case FPGA_READ_FROM_FPGA_STATE: + fpgaState = handleFPGAReadFromFPGAState(); + break; + + case FPGA_IDLE_STATE: + fpgaState = handleFPGAIdleState(); + break; + + default: + // Do nothing + break; + } +} + +void signalFPGAReceiptCompleted( void ) +{ + // TODO What is the purpose of fpgaReceiptCounter++ in firmware? + + if ( FPGA_COMM_WRITE_IN_PROGRESS == fpgaCommStatus.fpgaCommWrite ) + { + fpgaCommStatus.fpgaCommWrite = FPGA_COMM_WRITE_RESP_RECEIVED; + } + else if ( FPGA_COMM_READ_IN_PROGRESS == fpgaCommStatus.fpgaCommRead ) + { + fpgaCommStatus.fpgaCommRead = FPGA_COMM_READ_RESP_RECEIVED; + } +} + +void clearSCI2DMAReceiveInterrupt( void ) +{ + scilinREG->CLEARINT = SCI_DMA_RECEIVE_INT; +} + +/*********************************************************************//** + * @brief + * The clearSCI2DMATransmitInterrupt function disables DMA transmit interrupts + * for the SCI2 peripheral. + * @details Inputs: none + * @details Outputs: DMA transmit interrupt is disabled. + * @return none + *************************************************************************/ +void clearSCI2DMATransmitInterrupt( void ) +{ + scilinREG->CLEARINT = SCI_DMA_TRANSMIT_INT; +} + +static void initDMA( void ) +{ + // Enable interrupt notifications for FPGA serial port + sciEnableNotification( scilinREG, SCI_OE_INT | SCI_FE_INT ); + + // Assign DMA channels to h/w DMA requests + dmaReqAssign( DMA_CH0, SCI2_RECEIVE_DMA_REQUEST ); + dmaReqAssign( DMA_CH2, SCI2_TRANSMIT_DMA_REQUEST ); + + // Set DMA channel priorities + dmaSetPriority( DMA_CH0, HIGHPRIORITY ); + dmaSetPriority( DMA_CH2, LOWPRIORITY ); + + // Enable DMA block transfer complete interrupts + dmaEnableInterrupt( DMA_CH0, BTC ); + dmaEnableInterrupt( DMA_CH2, BTC ); + + // Initialize FPGA DMA Write Control Record + fpgaDMAWriteControlRecord.PORTASGN = 4; // Port B (only choice per datasheet) + fpgaDMAWriteControlRecord.SADD = (U32)fpgaWriteCmdBuffer; // Transfer source address + fpgaDMAWriteControlRecord.DADD = (U32)(&(scilinREG->TD)); // Dest. is SCI2 xmit register + fpgaDMAWriteControlRecord.CHCTRL = 0; // No chaining + fpgaDMAWriteControlRecord.ELCNT = 1; // Frame is 1 element + fpgaDMAWriteControlRecord.FRCNT = 0; // Block is TBD frames - will be populated later when known + fpgaDMAWriteControlRecord.RDSIZE = ACCESS_8_BIT; // Element size is 1 byte + fpgaDMAWriteControlRecord.WRSIZE = ACCESS_8_BIT; // + fpgaDMAWriteControlRecord.TTYPE = FRAME_TRANSFER; // Transfer type is block transfer + fpgaDMAWriteControlRecord.ADDMODERD = ADDR_INC1; // Source addressing mode is post-increment + fpgaDMAWriteControlRecord.ADDMODEWR = ADDR_FIXED; // Dest. addressing mode is fixed + fpgaDMAWriteControlRecord.AUTOINIT = AUTOINIT_OFF; // Auto-init off + fpgaDMAWriteControlRecord.ELSOFFSET = 0; // Not used + fpgaDMAWriteControlRecord.ELDOFFSET = 0; // Not used + fpgaDMAWriteControlRecord.FRSOFFSET = 0; // Not used + fpgaDMAWriteControlRecord.FRDOFFSET = 0; // Not used + + // Initialize FPGA DMA Write Response Control Record + fpgaDMAWriteRespControlRecord.PORTASGN = 4; // Port B (only choice per datasheet) + fpgaDMAWriteRespControlRecord.SADD = (U32)(&(scilinREG->RD)); // Source is SCI2 recv register + fpgaDMAWriteRespControlRecord.DADD = (U32)fpgaWriteResponseBuffer; // Transfer destination address + fpgaDMAWriteRespControlRecord.CHCTRL = 0; // No chaining + fpgaDMAWriteRespControlRecord.ELCNT = 1; // Frame is 1 element + fpgaDMAWriteRespControlRecord.FRCNT = 0; // Block is TBD frames - will be populated later when known + fpgaDMAWriteRespControlRecord.RDSIZE = ACCESS_8_BIT; // Element size is 1 byte + fpgaDMAWriteRespControlRecord.WRSIZE = ACCESS_8_BIT; // + fpgaDMAWriteRespControlRecord.TTYPE = FRAME_TRANSFER; // Transfer type is block transfer + fpgaDMAWriteRespControlRecord.ADDMODERD = ADDR_FIXED; // Source addressing mode is fixed + fpgaDMAWriteRespControlRecord.ADDMODEWR = ADDR_INC1; // Dest. addressing mode is post-increment + fpgaDMAWriteRespControlRecord.AUTOINIT = AUTOINIT_OFF; // Auto-init off + fpgaDMAWriteRespControlRecord.ELDOFFSET = 0; // Not used + fpgaDMAWriteRespControlRecord.ELSOFFSET = 0; // Not used + fpgaDMAWriteRespControlRecord.FRDOFFSET = 0; // Not used + fpgaDMAWriteRespControlRecord.FRSOFFSET = 0; // Not used + + // Initialize FPGA DMA Read Control Record + fpgaDMAReadControlRecord.PORTASGN = 4; // Port B (only choice per datasheet) + fpgaDMAReadControlRecord.SADD = (U32)fpgaReadCmdBuffer; // Transfer source address + fpgaDMAReadControlRecord.DADD = (U32)(&(scilinREG->TD)); // Dest. is SCI2 xmit register + fpgaDMAReadControlRecord.CHCTRL = 0; // No chaining + fpgaDMAReadControlRecord.ELCNT = 1; // Frame is 1 element + fpgaDMAReadControlRecord.FRCNT = 0; // Block is TBD frames - will be populated later when known + fpgaDMAReadControlRecord.RDSIZE = ACCESS_8_BIT; // Element size is 1 byte + fpgaDMAReadControlRecord.WRSIZE = ACCESS_8_BIT; // + fpgaDMAReadControlRecord.TTYPE = FRAME_TRANSFER; // Transfer type is block transfer + fpgaDMAReadControlRecord.ADDMODERD = ADDR_INC1; // Source addressing mode is post-increment + fpgaDMAReadControlRecord.ADDMODEWR = ADDR_FIXED; // Dest. addressing mode is fixed + fpgaDMAReadControlRecord.AUTOINIT = AUTOINIT_OFF; // Auto-init off + fpgaDMAReadControlRecord.ELSOFFSET = 0; // Not used + fpgaDMAReadControlRecord.ELDOFFSET = 0; // Not used + fpgaDMAReadControlRecord.FRSOFFSET = 0; // Not used + fpgaDMAReadControlRecord.FRDOFFSET = 0; // Not used + + // Initialize FPGA DMA Read Response Control Record + fpgaDMAReadRespControlRecord.PORTASGN = 4; // Port B (only choice per datasheet) + fpgaDMAReadRespControlRecord.SADD = (U32)(&(scilinREG->RD)); // Source is SCI2 recv register + fpgaDMAReadRespControlRecord.DADD = (U32)fpgaReadResponseBuffer; // Transfer destination address + fpgaDMAReadRespControlRecord.CHCTRL = 0; // No chaining + fpgaDMAReadRespControlRecord.ELCNT = 1; // Frame is 1 element + fpgaDMAReadRespControlRecord.FRCNT = 0; // Block is TBD frames - will be populated later when known + fpgaDMAReadRespControlRecord.RDSIZE = ACCESS_8_BIT; // Element size is 1 byte + fpgaDMAReadRespControlRecord.WRSIZE = ACCESS_8_BIT; // + fpgaDMAReadRespControlRecord.TTYPE = FRAME_TRANSFER; // Transfer type is block transfer + fpgaDMAReadRespControlRecord.ADDMODERD = ADDR_FIXED; // Source addressing mode is fixed + fpgaDMAReadRespControlRecord.ADDMODEWR = ADDR_INC1; // Dest. addressing mode is post-increment + fpgaDMAReadRespControlRecord.AUTOINIT = AUTOINIT_OFF; // Auto-init off + fpgaDMAReadRespControlRecord.ELDOFFSET = 0; // Not used + fpgaDMAReadRespControlRecord.ELSOFFSET = 0; // Not used + fpgaDMAReadRespControlRecord.FRDOFFSET = 0; // Not used + fpgaDMAReadRespControlRecord.FRSOFFSET = 0; // Not used +} + +static void consumeUnexpectedData( void ) +{ + // Clear any errors + sciRxError( scilinREG ); + + // If a byte is pending read, read it + if ( sciIsRxReady( scilinREG ) != 0 ) + { + sciReceiveByte( scilinREG ); + } +} + +static void setSCI2DMAReceiveInterrupt( void ) +{ + scilinREG->SETINT = SCI_DMA_RECEIVE_INT; +} + +void setSCI2DMATransmitInterrupt( void ) +{ + scilinREG->SETINT = SCI_DMA_TRANSMIT_INT; +} + + +static void setupDMAForReadResp( U32 bytes2Receive ) +{ + // Verify # of bytes does not exceed buffer length + if ( bytes2Receive <= FPGA_READ_RSP_BUFFER_LEN ) + { + fpgaDMAReadRespControlRecord.FRCNT = bytes2Receive; + } +} + +static void setupDMAForReadCmd( U32 bytes2Transmit ) +{ + // Verify # of bytes does not exceed buffer length + if ( bytes2Transmit <= FPGA_READ_CMD_BUFFER_LEN ) + { + fpgaDMAReadControlRecord.FRCNT = bytes2Transmit; + } +} + +static void startDMAReceiptOfReadResp( void ) +{ + dmaSetCtrlPacket( DMA_CH0, fpgaDMAReadRespControlRecord ); + dmaSetChEnable( DMA_CH0, DMA_HW ); + setSCI2DMAReceiveInterrupt(); +} + +static void startDMAReadCmd( void ) +{ + dmaSetCtrlPacket( DMA_CH2, fpgaDMAReadControlRecord ); + dmaSetChEnable( DMA_CH2, DMA_HW ); + setSCI2DMATransmitInterrupt(); +} + +static void resetFPGACommFlags( void ) +{ + memset( &fpgaCommStatus, 0x0, sizeof( FPGA_COMM_STATUS_T ) ); +} + +static FPGA_STATE_T handleFPGARequestHeaderState( void ) +{ + FPGA_STATE_T state = FPGA_RCV_HEADER_STATE; + 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( FPGA_HEADER_START_ADDR ); + fpgaReadCmdBuffer[ 2 ] = GET_MSB_OF_WORD( FPGA_HEADER_START_ADDR ); + fpgaReadCmdBuffer[ 3 ] = sizeof( FPGA_HEADER_T ); + crc = crc16( fpgaReadCmdBuffer, FPGA_READ_CMD_HDR_LEN ); + fpgaReadCmdBuffer[ 4 ] = GET_MSB_OF_WORD( crc ); + fpgaReadCmdBuffer[ 5 ] = GET_LSB_OF_WORD( crc ); + + // Prep DMA for sending the read cmd and receiving the response + fpgaCommStatus.fpgaCommRead = FPGA_COMM_READ_IN_PROGRESS; + + setupDMAForReadResp( FPGA_READ_RSP_HDR_LEN + sizeof( FPGA_HEADER_T ) + sizeof( U16 ) ); + setupDMAForReadCmd( FPGA_READ_CMD_HDR_LEN + sizeof( U16 ) ); + startDMAReceiptOfReadResp(); + startDMAReadCmd(); + + return state; +} + +static FPGA_STATE_T handleFPGARecieveHeaderState( void ) +{ + FPGA_STATE_T state = FPGA_RCV_HEADER_STATE; + + if ( FPGA_COMM_READ_RESP_RECEIVED == fpgaCommStatus.fpgaCommRead ) + { + if ( FPGA_READ_CMD_ACK == fpgaReadResponseBuffer[ 0 ] ) + { + U32 rspSize = FPGA_READ_RSP_HDR_LEN + sizeof( FPGA_HEADER_T ); + 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 ) ) + { + // Capture the read values + memcpy( &fpgaHeader, &fpgaReadResponseBuffer[ FPGA_READ_RSP_HDR_LEN ], sizeof( FPGA_HEADER_T ) ); + state = FPGA_IDLE_STATE; + } + } + } + + resetFPGACommFlags(); + + // Should not be any data received at this time + consumeUnexpectedData(); + + return state; +} + +static FPGA_STATE_T handleFPGAWriteToFPGAState( void ) +{ + FPGA_STATE_T state = FPGA_WRITE_TO_FPGA_STATE; + + return state; +} + +static FPGA_STATE_T handleFPGAReadFromFPGAState( void ) +{ + FPGA_STATE_T state = FPGA_READ_FROM_FPGA_STATE; + + // Should not be any data received at this time + consumeUnexpectedData(); + + return state; +} + +static FPGA_STATE_T handleFPGAIdleState( void ) +{ + FPGA_STATE_T state = FPGA_IDLE_STATE; + + return state; +} + Index: firmware/App/Services/FPGA.h =================================================================== diff -u --- firmware/App/Services/FPGA.h (revision 0) +++ firmware/App/Services/FPGA.h (revision f100557efc2f7916054a63bbafb187d8017914d0) @@ -0,0 +1,22 @@ +/* + * FPGA.h + * + * Created on: Aug 15, 2024 + * Author: fw + */ + +#ifndef __FPGA_H__ +#define __FPGA_H__ + +#include "BLCommon.h" + +void initFPGA( void ); + +void execFPGA( void ); + +void signalFPGAReceiptCompleted( void ); + +void clearSCI2DMAReceiveInterrupt( void ); +void clearSCI2DMATransmitInterrupt( void ); + +#endif Index: firmware/App/Services/Interrupts.c =================================================================== diff -u -r9af6fc3e5afc442a877bd5e23ecfa6872a3ad5a4 -rf100557efc2f7916054a63bbafb187d8017914d0 --- firmware/App/Services/Interrupts.c (.../Interrupts.c) (revision 9af6fc3e5afc442a877bd5e23ecfa6872a3ad5a4) +++ firmware/App/Services/Interrupts.c (.../Interrupts.c) (revision f100557efc2f7916054a63bbafb187d8017914d0) @@ -12,14 +12,17 @@ #include "BLCommon.h" #include "CommBuffers.h" +#include "FPGA.h" #include "TaskGeneral.h" #include "TaskPriority.h" #include "TaskTimer.h" +static BOOL sci2FEOEError; ///< FPGA serial frame or overrun flag; + void initInterrupts( void ) { - // TODO fill up + sci2FEOEError = FALSE; } @@ -53,3 +56,49 @@ handleCANMsgInterrupt( (SW_UPDATE_CAN_MAIL_BOX_T)messageBox ); } } + +void sciNotification( sciBASE_t *sci, uint32 flags ) +{ +#ifndef _VECTORCAST_ + // Cannot set the pointers to be equal in VectorCAST. Can define pointers but the user does not have any control on the address of it + if ( sci == scilinREG ) +#endif + { + if ( ( flags & SCI_FE_INT ) != 0 ) + { + sci2FEOEError = TRUE; + scilinREG->FLR |= SCI_FE_INT; + } + + if ( ( flags & SCI_OE_INT ) != 0 ) + { + sci2FEOEError = TRUE; + scilinREG->FLR |= SCI_OE_INT; + } + } +} + +void dmaGroupANotification( dmaInterrupt_t inttype, uint32 channel ) +{ + if ( inttype == BTC ) // Block transfer completed interrupt + { + switch ( channel ) + { + case DMA_CH0: // FPGA receive channel + clearSCI2DMAReceiveInterrupt(); + signalFPGAReceiptCompleted(); + break; + + case DMA_CH2: // FPGA transmit channel + //clearSCI2DMATransmitInterrupt(); + //signalFPGATransmitCompleted(); + break; + + default: + // Do nothing + break; + } + } +} + + Index: firmware/App/Services/NVDataMgmt.c =================================================================== diff -u -r84f337383202622f14cd6148e26bab8f68333847 -rf100557efc2f7916054a63bbafb187d8017914d0 --- firmware/App/Services/NVDataMgmt.c (.../NVDataMgmt.c) (revision 84f337383202622f14cd6148e26bab8f68333847) +++ firmware/App/Services/NVDataMgmt.c (.../NVDataMgmt.c) (revision f100557efc2f7916054a63bbafb187d8017914d0) @@ -5,16 +5,16 @@ * Author: fw */ -#include "F021.h" -#include "string.h" +#include // For memcpy and memset + +#include "F021.h" // For fapi operations #include "system.h" // For fapi operations #include "NVDataMgmt.h" /* * TODO * 1. Clean up the flash with the bad data packets - * 2. Reset the counter to start the write from 0x10000 */ #define BANK0_NUM_OF_SECTORS 16 Index: firmware/App/Services/Utilities.c =================================================================== diff -u -r84f337383202622f14cd6148e26bab8f68333847 -rf100557efc2f7916054a63bbafb187d8017914d0 --- firmware/App/Services/Utilities.c (.../Utilities.c) (revision 84f337383202622f14cd6148e26bab8f68333847) +++ firmware/App/Services/Utilities.c (.../Utilities.c) (revision f100557efc2f7916054a63bbafb187d8017914d0) @@ -5,11 +5,14 @@ * Author: fw */ +#ifndef _VECTORCAST_ +// This header file is disabled in VectorCAST because this is a TI library and VectorCAST uses GNU 7.4 compiler for testing #include +#endif #include "Utilities.h" -#define SHIFT_8_BITS_FOR_BYTE_SHIFT 8 ///< Number of bits to shift in order to shift a byte +#define INITIAL_CRC16_VAL 0xFFFF ///< Seed for 16-bit CRC function. #define SHIFT_24_BITS 24 ///< Number of bits to shift in order to shift 3 bytes @@ -50,20 +53,44 @@ 0xD2DFB272, 0xCC03DD33, 0xEF676CF0, 0xF1BB03B1, 0xA9AE0F76, 0xB7726037, 0x9416D1F4, 0x8ACABEB5, }; - -U32 crc32( U32 initialValue, U08 *address, U32 len ) +/// CRC-16 look-up table. +const U16 CRC16_TABLE[] = { - U32 crc = initialValue; + 0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50a5, 0x60c6, 0x70e7, + 0x8108, 0x9129, 0xa14a, 0xb16b, 0xc18c, 0xd1ad, 0xe1ce, 0xf1ef, + 0x1231, 0x0210, 0x3273, 0x2252, 0x52b5, 0x4294, 0x72f7, 0x62d6, + 0x9339, 0x8318, 0xb37b, 0xa35a, 0xd3bd, 0xc39c, 0xf3ff, 0xe3de, + 0x2462, 0x3443, 0x0420, 0x1401, 0x64e6, 0x74c7, 0x44a4, 0x5485, + 0xa56a, 0xb54b, 0x8528, 0x9509, 0xe5ee, 0xf5cf, 0xc5ac, 0xd58d, + 0x3653, 0x2672, 0x1611, 0x0630, 0x76d7, 0x66f6, 0x5695, 0x46b4, + 0xb75b, 0xa77a, 0x9719, 0x8738, 0xf7df, 0xe7fe, 0xd79d, 0xc7bc, + 0x48c4, 0x58e5, 0x6886, 0x78a7, 0x0840, 0x1861, 0x2802, 0x3823, + 0xc9cc, 0xd9ed, 0xe98e, 0xf9af, 0x8948, 0x9969, 0xa90a, 0xb92b, + 0x5af5, 0x4ad4, 0x7ab7, 0x6a96, 0x1a71, 0x0a50, 0x3a33, 0x2a12, + 0xdbfd, 0xcbdc, 0xfbbf, 0xeb9e, 0x9b79, 0x8b58, 0xbb3b, 0xab1a, + 0x6ca6, 0x7c87, 0x4ce4, 0x5cc5, 0x2c22, 0x3c03, 0x0c60, 0x1c41, + 0xedae, 0xfd8f, 0xcdec, 0xddcd, 0xad2a, 0xbd0b, 0x8d68, 0x9d49, + 0x7e97, 0x6eb6, 0x5ed5, 0x4ef4, 0x3e13, 0x2e32, 0x1e51, 0x0e70, + 0xff9f, 0xefbe, 0xdfdd, 0xcffc, 0xbf1b, 0xaf3a, 0x9f59, 0x8f78, + 0x9188, 0x81a9, 0xb1ca, 0xa1eb, 0xd10c, 0xc12d, 0xf14e, 0xe16f, + 0x1080, 0x00a1, 0x30c2, 0x20e3, 0x5004, 0x4025, 0x7046, 0x6067, + 0x83b9, 0x9398, 0xa3fb, 0xb3da, 0xc33d, 0xd31c, 0xe37f, 0xf35e, + 0x02b1, 0x1290, 0x22f3, 0x32d2, 0x4235, 0x5214, 0x6277, 0x7256, + 0xb5ea, 0xa5cb, 0x95a8, 0x8589, 0xf56e, 0xe54f, 0xd52c, 0xc50d, + 0x34e2, 0x24c3, 0x14a0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405, + 0xa7db, 0xb7fa, 0x8799, 0x97b8, 0xe75f, 0xf77e, 0xc71d, 0xd73c, + 0x26d3, 0x36f2, 0x0691, 0x16b0, 0x6657, 0x7676, 0x4615, 0x5634, + 0xd94c, 0xc96d, 0xf90e, 0xe92f, 0x99c8, 0x89e9, 0xb98a, 0xa9ab, + 0x5844, 0x4865, 0x7806, 0x6827, 0x18c0, 0x08e1, 0x3882, 0x28a3, + 0xcb7d, 0xdb5c, 0xeb3f, 0xfb1e, 0x8bf9, 0x9bd8, 0xabbb, 0xbb9a, + 0x4a75, 0x5a54, 0x6a37, 0x7a16, 0x0af1, 0x1ad0, 0x2ab3, 0x3a92, + 0xfd2e, 0xed0f, 0xdd6c, 0xcd4d, 0xbdaa, 0xad8b, 0x9de8, 0x8dc9, + 0x7c26, 0x6c07, 0x5c64, 0x4c45, 0x3ca2, 0x2c83, 0x1ce0, 0x0cc1, + 0xef1f, 0xff3e, 0xcf5d, 0xdf7c, 0xaf9b, 0xbfba, 0x8fd9, 0x9ff8, + 0x6e17, 0x7e36, 0x4e55, 0x5e74, 0x2e93, 0x3eb2, 0x0ed1, 0x1ef0 +}; - while ( len-- > 0 ) - { - crc = ( crc << SHIFT_8_BITS_FOR_BYTE_SHIFT ) ^ CRC32_TABLE[ *address ^ ( crc >> SHIFT_24_BITS ) ]; - address++; - } - return crc; -} - BOOL runFWIntegrityTest( void ) { U32 remainingSize = 0; @@ -104,4 +131,33 @@ return integrityStatus; } +U16 crc16( U08 *address, U32 len ) +{ + U16 crc = INITIAL_CRC16_VAL; + while ( len-- > 0 ) + { + crc = ( crc << SHIFT_8_BITS_FOR_BYTE_SHIFT ) ^ CRC16_TABLE[ *address ^ ( ( crc >> SHIFT_8_BITS_FOR_BYTE_SHIFT ) & MASK_OFF_MSB ) ]; + address++; + } + + return crc; +} + + + +U32 crc32( U32 initialValue, U08 *address, U32 len ) +{ + U32 crc = initialValue; + + while ( len-- > 0 ) + { + crc = ( crc << SHIFT_8_BITS_FOR_BYTE_SHIFT ) ^ CRC32_TABLE[ *address ^ ( crc >> SHIFT_24_BITS ) ]; + address++; + } + + return crc; +} + + + Index: firmware/App/Services/Utilities.h =================================================================== diff -u -r84f337383202622f14cd6148e26bab8f68333847 -rf100557efc2f7916054a63bbafb187d8017914d0 --- firmware/App/Services/Utilities.h (.../Utilities.h) (revision 84f337383202622f14cd6148e26bab8f68333847) +++ firmware/App/Services/Utilities.h (.../Utilities.h) (revision f100557efc2f7916054a63bbafb187d8017914d0) @@ -12,9 +12,12 @@ #define MAX_CRC_CALC_DATA_SIZE 0x8000 ///< The maximum size of data for each CRC calculation. +BOOL runFWIntegrityTest( void ); +U16 crc16( U08 *address, U32 len ); + U32 crc32( U32 initialValue, U08 *address, U32 len ); -BOOL runFWIntegrityTest( void ); + #endif Index: firmware/App/Tasks/TaskPriority.c =================================================================== diff -u -rf2652e85c8676d0356fea2690cfd9cac716ca795 -rf100557efc2f7916054a63bbafb187d8017914d0 --- firmware/App/Tasks/TaskPriority.c (.../TaskPriority.c) (revision f2652e85c8676d0356fea2690cfd9cac716ca795) +++ firmware/App/Tasks/TaskPriority.c (.../TaskPriority.c) (revision f100557efc2f7916054a63bbafb187d8017914d0) @@ -7,10 +7,11 @@ #include "BLCommon.h" #include "CommBuffers.h" +#include "FPGA.h" #include "TaskPriority.h" void taskPriority( void ) { - BOOL test; + execFPGA(); } Index: firmware/BL.dil =================================================================== diff -u -rda12d1065b9bc93d30500255d8b986f00d1bdd69 -rf100557efc2f7916054a63bbafb187d8017914d0 --- firmware/BL.dil (.../BL.dil) (revision da12d1065b9bc93d30500255d8b986f00d1bdd69) +++ firmware/BL.dil (.../BL.dil) (revision f100557efc2f7916054a63bbafb187d8017914d0) @@ -1,4 +1,4 @@ -# RM46L852PGE 08/08/24 11:33:04 +# RM46L852PGE 08/15/24 10:42:26 # ARCH=RM46L852PGE # @@ -1723,7 +1723,7 @@ DRIVER.SCI.VAR.SCI_FEINTLVL.VALUE=0 DRIVER.SCI.VAR.SCILIN_EVENPARITY.VALUE=0 DRIVER.SCI.VAR.SCI_TXINTLVL.VALUE=0 -DRIVER.SCI.VAR.SCILIN_OEINTENA.VALUE=0 +DRIVER.SCI.VAR.SCILIN_OEINTENA.VALUE=1 DRIVER.SCI.VAR.SCILIN_PORT_BIT2_DOUT.VALUE=0 DRIVER.SCI.VAR.SCI_PORT_BIT1_DOUT.VALUE=0 DRIVER.SCI.VAR.SCI_PEINTENA.VALUE=0 @@ -1733,7 +1733,7 @@ DRIVER.SCI.VAR.SCI_PORT_BIT2_DOUT.VALUE=0 DRIVER.SCI.VAR.SCILIN_BASE.VALUE=0xFFF7E400 DRIVER.SCI.VAR.SCI_RXINTLVL.VALUE=0 -DRIVER.SCI.VAR.SCILIN_FEINTENA.VALUE=0 +DRIVER.SCI.VAR.SCILIN_FEINTENA.VALUE=1 DRIVER.SCI.VAR.SCI_PRESCALE.VALUE=55 DRIVER.SCI.VAR.SCILIN_OEINTLVL.VALUE=0 DRIVER.SCI.VAR.SCILIN_TXINTENA.VALUE=0 Index: firmware/include/sci.h =================================================================== diff -u -rabb9687e52d9db5df1abe7626ba04a6d431ba823 -rf100557efc2f7916054a63bbafb187d8017914d0 --- firmware/include/sci.h (.../sci.h) (revision abb9687e52d9db5df1abe7626ba04a6d431ba823) +++ firmware/include/sci.h (.../sci.h) (revision f100557efc2f7916054a63bbafb187d8017914d0) @@ -165,8 +165,8 @@ |(uint32)((uint32)0U << 1U) \ |(uint32)((uint32)0U)) -#define SCILIN_SETINT_CONFIGVALUE ((uint32)((uint32)0U << 26U) \ - |(uint32)((uint32)0U << 25U) \ +#define SCILIN_SETINT_CONFIGVALUE ((uint32)((uint32)1U << 26U) \ + |(uint32)((uint32)1U << 25U) \ |(uint32)((uint32)0U << 24U) \ |(uint32)((uint32)0U << 9U) \ |(uint32)((uint32)0U << 1U) \ Index: firmware/source/sci.c =================================================================== diff -u -rabb9687e52d9db5df1abe7626ba04a6d431ba823 -rf100557efc2f7916054a63bbafb187d8017914d0 --- firmware/source/sci.c (.../sci.c) (revision abb9687e52d9db5df1abe7626ba04a6d431ba823) +++ firmware/source/sci.c (.../sci.c) (revision f100557efc2f7916054a63bbafb187d8017914d0) @@ -217,8 +217,8 @@ | (uint32)((uint32)0U); /* Break detect */ /** - set interrupt enable */ - scilinREG->SETINT = (uint32)((uint32)0U << 26U) /* Framing error */ - | (uint32)((uint32)0U << 25U) /* Overrun error */ + scilinREG->SETINT = (uint32)((uint32)1U << 26U) /* Framing error */ + | (uint32)((uint32)1U << 25U) /* Overrun error */ | (uint32)((uint32)0U << 24U) /* Parity error */ | (uint32)((uint32)0U << 9U) /* Receive */ | (uint32)((uint32)0U << 1U) /* Wakeup */ Index: firmware/source/sys_link.cmd =================================================================== diff -u -rda12d1065b9bc93d30500255d8b986f00d1bdd69 -rf100557efc2f7916054a63bbafb187d8017914d0 --- firmware/source/sys_link.cmd (.../sys_link.cmd) (revision da12d1065b9bc93d30500255d8b986f00d1bdd69) +++ firmware/source/sys_link.cmd (.../sys_link.cmd) (revision f100557efc2f7916054a63bbafb187d8017914d0) @@ -60,8 +60,6 @@ RAM (RW) : origin=0x08005800 length=0x0002a800 /* USER CODE BEGIN (2) */ - - /* USER CODE END */ } Index: firmware/source/sys_main.c =================================================================== diff -u -r9af6fc3e5afc442a877bd5e23ecfa6872a3ad5a4 -rf100557efc2f7916054a63bbafb187d8017914d0 --- firmware/source/sys_main.c (.../sys_main.c) (revision 9af6fc3e5afc442a877bd5e23ecfa6872a3ad5a4) +++ firmware/source/sys_main.c (.../sys_main.c) (revision f100557efc2f7916054a63bbafb187d8017914d0) @@ -43,7 +43,6 @@ /* USER CODE BEGIN (0) */ - static void initProcessor( void ); static void initSoftware( void ); static void initTasks( void ); @@ -62,6 +61,7 @@ #include "BLCommon.h" #include "CommBuffers.h" +#include "FPGA.h" #include "Interrupts.h" #include "NVDataMgmt.h" #include "OperationModes.h" @@ -105,6 +105,7 @@ static void initSoftware( void ) { initCommBuffers(); + initFPGA(); initInterrupts(); initNVDataMgmt(); initOperationModes();