* - 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
+#define SPIE_JOB_NOT_DONE 1\r
\r
#define IMPL_SIMPLE 0 /* Not implemented, NOT TESTED */\r
-#define IMPL_FIFO 1 /* Partly implemented, NOT TESTED */\r
+#define IMPL_FIFO 1\r
#define IMPL_DMA 2\r
\r
-#define SPI_IMPLEMENTATION IMPL_DMA\r
+#define SPI_IMPLEMENTATION IMPL_FIFO\r
+#define USE_DIO_CS STD_OFF\r
\r
// E2 read = cmd + addr + data = 1 + 2 + 64 ) = 67 ~ 72\r
#define SPI_INTERNAL_MTU 72\r
\r
//#define USE_LOCAL_RAMLOG\r
\r
+\r
+\r
#if defined(USE_LOCAL_RAMLOG)\r
#define RAMLOG_STR(_x) ramlog_str(_x)\r
#define RAMLOG_DEC(_x) ramlog_dec(_x)\r
} Spi_EbType;\r
\r
typedef enum {\r
- SPI_ASYNC, SPI_SYNC,\r
+ SPI_ASYNC_CALL, SPI_SYNC_CALL,\r
} Spi_CallTypeType;\r
\r
typedef struct {\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
} Spi_UnitType;\r
\r
const Spi_ChannelType *channelsPtr;\r
\r
-#if (SPI_IMPLEMENTATION == SPI_FIFO )\r
+#if (SPI_IMPLEMENTATION == IMPL_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
\r
/* the currently receiving channel index for FIFO */\r
uint32_t currRxChIndex;\r
+\r
#endif\r
\r
Spi_JobResultType jobResult;\r
\r
Spi_GlobalType Spi_Global;\r
\r
-Spi_UnitType Spi_Unit[4];\r
+Spi_UnitType Spi_Unit[4]; // TODO:?\r
Spi_SeqUnitType Spi_SeqUnit[SPI_MAX_SEQUENCE];\r
Spi_JobUnitType Spi_JobUnit[SPI_MAX_JOB];\r
\r
\r
/* ----------------------------[private functions]---------------------------*/\r
\r
+\r
#if (SPI_IMPLEMENTATION == IMPL_FIFO )\r
+\r
+static void Spi_WriteJob_FIFO( Spi_JobType jobIndex );\r
+\r
+\r
/**\r
* Get the buffer for a channel.\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
\r
\r
#elif (SPI_IMPLEMENTATION==IMPL_FIFO)\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
+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
\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( jobUnitPtr->fifoSent, bufLen - jobUnitPtr->rxChCnt );\r
+ copyCnt = MIN( (bufLen - jobUnitPtr->rxChCnt) >> ((chConfig->SpiDataWidth-1)/8), jobUnitPtr->fifoSent );\r
\r
+ if( copyCnt == 0 ) {\r
+ while(1);\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
}\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
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
#if (SPI_IMPLEMENTATION==IMPL_DMA)\r
rv = Spi_PostTransmit_DMA(spiUnit);\r
#elif (SPI_IMPLEMENTATION==IMPL_FIFO)\r
- rv = Spi_PostTransmit_FIFO(spiUnit);\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
+ Spi_JobUnit[spiUnit->currJobIndex].extDeviceCfgPtr->SpiCsCallback(1);\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
+ while(1);\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
spiHw->MCR.B.PCSSE = 0;\r
\r
/* Enable FIFO's. */\r
+#if (SPI_IMPLEMENTATION == IMPL_DMA)\r
spiHw->MCR.B.DIS_RXF = 1;\r
spiHw->MCR.B.DIS_TXF = 1;\r
+#elif (SPI_IMPLEMENTATION == IMPL_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
\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
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
* @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
- jobUnitPtr->fifoSent = 0;\r
+\r
+ fifoLeft = FIFO_DEPTH;\r
+\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
unitPtr->txCurrIndex = 0;\r
unitPtr->currJob = Spi_JobUnit[jobIndex].jobCfgPtr;\r
unitPtr->currJobIndex = jobIndex;\r
+#if (SPI_IMPLEMENTATION == IMPL_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
Spi_DoWrite_DMA( unitPtr, jobIndex, Spi_JobUnit[jobIndex].jobCfgPtr );\r
#elif (SPI_IMPLEMENTATION==IMPL_FIFO)\r
Spi_JobUnit[jobIndex].currTxChIndex = 0;\r
- Spi_DoWrite_FIFO ( jobIndex );\r
+#if (USE_DIO_CS == STD_ON)\r
+ Spi_JobUnit[jobIndex].extDeviceCfgPtr->SpiCsCallback(0);\r
+#endif\r
+ Spi_WriteJob_FIFO ( jobIndex );\r
#endif\r
\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