summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: 0f43eca)
raw | patch | inline | side by side (parent: 0f43eca)
author | Prasad Konnur <prasadkonnur@ti.com> | |
Fri, 23 Apr 2021 14:44:01 +0000 (20:14 +0530) | ||
committer | Sujith Shivalingappa <sujith.s@ti.com> | |
Thu, 29 Apr 2021 09:10:27 +0000 (04:10 -0500) |
- Added callback mode
- Updated example to test callback mode
Signed-off-by: Prasad Konnur <prasadkonnur@ti.com>
- Updated example to test callback mode
Signed-off-by: Prasad Konnur <prasadkonnur@ti.com>
index 93f72035ea23c35905de0f77c7e3791e701f0c65..1cd9bea58b31184d97656570f0ecba5a2d265ed0 100644 (file)
}
}
+ /* Validate transfer mode. */
+ if(params->transferMode == MIBSPI_MODE_CALLBACK)
+ {
+ if(params->transferCallbackFxn == NULL)
+ {
+ retVal = MIBSPI_STATUS_ERROR;
+ goto Exit;
+ }
+ }
+
/* Validate DMA driver handle */
if(params->dmaEnable == (uint8_t)1U)
{
retVal = MIBSPI_STATUS_ERROR;
}
}
+
Exit:
return retVal;
}
@@ -2065,6 +2076,9 @@ static void MIBSPI_initTransactionState(Mibspi_transactionState_t *transactionSt
transactionState->transferErr = MIBSPI_XFER_ERR_NONE;
transactionState->transaction = transaction;
transactionState->transaction->status = MIBSPI_TRANSFER_STARTED;
+ transactionState->remainSize = 0U;
+ transactionState->dataLength = 0U;
+ transactionState->dataSizeInBytes = 0U;
HwiP_restore(key);
}
@@ -2078,6 +2092,9 @@ static void MIBSPI_resetTransactionState(Mibspi_transactionState_t *transactionS
transactionState->edmaCbCheck = MIBSPI_NONE_EDMA_CALLBACK_OCCURED;
transactionState->transferErr = MIBSPI_XFER_ERR_NONE;
transactionState->transaction = NULL;
+ transactionState->remainSize = 0U;
+ transactionState->dataLength = 0U;
+ transactionState->dataSizeInBytes = 0U;
HwiP_restore(key);
}
@@ -2203,6 +2220,15 @@ bool MIBSPI_transferCore(MIBSPI_Handle handle, MIBSPI_Transaction *transaction)
dataLength -= remainSize;
}
+ if (ptrMibSpiDriver->params.transferMode == MIBSPI_MODE_CALLBACK)
+ {
+ /* Tell ISR function how much data there is remaining after this transfer
+ * (if remainSize > 0 then this is the first of two transfers) */
+ ptrMibSpiDriver->transactionState.remainSize = remainSize;
+ ptrMibSpiDriver->transactionState.dataLength = dataLength;
+ ptrMibSpiDriver->transactionState.dataSizeInBytes = dataSizeInBytes;
+ }
+
if(ptrMibSpiDriver->params.mode == MIBSPI_SLAVE)
{
MIBSPI_dataTransfer(ptrMibSpiDriver, (uint8_t *)transaction->txBuf, (uint8_t *)transaction->rxBuf, dataLength, MIBSPI_SLAVEMODE_TRANS_GROUP);
@@ -2231,10 +2257,9 @@ bool MIBSPI_transferCore(MIBSPI_Handle handle, MIBSPI_Transaction *transaction)
}
else
{
- /* Execution should not reach here */
- transaction->status = MIBSPI_TRANSFER_FAILED;
- ret = false;
- remainSize = 0;
+ /* Return success status if non-blocking mode */
+ ret = true;
+ return ret;
}
/* Check if transfer finished */
{
/* Call the transfer completion callback function */
if ((ptrMibSpiDriver->transactionState.transaction->status == MIBSPI_TRANSFER_STARTED) &&
+ (ptrMibSpiDriver->transactionState.transferErr == MIBSPI_XFER_ERR_NONE) &&
+ (ptrMibSpiDriver->transactionState.remainSize > 0U))
+ {
+ /* Change buffer pointer and data size for the second transfer */
+ ptrMibSpiDriver->transactionState.transaction->txBuf = (void *)((ptrMibSpiDriver->transactionState.transaction->txBuf == NULL) ?
+ NULL : (uint8_t *)ptrMibSpiDriver->transactionState.transaction->txBuf +
+ ptrMibSpiDriver->transactionState.dataLength * (ptrMibSpiDriver->transactionState.dataSizeInBytes));
+ ptrMibSpiDriver->transactionState.transaction->rxBuf = (void *)((ptrMibSpiDriver->transactionState.transaction->rxBuf == NULL) ?
+ NULL : (uint8_t *)ptrMibSpiDriver->transactionState.transaction->rxBuf +
+ ptrMibSpiDriver->transactionState.dataLength * (ptrMibSpiDriver->transactionState.dataSizeInBytes));
+ ptrMibSpiDriver->transactionState.dataLength = ptrMibSpiDriver->transactionState.remainSize;
+ ptrMibSpiDriver->transactionState.remainSize = 0U;
+
+ /* Transfer the remaining size */
+ if(ptrMibSpiDriver->params.mode == MIBSPI_SLAVE)
+ {
+ MIBSPI_dataTransfer(ptrMibSpiDriver, (uint8_t *)ptrMibSpiDriver->transactionState.transaction->txBuf,
+ (uint8_t *)ptrMibSpiDriver->transactionState.transaction->rxBuf, ptrMibSpiDriver->transactionState.dataLength, MIBSPI_SLAVEMODE_TRANS_GROUP);
+ }
+ else
+ {
+ MIBSPI_dataTransfer(ptrMibSpiDriver, (uint8_t *)ptrMibSpiDriver->transactionState.transaction->txBuf,
+ (uint8_t *)ptrMibSpiDriver->transactionState.transaction->rxBuf, ptrMibSpiDriver->transactionState.dataLength, ptrMibSpiDriver->transactionState.transaction->slaveIndex);
+ }
+ }
+ else if ((ptrMibSpiDriver->transactionState.transaction->status == MIBSPI_TRANSFER_STARTED) &&
(ptrMibSpiDriver->transactionState.transferErr == MIBSPI_XFER_ERR_NONE))
{
+ /* Update status*/
ptrMibSpiDriver->transactionState.transaction->status = MIBSPI_TRANSFER_COMPLETED;
}
else
{
+ /* Update status */
ptrMibSpiDriver->transactionState.transaction->status = MIBSPI_TRANSFER_FAILED;
}
- ptrMibSpiDriver->params.transferCallbackFxn(mibspiHandle, ptrMibSpiDriver->transactionState.transaction);
- MIBSPI_resetTransactionState(&ptrMibSpiDriver->transactionState);
+ if ((ptrMibSpiDriver->transactionState.transaction->status == MIBSPI_TRANSFER_COMPLETED) ||
+ (ptrMibSpiDriver->transactionState.transaction->status == MIBSPI_TRANSFER_FAILED))
+ {
+ /* Call transferCallbackFxn */
+ ptrMibSpiDriver->params.transferCallbackFxn(mibspiHandle, ptrMibSpiDriver->transactionState.transaction);
+
+ /* Disable transfer group */
+ MIBSPI_transferGroupDisable((ptrMibSpiDriver->ptrHwCfg->ptrSpiRegBase), ptrMibSpiDriver->transactionState.transaction->slaveIndex);
+
+ /* Reset transaction state */
+ MIBSPI_resetTransactionState(&ptrMibSpiDriver->transactionState);
+ }
}
}
}
index 3f9ea044243e17b8e94e29ae6dbc9ad004a0e622..7733c4c955058a30fca422a87d95450650c2bac2 100644 (file)
enum MibSpi_xferErr_e transferErr;
MIBSPI_Transaction *transaction;
+
+ volatile uint16_t remainSize;
+ volatile uint16_t dataLength;
+ volatile uint16_t dataSizeInBytes;
} Mibspi_transactionState_t;
diff --git a/packages/ti/drv/mibspi/test/loopback/src/main_mibspi_test.c b/packages/ti/drv/mibspi/test/loopback/src/main_mibspi_test.c
index cfed9e6551d2d50c745e755704e9e28676461f04..a57eb70caf776342043cbbc39dc4e2a1a0ef1d29 100644 (file)
Test_loopback_oneInstance(1U, 2U);
MIBSPI_log("Debug: Loopback test finished!\n");
+#ifdef MIBSPI_DMA_ENABLE
+ /* MibSPIA loopback test , MibSPIA only supports one slave */
+ Test_loopback_oneInstance_callback(0U, 0U);
+ MIBSPI_log("Debug: Loopback test in callback mode finished!\n");
+#endif
}
diff --git a/packages/ti/drv/mibspi/test/loopback/src/mibspi_test_common.c b/packages/ti/drv/mibspi/test/loopback/src/mibspi_test_common.c
index 037a4342cd2f8cfa12bcb0db25fa48506dc37b1d..d120c5f51106797f71d238968f0aa29212832937 100644 (file)
#include <ti/drv/edma/edma.h>
#include <ti/osal/HwiP.h>
-
#include "mibspi_test_common.h"
/**************************************************************************
@@ -296,6 +295,13 @@ static int32_t Test_spiWrite(const MIBSPI_Handle handle, uint32_t dataLen, void*
return 0;
}
+/* Test_spiReadWrite is called for the callback mode test also.
+ * So keep the MIBSPI_Transaction object persistant till the transfer is complete.
+ * So use the global variable insted of using the local variable
+ * which is initialized in stack.
+ */
+static MIBSPI_Transaction gTransactionRdWr;
+
/**
* @b Description
* @n
@@ -312,16 +318,14 @@ static int32_t Test_spiWrite(const MIBSPI_Handle handle, uint32_t dataLen, void*
*/
static int32_t Test_spiReadWrite(const MIBSPI_Handle handle, uint32_t dataLen, void* inBuffer, void* outBuffer, uint8_t slaveIndex)
{
- MIBSPI_Transaction transaction;
-
/* Configure Data Transfer */
- transaction.count = dataLen;
- transaction.txBuf = outBuffer;
- transaction.rxBuf = inBuffer;
- transaction.slaveIndex = slaveIndex;
+ gTransactionRdWr.count = dataLen;
+ gTransactionRdWr.txBuf = outBuffer;
+ gTransactionRdWr.rxBuf = inBuffer;
+ gTransactionRdWr.slaveIndex = slaveIndex;
/* Start Data Transfer */
- if (MIBSPI_transfer(handle, &transaction) != true)
+ if (MIBSPI_transfer(handle, &gTransactionRdWr) != true)
{
return -1;
}
@@ -399,6 +403,93 @@ static int32_t Test_spiLoopback(const MIBSPI_Handle handle, uint8_t slaveIndex,
return failed;
}
+#ifdef MIBSPI_DMA_ENABLE
+uint32_t gTestCallbackDone = 0;
+
+void Test_loopback_callbackFxn (MIBSPI_Handle handle,
+ MIBSPI_Transaction * transaction)
+{
+ gTestCallbackDone = 1;
+}
+
+/**
+ * @b Description
+ * @n
+ * This function tests SPI driver in Digital Loopback mode.
+ *
+ * @param[in] handle SPI driver handle
+ * @param[in] slaveIndex Flag for internal/external loopback
+ * @param[in] maxElem Maxim data element
+ * @param[in] dataSize Data size in number of bytes
+ *
+ * @retval Successful =0
+ * Number of transfer failures >0
+ * API failures <0
+ */
+static int32_t Test_spiLoopback_callback(const MIBSPI_Handle handle, uint8_t slaveIndex, uint32_t maxElem, uint8_t dataSize)
+{
+ MibSpi_LoopBackType loopback;
+ uint32_t loop;
+ uint32_t idx;
+ uint32_t failed = 0;
+ uint32_t len=0;
+
+ /* Only dataSize of 1 byte or 2 bytes are supported */
+ if ((dataSize != (uint8_t)1U) && (dataSize != (uint8_t)2U))
+ return -1;
+
+ /* Enable digital loopback */
+ loopback = MIBSPI_LOOPBK_DIGITAL;
+ if(MIBSPI_control(handle, MIBSPI_CMD_LOOPBACK_ENABLE, (void *)&loopback) < 0)
+ return -1;
+ for(loop=0; loop < maxElem; loop++)
+ {
+ len = (maxElem - loop) * dataSize;
+
+ /* Prepare Tx/Rx Buffer */
+ for(idx=0; idx<maxElem * dataSize; idx++)
+ {
+ txBuf[idx] = (loop * 0x10 + 0x55 + idx) & 0xFF;
+ }
+
+ /* Clear receive buffer */
+ memset((void *)&rxBuf[0], 0x0, SPI_DATA_BLOCK_SIZE);
+
+ CacheP_wbInv((Ptr)txBuf, sizeof(txBuf));
+ CacheP_wbInv((Ptr)rxBuf, sizeof(rxBuf));
+ gTestCallbackDone = 0;
+ if(Test_spiReadWrite(handle, len, (void *)rxBuf, (void *)txBuf, slaveIndex) == 0)
+ {
+ /* Wait for the callback function. */
+ while (gTestCallbackDone == 0)
+ {
+ /* waiting for the callback funciton to be called. */
+ }
+ /* Check data integrity */
+ if (memcmp((void *)txBuf, (void *)rxBuf, len) != 0)
+ {
+ MIBSPI_log("Error: MIBSPI_transfer is successful with incorrect data(0x%x), length = %d\n", rxBuf[0], len);
+ failed++;
+ }
+ }
+ else
+ {
+ MIBSPI_log("Debug: MIBSPI_transfer failed for length = %d\n", len);
+ failed++;
+ }
+ }
+ MIBSPI_log("Debug: Finished Digital loopback with various length test, failed %d out of %d times\n", failed, loop);
+
+ /* Disable digital loopback */
+ loopback = MIBSPI_LOOPBK_NONE;
+ if(MIBSPI_control(handle, MIBSPI_CMD_LOOPBACK_ENABLE, (void *)&loopback) < 0)
+ return -1;
+
+ /* Return number of failures */
+ return failed;
+}
+#endif
+
/**
* @b Description
* @n
Test_spiLoopBackDataThroughput(inst, 40000000U);
}
+#ifdef MIBSPI_DMA_ENABLE
+/**
+ * @b Description
+ * @n
+ * SPI loopback test.
+ *
+ * @param[in] inst SPI instance: 0-SPIA, 1-SPIB
+ *
+ * @retval
+ * Not Applicable.
+ */
+void Test_loopback_oneInstance_callback(uint32_t inst, uint8_t slaveIndex)
+{
+ MIBSPI_Params params;
+ MIBSPI_Handle handle;
+ char testCase[64];
+
+ snprintf(testCase, 64, "SPI loopback test callback mode - instance(%d), 16bits DMA mode", inst);
+
+ /**************************************************************************
+ * Test: Open the driver in master mode for loopback test
+ **************************************************************************/
+ /* Setup the default SPI Parameters */
+ MIBSPI_Params_init(¶ms);
+ params.frameFormat = MIBSPI_POL0_PHA0;
+
+ /* Configure for the callback mode. */
+ params.transferMode = MIBSPI_MODE_CALLBACK;
+ params.transferCallbackFxn = &Test_loopback_callbackFxn;
+
+ /* Enable DMA and set DMA channels to be used */
+ params.dmaEnable = 1;
+ params.dmaHandle = gDmaHandle[inst];
+
+ params.eccEnable = 0;
+ params.mode = MIBSPI_MASTER;
+ params.u.masterParams.bitRate = 1000000U;
+
+ /* mibSPIA support only one slave */
+ if(inst == 0)
+ {
+ params.u.masterParams.numSlaves = 1;
+ params.u.masterParams.slaveProf[0].chipSelect = 0;
+ params.u.masterParams.slaveProf[0].ramBufLen = MIBSPI_RAM_MAX_ELEM;
+ params.u.masterParams.slaveProf[0].dmaReqLine = 0U;
+ }
+ else if(inst == 1)
+ {
+ /* The total element size of 3 slaves is MIBSPI_RAM_MAX_ELEM
+ * In this example, it is distributed among 3 slaves by MIBSPI_RAM_MAX_ELEM - 6U, 4U, and 2U
+ */
+ memset((void *)¶ms.u.masterParams.slaveProf[0], 0, sizeof(params.u.masterParams.slaveProf));
+
+ params.u.masterParams.numSlaves = 3;
+ params.u.masterParams.slaveProf[0].chipSelect = 0;
+ params.u.masterParams.slaveProf[0].ramBufLen = MIBSPI_RAM_MAX_ELEM/2;
+ params.u.masterParams.slaveProf[0].dmaReqLine = 0U;
+ params.u.masterParams.slaveProf[1].chipSelect = 1;
+ params.u.masterParams.slaveProf[1].ramBufLen = MIBSPI_RAM_MAX_ELEM/4;
+ params.u.masterParams.slaveProf[1].dmaReqLine = 1U;
+ params.u.masterParams.slaveProf[2].chipSelect = 2;
+ params.u.masterParams.slaveProf[2].ramBufLen = MIBSPI_RAM_MAX_ELEM/4;
+ params.u.masterParams.slaveProf[2].dmaReqLine = 2U;
+ }
+ else
+ {
+ printf("Error: Invalid instance(=%d) of MibSPI\n", inst);
+ }
+
+ handle = MIBSPI_open(gMibspiInst[inst], ¶ms);
+ if (handle == NULL)
+ {
+ MIBSPI_log("Error: Unable to open the SPI Instance\n");
+ return;
+ }
+ MIBSPI_log("Debug: SPI Instance %p has been reopened in master mode successfully\n", handle);
+
+ /* Start Internal Loopback Test in master mode */
+ if(Test_spiLoopback_callback(handle, slaveIndex, 128, 2) == 0)
+ {
+
+ }
+ else
+ {
+
+ }
+
+ /* Close the driver: */
+ MIBSPI_close(handle);
+ MIBSPI_log("Debug: SPI Instance %p has been closed successfully\n", handle);
+}
+#endif
+
/**
* @b Description
* @n
diff --git a/packages/ti/drv/mibspi/test/loopback/src/mibspi_test_common.h b/packages/ti/drv/mibspi/test/loopback/src/mibspi_test_common.h
index cd8e293f29a389e5c2720c30226453ee66eb05b2..17583a02261f4742a8a6506dbee8037e48c1e0bb 100644 (file)
extern void Test_spiAPI_twoInstance(void);
extern void Test_spiAPI_oneInstance(uint8_t inst);
extern void Test_loopback_oneInstance(uint32_t inst, uint8_t slaveIndex);
+extern void Test_loopback_oneInstance_callback(uint32_t inst, uint8_t slaveIndex);
extern void Test_loopbackSlave_oneInstance(uint32_t inst);
#ifdef __cplusplus