Index: App/Services/CommInterrupts.c =================================================================== diff -u -r40a959e1341c8964f872df462ac3a2d874e3b0b3 -r81ca79980a75ab71985d3d610bcef45fd6730458 --- App/Services/CommInterrupts.c (.../CommInterrupts.c) (revision 40a959e1341c8964f872df462ac3a2d874e3b0b3) +++ App/Services/CommInterrupts.c (.../CommInterrupts.c) (revision 81ca79980a75ab71985d3d610bcef45fd6730458) @@ -90,27 +90,23 @@ switch ( channel ) { case DMA_CH0: // FPGA receive channel - // clear DMA receipt - scilinREG->CLEARINT = SCI_DMA_RECEIVE_INT; + clearSCI2DMAReceiveInterrupt(); signalFPGAReceiptCompleted(); break; case DMA_CH1: // PC receive channel - // clear DMA receipt - sciREG->CLEARINT = SCI_DMA_RECEIVE_INT; + clearSCI1DMAReceiveInterrupt(); // handle received packet from PC handleUARTMsgRecvPacketInterrupt(); break; case DMA_CH2: // FPGA transmit channel - // clear DMA xmit - scilinREG->CLEARINT = SCI_DMA_TRANSMIT_INT; + clearSCI2DMATransmitInterrupt(); signalFPGATransmitCompleted(); break; case DMA_CH3: // PC transmit channel - // clear DMA xmit - sciREG->CLEARINT = SCI_DMA_TRANSMIT_INT; + clearSCI1DMATransmitInterrupt(); // send next pending packet to PC (if any) handleUARTMsgXmitPacketInterrupt(); break; @@ -122,3 +118,60 @@ } } +void setSCI1DMAReceiveInterrupt( void ) +{ + sciREG->SETINT = SCI_DMA_RECEIVE_INT; +} + +void setSCI1DMATransmitInterrupt( void ) +{ + sciREG->SETINT = SCI_DMA_TRANSMIT_INT; +} + +void clearSCI1DMAReceiveInterrupt( void ) +{ + sciREG->CLEARINT = SCI_DMA_RECEIVE_INT; +} + +void clearSCI1DMATransmitInterrupt( void ) +{ + sciREG->CLEARINT = SCI_DMA_TRANSMIT_INT; +} + +void setSCI2DMAReceiveInterrupt( void ) +{ + scilinREG->SETINT = SCI_DMA_RECEIVE_INT; +} + +void setSCI2DMATransmitInterrupt( void ) +{ + scilinREG->SETINT = SCI_DMA_TRANSMIT_INT; +} + +void clearSCI2DMAReceiveInterrupt( void ) +{ + scilinREG->CLEARINT = SCI_DMA_RECEIVE_INT; +} + +void clearSCI2DMATransmitInterrupt( void ) +{ + scilinREG->CLEARINT = SCI_DMA_TRANSMIT_INT; +} + +BOOL isSCI1DMATransmitInProgress( void ) +{ + BOOL transmitterBusy = ( ( sciREG->FLR & (uint32)SCI_TX_INT ) == 0U ? TRUE : FALSE ); + BOOL dmaTransmitterBusy = ( ( sciREG->CLEARINT & SCI_DMA_RECEIVE_INT ) != 0 ? TRUE : FALSE ); + + return ( ( transmitterBusy == TRUE ) || ( dmaTransmitterBusy == TRUE ) ? TRUE : FALSE ); +} + +BOOL isSCI2DMATransmitInProgress( void ) +{ + BOOL transmitterBusy = ( ( scilinREG->FLR & (uint32)SCI_TX_INT ) == 0U ? TRUE : FALSE ); + BOOL dmaTransmitterBusy = ( ( scilinREG->CLEARINT & SCI_DMA_RECEIVE_INT ) != 0 ? TRUE : FALSE ); + + return ( ( transmitterBusy == TRUE ) || ( dmaTransmitterBusy == TRUE ) ? TRUE : FALSE ); +} + + Index: App/Services/CommInterrupts.h =================================================================== diff -u -r38ff7a6fbf82b86ab1bac3b7b24c4ea33d5419f9 -r81ca79980a75ab71985d3d610bcef45fd6730458 --- App/Services/CommInterrupts.h (.../CommInterrupts.h) (revision 38ff7a6fbf82b86ab1bac3b7b24c4ea33d5419f9) +++ App/Services/CommInterrupts.h (.../CommInterrupts.h) (revision 81ca79980a75ab71985d3d610bcef45fd6730458) @@ -24,14 +24,18 @@ #define SCI_DMA_TRANSMIT_INT 0x00010000 #define SCI_DMA_RECEIVE_INT 0x00060000 -#define SCI1_TX_BUSY() ( ( sciREG->FLR & (uint32)SCI_TX_INT ) == 0U ? TRUE : FALSE ) -#define SCI1_TX_DMA_BUSY() ( ( sciREG->CLEARINT & SCI_DMA_RECEIVE_INT ) != 0 ? TRUE : FALSE ) -#define SCI1_TX_IN_PROGRESS() ( ( SCI1_TX_BUSY() == TRUE ) || ( SCI1_TX_DMA_BUSY() == TRUE ) ? TRUE : FALSE ) +// ********** public function prototypes ********** -#define SCI2_TX_BUSY() ( ( scilinREG->FLR & (uint32)SCI_TX_INT ) == 0U ? TRUE : FALSE ) -#define SCI2_TX_DMA_BUSY() ( ( scilinREG->CLEARINT & SCI_DMA_RECEIVE_INT ) != 0 ? TRUE : FALSE ) -#define SCI2_TX_IN_PROGRESS() ( ( SCI2_TX_BUSY() == TRUE ) || ( SCI2_TX_DMA_BUSY() == TRUE ) ? TRUE : FALSE ) +void setSCI1DMAReceiveInterrupt( void ); +void setSCI1DMATransmitInterrupt( void ); +void clearSCI1DMAReceiveInterrupt( void ); +void clearSCI1DMATransmitInterrupt( void ); +void setSCI2DMAReceiveInterrupt( void ); +void setSCI2DMATransmitInterrupt( void ); +void clearSCI2DMAReceiveInterrupt( void ); +void clearSCI2DMATransmitInterrupt( void ); -// ********** public function prototypes ********** +BOOL isSCI1DMATransmitInProgress( void ); +BOOL isSCI2DMATransmitInProgress( void ); #endif Index: App/Services/FPGA.c =================================================================== diff -u -r40a959e1341c8964f872df462ac3a2d874e3b0b3 -r81ca79980a75ab71985d3d610bcef45fd6730458 --- App/Services/FPGA.c (.../FPGA.c) (revision 40a959e1341c8964f872df462ac3a2d874e3b0b3) +++ App/Services/FPGA.c (.../FPGA.c) (revision 81ca79980a75ab71985d3d610bcef45fd6730458) @@ -54,7 +54,7 @@ #define FPGA_READ_CMD_NAK 0xAF #define FPGA_CRC_LEN 2 -#define FPGA_WRITE_CMD_HDR_LEN 5 +#define FPGA_WRITE_CMD_HDR_LEN 4 #define FPGA_READ_CMD_HDR_LEN 4 #define FPGA_WRITE_RSP_HDR_LEN 1 #define FPGA_READ_RSP_HDR_LEN 1 @@ -480,7 +480,7 @@ FPGA_STATE_T result = FPGA_STATE_READ_HEADER; // did we get an FPGA response? - if ( fpgaReceiptCounter > 0 ) + if ( ( TRUE == fpgaWriteCommandACKed ) && ( TRUE == fpgaReadCommandACKed ) ) { // did FPGA Ack the read command? if ( fpgaReadResponseBuffer[0] == FPGA_READ_CMD_ACK ) @@ -510,11 +510,38 @@ static FPGA_STATE_T handleFPGAWriteAllActuatorsState( void ) { FPGA_STATE_T result = FPGA_STATE_RCV_ALL_SENSORS; + U16 crc; + // construct bulk write command to write actuator data registers starting at address 3 (TODO - change address later) + fpgaWriteCmdBuffer[0] = FPGA_WRITE_CMD_CODE; + fpgaWriteCmdBuffer[1] = 0x02; // start at FPGA address 8 + fpgaWriteCmdBuffer[2] = 0x00; + fpgaWriteCmdBuffer[3] = 1; // TODO - replace 1 with sizeof(FPGA_ACTUATORS_T) +// memcpy( &(fpgaWriteCmdBuffer[FPGA_WRITE_CMD_HDR_LEN]), &fpgaActuatorSetPoints, sizeof(FPGA_ACTUATORS_T) ); + fpgaWriteCmdBuffer[FPGA_WRITE_CMD_HDR_LEN] = 99; // TODO - remove and replace with memcpy above + crc = crc16( fpgaWriteCmdBuffer, FPGA_WRITE_CMD_HDR_LEN+1 ); // TODO - replace +1 with +sizeof(FPGA_ACTUATORS_T) + fpgaWriteCmdBuffer[FPGA_WRITE_CMD_HDR_LEN+1] = GET_LSB_OF_WORD( crc ); // TODO - replace +1 with +sizeof(FPGA_ACTUATORS_T) + fpgaWriteCmdBuffer[FPGA_WRITE_CMD_HDR_LEN+1+1] = GET_MSB_OF_WORD( crc ); // TODO - replace +1 with +sizeof(FPGA_ACTUATORS_T) + // construct bulk read command to read sensor data registers starting at address 8 + fpgaReadCmdBuffer[0] = FPGA_READ_CMD_CODE; + fpgaReadCmdBuffer[1] = 0x08; // start at FPGA address 8 + fpgaReadCmdBuffer[2] = 0x00; + fpgaReadCmdBuffer[3] = sizeof(FPGA_SENSORS_T); + crc = crc16( fpgaReadCmdBuffer, FPGA_READ_CMD_HDR_LEN ); + fpgaReadCmdBuffer[4] = GET_LSB_OF_WORD( crc ); + fpgaReadCmdBuffer[5] = GET_MSB_OF_WORD( crc ); + // prep DMA for sending the bulk write cmd and receiving its response + setupDMAForWriteCmd( FPGA_WRITE_CMD_HDR_LEN + 1 + FPGA_CRC_LEN ); // TODO s/b sizeof(FPGA_ACTUATORS_T) instead of 1 + setupDMAForWriteResp( FPGA_WRITE_RSP_HDR_LEN ); + // prep DMA for sending the bulk read cmd and receiving its response + setupDMAForReadCmd( FPGA_READ_CMD_HDR_LEN + FPGA_CRC_LEN ); + setupDMAForReadResp( FPGA_READ_RSP_HDR_LEN + sizeof(FPGA_SENSORS_T) + FPGA_CRC_LEN ); + // set fpga comm flags for bulk write cmd and follow-up bulk read command fpgaWriteCommandInProgress = TRUE; fpgaBulkWriteAndReadInProgress = TRUE; - // TODO - setup for bulk write and follow-up bulk read commands - // TODO - initiate bulk write command + // initiate bulk write command and it's receipt - read will follow + startDMAReceiptOfWriteResp(); + startDMAWriteCmd(); return result; } @@ -533,17 +560,35 @@ { FPGA_STATE_T result = FPGA_STATE_WRITE_ALL_ACTUATORS; - // check commands success + // check bulk write command success if ( FALSE == fpgaWriteCommandACKed ) { // TODO - ??? } - if ( FALSE == fpgaReadCommandACKed ) + + // if bulk read command is ACK'd, collect the readings + if ( TRUE == fpgaReadCommandACKed ) { + // did we get an FPGA response? + if ( ( TRUE == fpgaWriteCommandACKed ) && ( TRUE == fpgaReadCommandACKed ) ) + { + // did FPGA Ack the read command? + if ( fpgaReadResponseBuffer[0] == FPGA_READ_CMD_ACK ) + { + // does the FPGA response CRC check out? + if ( 1 ) // TODO - check response CRC + { // capture the read values + memcpy( &fpgaSensorReadings, fpgaReadResponseBuffer, sizeof(FPGA_SENSORS_T) ); + result = FPGA_STATE_WRITE_ALL_ACTUATORS; + } + } + } + } + else + { // TODO - ??? } - // TODO - collect sensor readings return result; } @@ -577,7 +622,7 @@ { dmaSetCtrlPacket( DMA_CH2, fpgaDMAWriteControlRecord ); dmaSetChEnable( DMA_CH2, DMA_HW ); - scilinREG->SETINT = SCI_DMA_TRANSMIT_INT; + setSCI2DMATransmitInterrupt(); } /************************************************************************* @@ -609,7 +654,7 @@ { dmaSetCtrlPacket( DMA_CH0, fpgaDMAWriteRespControlRecord ); dmaSetChEnable( DMA_CH0, DMA_HW ); - scilinREG->SETINT = SCI_DMA_RECEIVE_INT; + setSCI2DMAReceiveInterrupt(); } /************************************************************************* @@ -641,7 +686,7 @@ { dmaSetCtrlPacket( DMA_CH2, fpgaDMAReadControlRecord ); dmaSetChEnable( DMA_CH2, DMA_HW ); - scilinREG->SETINT = SCI_DMA_TRANSMIT_INT; + setSCI2DMATransmitInterrupt(); } /************************************************************************* @@ -673,7 +718,7 @@ { dmaSetCtrlPacket( DMA_CH0, fpgaDMAReadRespControlRecord ); dmaSetChEnable( DMA_CH0, DMA_HW ); - scilinREG->SETINT = SCI_DMA_RECEIVE_INT; + setSCI2DMAReceiveInterrupt(); } /************************************************************************* Index: App/Services/SystemComm.c =================================================================== diff -u -r40a959e1341c8964f872df462ac3a2d874e3b0b3 -r81ca79980a75ab71985d3d610bcef45fd6730458 --- App/Services/SystemComm.c (.../SystemComm.c) (revision 40a959e1341c8964f872df462ac3a2d874e3b0b3) +++ App/Services/SystemComm.c (.../SystemComm.c) (revision 81ca79980a75ab71985d3d610bcef45fd6730458) @@ -103,7 +103,7 @@ // TODO - remove this test code that sends a packet // dmaSetCtrlPacket( DMA_CH3, pcDMAXmitControlRecord ); // dmaSetChEnable( DMA_CH3, DMA_HW ); -// sciREG->SETINT = SCI_DMA_TRANSMIT_INT; +// setSCI1DMATransmitInterrupt(); } /************************************************************************* @@ -143,7 +143,7 @@ } // if UART transmitter is idle, start transmitting any pending packets - if ( FALSE == SCI1_TX_IN_PROGRESS() ) + if ( FALSE == isSCI1DMATransmitInProgress() ) { transmitNextUARTPacket(); } @@ -204,8 +204,7 @@ // prepare to receive next packet dmaSetCtrlPacket( DMA_CH1, pcDMARecvControlRecord ); dmaSetChEnable( DMA_CH1, DMA_HW ); - sciREG->SETINT = (uint32)((uint32)1U << 18U); /* Rx DMA All */ - sciREG->SETINT = (uint32)((uint32)1U << 17U); /* Rx DMA */ + setSCI1DMAReceiveInterrupt(); } /************************************************************************* @@ -284,7 +283,7 @@ // initiate UART packet receiving readiness via DMA dmaSetCtrlPacket( DMA_CH1, pcDMARecvControlRecord ); dmaSetChEnable( DMA_CH1, DMA_HW ); - sciREG->SETINT = SCI_DMA_RECEIVE_INT; + setSCI1DMAReceiveInterrupt(); } /************************************************************************* @@ -424,7 +423,7 @@ { dmaSetCtrlPacket( DMA_CH3, pcDMAXmitControlRecord ); dmaSetChEnable( DMA_CH3, DMA_HW ); - sciREG->SETINT = (uint32)((uint32)1U << 16U); /* Tx DMA */ + setSCI1DMATransmitInterrupt(); } } Index: App/Services/Utilities.c =================================================================== diff -u --- App/Services/Utilities.c (revision 0) +++ App/Services/Utilities.c (revision 81ca79980a75ab71985d3d610bcef45fd6730458) @@ -0,0 +1,88 @@ +/************************************************************************** + * + * Copyright (c) 2019-2019 Diality Inc. - All Rights Reserved. + * + * THIS CODE MAY NOT BE COPIED OR REPRODUCED IN ANY FORM, IN PART OR IN + * WHOLE, WITHOUT THE EXPLICIT PERMISSION OF THE COPYRIGHT OWNER. + * + * @file Utilities.c + * + * @date 23-Oct-2019 + * @author S. Nash + * + * @brief Utilities service module. Provides miscellaneous utility \n + * functions. + * + **************************************************************************/ + +#include "Common.h" +#include "Utilities.h" + +// ********** private definitions ********** + +#define INITIAL_CRC16_VAL 0xFFFF + +// ********** private data ********** + +const U16 crc16_table[] = +{ 0x00000,0x1189,0x2312,0x329b,0x4624,0x57ad,0x6536,0x74bf, + 0x08c48,0x9dc1,0xaf5a,0xbed3,0xca6c,0xdbe5,0xe97e,0xf8f7, + 0x01081,0x0108,0x3393,0x221a,0x56a5,0x472c,0x75b7,0x643e, + 0x09cc9,0x8d40,0xbfdb,0xae52,0xdaed,0xcb64,0xf9ff,0xe876, + 0x02102,0x308b,0x0210,0x1399,0x6726,0x76af,0x4434,0x55bd, + 0x0ad4a,0xbcc3,0x8e58,0x9fd1,0xeb6e,0xfae7,0xc87c,0xd9f5, + 0x03183,0x200a,0x1291,0x0318,0x77a7,0x662e,0x54b5,0x453c, + 0x0bdcb,0xac42,0x9ed9,0x8f50,0xfbef,0xea66,0xd8fd,0xc974, + 0x04204,0x538d,0x6116,0x709f,0x0420,0x15a9,0x2732,0x36bb, + 0x0ce4c,0xdfc5,0xed5e,0xfcd7,0x8868,0x99e1,0xab7a,0xbaf3, + 0x05285,0x430c,0x7197,0x601e,0x14a1,0x0528,0x37b3,0x263a, + 0x0decd,0xcf44,0xfddf,0xec56,0x98e9,0x8960,0xbbfb,0xaa72, + 0x06306,0x728f,0x4014,0x519d,0x2522,0x34ab,0x0630,0x17b9, + 0x0ef4e,0xfec7,0xcc5c,0xddd5,0xa96a,0xb8e3,0x8a78,0x9bf1, + 0x07387,0x620e,0x5095,0x411c,0x35a3,0x242a,0x16b1,0x0738, + 0x0ffcf,0xee46,0xdcdd,0xcd54,0xb9eb,0xa862,0x9af9,0x8b70, + 0x08408,0x9581,0xa71a,0xb693,0xc22c,0xd3a5,0xe13e,0xf0b7, + 0x00840,0x19c9,0x2b52,0x3adb,0x4e64,0x5fed,0x6d76,0x7cff, + 0x09489,0x8500,0xb79b,0xa612,0xd2ad,0xc324,0xf1bf,0xe036, + 0x018c1,0x0948,0x3bd3,0x2a5a,0x5ee5,0x4f6c,0x7df7,0x6c7e, + 0x0a50a,0xb483,0x8618,0x9791,0xe32e,0xf2a7,0xc03c,0xd1b5, + 0x02942,0x38cb,0x0a50,0x1bd9,0x6f66,0x7eef,0x4c74,0x5dfd, + 0x0b58b,0xa402,0x9699,0x8710,0xf3af,0xe226,0xd0bd,0xc134, + 0x039c3,0x284a,0x1ad1,0x0b58,0x7fe7,0x6e6e,0x5cf5,0x4d7c, + 0x0c60c,0xd785,0xe51e,0xf497,0x8028,0x91a1,0xa33a,0xb2b3, + 0x04a44,0x5bcd,0x6956,0x78df,0x0c60,0x1de9,0x2f72,0x3efb, + 0x0d68d,0xc704,0xf59f,0xe416,0x90a9,0x8120,0xb3bb,0xa232, + 0x05ac5,0x4b4c,0x79d7,0x685e,0x1ce1,0x0d68,0x3ff3,0x2e7a, + 0x0e70e,0xf687,0xc41c,0xd595,0xa12a,0xb0a3,0x8238,0x93b1, + 0x06b46,0x7acf,0x4854,0x59dd,0x2d62,0x3ceb,0x0e70,0x1ff9, + 0x0f78f,0xe606,0xd49d,0xc514,0xb1ab,0xa022,0x92b9,0x8330, + 0x07bc7,0x6a4e,0x58d5,0x495c,0x3de3,0x2c6a,0x1ef1,0x0f78 +}; + +// ********** private function prototypes ********** + + +/************************************************************************* + * @brief crc16 + * The crc16 function calculates a 16-bit CRC for a given range of bytes \n + * in memory. + * @details + * Inputs : none + * Outputs : none + * @param address : pointer to start address of memory range to calculate CRC for + * @param len : # of bytes in the memory range to calculate CRC for + * @return CRC + *************************************************************************/ +U16 crc16( U08 *address, U32 len ) +{ + U16 crc = INITIAL_CRC16_VAL; + + while ( len-- > 0 ) + { + crc = (crc >> SHIFT_BITS_IN_BYTE) ^ crc16_table[*address++ ^ (crc & MASK_OFF_MSB)]; + } + + return crc; +} + + Index: App/Services/Utilities.h =================================================================== diff -u --- App/Services/Utilities.h (revision 0) +++ App/Services/Utilities.h (revision 81ca79980a75ab71985d3d610bcef45fd6730458) @@ -0,0 +1,27 @@ +/************************************************************************** + * + * Copyright (c) 2019-2019 Diality Inc. - All Rights Reserved. + * + * THIS CODE MAY NOT BE COPIED OR REPRODUCED IN ANY FORM, IN PART OR IN + * WHOLE, WITHOUT THE EXPLICIT PERMISSION OF THE COPYRIGHT OWNER. + * + * @file Utilities.h + * + * @date 23-Oct-2019 + * @author S. Nash + * + * @brief header file for utilities service module. + * + **************************************************************************/ + +#ifndef __UTILITIES_H__ +#define __UTILITIES_H__ + +// ********** public definitions ********** + + +// ********** public function prototypes ********** + +U16 crc16( U08 *address, U32 len ); + +#endif