]> Gitweb @ Texas Instruments - Open Source Git Repositories - git.TI.com/gitweb - keystone-rtos/spi-lld.git/commitdiff
spi: PRSDK-1256: add timeout support for polled mode SPI/McSPI transaction
authorHao Zhang <hzhang@ti.com>
Tue, 12 Mar 2019 15:51:51 +0000 (11:51 -0400)
committerHao Zhang <hzhang@ti.com>
Tue, 12 Mar 2019 15:51:51 +0000 (11:51 -0400)
Signed-off-by: Hao Zhang <hzhang@ti.com>
src/v1/SPI_v1.c

index b9c2f2112305ff9b14893a77b1129a3dfe506780..2f160361c16626061304894b38f614172da99b41 100644 (file)
@@ -664,6 +664,35 @@ void MCSPI_xferSetup_v1(MCSPI_Handle mcHandle, SPI_Transaction *transaction)
     }
 }
 
+static bool MCSPI_pollingXferTimeout_v1(uint32_t *timeout, uint32_t *timeoutLoop, uint32_t timeoutVal);
+static bool MCSPI_pollingXferTimeout_v1(uint32_t *timeout, uint32_t *timeoutLoop, uint32_t timeoutVal)
+{
+    bool     timeoutFlag = (bool)false;
+
+    if (*timeout > 0)
+    {
+        *timeout -= 1U;
+        if (*timeout == 0U)
+        {
+            if (*timeoutLoop > 0U)
+            {
+                *timeoutLoop -= 1U;
+                *timeout = timeoutVal;
+            }
+        }
+    }
+    else
+    {
+        if (*timeoutLoop == 0U)
+        {
+            /* Polling transfer timed out */
+            timeoutFlag = (bool)true;
+        }
+    }
+
+    return (timeoutFlag);
+}
+
 /*
  *  ======== MCSPI_primeTransfer_v1 ========
  *  This functions configures the transmit and receive channels for a given
@@ -699,7 +728,7 @@ static void MCSPI_primeTransfer_v1(MCSPI_Handle mcHandle, SPI_Transaction *trans
     uint32_t              intStatus;
     uint32_t              timeout;
     uint32_t              timeoutLoop;
-    bool                  xferFlag = true;
+    bool                  timeoutFlag;
 
     /* Get the pointer to the object and hwAttrs */
     handle  = mcHandle->handle;
@@ -761,14 +790,27 @@ static void MCSPI_primeTransfer_v1(MCSPI_Handle mcHandle, SPI_Transaction *trans
         /* Initialize the timeout value and loop count in polling mode */
         timeout = chObj->spiParams.transferTimeout;
         timeoutLoop = MCSPI_POLLING_TIMEOUT_LOOP;
+        timeoutFlag = (bool)false;
 
         /* Polling mode transfer */
-        while (xferFlag)
+        while (((chObj->readCountIdx != 0) || (chObj->writeCountIdx != 0)) &&
+               (timeoutFlag == (bool)false))
         {
             channelStatus = McSPIChannelStatusGet(hwAttrs->baseAddr, chNum);
             if ((SPI_MASTER == chObj->spiParams.mode) && (chObj->writeCountIdx != 0))
             {
-                if (0U != (channelStatus & CSL_MCSPI_CH0STAT_TXS_MASK))
+                while (0U == (channelStatus & CSL_MCSPI_CH0STAT_TXS_MASK))
+                {
+                    channelStatus = McSPIChannelStatusGet(hwAttrs->baseAddr, chNum);
+                    timeoutFlag = MCSPI_pollingXferTimeout_v1(&timeout,
+                                                              &timeoutLoop,
+                                                              chObj->spiParams.transferTimeout);
+                    if (timeoutFlag == (bool)true)
+                    {
+                        break;
+                    }
+                }
+                if (timeoutFlag == (bool)false)
                 {
                     chObj->writeBufIdx = MCSPI_transmitData_v1 (hwAttrs->baseAddr,
                                                                 chObj->spiParams.dataSize,
@@ -778,9 +820,20 @@ static void MCSPI_primeTransfer_v1(MCSPI_Handle mcHandle, SPI_Transaction *trans
                 }
             }
 
-            if (chObj->readCountIdx != 0)
+            if ((chObj->readCountIdx != 0) && (timeoutFlag == (bool)false))
             {
-                if (0U != (channelStatus & CSL_MCSPI_CH0STAT_RXS_MASK))
+                while (0U == (channelStatus & CSL_MCSPI_CH0STAT_RXS_MASK))
+                {
+                    channelStatus = McSPIChannelStatusGet(hwAttrs->baseAddr, chNum);
+                    timeoutFlag = MCSPI_pollingXferTimeout_v1(&timeout,
+                                                              &timeoutLoop,
+                                                              chObj->spiParams.transferTimeout);
+                    if (timeoutFlag == (bool)true)
+                    {
+                        break;
+                    }
+                }
+                if (timeoutFlag == (bool)false)
                 {
                     chObj->readBufIdx = MCSPI_receiveData_v1(hwAttrs->baseAddr,
                                                              chObj->spiParams.dataSize,
@@ -790,7 +843,9 @@ static void MCSPI_primeTransfer_v1(MCSPI_Handle mcHandle, SPI_Transaction *trans
                 }
             }
 
-            if ((SPI_SLAVE == chObj->spiParams.mode) && (chObj->writeCountIdx != 0))
+            if ((SPI_SLAVE == chObj->spiParams.mode) &&
+                (chObj->writeCountIdx != 0)          &&
+                (timeoutFlag == (bool)false))
             {
                 chObj->writeBufIdx = MCSPI_transmitData_v1 (hwAttrs->baseAddr,
                                                             chObj->spiParams.dataSize,
@@ -802,29 +857,18 @@ static void MCSPI_primeTransfer_v1(MCSPI_Handle mcHandle, SPI_Transaction *trans
 
             if ((chObj->readCountIdx != 0) || (chObj->writeCountIdx != 0))
             {
-                if (timeout > 0U)
+                timeoutFlag = MCSPI_pollingXferTimeout_v1(&timeout,
+                                                          &timeoutLoop,
+                                                          chObj->spiParams.transferTimeout);
+                if (timeoutFlag == (bool)true)
                 {
-                    timeout--;
-                }
-                else
-                {
-                    if (timeoutLoop == 0U)
-                    {
-                        /* Transfer timeout */
-                        xferFlag = false;
-                        transaction->status=SPI_TRANSFER_TIMEOUT;
-                    }
-                    else
-                    {
-                        timeoutLoop--;
-                        timeout = chObj->spiParams.transferTimeout;
-                    }
+                    /* Transfer timeout */
+                    transaction->status=SPI_TRANSFER_TIMEOUT;
                 }
             }
             else
             {
                 /* Transfer completed successfully */
-                xferFlag = false;
                 transaction->status=SPI_TRANSFER_COMPLETED;
             }
         }