* for more details.\r
* -------------------------------- Arctic Core ------------------------------*/\r
\r
-/* IMPLEMENTATION NOTES\r
- * -----------------------------------------------\r
+/** @reqSettings DEFAULT_SPECIFICATION_REVISION=3.1.5 */\r
+\r
+/* ----------------------------[information]----------------------------------*/\r
+/*\r
+ * Author: mahi\r
+ *\r
+ * Part of Release:\r
+ * 3.1.5\r
+ *\r
+ * Description:\r
+ * Implements the SPI driver module\r
+ *\r
+ * Support:\r
+ * General Have Support\r
+ * -------------------------------------------\r
+ * SPI_CANCEL_API N\r
+ * SPI_CHANNEL_BUFFERS_ALLOWED Y/N, Supports only level 1 (0:IB,1:EB,2:IB+EB)\r
+ * SPI_DEV_ERROR_DETECT Y\r
+ * SPI_HW_STATUS_API N\r
+ * SPI_INTERRUPTIBLE_SEQ_ALLOWED N\r
+ * SPI_LEVEL_DELIVERED Y/N, supports only level 2 (0:sync,1:sync,2:both)\r
+ * SPI_VERSION_INFO_API Y\r
+ *\r
+ * Extra:\r
+ * - DMA and FIFO is implementations\r
+ * - Soft CS by callback\r
+ *\r
+ *\r
+ * Device\r
+ * - MPC5606S\r
+ *\r
+ * Implementation Notes:\r
* - This driver implements SPI_LEVEL_DELIVERED = 2 but with a number\r
* of restrictions. See REQ. below for more information.\r
*\r
* - It's not obvious how to use different modes. My interpretation:\r
*\r
* Sync\r
- * Always blocking in Spi_SyncTranmit()\r
+ * Always blocking in Spi_SyncTransmit()\r
+ *\r
+ *\r
+ * Info:\r
+ * - The AsyncModeType (SPI_POLLING_MODE,SPI_INTERRUPT_MODE) is used to handle only the\r
+ * async API, ie Spi_AsyncTransmit(). The synchrone API just calls Spi_SyncTransmit()->Spi_Isr()....\r
+ *\r
*\r
* Async and INTERRUPT\r
*\r
\r
#define SPIE_BAD (-1)\r
#define SPIE_OK 0\r
-#define SPIE_MORE_TO_SEND 1\r
-\r
-#define IMPL_SIMPLE 0 /* Not implemented, NOT TESTED */\r
-#define IMPL_FIFO 1 /* Partly implemented, NOT TESTED */\r
-#define IMPL_DMA 2\r
+#define SPIE_JOB_NOT_DONE 1\r
\r
-#define SPI_IMPLEMENTATION IMPL_DMA\r
+//#define SPI_IMPLEMENTATION SPI_FIFO\r
+#define USE_DIO_CS STD_ON\r
\r
// E2 read = cmd + addr + data = 1 + 2 + 64 ) = 67 ~ 72\r
#define SPI_INTERNAL_MTU 72\r
#include "debug.h"\r
\r
//#define USE_LOCAL_RAMLOG\r
-\r
#if defined(USE_LOCAL_RAMLOG)\r
#define RAMLOG_STR(_x) ramlog_str(_x)\r
#define RAMLOG_DEC(_x) ramlog_dec(_x)\r
\r
/* ----------------------------[private typedef]-----------------------------*/\r
\r
-#if (SPI_IMPLEMENTATION == IMPL_DMA )\r
+#if (SPI_IMPLEMENTATION == SPI_DMA )\r
typedef struct Spi_DmaConfig {\r
Dma_ChannelType RxDmaChannel;\r
Dma_ChannelType TxDmaChannel;\r
\r
typedef SPICommandType Spi_CommandType;\r
typedef struct {\r
- // Pointer to source buffer\r
- const Spi_DataType *src;\r
- // Pointer to destination buffer\r
- Spi_DataType *dest;\r
- // Number of elements of Spi_DataType in destination buffer\r
- Spi_NumberOfDataType length;\r
- // Set if the buffer is configured.\r
- // Used for sanity check\r
- _Bool active;\r
+ const Spi_DataType * src; /* Pointer to source buffer */\r
+ Spi_DataType * dest; /* Pointer to destination buffer */\r
+ Spi_NumberOfDataType length; // Number of elements of Spi_DataType in destination buffer\r
+ _Bool active; // Set if the buffer is configured.\r
} Spi_EbType;\r
\r
typedef enum {\r
- SPI_ASYNC, SPI_SYNC,\r
+ SPI_ASYNC_CALL,\r
+ SPI_SYNC_CALL,\r
} Spi_CallTypeType;\r
\r
typedef struct {\r
- // this channel is assigned to this CTAR\r
- uint8 ctarId;\r
+ uint8 ctarId; // this channel is assigned to this CTAR\r
} Spi_ChannelInfoType;\r
\r
/**\r
*/\r
typedef struct {\r
\r
-#if (SPI_IMPLEMENTATION==IMPL_DMA)\r
- // Tx DMA channel information\r
- Dma_ChannelType dmaTxChannel;\r
- Dma_TcdType dmaTxTCD;\r
-\r
- // Rx DMA channel information\r
- Dma_ChannelType dmaRxChannel;\r
- Dma_TcdType dmaRxTCD;\r
+#if (SPI_IMPLEMENTATION==SPI_DMA)\r
+ Dma_ChannelType dmaTxChannel; // Tx DMA channel information\r
+ Dma_TcdType dmaTxTCD;\r
+ Dma_ChannelType dmaRxChannel; // Rx DMA channel information\r
+ Dma_TcdType dmaRxTCD;\r
+ Spi_CommandType txQueue[SPI_INTERNAL_MTU]; // Pointed to by SADDR of DMA\r
+ uint32 rxQueue[SPI_INTERNAL_MTU]; // Pointed to by DADDR of DMA\r
#endif\r
-\r
- // Pointed to by SADDR of DMA\r
- Spi_CommandType txQueue[SPI_INTERNAL_MTU];\r
- // Pointed to by DADDR of DMA\r
- uint32 rxQueue[SPI_INTERNAL_MTU];\r
-\r
- // current index for data when sending\r
- // mostly here for debug purposes( since it could be local )\r
- uint32 txCurrIndex;\r
-\r
- // Helper array to assign CTAR's\r
- uint32 channelCodes[7];\r
-\r
- // Status for this unit\r
- Spi_StatusType status;\r
-\r
-\r
-\r
- // The current job\r
- const Spi_JobConfigType *currJob;\r
- Spi_JobType currJobIndex;\r
-\r
- // Points array of jobs current\r
- const Spi_JobType *currJobIndexPtr;\r
- // The Sequence\r
- const Spi_SequenceConfigType *currSeqPtr;\r
-\r
- // Used by sync call to check when a job is done\r
- // volatile _Bool done;\r
-\r
- // 1 - if the current job is sync. 0 - if not\r
- Spi_CallTypeType callType;\r
+ uint32 txCurrIndex; // current index for data when sending\r
+ uint32 channelCodes[7]; // Helper array to assign CTAR's\r
+ Spi_StatusType status; // Status for this unit\r
+ const Spi_JobConfigType * currJob; // The current job\r
+ const Spi_JobType * currJobIndexPtr; // Points array of jobs current\r
+ Spi_JobType currJobIndex;\r
+ const Spi_SequenceConfigType * currSeqPtr; // The Sequence\r
+ Spi_CallTypeType callType; // 1 - if the current job is sync. 0 - if not\r
} Spi_UnitType;\r
\r
typedef struct {\r
} Spi_SeqUnitType;\r
\r
typedef struct {\r
- /* The HW device used by this Job */\r
- volatile struct DSPI_tag *hwPtr;\r
-\r
- /* The external device used by this job */\r
- const Spi_ExternalDeviceType *extDeviceCfgPtr;\r
-\r
- const Spi_JobConfigType *jobCfgPtr;\r
-\r
- Spi_UnitType *unitPtr;\r
-\r
- const Spi_ChannelType *channelsPtr;\r
-\r
+ volatile struct DSPI_tag * hwPtr; /* The HW device used by this Job */\r
+ const Spi_ExternalDeviceType * extDeviceCfgPtr; /* The external device used by this job */\r
+ const Spi_JobConfigType * jobCfgPtr;\r
+ Spi_UnitType * unitPtr;\r
+ const Spi_ChannelType * channelsPtr;\r
#if (SPI_IMPLEMENTATION == SPI_FIFO )\r
- /* Number of bytes in FIFO (before EOQ is set) */\r
- uint32_t fifoSent;\r
-\r
- /* the currently transmitting channel index for FIFO */\r
- uint8_t currTxChIndex;\r
-\r
- /* The FIFO is filled for the last time for this job */\r
- _Bool jobComplete;\r
-\r
- /* number of Spi_DataType sent for the current channel */\r
- uint32_t txChCnt;\r
-\r
- /* number of Spi_DataType received for the current channel */\r
- uint32_t rxChCnt;\r
-\r
- /* the currently receiving channel index for FIFO */\r
- uint32_t currRxChIndex;\r
+ uint32_t fifoSent; /* Number of bytes in FIFO (before EOQ is set) */\r
+ uint8_t currTxChIndex; /* the currently transmitting channel index for FIFO */\r
+ uint32_t txChCnt; /* number of Spi_DataType sent for the current channel */\r
+ uint32_t rxChCnt; /* number of Spi_DataType received for the current channel */\r
+ uint32_t currRxChIndex; /* the currently receiving channel index for FIFO */\r
#endif\r
-\r
Spi_JobResultType jobResult;\r
} Spi_JobUnitType;\r
\r
typedef struct {\r
- // Initially FALSE set to TRUE if Spi_Init() have been called\r
- boolean initRun;\r
-\r
- // Pointer to the configuration\r
- const Spi_ConfigType *configPtr;\r
-\r
- // Pointer to the external buffers\r
- Spi_EbType *extBufPtr;\r
-\r
- Spi_ChannelInfoType *channelInfo;\r
-\r
- // Mask if the HW unit is configured or not\r
- uint32 spiHwConfigured;\r
-\r
- Spi_AsyncModeType asyncMode;\r
+ boolean initRun; // Initially FALSE set to TRUE if Spi_Init() have been called\r
+ const Spi_ConfigType * configPtr; // Pointer to the configuration\r
+ Spi_EbType * extBufPtr; // Pointer to the external buffers\r
+ Spi_ChannelInfoType * channelInfo;\r
+ uint32 spiHwConfigured; // Mask if the HW unit is configured or not\r
+ Spi_AsyncModeType asyncMode;\r
\r
/* This is a bunch of debug counters. */\r
uint32 totalNbrOfTranfers;\r
/* Counters for busy waiting for DSPI and DMA. */\r
uint32 totalNbrOfWaitTXRXS;\r
uint32 totalNbrOfWaitRxDMA;\r
-\r
#if defined(STEP_VALIDATION)\r
int eoqf_cnt;\r
int txrxs_cnt;\r
#endif\r
-\r
} Spi_GlobalType;\r
\r
-\r
/* ----------------------------[private function prototypes]-----------------*/\r
/* ----------------------------[private variables]---------------------------*/\r
\r
-#if (SPI_IMPLEMENTATION==IMPL_DMA)\r
+#if (SPI_IMPLEMENTATION==SPI_DMA)\r
/* Templates for Rx/Tx DMA structures */\r
const Dma_TcdType Spi_DmaTx = {\r
.SADDR = 0, .SMOD = 0, .SSIZE = DMA_TRANSFER_SIZE_32BITS, .DMOD = 0,\r
.START = 0 };\r
#endif\r
\r
-Spi_EbType Spi_Eb[SPI_MAX_CHANNEL];\r
-\r
-Spi_ChannelInfoType Spi_ChannelInfo[SPI_MAX_CHANNEL];\r
-\r
-Spi_GlobalType Spi_Global;\r
-\r
-Spi_UnitType Spi_Unit[4];\r
+Spi_GlobalType Spi_Global;\r
+Spi_EbType Spi_Eb[SPI_MAX_CHANNEL];\r
+Spi_UnitType Spi_Unit[SPI_CONTROLLER_CNT];\r
Spi_SeqUnitType Spi_SeqUnit[SPI_MAX_SEQUENCE];\r
Spi_JobUnitType Spi_JobUnit[SPI_MAX_JOB];\r
+Spi_ChannelInfoType Spi_ChannelInfo[SPI_MAX_CHANNEL];\r
\r
\r
-#if (SPI_IMPLEMENTATION == IMPL_DMA)\r
+#if (SPI_IMPLEMENTATION == SPI_DMA)\r
/* When using DMA it assumes predefined names */\r
Spi_DmaConfigType Spi_DmaConfig[4] = {\r
#if (SPI_USE_HW_UNIT_0 == STD_ON )\r
};\r
#endif\r
\r
-\r
-\r
-\r
-\r
-\r
/* ----------------------------[private functions]---------------------------*/\r
\r
-#if (SPI_IMPLEMENTATION == IMPL_FIFO )\r
+#if (SPI_IMPLEMENTATION == SPI_FIFO )\r
+static void Spi_WriteJob_FIFO( Spi_JobType jobIndex );\r
+\r
/**\r
* Get the buffer for a channel.\r
*
}\r
return buf;\r
}\r
-\r
#endif\r
\r
static void Spi_Isr(uint32);\r
static void Spi_Isr_D(void) {\r
Spi_Isr(DSPI_CTRL_D);\r
}\r
-\r
-\r
/* ----------------------------[public functions]----------------------------*/\r
\r
-\r
uint32 Spi_GetJobCnt(void);\r
uint32 Spi_GetChannelCnt(void);\r
uint32 Spi_GetExternalDeviceCnt(void);\r
\r
-\r
#if 0\r
static void Spi_Isr_DMA( void )\r
{\r
}\r
//-------------------------------------------------------------------\r
\r
-#if 0\r
-/**\r
- * Schedules next job to do( calls Spi_jobWrite() or not )\r
- *\r
- * @param spiUnit The SPI unit\r
- */\r
-static int Spi_WriteNextJob(Spi_UnitType *spiUnit) {\r
- Spi_JobType nextJob;\r
- // Re-cap.\r
- // - Jobs have the controller\r
- // - Sequences can we interruptible between jobs.\r
- // But\r
- // According to SPI086 you can't share a job with a sequence that\r
- // is in SPI_SEQ_PENDING ( that happens first thing at Spi_AsyncTranmit() )\r
- //\r
- // So, I no clue what to use the priority thing for :(\r
\r
- nextJob = Spi_GetNextJob(spiUnit);\r
- if ((int) nextJob == JOB_NOT_VALID) {\r
- return JOB_NOT_VALID;\r
-\r
- } else {\r
- // Schedule next job\r
- Spi_JobWrite(nextJob);\r
- }\r
- return 0;\r
-}\r
-#endif\r
-\r
-//-------------------------------------------------------------------\r
-\r
-#if (SPI_IMPLEMENTATION==IMPL_DMA)\r
+#if (SPI_IMPLEMENTATION==SPI_DMA)\r
\r
/**\r
* Function to handle things after a transmit on the SPI is finished.\r
* @param spiUnit Ptr to a SPI unit\r
*/\r
\r
-static int Spi_PostTransmit_DMA(Spi_UnitType *spiUnit) {\r
+static int Spi_Rx_DMA(Spi_UnitType *spiUnit) {\r
_Bool printedSomeThing = 0;\r
\r
/* Stop the channels */\r
return 0;\r
}\r
\r
-#elif (SPI_IMPLEMENTATION==IMPL_FIFO)\r
+#elif (SPI_IMPLEMENTATION==SPI_FIFO)\r
+\r
+static int Spi_Rx_FIFO(Spi_UnitType *spiUnit) {\r
+ Spi_JobUnitType * jobUnitPtr;\r
+ Spi_DataType * buf;\r
+ uint32_t copyCnt;\r
+ uint32_t popVal;\r
+ Spi_ChannelType currChannel;\r
+ Spi_NumberOfDataType bufLen;\r
+ int i = 0;\r
+ int rv = SPIE_JOB_NOT_DONE;\r
+ const Spi_ChannelConfigType * chConfig;\r
+ uint32_t bInChar;\r
\r
-static int Spi_PostTransmit_FIFO(Spi_UnitType *spiUnit) {\r
- Spi_JobType jobIndex;\r
- volatile struct DSPI_tag *spiHw;\r
- Spi_JobUnitType *jobUnitPtr;\r
- Spi_DataType *buf;\r
- uint32_t length;\r
- int i = 0;\r
- uint32_t popVal;\r
\r
// RAMLOG_STR("PostTransmit Job: "); RAMLOG_DEC(spiUnit->currJob->SpiJobId); RAMLOG_STR("\n");\r
+ RAMLOG_STR("Spi_Rx_FIFO\n");\r
\r
- jobIndex = spiUnit->currJobIndex;\r
- spiHw = Spi_JobUnit[jobIndex].hwPtr;\r
+ jobUnitPtr = &Spi_JobUnit[spiUnit->currJobIndex];\r
\r
- if( spiHw->TCR.B.SPI_TCNT != jobUnitPtr->fifoSent ) {\r
+ if( jobUnitPtr->hwPtr->TCR.B.SPI_TCNT != jobUnitPtr->fifoSent ) {\r
+#if defined(STEP_VALIDATION)\r
+ while(1) {};\r
+#endif\r
return SPIE_BAD;\r
}\r
\r
/*\r
- * Fill receive buffers, either EB or IB
+ * Fill receive buffers, either EB or IB\r
+ * Example with 8-bit CMD, 16-bit ADDR and some data.\r
+ * CMD | ADDR | DATA\r
+ * | 12 | 23 | 34 | 00 | 01 | 02 | 03\r
+ * 1 2 3 4 5 6 BYTE CNT\r
+ * 1 2 3 4 5 6 FIFO\r
+ * With a FIFO of 5 we can see that the CMD, ADDR and almost the whole\r
+ * DATA channel is sent.\r
*/\r
- while ( jobUnitPtr->fifoSent != 0 ) {\r
- currChannel = jobUnitPtr->channelsPtr[jobUnitPtr->currRxChIndex];\r
- assert( currChannel != CH_NOT_VALID );\r
-\r
- buf = spiGetRxBuf(jobUnitPtr->rxChCnt, &bufLen);\r
- copyCnt = MIN( jobUnitPtr->fifoSent, bufLen - jobUnitPtr->rxChCnt );\r
- jobUnitPtr->fifoSent -= copyCnt;\r
-\r
- /* Pop the FIFO */\r
- if( buff != NULL ) {\r
- for(i=0;copyCnt;i++) {\r
- popVal = jobUnitPtr->hwPtr->POPR.B.RXDATA;\r
- buf[jobUnitPtr->rxChCnt++] = (Spi_DataType)popVal;\r
- }\r
- } else {\r
- for(i=0;copyCnt;i++) {\r
- popVal = jobUnitPtr->hwPtr->POPR.B.RXDATA;\r
- }\r
- }\r
+ currChannel = jobUnitPtr->channelsPtr[jobUnitPtr->currRxChIndex];\r
+ assert( currChannel != CH_NOT_VALID );\r
\r
- if( (bufLen - jobUnitPtr->rxChCnt) == 0 ) {\r
- jobUnitPtr->rxChCnt = 0;\r
- jobUnitPtr->currRxChIndex++;\r
- }\r
- }\r
+ if( jobUnitPtr->fifoSent != jobUnitPtr->hwPtr->SR.B.RXCTR ) {\r
+#if defined(STEP_VALIDATION)\r
+ while(1) {};\r
+#endif\r
+ return SPIE_BAD;\r
+ }\r
\r
+ while ( jobUnitPtr->fifoSent != 0 ) {\r
\r
- /* Check if we are done with this job */\r
- if( jobUnitPtr->jobComplete == 0 ) {\r
- return SPIE_MORE_TO_SEND;\r
- }\r
+ chConfig = &Spi_Global.configPtr->SpiChannelConfig[currChannel];\r
\r
- Spi_DoWrite_FIFO( jobIndex );\r
+ RAMLOG_STR("CIR#");RAMLOG_DEC(jobUnitPtr->currRxChIndex);RAMLOG_STR("\n");\r
\r
- return SPIE_OK;\r
+ /* Get this channels destination buffer */\r
+ buf = spiGetRxBuf(currChannel, &bufLen);\r
+ assert(bufLen!=0); /* We should always get a valid bufLen */\r
\r
-#if 0\r
+ copyCnt = MIN( (bufLen - jobUnitPtr->rxChCnt) >> ((chConfig->SpiDataWidth-1)/8), jobUnitPtr->fifoSent );\r
\r
+ if( copyCnt == 0 ) {\r
+#if defined(STEP_VALIDATION)\r
+ while(1) {};\r
+#endif\r
+ return SPIE_BAD;\r
+ }\r
\r
+ jobUnitPtr->fifoSent -= copyCnt;\r
\r
- /* Copy data from RX queue to the external buffer( if any ) */\r
- {\r
- int j = 0;\r
- int currIndex = 0;\r
- int channelIndex;\r
- const Spi_ChannelConfigType *chConfig;\r
- Spi_EbType *extChBuff;\r
- int gotTx;\r
- int sentTx;\r
+ bInChar = (chConfig->SpiDataWidth > 8 ) ? 2 : 1;\r
\r
- // Check that we got the number of bytes we sent\r
- sentTx = spiUnit->txCurrIndex + 1;\r
- gotTx = (Dma_GetTcd(spiUnit->dmaRxChannel)->DADDR\r
- - (uint32) &spiUnit->rxQueue[0]) / sizeof(uint32);\r
+ /* Pop the FIFO */\r
+ if( buf != NULL ) {\r
+ for(i=0;i<copyCnt;i++) {\r
+ popVal = jobUnitPtr->hwPtr->POPR.B.RXDATA;\r
+ buf[jobUnitPtr->rxChCnt] = (Spi_DataType)popVal;\r
+ jobUnitPtr->rxChCnt += bInChar;\r
+ }\r
+ } else {\r
+ for(i=0;i<copyCnt;i++) {\r
+ popVal = jobUnitPtr->hwPtr->POPR.B.RXDATA;\r
+ jobUnitPtr->rxChCnt += bInChar;\r
\r
- if (sentTx != gotTx) {\r
- // Something failed\r
- DEBUG(DEBUG_LOW,"%s: Expected %d bytes. Got %d bytes\n ",MODULE_NAME,sentTx, gotTx );\r
- return SPIE_BAD;\r
- } else {\r
- RAMLOG_STR("Rx "); RAMLOG_DEC(gotTx); RAMLOG_STR(" Bytes\n"); DEBUG(DEBUG_LOW,"%s: Got %d bytes\n",MODULE_NAME,gotTx);\r
- }\r
+ }\r
+ }\r
\r
- // Find the channels for this job\r
- while ((channelIndex = spiUnit->currJob->ChannelAssignment[j++])\r
- != CH_NOT_VALID) {\r
- chConfig = &Spi_Global.configPtr->SpiChannelConfig[channelIndex];\r
+ if( (bufLen - jobUnitPtr->rxChCnt ) == 0 ) {\r
+ /* advance to the next channel */\r
+ jobUnitPtr->rxChCnt = 0;\r
+ jobUnitPtr->currRxChIndex++;\r
+ currChannel = jobUnitPtr->channelsPtr[jobUnitPtr->currRxChIndex];\r
+ if( currChannel == CH_NOT_VALID ) {\r
+ //assert( jobUnitPtr->fifoSent == 0);\r
+ jobUnitPtr->fifoSent = 0;\r
+ jobUnitPtr->currRxChIndex = 0;\r
+ rv = SPIE_OK;\r
+ break;\r
+ }\r
\r
- /* Check configuration error */\r
-#if ( SPI_CHANNEL_BUFFERS_ALLOWED == 1 )\r
- assert( chConfig->SpiChannelType == SPI_EB );\r
-#endif\r
+ }\r
+ }\r
\r
- // Send the channels that are setup with external buffers\r
- // Get the external buffer for this channel\r
- extChBuff = &Spi_Global.extBufPtr[channelIndex];\r
- if (extChBuff->dest != NULL) {\r
- // Note! No support for >8 "data"\r
- for (int k = 0; k < extChBuff->length; k++) {\r
- extChBuff->dest[k] = spiUnit->rxQueue[currIndex++];\r
- DEBUG(DEBUG_LOW," %02x ",extChBuff->dest[k]);\r
- printedSomeThing = 1;\r
- }\r
+ /* Check if we are done with this job */\r
+ if( 0 != jobUnitPtr->hwPtr->SR.B.RXCTR ) {\r
+ while(1) {};\r
+ }\r
\r
- } else {\r
- if (chConfig->SpiDataWidth > 8) {\r
- currIndex += (extChBuff->length / 2);\r
- } else {\r
- currIndex += extChBuff->length;\r
- }\r
- }\r
- }\r
- if (printedSomeThing)\r
- DEBUG(DEBUG_LOW,"\n");\r
- }\r
\r
- return 0;\r
-#endif\r
+\r
+ return rv;\r
}\r
\r
#endif\r
Spi_Global.totalNbrOfWaitTXRXS++;\r
}\r
\r
-#if (SPI_IMPLEMENTATION == IMPL_DMA)\r
- // To be 100% sure also wait for the DMA transfer to complete.\r
-#if 0\r
- while (!Dma_ChannelDone(\r
- Spi_Global.configPtr->SpiHwConfig[unit].RxDmaChannel)) {\r
- Spi_Global.totalNbrOfWaitRxDMA++;\r
- }\r
-#else\r
+#if (SPI_IMPLEMENTATION == SPI_DMA)\r
while (!Dma_ChannelDone(Spi_Unit[unit].dmaRxChannel)) {\r
Spi_Global.totalNbrOfWaitRxDMA++;\r
}\r
-\r
-#endif\r
#endif\r
\r
/* Halt DSPI unit until we are ready for next transfer. */\r
DISABLE_EOQ_INTERRUPT(spiHw);\r
\r
// Update external buffers\r
-#if (SPI_IMPLEMENTATION==IMPL_DMA)\r
- rv = Spi_PostTransmit_DMA(spiUnit);\r
-#elif (SPI_IMPLEMENTATION==IMPL_FIFO)\r
- rv = Spi_PostTransmit_FIFO(spiUnit);\r
+#if (SPI_IMPLEMENTATION==SPI_DMA)\r
+ rv = Spi_Rx_DMA(spiUnit);\r
+\r
+#if (USE_DIO_CS == STD_ON)\r
+ void (*cb)(int) = Spi_JobUnit[spiUnit->currJobIndex].extDeviceCfgPtr->SpiCsCallback;\r
+ if( cb != NULL ) {\r
+ cb(0);\r
+ }\r
+#endif\r
+#elif (SPI_IMPLEMENTATION==SPI_FIFO)\r
+ rv = Spi_Rx_FIFO(spiUnit);\r
\r
- if( rv == SPIE_MORE_TO_SEND ) {\r
+ if( rv == SPIE_JOB_NOT_DONE ) {\r
+ /* RX FIFO now empty, but the job is not done -> send more */\r
+ Spi_WriteJob_FIFO ( spiUnit->currJobIndex );\r
RAMLOG_STR("Spi_Isr END\n");\r
return;\r
}\r
+#if (USE_DIO_CS == STD_ON)\r
+ else {\r
+ void (*cb)(int) = Spi_JobUnit[spiUnit->currJobIndex].extDeviceCfgPtr->SpiCsCallback;\r
+ if( cb != NULL ) {\r
+ cb(0);\r
+ }\r
+ }\r
+#endif\r
#endif\r
\r
// Call notification end\r
Spi_SetJobResult(spiUnit->currJob->SpiJobId, SPI_JOB_FAILED);\r
Spi_SetSequenceResult(spiUnit->currSeqPtr->SpiSequenceId,\r
SPI_SEQ_FAILED);\r
+#if defined(STEP_VALIDATION)\r
+ while(1) {};\r
+#endif\r
} else {\r
Spi_JobType nextJob;\r
\r
nextJob = Spi_GetNextJob(spiUnit);\r
if( nextJob != JOB_NOT_VALID ) {\r
Spi_JobWrite(nextJob);\r
- RAMLOG_STR("More jobs\n");\r
+ RAMLOG_STR("more_jobs\n");\r
} else {\r
// No more jobs, so set HwUnit and sequence IDLE/OK also.\r
Spi_SetHWUnitStatus(unit, SPI_IDLE);\r
/* We are now ready for next transfer. */\r
spiHw->MCR.B.HALT = 1;\r
\r
- RAMLOG_STR("NO more jobs\n");\r
+ RAMLOG_STR("NO_more_jobs\n");\r
}\r
}\r
\r
}\r
\r
/* Clock tables */\r
-uint32 clk_table_asc[] = { 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048,\r
+const uint32 clk_table_asc[] = { 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048,\r
4096, 8192, 16384, 32768, 65536 };\r
-uint32 clk_table_cssck[] = { 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048,\r
+const uint32 clk_table_cssck[] = { 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048,\r
4096, 8192, 16384, 32768, 65536 };\r
-uint16 clk_table_br[] = { 2, 4, 6, 8, 16, 32, 64, 128, 256, 512, 1024, 2048,\r
+const uint16 clk_table_br[] = { 2, 4, 6, 8, 16, 32, 64, 128, 256, 512, 1024, 2048,\r
4096, 8192, 16384, 32768 };\r
-uint8 clk_table_pasc[] = { 1, 3, 5, 7 };\r
-uint8 clk_table_pcssck[] = { 1, 3, 5, 7 };\r
-uint8 clk_table_pbr[] = { 2, 3, 5, 7 };\r
+const uint8 clk_table_pasc[] = { 1, 3, 5, 7 };\r
+const uint8 clk_table_pcssck[] = { 1, 3, 5, 7 };\r
+const uint8 clk_table_pbr[] = { 2, 3, 5, 7 };\r
\r
/**\r
* Function to setup CTAR's from configuration\r
spiHw->MCR.B.PCSSE = 0;\r
\r
/* Enable FIFO's. */\r
+#if (SPI_IMPLEMENTATION == SPI_DMA)\r
spiHw->MCR.B.DIS_RXF = 1;\r
spiHw->MCR.B.DIS_TXF = 1;\r
+#elif (SPI_IMPLEMENTATION == SPI_FIFO)\r
+ spiHw->MCR.B.DIS_RXF = 0;\r
+ spiHw->MCR.B.DIS_TXF = 0;\r
+#endif\r
+\r
\r
/* Set all active low. */\r
spiHw->MCR.B.PCSIS0 = 1;\r
spiHw->MCR.B.PCSIS4 = 1;\r
spiHw->MCR.B.PCSIS5 = 1;\r
\r
-#if (SPI_IMPLEMENTATION == IMPL_DMA)\r
+#if (SPI_IMPLEMENTATION == SPI_DMA)\r
/* DMA TX FIFO fill. */\r
spiHw->RSER.B.TFFF_RE = 1;\r
spiHw->RSER.B.TFFF_DIRS = 1;\r
\r
//-------------------------------------------------------------------\r
\r
-#if (SPI_IMPLEMENTATION==IMPL_DMA)\r
+#if (SPI_IMPLEMENTATION==SPI_DMA)\r
static void Spi_DmaSetup(uint32 unit) {\r
\r
Dma_TcdType *tcd;\r
\r
Spi_Global.asyncMode = SPI_INTERRUPT_MODE;\r
\r
- // Spi_Global.currSeq = SEQ_NOT_VALID;\r
-\r
// Set all sequence results to OK\r
for (Spi_SequenceType i = (Spi_SequenceType) 0; i < SPI_MAX_SEQUENCE; i++) {\r
Spi_SetSequenceResult(i, SPI_SEQ_OK);\r
Spi_InitController(confNr);\r
Spi_SetHWUnitStatus(confNr, SPI_IDLE);\r
\r
-#if (SPI_IMPLEMENTATION == IMPL_DMA )\r
+#if (SPI_IMPLEMENTATION == SPI_DMA )\r
// DMA init...\r
//\r
\r
return E_OK;\r
}\r
\r
-#if (SPI_IMPLEMENTATION==IMPL_DMA)\r
+#if (SPI_IMPLEMENTATION==SPI_DMA)\r
/**\r
*
* @param spiUnit
spiHw->TCR.B.SPI_TCNT = 0;\r
\r
if ( (Spi_Global.asyncMode == SPI_INTERRUPT_MODE) &&\r
- (spiUnit->callType == SPI_ASYNC)) {\r
+ (spiUnit->callType == SPI_ASYNC_CALL)) {\r
ENABLE_EOQ_INTERRUPT(spiHw);\r
} else {\r
DISABLE_EOQ_INTERRUPT(spiHw);\r
}\r
#endif\r
\r
-#if (SPI_IMPLEMENTATION==IMPL_FIFO)\r
+#if (SPI_IMPLEMENTATION==SPI_FIFO)\r
/**\r
*\r
* @param spiUnit\r
* @param jobConfig\r
* @return\r
*/\r
-static void Spi_DoWrite_FIFO( Spi_JobType jobIndex )\r
+static void Spi_WriteJob_FIFO( Spi_JobType jobIndex )\r
{\r
- Spi_ChannelType currChannel;\r
- Spi_CommandType cmd;\r
- uint32_t length;\r
- Spi_EbType * extChBuff;\r
- const Spi_ChannelConfigType *chConfig;\r
- _Bool fifoFull = 0;\r
- int fifoCnt = 0;\r
- Spi_JobUnitType *jobUnitPtr = Spi_JobUnit[jobIndex];\r
+ Spi_ChannelType currChannel;\r
+ Spi_CommandType cmd;\r
+ Spi_CommandType dCmd;\r
+ Spi_NumberOfDataType bufLen;\r
+ const Spi_ChannelConfigType * chConfig;\r
+ Spi_JobUnitType * jobUnitPtr;\r
+ const Spi_DataType * buf;\r
+ Spi_NumberOfDataType copyCnt;\r
+ Spi_NumberOfDataType fifoLeft;\r
+ boolean done = 0;\r
+ boolean lastJob = 0;\r
+ int i;\r
+ jobUnitPtr = &Spi_JobUnit[jobIndex];\r
+\r
+\r
+ fifoLeft = FIFO_DEPTH;\r
\r
- jobUnitPtr->fifoSent = 0;\r
+ RAMLOG_STR("Spi_WriteJob_FIFO\n");\r
+\r
+#if defined(STEP_VALIDATION)\r
+ if( jobUnitPtr->hwPtr->SR.B.TXCTR != 0 ) {\r
+ while(1) {};\r
+ }\r
+#endif\r
+\r
+ cmd.R = 0;\r
+ dCmd.R = 0xfffffffful;\r
\r
/* Iterate over the channels for this job */\r
- while ((currChannel = jobUnitPtr->channelsPtr[jobUnitPtr->currTxChIndex]) != CH_NOT_VALID) {\r
+ currChannel = jobUnitPtr->channelsPtr[jobUnitPtr->currTxChIndex];\r
+ while ( fifoLeft != 0) {\r
\r
chConfig = &Spi_Global.configPtr->SpiChannelConfig[currChannel];\r
- buf = spiGetTxBuf(currChannel, &bufLen);\r
+ buf = spiGetTxBuf( currChannel, &bufLen);\r
\r
- /* === Push on the FIFO === */\r
- copyCnt = MIN( bufLen, (FIFO_DEPTH - jobUnitPtr->fifoSent));\r
+ /* Minimum of how much data to copy and the limit of the FIFO */\r
+ copyCnt = MIN( (bufLen - jobUnitPtr->txChCnt) >> ((chConfig->SpiDataWidth-1)/8), fifoLeft );\r
\r
- while( copyCnt != 0 ) {\r
+ /* Channels should keep CS active ( A job must assert CS continuously) */\r
+ cmd.B.CONT = 1;\r
+ /* Set the Chip Select (PCS) */\r
+ cmd.R |= (1 << (16 + jobUnitPtr->extDeviceCfgPtr->SpiCsIdentifier));\r
\r
- /* Channels should keep CS active ( A job must assert CS continuously) */\r
- cmd.B.CONT = 1;\r
- /* Set the Chip Select (PCS) */\r
- cmd.R |= (1 << (16 + jobUnitPtr->extDeviceCfgPtr->SpiCsIdentifier));\r
+ if( cmd.B.EOQ == 1) {\r
+ while(1) {};\r
+ }\r
\r
- cmd.B.CTAS = Spi_ChannelInfo[currChannel].ctarId;\r
- if (buf != NULL) {\r
- if (chConfig->SpiDataWidth > 8 ) {\r
- cmd.B.TXDATA = (buf[jobUnitPtr->dataIndex] << 8) +\r
- (buf[jobUnitPtr->dataIndex + 1] & 0xff);\r
- jobUnitPtr->dataIndex+=2;\r
- } else {\r
- cmd.B.TXDATA = buf[jobUnitPtr->dataIndex];\r
- jobUnitPtr->dataIndex++;\r
- }\r
+ /* Push as much as we can (FIFO or Channel limits) */\r
+ for(i=0; i < copyCnt ; i++ ) {\r
+ cmd.B.CTAS = Spi_ChannelInfo[currChannel].ctarId;\r
+ if (buf != NULL) {\r
+ if (chConfig->SpiDataWidth > 8 ) {\r
+ cmd.B.TXDATA = (buf[jobUnitPtr->txChCnt] << 8) +\r
+ (buf[jobUnitPtr->txChCnt + 1] & 0xff);\r
+ } else {\r
+ cmd.B.TXDATA = buf[jobUnitPtr->txChCnt];\r
+ }\r
+ } else {\r
+ cmd.B.TXDATA = chConfig->SpiDefaultData;\r
+ }\r
+\r
+ if (chConfig->SpiDataWidth > 8 ) {\r
+ jobUnitPtr->txChCnt+=2;\r
+ } else {\r
+ jobUnitPtr->txChCnt++;\r
+ }\r
+\r
+\r
+ if( dCmd.R != 0xfffffffful) {\r
+ jobUnitPtr->hwPtr->PUSHR.R = dCmd.R; // Write delayed\r
+ }\r
+\r
+ dCmd.R = cmd.R; // Save it\r
+ --fifoLeft;\r
+ } /* for */\r
+\r
+ RAMLOG_STR("CI#");RAMLOG_DEC(jobUnitPtr->currTxChIndex);RAMLOG_STR("\n");\r
+\r
+\r
+ /* Done with channel? */\r
+ if( ((bufLen - jobUnitPtr->txChCnt) == 0) ) {\r
+ jobUnitPtr->txChCnt = 0;\r
+ /* Done with job? */\r
+ jobUnitPtr->currTxChIndex++;\r
+ currChannel = jobUnitPtr->channelsPtr[jobUnitPtr->currTxChIndex];\r
+ if( currChannel == CH_NOT_VALID ) {\r
+ jobUnitPtr->currTxChIndex = 0;\r
+ cmd.B.CONT = 0;\r
+ break;\r
+ }\r
+ }\r
\r
- } else {\r
- cmd.B.TXDATA = chConfig->SpiDefaultData;\r
- }\r
- fifoCnt++;\r
+ } /* while */\r
\r
- /* Set EOQ if last */\r
- fifoFull = (fifoCnt == FIFO_DEPTH ) ? 1 : 0;\r
- cmd.B.EOQ = fifoFull;\r
+ cmd.B.EOQ = 1;\r
+ jobUnitPtr->hwPtr->PUSHR.R = cmd.R;\r
\r
- /* Push in to FIFO */\r
- jobUnitPtr->hwPtr->PUSHR.R = cmd.R;\r
- }\r
+ jobUnitPtr->fifoSent = FIFO_DEPTH - fifoLeft;\r
\r
- if( fifoFull ) {\r
- break;\r
- }\r
- jobUnitPtr->currTxChIndex++;\r
+#if defined(STEP_VALIDATION)\r
+ if( jobUnitPtr->fifoSent != jobUnitPtr->hwPtr->SR.B.TXCTR ) {\r
+ while(1);\r
}\r
+#endif\r
\r
- if(currChannel == CH_NOT_VALID ) {\r
- jobUnitPtr->jobComplete = 1;\r
- }\r
+ jobUnitPtr->hwPtr->TCR.B.SPI_TCNT = 0;\r
+\r
+ if ( (Spi_Global.asyncMode == SPI_INTERRUPT_MODE) &&\r
+ (jobUnitPtr->unitPtr->callType == SPI_ASYNC_CALL)) {\r
+ ENABLE_EOQ_INTERRUPT(jobUnitPtr->hwPtr);\r
+ } else {\r
+ DISABLE_EOQ_INTERRUPT(jobUnitPtr->hwPtr);\r
+ }\r
+\r
+#if defined(STEP_VALIDATION)\r
+ /* Verify FIFO before sending */\r
+ {\r
+ SPICommandType *base = (SPICommandType *)&jobUnitPtr->hwPtr->TXFR[0];\r
+ SPICommandType *curr;\r
+ int i,lastIndex;\r
+\r
+ i = jobUnitPtr->hwPtr->SR.B.TXNXTPTR;\r
+ lastIndex = ( i + jobUnitPtr->hwPtr->SR.B.TXCTR - 1 ) % FIFO_DEPTH;\r
+ while( i != lastIndex ) {\r
+ curr = base + i;\r
+ if( curr->B.EOQ == 1) {\r
+ while(1) {};\r
+ }\r
+\r
+ i = (i + 1) % FIFO_DEPTH;\r
+ }\r
+ curr = base + i;\r
+ if( curr->B.EOQ != 1) {\r
+ while(1) {};\r
+ }\r
+ }\r
+#endif\r
+\r
+ jobUnitPtr->hwPtr->SR.B.EOQF = 1;\r
+ jobUnitPtr->hwPtr->MCR.B.HALT = 0;\r
+\r
+#if defined(STEP_VALIDATION)\r
+ /* Wait for transfer to complete (EOQF bit is set) */\r
+ while (jobUnitPtr->hwPtr->SR.B.EOQF==1) {\r
+ Spi_Global.eoqf_cnt++;\r
+ }\r
+ while (jobUnitPtr->hwPtr->SR.B.TXRXS) {Spi_Global.txrxs_cnt++;}\r
+#endif\r
+\r
+ // TODO: Clear FIFO's? CLR_TXF?\r
\r
}\r
-#endif /* (SPI_IMPLEMENTATION==IMPL_FIFO) */\r
+#endif /* (SPI_IMPLEMENTATION==SPI_FIFO) */\r
\r
\r
//-------------------------------------------------------------------\r
unitPtr->txCurrIndex = 0;\r
unitPtr->currJob = Spi_JobUnit[jobIndex].jobCfgPtr;\r
unitPtr->currJobIndex = jobIndex;\r
+#if (SPI_IMPLEMENTATION == SPI_FIFO)\r
+ Spi_JobUnit[jobIndex].txChCnt = 0;\r
+ Spi_JobUnit[jobIndex].rxChCnt = 0;\r
+#endif\r
\r
Spi_SetHWUnitStatus(Spi_JobUnit[jobIndex].jobCfgPtr->SpiHwUnit, SPI_BUSY);\r
Spi_SetJobResult(jobIndex, SPI_JOB_PENDING);\r
\r
-#if (SPI_IMPLEMENTATION==IMPL_DMA)\r
+#if (USE_DIO_CS == STD_ON)\r
+ if( Spi_JobUnit[jobIndex].extDeviceCfgPtr->SpiCsCallback != NULL ) {\r
+ Spi_JobUnit[jobIndex].extDeviceCfgPtr->SpiCsCallback(1);\r
+ }\r
+#endif\r
+\r
+#if (SPI_IMPLEMENTATION==SPI_DMA)\r
Spi_DoWrite_DMA( unitPtr, jobIndex, Spi_JobUnit[jobIndex].jobCfgPtr );\r
-#elif (SPI_IMPLEMENTATION==IMPL_FIFO)\r
+#elif (SPI_IMPLEMENTATION==SPI_FIFO)\r
Spi_JobUnit[jobIndex].currTxChIndex = 0;\r
- Spi_DoWrite_FIFO ( jobIndex );\r
+ Spi_WriteJob_FIFO ( jobIndex );\r
#endif\r
\r
}\r
\r
+\r
void Spi_PrintSeqInfo(const Spi_SequenceConfigType *seqConfigPtr) {\r
int i = 0;\r
uint32 job;\r
} DEBUG(DEBUG_HIGH,"\n");\r
}\r
\r
+\r
/**\r
* Write a sequence to the SPI bus\r
*\r
\r
// Setup interrupt for end of queue\r
if ( (Spi_Global.asyncMode == SPI_INTERRUPT_MODE) &&\r
- (spiUnit->callType== SPI_ASYNC)) {\r
+ (spiUnit->callType== SPI_ASYNC_CALL)) {\r
DEBUG(DEBUG_MEDIUM,"%s: async/interrupt mode\n",MODULE_NAME);\r
} else {\r
DEBUG(DEBUG_MEDIUM,"%s: sync/polled mode\n",MODULE_NAME);\r
\r
Spi_JobWrite(jobIndex);\r
\r
- if (spiUnit->callType == SPI_SYNC) {\r
+ if (spiUnit->callType == SPI_SYNC_CALL) {\r
while (Spi_GetSequenceResult(seqIndex) == SPI_SEQ_PENDING) {\r
Spi_Isr(jobConfig->SpiHwUnit);\r
}\r
\r
//-------------------------------------------------------------------\r
\r
+\r
+/**\r
+ * Blocking write\r
+ *\r
+ * @param Sequence\r
+ * @return\r
+ */\r
Std_ReturnType Spi_SyncTransmit(Spi_SequenceType Sequence) {\r
\r
VALIDATE_W_RV( ( TRUE == Spi_Global.initRun ), SPI_SYNCTRANSMIT_SERVICE_ID, SPI_E_UNINIT, E_NOT_OK );\r
return E_NOT_OK;\r
}\r
\r
- Spi_SeqWrite(Sequence, SPI_SYNC);\r
+ Spi_SeqWrite(Sequence, SPI_SYNC_CALL);\r
\r
return rv;\r
}\r
\r
DEBUG(DEBUG_LOW,"%s: Starting seq: %d\n",MODULE_NAME,Sequence);\r
\r
- Spi_SeqWrite(Sequence, SPI_ASYNC);\r
+ Spi_SeqWrite(Sequence, SPI_ASYNC_CALL);\r
\r
return E_OK;\r
}\r
SCK/Blue 9-X X-10 \r
CS/Green 11-X X-12\r
13-X X-14\r
- Gnd/Black 15-X X-16 VCC/Red \r
- \r
+ 15-X X-16 \r
+ Gnd/Black 17-X X-18 VCC/Red \r
\r
\r
\r
* TODO: Call reset of card?\r
* */\r
DisableAllInterrupts();\r
- while(1);\r
+ while(1){}\r
}\r
\r
-\r
-\r
-extern char _end[];\r
-\r
-//static char *curbrk = _end;\r
-#if 0\r
-\r
-#ifndef HEAPSIZE\r
-#define HEAPSIZE 16000\r
-#endif\r
-\r
-/*\r
- * The heap sadly have alignment that depends on the pagesize that\r
- * you compile malloc newlib with. From what I can tell from the\r
- * code that is a pagesize of 4096.\r
- */\r
-\r
-unsigned char _heap[HEAPSIZE] __attribute__((aligned (4)));\r
-//__attribute__((section(".heap")));\r
-\r
-#else\r
-\r
-/* The linker will allocate a heap for us\r
- * Importing variables set by the linker is never pretty... */\r
-extern unsigned char _heap_addr[];\r
-extern void _heap_size(void);\r
-\r
-const ptrdiff_t _heap_size_proper = (const ptrdiff_t) &_heap_size; // Casting this to get a proper type\r
-\r
-#define HEAPSIZE _heap_size_proper\r
-#define _heap _heap_addr\r
-\r
-#endif\r
-\r
-\r
-void * sbrk( ptrdiff_t incr )\r
-{\r
- static unsigned char *heap_end;\r
- unsigned char *prev_heap_end;\r
-\r
-/* initialize */\r
- if( heap_end == 0 ){\r
- heap_end = _heap;\r
- }\r
- prev_heap_end = heap_end;\r
-\r
- if( heap_end + incr - _heap > HEAPSIZE ) {\r
- /* heap overflow - announce on stderr */\r
- abort();\r
- }\r
-\r
- heap_end += incr;\r
-\r
- return prev_heap_end;\r
-}\r
for (uint8 i = 0; i < CANSM_NETWORK_COUNT; ++i) {\r
const CanSM_NetworkType* Network = &CanSM_Config->Networks[i];\r
for (uint8 j = 0; j < Network->ControllerCount; ++j) {\r
- const CanSM_ControllerType* ptrController = &Network->Controllers[i];\r
+ const CanSM_ControllerType* ptrController = &Network->Controllers[j];\r
if(ptrController->CanIfControllerId == Controller)\r
{\r
CanSM_Internal.Networks[i].busoffevent = TRUE;\r
\r
uint8 failure = 0;\r
\r
- uint32 earliestDeadline;\r
uint32 firstTimeout;\r
\r
//lint --e(928) PC-Lint exception Misra 11.4, Must be like this. /tojo\r
\r
const ComIPdu_type *IPdu = GET_IPdu(i);\r
Com_Arc_IPdu_type *Arc_IPdu = GET_ArcIPdu(i);\r
+ Arc_IPdu->Com_Arc_DynSignalLength = 0;\r
\r
if (i >= COM_N_IPDUS) {\r
DET_REPORTERROR(COM_MODULE_ID, COM_INSTANCE_ID, 0x01, COM_E_TOO_MANY_IPDU);\r
}\r
\r
\r
- // Reset earliest deadline.\r
- earliestDeadline = 0xffffffffu;\r
+ // Reset firstTimeout.\r
firstTimeout = 0xffffffffu;\r
\r
// Initialize the memory with the default value.\r
if (IPdu->ComIPduDirection == SEND) {\r
- memset(Arc_IPdu->ComIPduDataPtr, IPdu->ComTxIPdu.ComTxIPduUnusedAreasDefault, IPdu->ComIPduSize);\r
+ memset((void *)IPdu->ComIPduDataPtr, IPdu->ComTxIPdu.ComTxIPduUnusedAreasDefault, IPdu->ComIPduSize);\r
}\r
\r
// For each signal in this PDU.\r
Signal = IPdu->ComIPduSignalRef[j];\r
Com_Arc_Signal_type * Arc_Signal = GET_ArcSignal(Signal->ComHandleId);\r
\r
- // If this signal already has been configured this is most likely an error.\r
- if (Arc_Signal->ComIPduDataPtr != NULL) {\r
- // DET_REPORTERROR(COM_MODULE_ID, COM_INSTANCE_ID, 0x01, COM_E_INVALID_SIGNAL_CONFIGURATION);\r
- // failure = 1;\r
- }\r
-\r
// Configure signal deadline monitoring if used.\r
if (Signal->ComTimeoutFactor > 0) {\r
\r
if (Signal->ComSignalArcUseUpdateBit) {\r
// This signal uses an update bit, and hence has its own deadline monitoring.\r
Arc_Signal->Com_Arc_DeadlineCounter = Signal->ComFirstTimeoutFactor; // Configure the deadline counter\r
- Arc_Signal->ComTimeoutFactor = Signal->ComTimeoutFactor;\r
\r
} else {\r
// This signal does not use an update bit, and should therefore use per I-PDU deadline monitoring.\r
- // Find the earliest deadline for this I-PDU and setup the deadline later.\r
- if (earliestDeadline > Signal->ComTimeoutFactor) {\r
- earliestDeadline = Signal->ComTimeoutFactor;\r
- }\r
if (firstTimeout > Signal->ComFirstTimeoutFactor) {\r
firstTimeout = Signal->ComFirstTimeoutFactor;\r
}\r
}\r
}\r
\r
- // Increment helper counters\r
- //Arc_IPdu->NComIPduSignalRef = j + 1;\r
-\r
- Arc_Signal->ComIPduDataPtr = Arc_IPdu->ComIPduDataPtr;\r
- Arc_Signal->ComIPduHandleId = i;\r
-\r
// Clear update bits\r
if (Signal->ComSignalArcUseUpdateBit) {\r
- CLEARBIT(Arc_IPdu->ComIPduDataPtr, Signal->ComUpdateBitPosition);\r
+ CLEARBIT(IPdu->ComIPduDataPtr, Signal->ComUpdateBitPosition);\r
}\r
\r
// If this signal is a signal group\r
GroupSignal = Signal->ComGroupSignal[h];\r
Com_Arc_GroupSignal_type *Arc_GroupSignal = GET_ArcGroupSignal(GroupSignal->ComHandleId);\r
// Set pointer to shadow buffer\r
- Arc_GroupSignal->Com_Arc_ShadowBuffer = Arc_Signal->Com_Arc_ShadowBuffer;\r
+ Arc_GroupSignal->Com_Arc_ShadowBuffer = (void *)Signal->Com_Arc_ShadowBuffer;\r
// Initialize group signal data.\r
Com_WriteGroupSignalDataToPdu(Signal->ComHandleId, GroupSignal->ComHandleId, GroupSignal->ComSignalInitValue);\r
}\r
-\r
} else {\r
// Initialize signal data.\r
Com_WriteSignalDataToPdu(Signal->ComHandleId, Signal->ComSignalInitValue);\r
}\r
}\r
-\r
+ if (IPdu->ComIPduDirection == RECEIVE && IPdu->ComIPduSignalProcessing == DEFERRED) {\r
+ // Copy the initialized pdu to deferred buffer\r
+ memcpy(IPdu->ComIPduDeferredDataPtr,IPdu->ComIPduDataPtr,IPdu->ComIPduSize);\r
+ }\r
// Configure per I-PDU based deadline monitoring.\r
for (uint16 j = 0; (IPdu->ComIPduSignalRef != NULL) && (IPdu->ComIPduSignalRef[j] != NULL); j++) {\r
Signal = IPdu->ComIPduSignalRef[j];\r
Com_Arc_Signal_type * Arc_Signal = GET_ArcSignal(Signal->ComHandleId);\r
\r
if ( (Signal->ComTimeoutFactor > 0) && (!Signal->ComSignalArcUseUpdateBit) ) {\r
- Arc_Signal->ComTimeoutFactor = earliestDeadline;\r
Arc_Signal->Com_Arc_DeadlineCounter = firstTimeout;\r
}\r
}\r
*/\r
BufReq_ReturnType Com_CopyTxData(PduIdType PduId, PduInfoType* PduInfoPtr, RetryInfoType* RetryInfoPtr, PduLengthType* TxDataCntPtr) {\r
imask_t state;\r
- Irq_Save(state);\r
BufReq_ReturnType r = BUFREQ_OK;\r
const ComIPdu_type *IPdu = GET_IPdu(PduId);\r
boolean dirOk = ComConfig->ComIPdu[PduId].ComIPduDirection == SEND;\r
- boolean sizeOk = IPdu->ComIPduSize >= Com_BufferPduState[PduId].currentPosition + PduInfoPtr->SduLength;\r
+ boolean sizeOk;\r
+ (void)RetryInfoPtr; // get rid of compiler warning\r
+\r
+ Irq_Save(state);\r
+ sizeOk = IPdu->ComIPduSize >= Com_BufferPduState[PduId].currentPosition + PduInfoPtr->SduLength;\r
Com_BufferPduState[PduId].locked = true;\r
if (dirOk && sizeOk) {\r
- void* source = GET_ArcIPdu(PduId)->ComIPduDataPtr;\r
+ void* source = (void *)IPdu->ComIPduDataPtr;\r
memcpy(PduInfoPtr->SduDataPtr,source + Com_BufferPduState[PduId].currentPosition, PduInfoPtr->SduLength);\r
Com_BufferPduState[PduId].currentPosition += PduInfoPtr->SduLength;\r
*TxDataCntPtr = IPdu->ComIPduSize - Com_BufferPduState[PduId].currentPosition;\r
}\r
BufReq_ReturnType Com_CopyRxData(PduIdType PduId, const PduInfoType* PduInfoPtr, PduLengthType* RxBufferSizePtr) {\r
imask_t state;\r
- Irq_Save(state);\r
BufReq_ReturnType r = BUFREQ_OK;\r
- uint8 remainingBytes = GET_IPdu(PduId)->ComIPduSize - Com_BufferPduState[PduId].currentPosition;\r
- boolean sizeOk = remainingBytes >= PduInfoPtr->SduLength;\r
- boolean dirOk = GET_IPdu(PduId)->ComIPduDirection == RECEIVE;\r
- boolean lockOk = isPduBufferLocked(PduId);\r
+ uint8 remainingBytes;\r
+ boolean sizeOk;\r
+ boolean dirOk;\r
+ boolean lockOk;\r
+\r
+ Irq_Save(state);\r
+\r
+ remainingBytes = GET_IPdu(PduId)->ComIPduSize - Com_BufferPduState[PduId].currentPosition;\r
+ sizeOk = remainingBytes >= PduInfoPtr->SduLength;\r
+ dirOk = GET_IPdu(PduId)->ComIPduDirection == RECEIVE;\r
+ lockOk = isPduBufferLocked(PduId);\r
if (dirOk && lockOk && sizeOk) {\r
- memcpy(GET_ArcIPdu(PduId)->ComIPduDataPtr+Com_BufferPduState[PduId].currentPosition, PduInfoPtr->SduDataPtr, PduInfoPtr->SduLength);\r
+ memcpy((void *)(GET_IPdu(PduId)->ComIPduDataPtr+Com_BufferPduState[PduId].currentPosition), PduInfoPtr->SduDataPtr, PduInfoPtr->SduLength);\r
Com_BufferPduState[PduId].currentPosition += PduInfoPtr->SduLength;\r
*RxBufferSizePtr = GET_IPdu(PduId)->ComIPduSize - Com_BufferPduState[PduId].currentPosition;\r
} else {\r
r = BUFREQ_NOT_OK;\r
}\r
- return r;\r
Irq_Restore(state);\r
+ return r;\r
}\r
+\r
+static void Com_SetDynSignalLength(PduIdType ComRxPduId,PduLengthType TpSduLength) {\r
+ const ComIPdu_type *IPdu = GET_IPdu(ComRxPduId);\r
+ if (IPdu->ComIPduDynSignalRef == 0) {\r
+ return;\r
+ }\r
+ const ComSignal_type * const dynSignal = IPdu->ComIPduDynSignalRef;\r
+ Com_Arc_IPdu_type *Arc_IPdu = GET_ArcIPdu(ComRxPduId);\r
+ Arc_IPdu->Com_Arc_DynSignalLength = TpSduLength - (dynSignal->ComBitPosition/8);\r
+ return;\r
+}\r
+\r
BufReq_ReturnType Com_StartOfReception(PduIdType ComRxPduId, PduLengthType TpSduLength, PduLengthType* RxBufferSizePtr) {\r
PduLengthType ComIPduSize;\r
imask_t state;\r
- Irq_Save(state);\r
BufReq_ReturnType r = BUFREQ_OK;\r
Com_Arc_IPdu_type *Arc_IPdu = GET_ArcIPdu(ComRxPduId);\r
+\r
+ Irq_Save(state);\r
if (Arc_IPdu->Com_Arc_IpduStarted) {\r
if (GET_IPdu(ComRxPduId)->ComIPduDirection == RECEIVE) {\r
if (!Com_BufferPduState[ComRxPduId].locked) {\r
if (ComIPduSize >= TpSduLength) {\r
Com_BufferPduState[ComRxPduId].locked = true;\r
*RxBufferSizePtr = ComIPduSize;\r
- Com_BufferPduState[ComRxPduId].locked = true;\r
+ Com_SetDynSignalLength(ComRxPduId,TpSduLength);\r
} else {\r
r = BUFREQ_OVFL;\r
}\r
typedef struct {\r
\r
uint32 Com_Arc_DeadlineCounter;\r
- uint32 ComTimeoutFactor;\r
- void *ComIPduDataPtr;\r
-\r
- uint16 ComIPduHandleId;\r
uint8 ComSignalUpdated;\r
-\r
- /* For signal groups */\r
- void *Com_Arc_ShadowBuffer;\r
-\r
} Com_Arc_Signal_type;\r
\r
\r
typedef struct {\r
\r
Com_Arc_TxIPduTimer_type Com_Arc_TxIPduTimers;\r
- void *ComIPduDataPtr;\r
uint8 Com_Arc_IpduStarted;\r
+ uint16 Com_Arc_DynSignalLength;\r
} Com_Arc_IPdu_type;\r
\r
typedef struct {\r
VALIDATE_SIGNAL(SignalId, 0x0a, E_NOT_OK);\r
// Store pointer to signal for easier coding.\r
const ComSignal_type * Signal = GET_Signal(SignalId);\r
- Com_Arc_Signal_type * Arc_Signal = GET_ArcSignal(SignalId);\r
- const ComIPdu_type *IPdu = GET_IPdu(Arc_Signal->ComIPduHandleId);\r
- Com_Arc_IPdu_type *Arc_IPdu = GET_ArcIPdu(Arc_Signal->ComIPduHandleId);\r
+ const ComIPdu_type *IPdu = GET_IPdu(Signal->ComIPduHandleId);\r
+ Com_Arc_IPdu_type *Arc_IPdu = GET_ArcIPdu(Signal->ComIPduHandleId);\r
\r
if (isPduBufferLocked(getPduId(IPdu))) {\r
return COM_BUSY;\r
}\r
//DEBUG(DEBUG_LOW, "Com_SendSignal: id %d, nBytes %d, BitPosition %d, intVal %d\n", SignalId, nBytes, signal->ComBitPosition, (uint32)*(uint8 *)SignalDataPtr);\r
\r
- // TODO: CopyData\r
- // Com_CopyData(Arc_IPdu->ComIPduDataPtr, dataPtr, Signal->ComBitSize, Signal->ComBitPosition, 0);\r
+ imask_t irq_state;\r
+\r
+ Irq_Save(irq_state);\r
Com_WriteSignalDataToPdu(Signal->ComHandleId, SignalDataPtr);\r
\r
// If the signal has an update bit. Set it!\r
if (Signal->ComSignalArcUseUpdateBit) {\r
- SETBIT(Arc_IPdu->ComIPduDataPtr, Signal->ComUpdateBitPosition);\r
+ SETBIT(IPdu->ComIPduDataPtr, Signal->ComUpdateBitPosition);\r
}\r
\r
/*\r
if (Signal->ComTransferProperty == TRIGGERED) {\r
Arc_IPdu->Com_Arc_TxIPduTimers.ComTxIPduNumberOfRepetitionsLeft = IPdu->ComTxIPdu.ComTxModeTrue.ComTxModeNumberOfRepetitions + 1;\r
}\r
+ Irq_Restore(irq_state);\r
+\r
return E_OK;\r
}\r
\r
DEBUG(DEBUG_LOW, "Com_ReceiveSignal: SignalId %d\n", SignalId);\r
\r
const ComSignal_type * Signal = GET_Signal(SignalId);\r
- Com_Arc_Signal_type * Arc_Signal = GET_ArcSignal(Signal->ComHandleId);\r
- const ComIPdu_type *IPdu = GET_IPdu(Arc_Signal->ComIPduHandleId);\r
+ const ComIPdu_type *IPdu = GET_IPdu(Signal->ComIPduHandleId);\r
+\r
+ uint8 r = E_OK;\r
+ const void* pduDataPtr = 0;\r
+ if (IPdu->ComIPduSignalProcessing == DEFERRED && IPdu->ComIPduDirection == RECEIVE) {\r
+ pduDataPtr = IPdu->ComIPduDeferredDataPtr;\r
+ } else {\r
+ if (isPduBufferLocked(getPduId(IPdu))) {\r
+ r = COM_BUSY;\r
+ }\r
+ pduDataPtr = IPdu->ComIPduDataPtr;\r
+ }\r
+ Com_ReadSignalDataFromPduBuffer(\r
+ SignalId,\r
+ FALSE,\r
+ SignalDataPtr,\r
+ pduDataPtr,\r
+ IPdu->ComIPduSize);\r
+\r
+ return r;\r
+}\r
+\r
+uint8 Com_ReceiveDynSignal(Com_SignalIdType SignalId, void* SignalDataPtr, uint16* Length) {\r
+ const ComSignal_type * Signal = GET_Signal(SignalId);\r
+ Com_Arc_IPdu_type *Arc_IPdu = GET_ArcIPdu(Signal->ComIPduHandleId);\r
+ const ComIPdu_type *IPdu = GET_IPdu(Signal->ComIPduHandleId);\r
+ imask_t state;\r
+\r
+ Com_SignalType signalType = Signal->ComSignalType;\r
+ if (signalType != UINT8_DYN) {\r
+ return COM_SERVICE_NOT_AVAILABLE;\r
+ }\r
+\r
+ Irq_Save(state);\r
+\r
+ if (*Length > Arc_IPdu->Com_Arc_DynSignalLength) {\r
+ *Length = Arc_IPdu->Com_Arc_DynSignalLength;\r
+ }\r
+ uint8 startFromPduByte = (Signal->ComBitPosition) / 8;\r
+ uint8 r = E_OK;\r
+ const void* pduDataPtr = 0;\r
+ if (IPdu->ComIPduSignalProcessing == DEFERRED && IPdu->ComIPduDirection == RECEIVE) {\r
+ pduDataPtr = IPdu->ComIPduDeferredDataPtr;\r
+ } else {\r
+ if (isPduBufferLocked(getPduId(IPdu))) {\r
+ r = COM_BUSY;\r
+ }\r
+ pduDataPtr = IPdu->ComIPduDataPtr;\r
+ }\r
+ memcpy(SignalDataPtr, pduDataPtr + startFromPduByte, *Length);\r
+\r
+ Irq_Restore(state);\r
+\r
+ return r;\r
+}\r
+\r
+uint8 Com_SendDynSignal(Com_SignalIdType SignalId, const void* SignalDataPtr, uint16 Length) {\r
+ const ComSignal_type * Signal = GET_Signal(SignalId);\r
+ Com_Arc_IPdu_type *Arc_IPdu = GET_ArcIPdu(Signal->ComIPduHandleId);\r
+ const ComIPdu_type *IPdu = GET_IPdu(Signal->ComIPduHandleId);\r
+ imask_t state;\r
+\r
+ Com_SignalType signalType = Signal->ComSignalType;\r
+ if (signalType != UINT8_DYN) {\r
+ return COM_SERVICE_NOT_AVAILABLE;\r
+ }\r
if (isPduBufferLocked(getPduId(IPdu))) {\r
return COM_BUSY;\r
}\r
+ uint8 signalLength = Signal->ComBitSize / 8;\r
+ Com_BitPositionType bitPosition = Signal->ComBitPosition;\r
+ if (signalLength < Length) {\r
+ return E_NOT_OK;\r
+ }\r
+ uint8 startFromPduByte = bitPosition / 8;\r
\r
- // Com_CopyFromSignal(&ComConfig->ComSignal[SignalId], SignalDataPtr);\r
- Com_ReadSignalDataFromPdu(SignalId, SignalDataPtr);\r
+ Irq_Save(state);\r
+ memcpy((void *)(IPdu->ComIPduDataPtr + startFromPduByte), SignalDataPtr, Length);\r
+ Arc_IPdu->Com_Arc_DynSignalLength = Length;\r
+ // If the signal has an update bit. Set it!\r
+ if (Signal->ComSignalArcUseUpdateBit) {\r
+ SETBIT(IPdu->ComIPduDataPtr, Signal->ComUpdateBitPosition);\r
+ }\r
+ // If signal has triggered transmit property, trigger a transmission!\r
+ if (Signal->ComTransferProperty == TRIGGERED) {\r
+ Arc_IPdu->Com_Arc_TxIPduTimers.ComTxIPduNumberOfRepetitionsLeft = IPdu->ComTxIPdu.ComTxModeTrue.ComTxModeNumberOfRepetitions + 1;\r
+ }\r
+ Irq_Restore(state);\r
\r
- //uint16 val = *(uint16 *)SignalDataPtr;\r
- //val = bswap16(val);\r
- // Sign extend!\r
- return E_OK;\r
+ return E_OK;\r
}\r
\r
Std_ReturnType Com_TriggerTransmit(PduIdType ComTxPduId, PduInfoType *PduInfoPtr) {\r
* COM395: This function must override the IPdu callouts used in Com_TriggerIPduTransmit();\r
*/\r
const ComIPdu_type *IPdu = GET_IPdu(ComTxPduId);\r
- Com_Arc_IPdu_type *Arc_IPdu = GET_ArcIPdu(ComTxPduId);\r
\r
- memcpy(PduInfoPtr->SduDataPtr, Arc_IPdu->ComIPduDataPtr, IPdu->ComIPduSize);\r
+ imask_t state;\r
+ Irq_Save(state);\r
+\r
+ memcpy(PduInfoPtr->SduDataPtr, IPdu->ComIPduDataPtr, IPdu->ComIPduSize);\r
+\r
+ Irq_Restore(state);\r
+\r
PduInfoPtr->SduLength = IPdu->ComIPduSize;\r
return E_OK;\r
}\r
\r
const ComIPdu_type *IPdu = GET_IPdu(ComTxPduId);\r
Com_Arc_IPdu_type *Arc_IPdu = GET_ArcIPdu(ComTxPduId);\r
+ imask_t state;\r
+ Irq_Save(state);\r
\r
// Is the IPdu ready for transmission?\r
if (Arc_IPdu->Com_Arc_TxIPduTimers.ComTxIPduMinimumDelayTimer == 0) {\r
\r
- imask_t state;\r
-\r
//lint --e(725) Suppress PC-Lint warning "Expected positive indentation...". What means?\r
- Irq_Save(state);\r
// Check callout status\r
if (IPdu->ComIPduCallout != NULL) {\r
- if (!IPdu->ComIPduCallout(ComTxPduId, Arc_IPdu->ComIPduDataPtr)) {\r
+ if (!IPdu->ComIPduCallout(ComTxPduId, IPdu->ComIPduDataPtr)) {\r
// TODO Report error to DET.\r
// Det_ReportError();\r
Irq_Restore(state);\r
return;\r
}\r
}\r
-\r
- PduInfoType PduInfoPackage = {\r
- .SduDataPtr = Arc_IPdu->ComIPduDataPtr,\r
- .SduLength = IPdu->ComIPduSize\r
- };\r
+ PduInfoType PduInfoPackage;\r
+ PduInfoPackage.SduDataPtr = (uint8 *)IPdu->ComIPduDataPtr;\r
+ if (IPdu->ComIPduDynSignalRef != 0) {\r
+ uint8 sizeWithoutDynSignal = IPdu->ComIPduSize - (IPdu->ComIPduDynSignalRef->ComBitSize/8);\r
+ PduInfoPackage.SduLength = sizeWithoutDynSignal + Arc_IPdu->Com_Arc_DynSignalLength;\r
+ } else {\r
+ PduInfoPackage.SduLength = IPdu->ComIPduSize;\r
+ }\r
\r
// Send IPdu!\r
if (PduR_ComTransmit(IPdu->ArcIPduOutgoingId, &PduInfoPackage) == E_OK) {\r
// Clear all update bits for the contained signals\r
for (uint8 i = 0; (IPdu->ComIPduSignalRef != NULL) && (IPdu->ComIPduSignalRef[i] != NULL); i++) {\r
if (IPdu->ComIPduSignalRef[i]->ComSignalArcUseUpdateBit) {\r
- CLEARBIT(Arc_IPdu->ComIPduDataPtr, IPdu->ComIPduSignalRef[i]->ComUpdateBitPosition);\r
+ CLEARBIT(IPdu->ComIPduDataPtr, IPdu->ComIPduSignalRef[i]->ComUpdateBitPosition);\r
}\r
}\r
} else {\r
UnlockTpBuffer(getPduId(IPdu));\r
}\r
- Irq_Restore(state);\r
\r
// Reset miminum delay timer.\r
Arc_IPdu->Com_Arc_TxIPduTimers.ComTxIPduMinimumDelayTimer = IPdu->ComTxIPdu.ComTxIPduMinimumDelayFactor;\r
-\r
} else {\r
//DEBUG(DEBUG_MEDIUM, "failed (MDT)!\n", ComTxPduId);\r
}\r
+ Irq_Restore(state);\r
}\r
\r
//lint -esym(904, Com_RxIndication) //PC-Lint Exception of rule 14.7\r
\r
const ComIPdu_type *IPdu = GET_IPdu(ComRxPduId);\r
Com_Arc_IPdu_type *Arc_IPdu = GET_ArcIPdu(ComRxPduId);\r
+ imask_t state;\r
+ Irq_Save(state);\r
\r
// If Ipdu is stopped\r
if (!Arc_IPdu->Com_Arc_IpduStarted) {\r
+ Irq_Restore(state);\r
return;\r
}\r
\r
if (!IPdu->ComIPduCallout(ComRxPduId, PduInfoPtr->SduDataPtr)) {\r
// TODO Report error to DET.\r
// Det_ReportError();\r
+ Irq_Restore(state);\r
return;\r
}\r
}\r
\r
// Copy IPDU data\r
- memcpy(Arc_IPdu->ComIPduDataPtr, PduInfoPtr->SduDataPtr, IPdu->ComIPduSize);\r
+ memcpy(IPdu->ComIPduDataPtr, PduInfoPtr->SduDataPtr, IPdu->ComIPduSize);\r
\r
Com_RxProcessSignals(IPdu,Arc_IPdu);\r
\r
+ Irq_Restore(state);\r
+\r
return;\r
}\r
\r
\r
const ComIPdu_type *IPdu = GET_IPdu(PduId);\r
Com_Arc_IPdu_type *Arc_IPdu = GET_ArcIPdu(PduId);\r
+ imask_t state;\r
+\r
+ Irq_Save(state);\r
\r
// If Ipdu is stopped\r
if (!Arc_IPdu->Com_Arc_IpduStarted) {\r
+ Irq_Restore(state);\r
return;\r
}\r
- // unlock buffer\r
- imask_t state;\r
- Irq_Save(state);\r
- UnlockTpBuffer(getPduId(IPdu));\r
- Irq_Restore(state);\r
-\r
if (Result == NTFRSLT_OK) {\r
+ if (IPdu->ComIPduSignalProcessing == IMMEDIATE) {\r
+ // irqs needs to be disabled until signal notifications have been called\r
+ // Otherwise a new Tp session can start and fill up pdus\r
+ UnlockTpBuffer(getPduId(IPdu));\r
+ }\r
+ // In deferred mode, buffers are unlocked in mainfunction\r
Com_RxProcessSignals(IPdu,Arc_IPdu);\r
+ } else {\r
+ UnlockTpBuffer(getPduId(IPdu));\r
}\r
+ Irq_Restore(state);\r
+\r
}\r
+\r
void Com_TpTxConfirmation(PduIdType PduId, NotifResultType Result) {\r
PDU_ID_CHECK(PduId, 0x15);\r
- const ComIPdu_type *IPdu = GET_IPdu(PduId);\r
+ (void)Result; // touch\r
\r
imask_t state;\r
Irq_Save(state);\r
- UnlockTpBuffer(getPduId(IPdu));\r
+ UnlockTpBuffer(PduId);\r
Irq_Restore(state);\r
}\r
void Com_TxConfirmation(PduIdType ComTxPduId) {\r
Std_ReturnType Com_SendSignalGroup(Com_SignalGroupIdType SignalGroupId) {\r
//#warning Com_SendSignalGroup should be performed atomically. Should we disable interrupts here?\r
const ComSignal_type * Signal = GET_Signal(SignalGroupId);\r
- Com_Arc_Signal_type * Arc_Signal = GET_ArcSignal(SignalGroupId);\r
- Com_Arc_IPdu_type *Arc_IPdu = GET_ArcIPdu(Arc_Signal->ComIPduHandleId);\r
- const ComIPdu_type *IPdu = GET_IPdu(Arc_Signal->ComIPduHandleId);\r
+ Com_Arc_IPdu_type *Arc_IPdu = GET_ArcIPdu(Signal->ComIPduHandleId);\r
+ const ComIPdu_type *IPdu = GET_IPdu(Signal->ComIPduHandleId);\r
\r
if (isPduBufferLocked(getPduId(IPdu))) {\r
return COM_BUSY;\r
\r
// Copy shadow buffer to Ipdu data space\r
const ComGroupSignal_type *groupSignal;\r
+ imask_t irq_state;\r
+\r
+ Irq_Save(irq_state);\r
for (uint8 i = 0; Signal->ComGroupSignal[i] != NULL; i++) {\r
groupSignal = Signal->ComGroupSignal[i];\r
- // TODO CopyData\r
- // Com_CopyData(Arc_IPdu->ComIPduDataPtr, Arc_Signal->Com_Arc_ShadowBuffer, groupSignal->ComBitSize, groupSignal->ComBitPosition, groupSignal->ComBitPosition);\r
- Com_WriteGroupSignalDataToPdu(Signal->ComHandleId, groupSignal->ComHandleId, Arc_Signal->Com_Arc_ShadowBuffer);\r
+\r
+ Com_WriteGroupSignalDataToPdu(Signal->ComHandleId, groupSignal->ComHandleId, Signal->Com_Arc_ShadowBuffer);\r
}\r
\r
// If the signal has an update bit. Set it!\r
if (Signal->ComSignalArcUseUpdateBit) {\r
- SETBIT(Arc_IPdu->ComIPduDataPtr, Signal->ComUpdateBitPosition);\r
+ SETBIT(IPdu->ComIPduDataPtr, Signal->ComUpdateBitPosition);\r
}\r
\r
- /*\r
- * If signal has triggered transmit property, trigger a transmission!\r
- */\r
+ // If signal has triggered transmit property, trigger a transmission!\r
if (Signal->ComTransferProperty == TRIGGERED) {\r
Arc_IPdu->Com_Arc_TxIPduTimers.ComTxIPduNumberOfRepetitionsLeft = IPdu->ComTxIPdu.ComTxModeTrue.ComTxModeNumberOfRepetitions + 1;\r
}\r
+ Irq_Restore(irq_state);\r
\r
return E_OK;\r
}\r
Std_ReturnType Com_ReceiveSignalGroup(Com_SignalGroupIdType SignalGroupId) {\r
//#warning Com_ReceiveSignalGroup should be performed atomically. Should we disable interrupts here?\r
const ComSignal_type * Signal = GET_Signal(SignalGroupId);\r
- Com_Arc_Signal_type * Arc_Signal = GET_ArcSignal(SignalGroupId);\r
- const ComIPdu_type *IPdu = GET_IPdu(Arc_Signal->ComIPduHandleId);\r
+ const ComIPdu_type *IPdu = GET_IPdu(Signal->ComIPduHandleId);\r
\r
if (isPduBufferLocked(getPduId(IPdu))) {\r
return COM_BUSY;\r
}\r
// Copy Ipdu data buffer to shadow buffer.\r
const ComGroupSignal_type *groupSignal;\r
+ imask_t irq_state;\r
+\r
+ Irq_Save(irq_state);\r
for (uint8 i = 0; Signal->ComGroupSignal[i] != NULL; i++) {\r
groupSignal = Signal->ComGroupSignal[i];\r
- // TODO: CopyData\r
- // Com_CopyData(Arc_Signal->Com_Arc_ShadowBuffer, Arc_IPdu->ComIPduDataPtr, groupSignal->ComBitSize, groupSignal->ComBitPosition, groupSignal->ComBitPosition);\r
- Com_ReadSignalDataFromPdu(groupSignal->ComHandleId, (void *)Arc_Signal->Com_Arc_ShadowBuffer);\r
- }\r
\r
+ Com_ReadSignalDataFromPdu(groupSignal->ComHandleId, (void *)Signal->Com_Arc_ShadowBuffer);\r
+ }\r
+ Irq_Restore(irq_state);\r
\r
return E_OK;\r
}\r
void Com_UpdateShadowSignal(Com_SignalIdType SignalId, const void *SignalDataPtr) {\r
Com_Arc_GroupSignal_type *Arc_GroupSignal = GET_ArcGroupSignal(SignalId);\r
\r
- // TODO: CopyData\r
- // Com_CopyData(Arc_GroupSignal->Com_Arc_ShadowBuffer, SignalDataPtr, GroupSignal->ComBitSize, GroupSignal->ComBitPosition, 0);\r
Com_WriteSignalDataToPduBuffer(SignalId, TRUE, SignalDataPtr, (void *)Arc_GroupSignal->Com_Arc_ShadowBuffer, 8);\r
}\r
\r
void Com_ReceiveShadowSignal(Com_SignalIdType SignalId, void *SignalDataPtr) {\r
Com_Arc_GroupSignal_type *Arc_GroupSignal = GET_ArcGroupSignal(SignalId);\r
- uint8 pduSize = GET_IPdu(GET_ArcSignal(SignalId)->ComIPduHandleId)->ComIPduSize;\r
- // TODO: CopyData\r
- // Com_CopyData(SignalDataPtr, Arc_GroupSignal->Com_Arc_ShadowBuffer, GroupSignal->ComBitSize, 0, GroupSignal->ComBitPosition);\r
+ uint8 pduSize = GET_IPdu(GET_Signal(SignalId)->ComIPduHandleId)->ComIPduSize;\r
+\r
Com_ReadSignalDataFromPduBuffer(SignalId, TRUE, SignalDataPtr, (void *)Arc_GroupSignal->Com_Arc_ShadowBuffer,pduSize);\r
}\r
\r
#include "Com_misc.h"\r
#include <string.h>\r
#include "debug.h"\r
+#include "Cpu.h"\r
\r
#define timerDec(timer) \\r
if (timer > 0) { \\r
\r
void Com_MainFunctionRx(void) {\r
//DEBUG(DEBUG_MEDIUM, "Com_MainFunctionRx() excecuting\n");\r
- const ComSignal_type *signal;\r
- for (uint16 i = 0; !ComConfig->ComSignal[i].Com_Arc_EOL; i++) {\r
- signal = &ComConfig->ComSignal[i];\r
- Com_Arc_Signal_type * Arc_Signal = GET_ArcSignal(signal->ComHandleId);\r
- Com_Arc_IPdu_type *Arc_IPdu = GET_ArcIPdu(Arc_Signal->ComIPduHandleId);\r
+ for (uint16 pduId = 0; !ComConfig->ComIPdu[pduId].Com_Arc_EOL; pduId++) {\r
+ boolean pduUpdated = false;\r
+ const ComIPdu_type *IPdu = GET_IPdu(pduId);\r
+ Com_Arc_IPdu_type *Arc_IPdu = GET_ArcIPdu(pduId);\r
+ imask_t irq_state;\r
+ Irq_Save(irq_state);\r
+ for (uint16 i = 0; (IPdu->ComIPduSignalRef != NULL) && (IPdu->ComIPduSignalRef[i] != NULL); i++) {\r
+ const ComSignal_type *signal = IPdu->ComIPduSignalRef[i];\r
+ Com_Arc_Signal_type * Arc_Signal = GET_ArcSignal(signal->ComHandleId);\r
+ // Monitor signal reception deadline\r
+ if ( (Arc_IPdu->Com_Arc_IpduStarted) && (signal->ComTimeoutFactor > 0) ) {\r
+\r
+ // Decrease deadline monitoring timer.\r
+ timerDec(Arc_Signal->Com_Arc_DeadlineCounter);\r
+\r
+ // Check if a timeout has occurred.\r
+ if (Arc_Signal->Com_Arc_DeadlineCounter == 0) {\r
+ if (signal->ComRxDataTimeoutAction == COM_TIMEOUT_DATA_ACTION_REPLACE) {\r
+ // Replace signal data.\r
+ Com_WriteSignalDataToPdu(signal->ComHandleId, signal->ComSignalInitValue);\r
\r
- // Monitor signal reception deadline\r
- if ( (Arc_IPdu->Com_Arc_IpduStarted) && (Arc_Signal->ComTimeoutFactor > 0) ) {\r
-\r
- // Decrease deadline monitoring timer.\r
- timerDec(Arc_Signal->Com_Arc_DeadlineCounter);\r
-\r
- // Check if a timeout has occurred.\r
- if (Arc_Signal->Com_Arc_DeadlineCounter == 0) {\r
- if (signal->ComRxDataTimeoutAction == COM_TIMEOUT_DATA_ACTION_REPLACE) {\r
- // Replace signal data.\r
- Com_WriteSignalDataToPdu(signal->ComHandleId, signal->ComSignalInitValue);\r
+ }\r
\r
- }\r
+ // A timeout has occurred.\r
+ if (signal->ComTimeoutNotification != NULL) {\r
+ signal->ComTimeoutNotification();\r
+ }\r
\r
- // A timeout has occurred.\r
- if (signal->ComTimeoutNotification != NULL) {\r
- signal->ComTimeoutNotification();\r
+ // Restart timer\r
+ Arc_Signal->Com_Arc_DeadlineCounter = signal->ComTimeoutFactor;\r
}\r
+ }\r
\r
- // Restart timer\r
- Arc_Signal->Com_Arc_DeadlineCounter = Arc_Signal->ComTimeoutFactor;\r
+ if (Arc_Signal->ComSignalUpdated) {\r
+ pduUpdated = true;\r
}\r
}\r
-\r
- if (Arc_Signal->ComSignalUpdated) {\r
- if (ComConfig->ComSignal[i].ComNotification != NULL) {\r
- ComConfig->ComSignal[i].ComNotification();\r
+ if (pduUpdated && IPdu->ComIPduSignalProcessing == DEFERRED && IPdu->ComIPduDirection == RECEIVE) {\r
+ UnlockTpBuffer(getPduId(IPdu));\r
+ memcpy(IPdu->ComIPduDeferredDataPtr,IPdu->ComIPduDataPtr,IPdu->ComIPduSize);\r
+ for (uint16 i = 0; (IPdu->ComIPduSignalRef != NULL) && (IPdu->ComIPduSignalRef[i] != NULL); i++) {\r
+ const ComSignal_type *signal = IPdu->ComIPduSignalRef[i];\r
+ Com_Arc_Signal_type * Arc_Signal = GET_ArcSignal(signal->ComHandleId);\r
+ if (Arc_Signal->ComSignalUpdated) {\r
+ if (signal->ComNotification != NULL) {\r
+ signal->ComNotification();\r
+ }\r
+ Arc_Signal->ComSignalUpdated = 0;\r
+ }\r
}\r
- Arc_Signal->ComSignalUpdated = 0;\r
}\r
+ Irq_Restore(irq_state);\r
}\r
}\r
\r
\r
void Com_MainFunctionTx(void) {\r
+ imask_t irq_state;\r
+\r
//DEBUG(DEBUG_MEDIUM, "Com_MainFunctionTx() excecuting\n");\r
// Decrease timers.\r
const ComIPdu_type *IPdu;\r
IPdu = &ComConfig->ComIPdu[i];\r
Com_Arc_IPdu_type *Arc_IPdu = GET_ArcIPdu(i);\r
\r
+ Irq_Save(irq_state);\r
+\r
// Is this a IPdu that should be transmitted?\r
if ( (IPdu->ComIPduDirection == SEND) && (Arc_IPdu->Com_Arc_IpduStarted) ) {\r
// Decrease minimum delay timer\r
// Don't send!\r
}\r
}\r
+\r
+ Irq_Restore(irq_state);\r
}\r
}\r
#include "debug.h"\r
#include "Cpu.h"\r
\r
+static void Com_ReadDataSegment(uint8 *dest, const uint8 *source, uint8 destByteLength,\r
+ Com_BitPositionType segmentStartBitOffset, uint8 segmentBitLength, boolean signedOutput);\r
+\r
+static void Com_WriteDataSegment(uint8 *pdu, uint8 *pduSignalMask, const uint8 *signalDataPtr, uint8 destByteLength,\r
+ Com_BitPositionType segmentStartBitOffset, uint8 segmentBitLength);\r
\r
void Com_ReadSignalDataFromPdu(\r
const Com_SignalIdType signalId,\r
\r
// Get PDU\r
const ComSignal_type * Signal = GET_Signal(signalId);\r
- Com_Arc_Signal_type * Arc_Signal = GET_ArcSignal(Signal->ComHandleId);\r
- Com_Arc_IPdu_type *Arc_IPdu = GET_ArcIPdu(Arc_Signal->ComIPduHandleId);\r
- uint8 pduSize = GET_IPdu(Arc_Signal->ComIPduHandleId)->ComIPduSize;\r
+ uint8 pduSize = GET_IPdu(Signal->ComIPduHandleId)->ComIPduSize;\r
// Get data\r
Com_ReadSignalDataFromPduBuffer(\r
signalId,\r
FALSE,\r
signalData,\r
- Arc_IPdu->ComIPduDataPtr,\r
+ GET_IPdu(Signal->ComIPduHandleId)->ComIPduDataPtr,\r
pduSize);\r
}\r
\r
\r
// Get PDU\r
const ComSignal_type * Signal = GET_Signal(parentSignalId);\r
- Com_Arc_Signal_type * Arc_Signal = GET_ArcSignal(Signal->ComHandleId);\r
- Com_Arc_IPdu_type *Arc_IPdu = GET_ArcIPdu(Arc_Signal->ComIPduHandleId);\r
- uint8 pduSize = GET_IPdu(Arc_Signal->ComIPduHandleId)->ComIPduSize;\r
+ uint8 pduSize = GET_IPdu(Signal->ComIPduHandleId)->ComIPduSize;\r
// Get data\r
Com_ReadSignalDataFromPduBuffer(\r
groupSignalId,\r
TRUE,\r
signalData,\r
- Arc_IPdu->ComIPduDataPtr,\r
+ GET_IPdu(Signal->ComIPduHandleId)->ComIPduDataPtr,\r
pduSize);\r
}\r
\r
uint8 signalDataBytesArray[8];\r
const uint8 *pduBufferBytes = (const uint8 *)pduBuffer + (bitPosition/8);\r
Com_BitPositionType startBitOffset = 0;\r
+ imask_t state;\r
+ Irq_Save(state);\r
\r
if (signalEndianess == COM_OPAQUE || signalType == UINT8_N) {\r
// Aligned opaque data -> straight copy\r
-\r
- //assert(bitPosition % 8 == 0);\r
- //assert(bitSize % 8 == 0);\r
memcpy(signalDataBytes, pduBufferBytes, destSize);\r
\r
} else {\r
assert(0);\r
}\r
}\r
+ Irq_Restore(state);\r
}\r
\r
\r
\r
// Get PDU\r
const ComSignal_type *Signal = GET_Signal(signalId);\r
- Com_Arc_Signal_type *Arc_Signal = GET_ArcSignal(Signal->ComHandleId);\r
- Com_Arc_IPdu_type *Arc_IPdu = GET_ArcIPdu(Arc_Signal->ComIPduHandleId);\r
- const ComIPdu_type *IPdu = GET_IPdu(Arc_Signal->ComIPduHandleId);\r
+ const ComIPdu_type *IPdu = GET_IPdu(Signal->ComIPduHandleId);\r
\r
// Get data\r
Com_WriteSignalDataToPduBuffer(\r
signalId,\r
FALSE,\r
signalData,\r
- Arc_IPdu->ComIPduDataPtr,\r
+ (void *)IPdu->ComIPduDataPtr,\r
IPdu->ComIPduSize);\r
}\r
\r
\r
// Get PDU\r
const ComSignal_type *Signal = GET_Signal(parentSignalId);\r
- Com_Arc_Signal_type *Arc_Signal = GET_ArcSignal(Signal->ComHandleId);\r
- Com_Arc_IPdu_type *Arc_IPdu = GET_ArcIPdu(Arc_Signal->ComIPduHandleId);\r
- const ComIPdu_type *IPdu = GET_IPdu(Arc_Signal->ComIPduHandleId);\r
+ const ComIPdu_type *IPdu = GET_IPdu(Signal->ComIPduHandleId);\r
\r
// Get data\r
Com_WriteSignalDataToPduBuffer(\r
groupSignalId,\r
TRUE,\r
signalData,\r
- Arc_IPdu->ComIPduDataPtr,\r
+ (void *)IPdu->ComIPduDataPtr,\r
IPdu->ComIPduSize);\r
}\r
\r
\r
uint8 signalDataBytesArray[8] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};\r
const uint8 *signalDataBytes = (const uint8 *)signalData;\r
+ imask_t irq_state;\r
+\r
+ Irq_Save(irq_state);\r
if (endian == COM_OPAQUE || signalType == UINT8_N) {\r
//assert(bitPosition % 8 == 0);\r
//assert(bitSize % 8 == 0);\r
// Straight copy into real pdu buffer (with mutex)\r
uint8 *pduBufferBytes = ((uint8 *)pduBuffer)+(bitPosition/8);\r
uint8 i;\r
- imask_t irq_state;\r
- Irq_Save(irq_state);\r
for (i = 0; i < 8; i++) {\r
pduBufferBytes[ i ] &= ~( pduSignalMask[ i ] );\r
pduBufferBytes[ i ] |= pduBufferBytesStraight[ i ];\r
}\r
- Irq_Restore(irq_state);\r
\r
} else {\r
uint8 startBitOffset = intelBitNrToPduOffset(bitPosition%8, bitSize, 64);\r
// Swapped copy into real pdu buffer (with mutex)\r
uint8 *pduBufferBytes = ((uint8 *)pduBuffer)+(bitPosition/8);\r
uint8 i;\r
- imask_t irq_state;\r
- Irq_Save(irq_state);\r
// actually it is only necessary to iterate through the bytes that are written.\r
for (i = 0; i < 8; i++) {\r
pduBufferBytes[ i ] &= ~( pduSignalMask[ (8 - 1) - i ] );\r
pduBufferBytes[ i ] |= pduBufferBytesSwapped[ (8 - 1) - i ];\r
}\r
- Irq_Restore(irq_state);\r
}\r
}\r
+ Irq_Restore(irq_state);\r
}\r
\r
\r
* | -------- | -------A | BCDEFGHI | JKLMNOPQ |\r
*\r
*/\r
-void Com_ReadDataSegment(uint8 *dest, const uint8 *source, uint8 destByteLength,\r
+static void Com_ReadDataSegment(uint8 *dest, const uint8 *source, uint8 destByteLength,\r
Com_BitPositionType segmentStartBitOffset, uint8 segmentBitLength, boolean signedOutput) {\r
\r
Com_BitPositionType sourceEndBitOffset = segmentStartBitOffset + segmentBitLength - 1;\r
\r
// If this signal uses an update bit, then it is only considered if this bit is set.\r
if ( (!comSignal->ComSignalArcUseUpdateBit) ||\r
- ( (comSignal->ComSignalArcUseUpdateBit) && (TESTBIT(Arc_IPdu->ComIPduDataPtr, comSignal->ComUpdateBitPosition)) ) ) {\r
+ ( (comSignal->ComSignalArcUseUpdateBit) && (TESTBIT(IPdu->ComIPduDataPtr, comSignal->ComUpdateBitPosition)) ) ) {\r
\r
if (comSignal->ComTimeoutFactor > 0) { // If reception deadline monitoring is used.\r
// Reset the deadline monitoring timer.\r
\r
//void Com_CopyData2(char *dest, const char *source, uint8 destByteLength, uint8 segmentStartBitOffset, uint8 segmentBitLength);\r
\r
-void Com_ReadDataSegment(uint8 *dest, const uint8 *source, uint8 destByteLength,\r
- Com_BitPositionType segmentStartBitOffset, uint8 segmentBitLength, boolean signedOutput);\r
-\r
-void Com_WriteDataSegment(uint8 *pdu, uint8 *pduSignalMask, const uint8 *signalDataPtr, uint8 destByteLength,\r
- Com_BitPositionType segmentStartBitOffset, uint8 segmentBitLength);\r
-\r
Com_BitPositionType motorolaBitNrToPduOffset (Com_BitPositionType motorolaBitNr);\r
Com_BitPositionType intelBitNrToPduOffset (Com_BitPositionType intelBitNr, Com_BitPositionType segmentBitLength, Com_BitPositionType pduBitLength);\r
void Com_RxProcessSignals(const ComIPdu_type *IPdu,Com_Arc_IPdu_type *Arc_IPdu);\r
if (globalState.State == J1939TP_ON) {\r
const J1939Tp_RxPduInfoRelationsType* RxPduRelationsInfo = 0;\r
if (J1939Tp_Internal_GetRxPduRelationsInfo(RxPdu, &RxPduRelationsInfo) == E_OK) {\r
+ imask_t state;\r
+ Irq_Save(state);\r
for (PduIdType i = 0; i < RxPduRelationsInfo->RxPduCount; i++) {\r
const J1939Tp_RxPduInfoType* RxPduInfo = RxPduRelationsInfo->RxPdus[i];\r
const J1939Tp_ChannelType* Channel = J1939Tp_Internal_GetChannel(RxPduInfo);\r
J1939Tp_Internal_ChannelInfoType* ChannelInfoPtr = J1939Tp_Internal_GetChannelState(RxPduInfo);\r
- imask_t state;\r
- Irq_Save(state);\r
switch (Channel->Direction) {\r
case J1939TP_TX:\r
J1939Tp_Internal_TxConfirmation_TxChannel(ChannelInfoPtr, RxPduInfo);\r
default:\r
break;\r
}\r
- Irq_Restore(state);\r
}\r
+ Irq_Restore(state);\r
}\r
}\r
}\r
}\r
static inline void J1939Tp_Internal_RxIndication_Cm(PduInfoType* PduInfoPtr, J1939Tp_Internal_ChannelInfoType* ChannelInfoPtr) {\r
const J1939Tp_PgType* pg = 0;\r
+ if (ChannelInfoPtr->RxState->State != J1939TP_RX_IDLE) {\r
+ return;\r
+ }\r
J1939Tp_PgnType pgn = J1939Tp_Internal_GetPgn(&(PduInfoPtr->SduDataPtr[CM_PGN_BYTE_1]));\r
if (J1939Tp_Internal_GetPgFromPgn(ChannelInfoPtr->ChannelConfPtr,pgn,&pg) != E_OK) {\r
return;\r
ChannelInfoPtr->RxState->DtToReceiveCount = PduInfoPtr->SduDataPtr[BAM_RTS_BYTE_NUM_PACKETS];\r
ChannelInfoPtr->RxState->TotalMessageSize = messageSize;\r
ChannelInfoPtr->RxState->CurrentPgPtr = pg;\r
- if (Command == RTS_CONTROL_VALUE) {\r
+ J1939Tp_ProtocolType channelProtocol = ChannelInfoPtr->ChannelConfPtr->Protocol;\r
+ if (Command == RTS_CONTROL_VALUE && channelProtocol == J1939TP_PROTOCOL_CMDT) {\r
PduLengthType remainingBuffer = 0;\r
if (PduR_J1939TpStartOfReception(pg->NSdu, messageSize, &remainingBuffer) == BUFREQ_OK) {\r
ChannelInfoPtr->RxState->State = J1939TP_RX_WAIT_CTS_CANIF_CONFIRM;\r
} else {\r
J1939Tp_Internal_SendConnectionAbort(pg->Channel->CmNPdu,pgn);\r
}\r
- } else if (Command == BAM_CONTROL_VALUE) {\r
+ } else if (Command == BAM_CONTROL_VALUE && channelProtocol == J1939TP_PROTOCOL_BAM) {\r
PduLengthType remainingBuffer = 0;\r
if (PduR_J1939TpStartOfReception(pg->NSdu, messageSize, &remainingBuffer) == BUFREQ_OK) {\r
J1939Tp_Internal_StartTimer(&(ChannelInfoPtr->RxState->TimerInfo),J1939TP_T2_TIMEOUT_MS);\r
ChannelInfoPtr->TxState->CurrentPgPtr = Pg;\r
ChannelInfoPtr->TxState->SentDtCount = 0;\r
J1939Tp_Internal_StartTimer(&(ChannelInfoPtr->TxState->TimerInfo),J1939TP_TX_CONF_TIMEOUT);\r
- J1939Tp_Internal_SendBam(ChannelInfoPtr,TxInfoPtr);\r
+ r = J1939Tp_Internal_SendBam(ChannelInfoPtr,TxInfoPtr);\r
break;\r
case J1939TP_PROTOCOL_CMDT:\r
ChannelInfoPtr->TxState->State = J1939TP_TX_WAIT_RTS_CANIF_CONFIRM;\r
ChannelInfoPtr->TxState->PduRPdu = TxSduId;\r
ChannelInfoPtr->TxState->CurrentPgPtr = Pg;\r
ChannelInfoPtr->TxState->SentDtCount = 0;\r
- J1939Tp_Internal_SendRts(ChannelInfoPtr,TxInfoPtr);\r
+ r = J1939Tp_Internal_SendRts(ChannelInfoPtr,TxInfoPtr);\r
J1939Tp_Internal_StartTimer(&(ChannelInfoPtr->TxState->TimerInfo),J1939TP_TX_CONF_TIMEOUT);\r
break;\r
}\r
}\r
\r
\r
-static inline void J1939Tp_Internal_SendBam(J1939Tp_Internal_ChannelInfoType* ChannelInfoPtr,const PduInfoType* TxInfoPtr) {\r
+static inline Std_ReturnType J1939Tp_Internal_SendBam(J1939Tp_Internal_ChannelInfoType* ChannelInfoPtr,const PduInfoType* TxInfoPtr) {\r
+ Std_ReturnType r;\r
uint8 cmBamData[BAM_RTS_SIZE];\r
cmBamData[BAM_RTS_BYTE_CONTROL] = BAM_CONTROL_VALUE;\r
cmBamData[BAM_RTS_BYTE_LENGTH_1] = (uint8)(TxInfoPtr->SduLength & 0x00FF);\r
cmBamPdu.SduLength = BAM_RTS_SIZE;\r
cmBamPdu.SduDataPtr = cmBamData;\r
\r
- CanIf_Transmit(ChannelInfoPtr->ChannelConfPtr->CmNPdu,&cmBamPdu);\r
+ r = CanIf_Transmit(ChannelInfoPtr->ChannelConfPtr->CmNPdu,&cmBamPdu);\r
+ return r;\r
}\r
static inline uint16 J1939Tp_Internal_GetRtsMessageSize(PduInfoType* pduInfo) {\r
return (((uint16)pduInfo->SduDataPtr[BAM_RTS_BYTE_LENGTH_2]) << 8) | pduInfo->SduDataPtr[BAM_RTS_BYTE_LENGTH_1];\r
\r
}\r
\r
-static inline void J1939Tp_Internal_SendRts(J1939Tp_Internal_ChannelInfoType* ChannelInfoPtr, const PduInfoType* TxInfoPtr) {\r
+static inline Std_ReturnType J1939Tp_Internal_SendRts(J1939Tp_Internal_ChannelInfoType* ChannelInfoPtr, const PduInfoType* TxInfoPtr) {\r
uint8 cmRtsData[BAM_RTS_SIZE];\r
cmRtsData[BAM_RTS_BYTE_CONTROL] = 16;\r
cmRtsData[BAM_RTS_BYTE_LENGTH_1] = (uint8)(TxInfoPtr->SduLength);\r
PduInfoType cmRtsPdu;\r
cmRtsPdu.SduLength = BAM_RTS_SIZE;\r
cmRtsPdu.SduDataPtr = cmRtsData;\r
-\r
- CanIf_Transmit(ChannelInfoPtr->ChannelConfPtr->CmNPdu,&cmRtsPdu);\r
+ Std_ReturnType r;\r
+ r = CanIf_Transmit(ChannelInfoPtr->ChannelConfPtr->CmNPdu,&cmRtsPdu);\r
+ return r;\r
}\r
\r
static inline void J1939Tp_Internal_SendEndOfMsgAck(J1939Tp_Internal_ChannelInfoType* ChannelInfoPtr) {\r
static inline J1939Tp_Internal_TimerStatusType J1939Tp_Internal_IncAndCheckTimer(J1939Tp_Internal_TimerType* TimerInfo);\r
static inline uint8 J1939Tp_Internal_GetDtDataSize(uint8 currentSeqNum, uint8 totalSize);\r
\r
-static inline void J1939Tp_Internal_SendBam(J1939Tp_Internal_ChannelInfoType* ChannelInfoPtr,const PduInfoType* TxInfoPtr);\r
+static inline Std_ReturnType J1939Tp_Internal_SendBam(J1939Tp_Internal_ChannelInfoType* ChannelInfoPtr,const PduInfoType* TxInfoPtr);\r
static inline Std_ReturnType J1939Tp_Internal_SendDt(J1939Tp_Internal_ChannelInfoType* Channel);\r
-static inline void J1939Tp_Internal_SendRts(J1939Tp_Internal_ChannelInfoType* ChannelInfoPtr, const PduInfoType* TxInfoPtr);\r
+static inline Std_ReturnType J1939Tp_Internal_SendRts(J1939Tp_Internal_ChannelInfoType* ChannelInfoPtr, const PduInfoType* TxInfoPtr);\r
static inline void J1939Tp_Internal_SendEndOfMsgAck(J1939Tp_Internal_ChannelInfoType* Channel);\r
static inline void J1939Tp_Internal_SendCts(J1939Tp_Internal_ChannelInfoType* ChannelInfoPtr, J1939Tp_PgnType Pgn, uint8 NextPacketSeqNum,uint8 NumPackets);\r
static inline void J1939Tp_Internal_SendConnectionAbort(PduIdType CmNPdu, J1939Tp_PgnType Pgn);\r
extern ComSignalEndianess_type Com_SystemEndianness;\r
\r
#define COM_BUSY 0x81\r
-\r
+#define COM_SERVICE_NOT_AVAILABLE 0x80\r
#endif /*COM_H_*/\r
\r
uint8 Com_SendSignal(Com_SignalIdType SignalId, const void *SignalDataPtr);\r
uint8 Com_ReceiveSignal(Com_SignalIdType SignalId, void* SignalDataPtr);\r
+uint8 Com_ReceiveDynSignal(Com_SignalIdType SignalId, void* SignalDataPtr, uint16* Length);\r
+uint8 Com_SendDynSignal(Com_SignalIdType SignalId, const void* SignalDataPtr, uint16 Length);\r
\r
Std_ReturnType Com_TriggerTransmit(PduIdType ComTxPduId, PduInfoType *PduInfoPtr);\r
\r
UINT16,\r
UINT32,\r
UINT8_N,\r
+ UINT8_DYN,\r
SINT8,\r
SINT16,\r
SINT32\r
const ComGroupSignal_type * const *ComGroupSignal;\r
\r
\r
- //void *Com_Arc_ShadowBuffer;\r
+ const void *Com_Arc_ShadowBuffer;\r
//void *Com_Arc_IPduDataPtr;\r
\r
/* Pointer to the data storage of this signals IPDU.\r
* This is initialized by Com_Init() and should not be configured.\r
*/\r
\r
- //const uint8 ComIPduHandleId;\r
+ const uint16 ComIPduHandleId;\r
//const uint8 ComSignalUpdated;\r
\r
/* Callback function used when an invalid signal is received.\r
/** Container of transmission related parameters. */\r
const ComTxIPdu_type ComTxIPdu;\r
\r
+ /** Reference to the actual pdu data storage */\r
+ void *const ComIPduDataPtr;\r
+ void *const ComIPduDeferredDataPtr;\r
+\r
/** References to all signals and signal groups contained in this IPDU.\r
* It probably makes little sense not to define at least one signal or signal group for each IPDU.\r
*/\r
const ComSignal_type * const *ComIPduSignalRef;\r
\r
+ const ComSignal_type * const ComIPduDynSignalRef;\r
+\r
/*\r
* The following two variables are used to control the per I-PDU based Rx/Tx-deadline monitoring.\r
*/\r
\r
#endif\r
\r
+#define SPI_SIMPLE 0 /* Not implemented, NOT TESTED */\r
+#define SPI_FIFO 1\r
+#define SPI_DMA 2\r
\r
#define SPI_EB_MAX_LENGTH 64\r
\r
// ArcCore extension...\r
// The controller ID(0..3)\r
//uint32 SpiControllerId;\r
+ void (*SpiCsCallback)(int);\r
\r
} Spi_ExternalDeviceType;\r
\r
#if OS_ISR_CNT != 0\r
return &Os_IsrVarList[id];\r
#else\r
+ (void)id;\r
return NULL;\r
#endif\r
}\r
%.s: %.sx\r
@echo\r
@echo " >> CPP $(notdir $<)"\r
- $(Q)$(CPP) $(CPP_ASM_FLAGS) -o $@ $(addprefix -I,$(inc-y)) $(addprefix -D,$(def-y)) $<\r
+ $(Q)$(CPP) $(CPP_ASM_FLAGS) $(CPPOUT) $@ $(addprefix -I,$(inc-y)) $(addprefix -D,$(def-y)) $<\r
\r
# Board linker files are in the board directory \r
inc-y += $(ROOTDIR)/boards/$(BOARDDIR)\r