]> Gitweb @ Texas Instruments - Open Source Git Repositories - git.TI.com/gitweb - processor-sdk/pdk.git/commitdiff
[Bugfix] PDK-9543: mibspi callback mode is not supported
authorPrasad Konnur <prasadkonnur@ti.com>
Fri, 23 Apr 2021 14:44:01 +0000 (20:14 +0530)
committerSujith 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>
packages/ti/drv/mibspi/src/mibspi_priv.c
packages/ti/drv/mibspi/src/mibspi_priv.h
packages/ti/drv/mibspi/test/loopback/src/main_mibspi_test.c
packages/ti/drv/mibspi/test/loopback/src/mibspi_test_common.c
packages/ti/drv/mibspi/test/loopback/src/mibspi_test_common.h

index 93f72035ea23c35905de0f77c7e3791e701f0c65..1cd9bea58b31184d97656570f0ecba5a2d265ed0 100644 (file)
@@ -218,6 +218,16 @@ static int32_t MIBSPI_validateParams(const MIBSPI_Params *params)
         }
     }
 
+    /* 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)
     {
@@ -226,6 +236,7 @@ static int32_t MIBSPI_validateParams(const MIBSPI_Params *params)
             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 */
@@ -2391,17 +2416,55 @@ void MIBSPI_dmaDoneCb(MIBSPI_Handle mibspiHandle)
         {
             /* 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)
@@ -219,6 +219,10 @@ typedef struct Mibspi_transactionState_s
     enum MibSpi_xferErr_e    transferErr;
 
     MIBSPI_Transaction         *transaction;
+
+    volatile uint16_t remainSize;
+    volatile uint16_t dataLength;
+    volatile uint16_t dataSizeInBytes;
 } Mibspi_transactionState_t;
 
 
index cfed9e6551d2d50c745e755704e9e28676461f04..a57eb70caf776342043cbbc39dc4e2a1a0ef1d29 100644 (file)
@@ -214,6 +214,11 @@ static void Test_initTask(void* arg0, void* arg1)
         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
 
     }
 
index 037a4342cd2f8cfa12bcb0db25fa48506dc37b1d..d120c5f51106797f71d238968f0aa29212832937 100644 (file)
@@ -62,7 +62,6 @@
 #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
@@ -1298,6 +1389,99 @@ void Test_loopback_oneInstance(uint32_t inst, uint8_t slaveIndex)
     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(&params);
+    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 *)&params.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], &params);
+    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
index cd8e293f29a389e5c2720c30226453ee66eb05b2..17583a02261f4742a8a6506dbee8037e48c1e0bb 100644 (file)
@@ -75,6 +75,7 @@ extern bool gXWR1xxxSlaveReady;
 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