You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nuttx.apache.org by ag...@apache.org on 2020/04/02 15:26:21 UTC
[incubator-nuttx] branch master updated: Check return from
nxsem_wait_uninterruptible()
This is an automated email from the ASF dual-hosted git repository.
aguettouche pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-nuttx.git
The following commit(s) were added to refs/heads/master by this push:
new 4892c27 Check return from nxsem_wait_uninterruptible()
4892c27 is described below
commit 4892c27b4ad466bcaf1702bc30aaedbb11109af5
Author: Gregory Nutt <gn...@nuttx.org>
AuthorDate: Thu Apr 2 08:45:32 2020 -0600
Check return from nxsem_wait_uninterruptible()
Resolution of Issue 619 will require multiple steps, this part of the first step in that resolution: Every call to nxsem_wait_uninterruptible() must handle the return value from nxsem_wait_uninterruptible properly. This commit is for all SPI drivers under arch/.
---
arch/arm/src/imx1/imx_spi.c | 48 ++++------
arch/arm/src/imx6/imx_ecspi.c | 53 ++++-------
arch/arm/src/samd2l2/sam_spi.c | 50 ++++------
arch/arm/src/samd5e5/sam_spi.c | 45 +++------
arch/arm/src/samv7/sam_spi_slave.c | 137 +++++++++++++++++----------
arch/arm/src/samv7/sam_ssc.c | 175 ++++++++++++++++++++---------------
arch/arm/src/stm32/stm32_spi.c | 49 +++++++---
arch/arm/src/stm32f0l0g0/stm32_spi.c | 89 ++++++++++--------
arch/arm/src/stm32f7/stm32_spi.c | 45 ++++++---
arch/arm/src/stm32h7/stm32_spi.c | 46 ++++++---
arch/arm/src/stm32l4/stm32l4_spi.c | 87 +++++++++--------
arch/arm/src/tiva/common/tiva_ssi.c | 74 ++++++---------
12 files changed, 489 insertions(+), 409 deletions(-)
diff --git a/arch/arm/src/imx1/imx_spi.c b/arch/arm/src/imx1/imx_spi.c
index 388ae8a..a3c5895 100644
--- a/arch/arm/src/imx1/imx_spi.c
+++ b/arch/arm/src/imx1/imx_spi.c
@@ -1,35 +1,20 @@
/****************************************************************************
* arch/arm/src/imx1/imx_spi.c
*
- * Copyright (C) 2009-2017 Gregory Nutt. All rights reserved.
- * Author: Gregory Nutt <gn...@nuttx.org>
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in
- * the documentation and/or other materials provided with the
- * distribution.
- * 3. Neither the name NuttX nor the names of its contributors may be
- * used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
- * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
- * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
- * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
- * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
- * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership. The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
*
****************************************************************************/
@@ -567,7 +552,7 @@ static int spi_transfer(struct imx_spidev_s *priv, const void *txbuffer,
/* Wait to be signaled from the interrupt handler */
- nxsem_wait_uninterruptible(&priv->waitsem);
+ return nxsem_wait_uninterruptible(&priv->waitsem);
#else
/* Perform the transfer using polling logic. This will totally
@@ -597,8 +582,9 @@ static int spi_transfer(struct imx_spidev_s *priv, const void *txbuffer,
sched_yield();
}
while (priv->nrxwords < priv->nwords);
-#endif
+
return OK;
+#endif
}
/****************************************************************************
diff --git a/arch/arm/src/imx6/imx_ecspi.c b/arch/arm/src/imx6/imx_ecspi.c
index 8bcc0d8..d767f18 100644
--- a/arch/arm/src/imx6/imx_ecspi.c
+++ b/arch/arm/src/imx6/imx_ecspi.c
@@ -1,40 +1,20 @@
/****************************************************************************
* arch/arm/src/imx6/imx_ecspi.c
*
- * Copyright (C) 2016-2017 Gregory Nutt. All rights reserved.
- * Author: Gregory Nutt <gn...@nuttx.org>
- *
- * Derives from the i.MX1 CSPI driver:
- *
- * Copyright (C) 2009-2010, 2013, 2016 Gregory Nutt. All rights reserved.
- * Author: Gregory Nutt <gn...@nuttx.org>
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in
- * the documentation and/or other materials provided with the
- * distribution.
- * 3. Neither the name NuttX nor the names of its contributors may be
- * used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
- * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
- * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
- * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
- * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
- * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership. The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
*
****************************************************************************/
@@ -688,7 +668,7 @@ static int spi_transfer(struct imx_spidev_s *priv, const void *txbuffer,
/* Wait to be signaled from the interrupt handler */
- nxsem_wait_uninterruptible(&priv->waitsem);
+ return nxsem_wait_uninterruptible(&priv->waitsem);
#else
/* Perform the transfer using polling logic. This will totally
@@ -718,8 +698,9 @@ static int spi_transfer(struct imx_spidev_s *priv, const void *txbuffer,
sched_yield();
}
while (priv->nrxwords < priv->nwords);
-#endif
+
return OK;
+#endif
}
/****************************************************************************
diff --git a/arch/arm/src/samd2l2/sam_spi.c b/arch/arm/src/samd2l2/sam_spi.c
index 74fd9cc..c918501 100644
--- a/arch/arm/src/samd2l2/sam_spi.c
+++ b/arch/arm/src/samd2l2/sam_spi.c
@@ -1,42 +1,28 @@
/****************************************************************************
* arch/arm/src/samd2l2/sam_spi.c
*
- * Copyright (C) 2014-2018 Gregory Nutt. All rights reserved.
- * Authors: Gregory Nutt <gn...@nuttx.org>
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership. The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at
*
- * References:
- * 1. "Atmel SAM D20J / SAM D20G / SAM D20E ARM-Based Microcontroller
- * Datasheet", 42129J–SAM–12/2013
+ * http://www.apache.org/licenses/LICENSE-2.0
*
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in
- * the documentation and/or other materials provided with the
- * distribution.
- * 3. Neither the name NuttX nor the names of its contributors may be
- * used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
- * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
- * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
- * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
- * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
- * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
*
****************************************************************************/
+/* References:
+ * 1. "Atmel SAM D20J / SAM D20G / SAM D20E ARM-Based Microcontroller
+ * Datasheet", 42129J–SAM–12/2013
+ */
+
/****************************************************************************
* Included Files
****************************************************************************/
@@ -1154,7 +1140,7 @@ static void spi_dma_callback(DMA_HANDLE dma, void *arg, int result)
****************************************************************************/
static void spi_exchange(struct spi_dev_s *dev, const void *txbuffer,
- void *rxbuffer, size_t nwords)
+ void *rxbuffer, size_t nwords)
{
struct sam_spidev_s *priv = (struct sam_spidev_s *)dev;
diff --git a/arch/arm/src/samd5e5/sam_spi.c b/arch/arm/src/samd5e5/sam_spi.c
index 0a8fd7c..e75ad22 100644
--- a/arch/arm/src/samd5e5/sam_spi.c
+++ b/arch/arm/src/samd5e5/sam_spi.c
@@ -1,35 +1,20 @@
/****************************************************************************
* arch/arm/src/samd5e5/sam_spi.c
*
- * Copyright (C) 2018 Gregory Nutt. All rights reserved.
- * Authors: Gregory Nutt <gn...@nuttx.org>
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in
- * the documentation and/or other materials provided with the
- * distribution.
- * 3. Neither the name NuttX nor the names of its contributors may be
- * used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
- * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
- * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
- * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
- * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
- * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership. The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
*
****************************************************************************/
@@ -1249,7 +1234,7 @@ static void spi_dma_callback(DMA_HANDLE dma, void *arg, int result)
****************************************************************************/
static void spi_exchange(struct spi_dev_s *dev, const void *txbuffer,
- void *rxbuffer, size_t nwords)
+ void *rxbuffer, size_t nwords)
{
struct sam_spidev_s *priv = (struct sam_spidev_s *)dev;
diff --git a/arch/arm/src/samv7/sam_spi_slave.c b/arch/arm/src/samv7/sam_spi_slave.c
index b4780ed..169ea1a 100644
--- a/arch/arm/src/samv7/sam_spi_slave.c
+++ b/arch/arm/src/samv7/sam_spi_slave.c
@@ -1,35 +1,20 @@
/****************************************************************************
* arch/arm/src/samv7/sam_spi_slave.c
*
- * Copyright (C) 2015, 2017 Gregory Nutt. All rights reserved.
- * Authors: Gregory Nutt <gn...@nuttx.org>
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in
- * the documentation and/or other materials provided with the
- * distribution.
- * 3. Neither the name NuttX nor the names of its contributors may be
- * used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
- * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
- * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
- * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
- * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
- * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership. The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
*
****************************************************************************/
@@ -68,6 +53,7 @@
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
+
/* Configuration ************************************************************/
#ifndef CONFIG_SAMV7_SPI_SLAVE_QSIZE
@@ -110,10 +96,10 @@ struct sam_spidev_s
/* Debug stuff */
#ifdef CONFIG_SAMV7_SPI_REGDEBUG
- bool wrlast; /* Last was a write */
- uint32_t addresslast; /* Last address */
- uint32_t valuelast; /* Last value */
- int ntimes; /* Number of times */
+ bool wrlast; /* Last was a write */
+ uint32_t addresslast; /* Last address */
+ uint32_t valuelast; /* Last value */
+ int ntimes; /* Number of times */
#endif
};
@@ -141,7 +127,8 @@ static void spi_dumpregs(struct sam_spidev_s *priv, const char *msg);
# define spi_dumpregs(priv,msg)
#endif
-static void spi_semtake(struct sam_spidev_s *priv);
+static int spi_semtake(struct sam_spidev_s *priv);
+static void spi_semtake_uninterruptible(struct sam_spidev_s *priv);
#define spi_semgive(priv) (nxsem_post(&(priv)->spisem))
/* Interrupt Handling */
@@ -348,7 +335,27 @@ static void spi_dumpregs(struct sam_spidev_s *priv, const char *msg)
*
* Description:
* Take the semaphore that enforces mutually exclusive access to SPI
- * resources, handling any exceptional conditions
+ * resources. May return ECANCELED if the calling thread was canceled.
+ *
+ * Input Parameters:
+ * priv - A reference to the MCAN peripheral state
+ *
+ * Returned Value:
+ * None
+ *
+ ****************************************************************************/
+
+static int spi_semtake(struct sam_spidev_s *priv)
+{
+ return nxsem_wait_uninterruptible(&priv->spisem);
+}
+
+/****************************************************************************
+ * Name: spi_semtake_uninterruptible
+ *
+ * Description:
+ * Take the semaphore that enforces mutually exclusive access to SPI
+ * resources, handling any exceptional conditions. Always successful.
*
* Input Parameters:
* priv - A reference to the MCAN peripheral state
@@ -358,9 +365,19 @@ static void spi_dumpregs(struct sam_spidev_s *priv, const char *msg)
*
****************************************************************************/
-static void spi_semtake(struct sam_spidev_s *priv)
+static void spi_semtake_uninterruptible(struct sam_spidev_s *priv)
{
- nxsem_wait_uninterruptible(&priv->spisem);
+ int ret;
+
+ do
+ {
+ ret = nxsem_wait_uninterruptible(&priv->spisem);
+
+ /* ECANCELED is the only error expected here */
+
+ DEBUGASSERT(ret == OK || ret == -ECANCELED);
+ }
+ while (ret < 0);
}
/****************************************************************************
@@ -458,7 +475,8 @@ static int spi_interrupt(int irq, void *context, FAR void *arg)
*/
regval = spi_getreg(priv, SAM_SPI_RDR_OFFSET);
- data = (uint16_t)((regval & SPI_RDR_RD_MASK) >> SPI_RDR_RD_SHIFT);
+ data = (uint16_t)
+ ((regval & SPI_RDR_RD_MASK) >> SPI_RDR_RD_SHIFT);
/* Enable TXDR/OVRE interrupts */
@@ -482,7 +500,8 @@ static int spi_interrupt(int irq, void *context, FAR void *arg)
* i.e., NSS falls and there is a valid clock on the SPCK pin. When
* the transfer occurs, the last data written in the SPI_TDR is
* transferred in the Shift register and the TDRE flag rises. This
- * enables frequent updates of critical variables with single transfers.
+ * enables frequent updates of critical variables with single
+ * transfers.
*
* Then, new data is loaded in the Shift register from the SPI_TDR. If
* no character is ready to be transmitted, i.e., no character has been
@@ -743,6 +762,7 @@ static void spi_bind(struct spi_sctrlr_s *sctrlr,
{
struct sam_spidev_s *priv = (struct sam_spidev_s *)sctrlr;
uint32_t regval;
+ int ret;
spiinfo("sdev=%p mode=%d nbits=%d\n", sdv, mode, nbits);
@@ -750,7 +770,16 @@ static void spi_bind(struct spi_sctrlr_s *sctrlr,
/* Get exclusive access to the SPI device */
- spi_semtake(priv);
+ ret = spi_semtake(priv);
+ if (ret < 0)
+ {
+ /* REVISIT: No mechanism to report error. This error should only
+ * occur if the calling task was canceled.
+ */
+
+ spierr("RROR: spi_semtake failed: %d\n", ret);
+ return;
+ }
/* Bind the SPI slave device interface instance to the SPI slave
* controller interface.
@@ -852,7 +881,7 @@ static void spi_unbind(struct spi_sctrlr_s *sctrlr)
/* Get exclusive access to the SPI device */
- spi_semtake(priv);
+ spi_semtake_uninterruptible(priv);
/* Disable SPI interrupts (still enabled at the NVIC) */
@@ -908,7 +937,11 @@ static int spi_enqueue(struct spi_sctrlr_s *sctrlr, uint16_t data)
/* Get exclusive access to the SPI device */
- spi_semtake(priv);
+ ret = spi_semtake(priv);
+ if (ret < 0)
+ {
+ return ret;
+ }
/* Check if this word would overflow the circular buffer
*
@@ -972,14 +1005,24 @@ static bool spi_qfull(struct spi_sctrlr_s *sctrlr)
{
struct sam_spidev_s *priv = (struct sam_spidev_s *)sctrlr;
irqstate_t flags;
+ bool bret;
+ int ret;
int next;
- bool ret;
DEBUGASSERT(priv != NULL && priv->sdev != NULL);
/* Get exclusive access to the SPI device */
- spi_semtake(priv);
+ ret = spi_semtake(priv);
+ if (ret < 0)
+ {
+ /* REVISIT: No mechanism to report error. This error should only
+ * occurr if the calling task was canceled.
+ */
+
+ spierr("RROR: spi_semtake failed: %d\n", ret);
+ return true;
+ }
/* Check if another word would overflow the circular buffer
*
@@ -993,10 +1036,10 @@ static bool spi_qfull(struct spi_sctrlr_s *sctrlr)
next = 0;
}
- ret = (next == priv->tail);
+ bret = (next == priv->tail);
leave_critical_section(flags);
spi_semgive(priv);
- return ret;
+ return bret;
}
/****************************************************************************
@@ -1026,7 +1069,7 @@ static void spi_qflush(struct spi_sctrlr_s *sctrlr)
/* Get exclusive access to the SPI device */
- spi_semtake(priv);
+ spi_semtake_uninterruptible(priv);
/* Mark the buffer empty, momentarily disabling interrupts */
diff --git a/arch/arm/src/samv7/sam_ssc.c b/arch/arm/src/samv7/sam_ssc.c
index 2e7a1fc..113278d 100644
--- a/arch/arm/src/samv7/sam_ssc.c
+++ b/arch/arm/src/samv7/sam_ssc.c
@@ -1,35 +1,20 @@
/****************************************************************************
* arch/arm/src/samv7/sam_ssc.c
*
- * Copyright (C) 2015-2017 Gregory Nutt. All rights reserved.
- * Authors: Gregory Nutt <gn...@nuttx.org>
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in
- * the documentation and/or other materials provided with the
- * distribution.
- * 3. Neither the name NuttX nor the names of its contributors may be
- * used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
- * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
- * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
- * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
- * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
- * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership. The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
*
****************************************************************************/
@@ -76,6 +61,7 @@
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
+
/* Configuration ************************************************************/
#ifndef CONFIG_SCHED_WORKQUEUE
@@ -368,7 +354,8 @@
#define DMA_TIMEOUT_MS (800)
#define DMA_TIMEOUT_TICKS MSEC2TICK(DMA_TIMEOUT_MS)
-/* Debug *******************************************************************/
+/* Debug ********************************************************************/
+
/* Check if SSC debug is enabled */
#ifndef CONFIG_DEBUG_I2S_INFO
@@ -393,6 +380,7 @@
/****************************************************************************
* Private Types
****************************************************************************/
+
/* I2S buffer container */
struct sam_buffer_s
@@ -466,10 +454,10 @@ struct sam_ssc_s
/* Debug stuff */
#ifdef CONFIG_SAMV7_SSC_REGDEBUG
- bool wr; /* Last was a write */
- uint32_t regaddr; /* Last address */
- uint32_t regval; /* Last value */
- int count; /* Number of times */
+ bool wr; /* Last was a write */
+ uint32_t regaddr; /* Last address */
+ uint32_t regval; /* Last value */
+ int count; /* Number of times */
#endif /* CONFIG_SAMV7_SSC_REGDEBUG */
};
@@ -480,13 +468,14 @@ struct sam_ssc_s
/* Register helpers */
#ifdef CONFIG_SAMV7_SSC_REGDEBUG
-static bool ssc_checkreg(struct sam_ssc_s *priv, bool wr, uint32_t regval,
- uint32_t regaddr);
+static bool ssc_checkreg(struct sam_ssc_s *priv, bool wr,
+ uint32_t regval, uint32_t regaddr);
#else
# define ssc_checkreg(priv,wr,regval,regaddr) (false)
#endif
-static inline uint32_t ssc_getreg(struct sam_ssc_s *priv, unsigned int offset);
+static inline uint32_t ssc_getreg(struct sam_ssc_s *priv,
+ unsigned int offset);
static inline void ssc_putreg(struct sam_ssc_s *priv, unsigned int offset,
uint32_t regval);
static inline uintptr_t ssc_regaddr(struct sam_ssc_s *priv,
@@ -518,10 +507,10 @@ static void ssc_dump_queues(struct sam_transport_s *xpt,
/* Semaphore helpers */
-static void ssc_exclsem_take(struct sam_ssc_s *priv);
+static int ssc_exclsem_take(struct sam_ssc_s *priv);
#define ssc_exclsem_give(priv) nxsem_post(&priv->exclsem)
-static void ssc_bufsem_take(struct sam_ssc_s *priv);
+static int ssc_bufsem_take(struct sam_ssc_s *priv);
#define ssc_bufsem_give(priv) nxsem_post(&priv->bufsem)
/* Buffer container helpers */
@@ -615,6 +604,7 @@ static void ssc1_configure(struct sam_ssc_s *priv);
/****************************************************************************
* Private Data
****************************************************************************/
+
/* I2S device operations */
static const struct i2s_ops_s g_sscops =
@@ -749,7 +739,8 @@ static inline void ssc_putreg(struct sam_ssc_s *priv, unsigned int offset,
*
****************************************************************************/
-static inline uintptr_t ssc_regaddr(struct sam_ssc_s *priv, unsigned int offset)
+static inline uintptr_t ssc_regaddr(struct sam_ssc_s *priv,
+ unsigned int offset)
{
return priv->base + offset;
}
@@ -860,9 +851,9 @@ static void ssc_dump_queues(struct sam_transport_s *xpt, const char *msg)
*
****************************************************************************/
-static void ssc_exclsem_take(struct sam_ssc_s *priv)
+static int ssc_exclsem_take(struct sam_ssc_s *priv)
{
- nxsem_wait_uninterruptible(&priv->exclsem);
+ return nxsem_wait_uninterruptible(&priv->exclsem);
}
/****************************************************************************
@@ -879,9 +870,9 @@ static void ssc_exclsem_take(struct sam_ssc_s *priv)
*
****************************************************************************/
-static void ssc_bufsem_take(struct sam_ssc_s *priv)
+static int ssc_bufsem_take(struct sam_ssc_s *priv)
{
- nxsem_wait_uninterruptible(&priv->bufsem);
+ return nxsem_wait_uninterruptible(&priv->bufsem);
}
/****************************************************************************
@@ -908,12 +899,17 @@ static struct sam_buffer_s *ssc_buf_allocate(struct sam_ssc_s *priv)
{
struct sam_buffer_s *bfcontainer;
irqstate_t flags;
+ int ret;
/* Set aside a buffer container. By doing this, we guarantee that we will
* have at least one free buffer container.
*/
- ssc_bufsem_take(priv);
+ ret = ssc_bufsem_take(priv);
+ if (ret < 0)
+ {
+ return NULL;
+ }
/* Get the buffer from the head of the free list */
@@ -946,7 +942,8 @@ static struct sam_buffer_s *ssc_buf_allocate(struct sam_ssc_s *priv)
*
****************************************************************************/
-static void ssc_buf_free(struct sam_ssc_s *priv, struct sam_buffer_s *bfcontainer)
+static void ssc_buf_free(struct sam_ssc_s *priv,
+ struct sam_buffer_s *bfcontainer)
{
irqstate_t flags;
@@ -1046,6 +1043,7 @@ static void ssc_rxdma_sampledone(struct sam_ssc_s *priv, int result)
sam_dmasample(priv->rx.dma, &priv->rx.dmaregs[DMA_END_TRANSFER]);
/* Then dump the sampled DMA registers */
+
/* Initial register values */
sam_dmadump(priv->rx.dma, &priv->rx.dmaregs[DMA_INITIAL],
@@ -1111,6 +1109,7 @@ static void ssc_txdma_sampledone(struct sam_ssc_s *priv, int result)
sam_dmasample(priv->tx.dma, &priv->tx.dmaregs[DMA_END_TRANSFER]);
/* Then dump the sampled DMA registers */
+
/* Initial register values */
sam_dmadump(priv->tx.dma, &priv->tx.dmaregs[DMA_INITIAL],
@@ -1360,10 +1359,10 @@ static void ssc_rx_worker(void *arg)
DEBUGASSERT(priv);
- /* When the transfer was started, the active buffer containers were removed
- * from the rx.pend queue and saved in the rx.act queue. We get here when the
- * DMA is finished... either successfully, with a DMA error, or with a DMA
- * timeout.
+ /* When the transfer was started, the active buffer containers were
+ * removed from the rx.pend queue and saved in the rx.act queue. We get
+ * here when the DMA is finished... either successfully, with a DMA
+ * error, or with a DMA timeout.
*
* In any case, the buffer containers in rx.act will be moved to the end
* of the rx.done queue and rx.act queue will be emptied before this worker
@@ -1776,10 +1775,10 @@ static void ssc_tx_worker(void *arg)
DEBUGASSERT(priv);
- /* When the transfer was started, the active buffer containers were removed
- * from the tx.pend queue and saved in the tx.act queue. We get here when the
- * DMA is finished... either successfully, with a DMA error, or with a DMA
- * timeout.
+ /* When the transfer was started, the active buffer containers were
+ * removed from the tx.pend queue and saved in the tx.act queue. We get
+ * here when the DMA is finished... either successfully, with a DMA
+ * error, or with a DMA timeout.
*
* In any case, the buffer containers in tx.act will be moved to the end
* of the tx.done queue and tx.act will be emptied before this worker is
@@ -2176,11 +2175,18 @@ static int ssc_receive(struct i2s_dev_s *dev, struct ap_buffer_s *apb,
/* Allocate a buffer container in advance */
bfcontainer = ssc_buf_allocate(priv);
- DEBUGASSERT(bfcontainer);
+ if (bfcontainer == NULL)
+ {
+ return -ENOMEM;
+ }
/* Get exclusive access to the SSC driver data */
- ssc_exclsem_take(priv);
+ ret = ssc_exclsem_take(priv);
+ if (ret < 0)
+ {
+ goto errout_with_buf;
+ }
/* Has the RX channel been enabled? */
@@ -2209,8 +2215,8 @@ static int ssc_receive(struct i2s_dev_s *dev, struct ap_buffer_s *apb,
sq_addlast((sq_entry_t *)bfcontainer, &priv->rx.pend);
ssc_dump_rxqueues(priv, "Receiving");
- /* Then start the next transfer. If there is already a transfer in progress,
- * then this will do nothing.
+ /* Then start the next transfer. If there is already a transfer in
+ * progress, then this will do nothing.
*/
ret = ssc_rxdma_setup(priv);
@@ -2221,6 +2227,8 @@ static int ssc_receive(struct i2s_dev_s *dev, struct ap_buffer_s *apb,
errout_with_exclsem:
ssc_exclsem_give(priv);
+
+errout_with_buf:
ssc_buf_free(priv, bfcontainer);
return ret;
@@ -2393,11 +2401,18 @@ static int ssc_send(struct i2s_dev_s *dev, struct ap_buffer_s *apb,
/* Allocate a buffer container in advance */
bfcontainer = ssc_buf_allocate(priv);
- DEBUGASSERT(bfcontainer);
+ if (bfcontainer == NULL)
+ {
+ return -ENOMEM;
+ }
/* Get exclusive access to the SSC driver data */
- ssc_exclsem_take(priv);
+ ret = ssc_exclsem_take(priv);
+ if (ret < 0)
+ {
+ goto errout_with_buf;
+ }
/* Has the TX channel been enabled? */
@@ -2426,8 +2441,8 @@ static int ssc_send(struct i2s_dev_s *dev, struct ap_buffer_s *apb,
sq_addlast((sq_entry_t *)bfcontainer, &priv->tx.pend);
ssc_dump_txqueues(priv, "Transmitting");
- /* Then start the next transfer. If there is already a transfer in progress,
- * then this will do nothing.
+ /* Then start the next transfer. If there is already a transfer in
+ * progress, then this will do nothing.
*/
ret = ssc_txdma_setup(priv);
@@ -2438,6 +2453,8 @@ static int ssc_send(struct i2s_dev_s *dev, struct ap_buffer_s *apb,
errout_with_exclsem:
ssc_exclsem_give(priv);
+
+errout_with_buf:
ssc_buf_free(priv, bfcontainer);
return ret;
@@ -2458,7 +2475,8 @@ errout_with_exclsem:
* priv - Fully initialized SSC device structure.
*
* Returned Value:
- * OK is returned on failure. A negated errno value is returned on failure.
+ * OK is returned on failure. A negated errno value is returned on
+ * failure.
*
****************************************************************************/
@@ -2474,6 +2492,7 @@ static int ssc_rx_configure(struct sam_ssc_s *priv)
fslen = priv->rxfslen - 1;
/* RCMR settings */
+
/* Configure the receiver input clock */
regval = 0;
@@ -2539,15 +2558,16 @@ static int ssc_rx_configure(struct sam_ssc_s *priv)
SSC_RCMR_STTDLY(priv->rxsttdly) | SSC_RCMR_PERIOD(0));
ssc_putreg(priv, SAM_SSC_RCMR_OFFSET, regval);
- /* RFMR settings. Some of these settings will need to be configurable as well.
- * Currently hardcoded to:
+ /* RFMR settings. Some of these settings will need to be configurable as
+ * well. Currently hardcoded to:
*
* SSC_RFMR_DATLEN(n) 'n' determined by configuration
* SSC_RFMR_LOOP Determined by configuration
* SSC_RFMR_MSBF Most significant bit first
* SSC_RFMR_DATNB(n) Data number 'n' per frame (hard-coded)
* SSC_RFMR_FSLEN Set to LS 4 bits of (CONFIG_SSCx_RX_FSLEN-1)
- * SSC_RFMR_FSLEN(1) Pulse length = FSLEN + (FSLEN_EXT * 16) + 1 = 2 clocks
+ * SSC_RFMR_FSLEN(1) Pulse length = FSLEN + (FSLEN_EXT * 16) + 1 =
+ * 2 clocks
* SSC_RFMR_FSOS_NONE RF pin is always in input
* SSC_RFMR_FSEDGE_POS Positive frame sync edge detection
* SSC_RFMR_FSLENEXT I Set to MS 4 bits of (CONFIG_SSCx_TX_FSLEN-1)
@@ -2558,7 +2578,8 @@ static int ssc_rx_configure(struct sam_ssc_s *priv)
/* Set the RX frame synch */
- regval |= (SSC_RFMR_FSLEN(fslen & 0x0f) | SSC_RFMR_FSLENEXT((fslen >> 4) & 0x0f));
+ regval |= (SSC_RFMR_FSLEN(fslen & 0x0f) |
+ SSC_RFMR_FSLENEXT((fslen >> 4) & 0x0f));
/* Loopback mode? */
@@ -2599,6 +2620,7 @@ static int ssc_tx_configure(struct sam_ssc_s *priv)
period = SCC_PERIOD(priv->txsttdly, priv->datalen);
/* TCMR settings */
+
/* Configure the transmitter input clock */
regval = 0;
@@ -2668,26 +2690,30 @@ static int ssc_tx_configure(struct sam_ssc_s *priv)
if (priv->txclk == SSC_CLKSRC_MCKDIV)
{
regval |= (SSC_TCMR_CKG_CONT | SSC_TCMR_START_CONT |
- SSC_TCMR_STTDLY(priv->txsttdly) | SSC_TCMR_PERIOD(period / 2 - 1));
+ SSC_TCMR_STTDLY(priv->txsttdly) |
+ SSC_TCMR_PERIOD(period / 2 - 1));
}
else
{
regval |= (SSC_TCMR_CKG_CONT | SSC_TCMR_START_EDGE |
- SSC_TCMR_STTDLY(priv->txsttdly) | SSC_TCMR_PERIOD(0));
+ SSC_TCMR_STTDLY(priv->txsttdly) |
+ SSC_TCMR_PERIOD(0));
}
ssc_putreg(priv, SAM_SSC_TCMR_OFFSET, regval);
- /* TFMR settings. Some of these settings will need to be configurable as well.
- * Currently set to:
+ /* TFMR settings. Some of these settings will need to be configurable as
+ * well. Currently set to:
*
* SSC_TFMR_DATLEN(n) 'n' determined by configuration
* SSC_TFMR_DATDEF Data default = 0
* SSC_TFMR_MSBF Most significant bit first
* SSC_TFMR_DATNB(n) Data number 'n' per frame (hard-coded)
* SSC_TFMR_FSDEN Enabled if CONFIG_SSCx_TX_FSLEN > 0
- * SSC_TFMR_FSLEN If enabled, set to LS 4 bits of (CONFIG_SSCx_TX_FSLEN-1)
- * SSC_TFMR_FSLENEXT If enabled, set to MS 4 bits of (CONFIG_SSCx_TX_FSLEN-1)
+ * SSC_TFMR_FSLEN If enabled, set to LS 4 bits of
+ * (CONFIG_SSCx_TX_FSLEN-1)
+ * SSC_TFMR_FSLENEXT If enabled, set to MS 4 bits of
+ * (CONFIG_SSCx_TX_FSLEN-1)
*
* If master (i.e., provides clocking):
* SSC_TFMR_FSOS_NEGATIVE Negative pulse TF output
@@ -2852,7 +2878,8 @@ static void ssc_clocking(struct sam_ssc_s *priv)
/* Reset, disable receiver & transmitter */
- ssc_putreg(priv, SAM_SSC_CR_OFFSET, SSC_CR_RXDIS | SSC_CR_TXDIS | SSC_CR_SWRST);
+ ssc_putreg(priv, SAM_SSC_CR_OFFSET,
+ SSC_CR_RXDIS | SSC_CR_TXDIS | SSC_CR_SWRST);
/* Configure MCK/2 divider */
diff --git a/arch/arm/src/stm32/stm32_spi.c b/arch/arm/src/stm32/stm32_spi.c
index 160e277..e6d3f73 100644
--- a/arch/arm/src/stm32/stm32_spi.c
+++ b/arch/arm/src/stm32/stm32_spi.c
@@ -247,8 +247,8 @@ static inline void spi_writeword(FAR struct stm32_spidev_s *priv, uint16_t byte)
/* DMA support */
#ifdef CONFIG_STM32_SPI_DMA
-static void spi_dmarxwait(FAR struct stm32_spidev_s *priv);
-static void spi_dmatxwait(FAR struct stm32_spidev_s *priv);
+static int spi_dmarxwait(FAR struct stm32_spidev_s *priv);
+static int spi_dmatxwait(FAR struct stm32_spidev_s *priv);
static inline void spi_dmarxwakeup(FAR struct stm32_spidev_s *priv);
static inline void spi_dmatxwakeup(FAR struct stm32_spidev_s *priv);
static void spi_dmarxcallback(DMA_HANDLE handle, uint8_t isr, void *arg);
@@ -889,17 +889,27 @@ static inline void spi_writeword(FAR struct stm32_spidev_s *priv, uint16_t word)
************************************************************************************/
#ifdef CONFIG_STM32_SPI_DMA
-static void spi_dmarxwait(FAR struct stm32_spidev_s *priv)
+static int spi_dmarxwait(FAR struct stm32_spidev_s *priv)
{
+ int ret;
+
/* Take the semaphore (perhaps waiting). If the result is zero, then the DMA
* must not really have completed???
*/
do
{
- nxsem_wait_uninterruptible(&priv->rxsem);
+ ret = nxsem_wait_uninterruptible(&priv->rxsem);
+
+ /* The only expected error is ECANCELED which would occur if the calling
+ * thread were canceled.
+ */
+
+ DEBUGASSERT(ret == OK || ret == -ECANCELED);
}
- while (priv->rxresult == 0);
+ while (priv->rxresult == 0 && ret == OK);
+
+ return ret;
}
#endif
@@ -912,17 +922,27 @@ static void spi_dmarxwait(FAR struct stm32_spidev_s *priv)
************************************************************************************/
#ifdef CONFIG_STM32_SPI_DMA
-static void spi_dmatxwait(FAR struct stm32_spidev_s *priv)
+static int spi_dmatxwait(FAR struct stm32_spidev_s *priv)
{
+ int ret;
+
/* Take the semaphore (perhaps waiting). If the result is zero, then the DMA
* must not really have completed???
*/
do
{
- nxsem_wait_uninterruptible(&priv->txsem);
+ ret = nxsem_wait_uninterruptible(&priv->txsem);
+
+ /* The only expected error is ECANCELED which would occur if the calling
+ * thread were canceled.
+ */
+
+ DEBUGASSERT(ret == OK || ret == -ECANCELED);
}
- while (priv->txresult == 0);
+ while (priv->txresult == 0 && ret == OK);
+
+ return ret;
}
#endif
@@ -1745,7 +1765,9 @@ static void spi_exchange(FAR struct spi_dev_s *dev, FAR const void *txbuffer,
FAR void *rxbuffer, size_t nwords)
{
FAR struct stm32_spidev_s *priv = (FAR struct stm32_spidev_s *)dev;
- FAR void * xbuffer = rxbuffer;
+ FAR void *xbuffer = rxbuffer;
+ int ret;
+
DEBUGASSERT(priv != NULL);
/* Convert the number of word to a number of bytes */
@@ -1843,10 +1865,13 @@ static void spi_exchange(FAR struct spi_dev_s *dev, FAR const void *txbuffer,
/* Then wait for each to complete */
- spi_dmarxwait(priv);
- spi_dmatxwait(priv);
+ ret = spi_dmarxwait(priv);
+ if (ret < 0)
+ {
+ ret = spi_dmatxwait(priv);
+ }
- if (rxbuffer && priv->rxbuf)
+ if (rxbuffer != NULL && priv->rxbuf != NULL && ret >= 0)
{
memcpy(xbuffer, priv->rxbuf, nbytes);
}
diff --git a/arch/arm/src/stm32f0l0g0/stm32_spi.c b/arch/arm/src/stm32f0l0g0/stm32_spi.c
index c035785..d7a11d4 100644
--- a/arch/arm/src/stm32f0l0g0/stm32_spi.c
+++ b/arch/arm/src/stm32f0l0g0/stm32_spi.c
@@ -2,35 +2,20 @@
* arch/arm/src/stm32f0l0g0/stm32_spi.c
* copied from arch/arm/src/stm32
*
- * Copyright (C) 2009-2013, 2016 Gregory Nutt. All rights reserved.
- * Author: Gregory Nutt <gn...@nuttx.org>
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in
- * the documentation and/or other materials provided with the
- * distribution.
- * 3. Neither the name NuttX nor the names of its contributors may be
- * used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
- * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
- * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
- * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
- * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
- * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership. The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
*
****************************************************************************/
@@ -198,8 +183,8 @@ static inline bool spi_16bitmode(FAR struct stm32_spidev_s *priv);
/* DMA support */
#ifdef CONFIG_STM32F0L0G0_SPI_DMA
-static void spi_dmarxwait(FAR struct stm32_spidev_s *priv);
-static void spi_dmatxwait(FAR struct stm32_spidev_s *priv);
+static int spi_dmarxwait(FAR struct stm32_spidev_s *priv);
+static int spi_dmatxwait(FAR struct stm32_spidev_s *priv);
static inline void spi_dmarxwakeup(FAR struct stm32_spidev_s *priv);
static inline void spi_dmatxwakeup(FAR struct stm32_spidev_s *priv);
static void spi_dmarxcallback(DMA_HANDLE handle, uint8_t isr,
@@ -581,7 +566,7 @@ static inline bool spi_16bitmode(FAR struct stm32_spidev_s *priv)
}
/****************************************************************************
- * Name: spi_dmarxwaitw
+ * Name: spi_dmarxwait
*
* Description:
* Wait for DMA to complete.
@@ -589,17 +574,27 @@ static inline bool spi_16bitmode(FAR struct stm32_spidev_s *priv)
****************************************************************************/
#ifdef CONFIG_STM32F0L0G0_SPI_DMA
-static void spi_dmarxwait(FAR struct stm32_spidev_s *priv)
+static int spi_dmarxwait(FAR struct stm32_spidev_s *priv)
{
+ int ret;
+
/* Take the semaphore (perhaps waiting). If the result is zero, then the
* DMA must not really have completed???
*/
do
{
- nxsem_wait_uninterruptible(&priv->rxsem);
+ ret = nxsem_wait_uninterruptible(&priv->rxsem);
+
+ /* The only expected error is ECANCELED which would occur if the
+ * calling thread were canceled.
+ */
+
+ DEBUGASSERT(ret == OK || ret == -ECANCELED);
}
- while (priv->rxresult == 0);
+ while (priv->rxresult == 0 && ret == OK);
+
+ return ret;
}
#endif
@@ -612,17 +607,27 @@ static void spi_dmarxwait(FAR struct stm32_spidev_s *priv)
****************************************************************************/
#ifdef CONFIG_STM32F0L0G0_SPI_DMA
-static void spi_dmatxwait(FAR struct stm32_spidev_s *priv)
+static int spi_dmatxwait(FAR struct stm32_spidev_s *priv)
{
+ int ret;
+
/* Take the semaphore (perhaps waiting). If the result is zero, then the
* DMA must not really have completed???
*/
do
{
- nxsem_wait_uninterruptible(&priv->txsem);
+ ret = nxsem_wait_uninterruptible(&priv->txsem);
+
+ /* The only expected error is ECANCELED which would occur if the
+ * calling thread were canceled.
+ */
+
+ DEBUGASSERT(ret == OK || ret == -ECANCELED);
}
- while (priv->txresult == 0);
+ while (priv->txresult == 0 && ret == OK);
+
+ return ret;
}
#endif
@@ -1446,8 +1451,12 @@ static void spi_exchange(FAR struct spi_dev_s *dev, FAR const void *txbuffer,
/* Then wait for each to complete */
- spi_dmarxwait(priv);
- spi_dmatxwait(priv);
+ ret = spi_dmarxwait(priv);
+ if (ret >= 0)
+ {
+ ret = spi_dmatxwait(priv);
+ UNUSED(ret);
+ }
#ifdef CONFIG_SPI_TRIGGER
priv->trigarmed = false;
diff --git a/arch/arm/src/stm32f7/stm32_spi.c b/arch/arm/src/stm32f7/stm32_spi.c
index 9d82b48..31c70b6 100644
--- a/arch/arm/src/stm32f7/stm32_spi.c
+++ b/arch/arm/src/stm32f7/stm32_spi.c
@@ -230,8 +230,8 @@ static inline void spi_writeword(FAR struct stm32_spidev_s *priv,
/* DMA support */
#ifdef CONFIG_STM32F7_SPI_DMA
-static void spi_dmarxwait(FAR struct stm32_spidev_s *priv);
-static void spi_dmatxwait(FAR struct stm32_spidev_s *priv);
+static int spi_dmarxwait(FAR struct stm32_spidev_s *priv);
+static int spi_dmatxwait(FAR struct stm32_spidev_s *priv);
static inline void spi_dmarxwakeup(FAR struct stm32_spidev_s *priv);
static inline void spi_dmatxwakeup(FAR struct stm32_spidev_s *priv);
static void spi_dmarxcallback(DMA_HANDLE handle, uint8_t isr,
@@ -897,17 +897,27 @@ static inline void spi_writebyte(FAR struct stm32_spidev_s *priv,
****************************************************************************/
#ifdef CONFIG_STM32F7_SPI_DMA
-static void spi_dmarxwait(FAR struct stm32_spidev_s *priv)
+static int spi_dmarxwait(FAR struct stm32_spidev_s *priv)
{
+ int ret;
+
/* Take the semaphore (perhaps waiting). If the result is zero, then the
* DMA must not really have completed???
*/
do
{
- nxsem_wait_uninterruptible(&priv->rxsem);
+ ret = nxsem_wait_uninterruptible(&priv->rxsem);
+
+ /* The only expected error is ECANCELED which would occur if the
+ * calling thread were canceled.
+ */
+
+ DEBUGASSERT(ret == OK || ret == -ECANCELED);
}
- while (priv->rxresult == 0);
+ while (priv->rxresult == 0 && ret == OK);
+
+ return ret;
}
#endif
@@ -920,17 +930,27 @@ static void spi_dmarxwait(FAR struct stm32_spidev_s *priv)
****************************************************************************/
#ifdef CONFIG_STM32F7_SPI_DMA
-static void spi_dmatxwait(FAR struct stm32_spidev_s *priv)
+static int spi_dmatxwait(FAR struct stm32_spidev_s *priv)
{
+ int ret;
+
/* Take the semaphore (perhaps waiting). If the result is zero, then the
* DMA must not really have completed???
*/
do
{
- nxsem_wait_uninterruptible(&priv->txsem);
+ ret = nxsem_wait_uninterruptible(&priv->txsem);
+
+ /* The only expected error is ECANCELED which would occur if the
+ * calling thread were canceled.
+ */
+
+ DEBUGASSERT(ret == OK || ret == -ECANCELED);
}
- while (priv->txresult == 0);
+ while (priv->txresult == 0 && ret == OK);
+
+ return ret;
}
#endif
@@ -1878,8 +1898,11 @@ static void spi_exchange(FAR struct spi_dev_s *dev, FAR const void *txbuffer,
/* Then wait for each to complete */
- spi_dmarxwait(priv);
- spi_dmatxwait(priv);
+ ret = spi_dmarxwait(priv);
+ if (ret >= 0)
+ {
+ ret = spi_dmatxwait(priv);
+ }
#ifdef CONFIG_SPI_TRIGGER
priv->trigarmed = false;
@@ -1887,7 +1910,7 @@ static void spi_exchange(FAR struct spi_dev_s *dev, FAR const void *txbuffer,
/* Force RAM re-read */
- if (rxbuffer)
+ if (rxbuffer != NULL && ret >= 0)
{
up_invalidate_dcache((uintptr_t)rxbuffer,
(uintptr_t)rxbuffer + nbytes);
diff --git a/arch/arm/src/stm32h7/stm32_spi.c b/arch/arm/src/stm32h7/stm32_spi.c
index a9251bb..c071585 100644
--- a/arch/arm/src/stm32h7/stm32_spi.c
+++ b/arch/arm/src/stm32h7/stm32_spi.c
@@ -226,8 +226,8 @@ static inline void spi_dumpregs(FAR struct stm32_spidev_s *priv);
/* DMA support */
#ifdef CONFIG_STM32H7_SPI_DMA
-static void spi_dmarxwait(FAR struct stm32_spidev_s *priv);
-static void spi_dmatxwait(FAR struct stm32_spidev_s *priv);
+static int spi_dmarxwait(FAR struct stm32_spidev_s *priv);
+static int spi_dmatxwait(FAR struct stm32_spidev_s *priv);
static inline void spi_dmarxwakeup(FAR struct stm32_spidev_s *priv);
static inline void spi_dmatxwakeup(FAR struct stm32_spidev_s *priv);
static void spi_dmarxcallback(DMA_HANDLE handle, uint8_t isr,
@@ -844,17 +844,27 @@ static inline bool spi_9to16bitmode(FAR struct stm32_spidev_s *priv)
****************************************************************************/
#ifdef CONFIG_STM32H7_SPI_DMA
-static void spi_dmarxwait(FAR struct stm32_spidev_s *priv)
+static int spi_dmarxwait(FAR struct stm32_spidev_s *priv)
{
+ int ret;
+
/* Take the semaphore (perhaps waiting). If the result is zero, then the
* DMA must not really have completed???
*/
do
{
- nxsem_wait_uninterruptible(&priv->rxsem);
+ ret = nxsem_wait_uninterruptible(&priv->rxsem);
+
+ /* The only expected error is ECANCELED which would occur if the
+ * calling thread were canceled.
+ */
+
+ DEBUGASSERT(ret == OK || ret == -ECANCELED);
}
- while (priv->rxresult == 0);
+ while (priv->rxresult == 0 && ret == OK);
+
+ return ret;
}
#endif
@@ -867,17 +877,27 @@ static void spi_dmarxwait(FAR struct stm32_spidev_s *priv)
****************************************************************************/
#ifdef CONFIG_STM32H7_SPI_DMA
-static void spi_dmatxwait(FAR struct stm32_spidev_s *priv)
+static int spi_dmatxwait(FAR struct stm32_spidev_s *priv)
{
+ int ret;
+
/* Take the semaphore (perhaps waiting). If the result is zero, then the
* DMA must not really have completed???
*/
do
{
- nxsem_wait_uninterruptible(&priv->txsem);
+ ret = nxsem_wait_uninterruptible(&priv->txsem);
+
+ /* The only expected error is ECANCELED which would occur if the
+ * calling thread were canceled.
+ */
+
+ DEBUGASSERT(ret == OK || ret == -ECANCELED);
}
- while (priv->txresult == 0);
+ while (priv->txresult == 0 && ret == OK);
+
+ return ret;
}
#endif
@@ -1828,8 +1848,12 @@ static void spi_exchange(FAR struct spi_dev_s *dev, FAR const void *txbuffer,
/* Then wait for each to complete */
- spi_dmarxwait(priv);
- spi_dmatxwait(priv);
+ ret = spi_dmarxwait(priv);
+ if (ret >= 0)
+ {
+ ret = spi_dmatxwait(priv);
+ UNUSED(ret);
+ }
#ifdef CONFIG_SPI_TRIGGER
priv->trigarmed = false;
@@ -1837,7 +1861,7 @@ static void spi_exchange(FAR struct spi_dev_s *dev, FAR const void *txbuffer,
/* Force RAM re-read */
- if (rxbuffer)
+ if (rxbuffer != NULL)
{
up_invalidate_dcache((uintptr_t)rxbuffer,
(uintptr_t)rxbuffer + buflen);
diff --git a/arch/arm/src/stm32l4/stm32l4_spi.c b/arch/arm/src/stm32l4/stm32l4_spi.c
index e264758..0771a1b 100644
--- a/arch/arm/src/stm32l4/stm32l4_spi.c
+++ b/arch/arm/src/stm32l4/stm32l4_spi.c
@@ -1,35 +1,20 @@
/****************************************************************************
* arch/arm/src/stm32l4/stm32l4_spi.c
*
- * Copyright (C) 2009-2013, 2016 Gregory Nutt. All rights reserved.
- * Author: Gregory Nutt <gn...@nuttx.org>
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in
- * the documentation and/or other materials provided with the
- * distribution.
- * 3. Neither the name NuttX nor the names of its contributors may be
- * used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
- * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
- * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
- * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
- * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
- * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership. The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
*
****************************************************************************/
@@ -199,8 +184,8 @@ static inline bool spi_16bitmode(FAR struct stm32l4_spidev_s *priv);
/* DMA support */
#ifdef CONFIG_STM32L4_SPI_DMA
-static void spi_dmarxwait(FAR struct stm32l4_spidev_s *priv);
-static void spi_dmatxwait(FAR struct stm32l4_spidev_s *priv);
+static int spi_dmarxwait(FAR struct stm32l4_spidev_s *priv);
+static int spi_dmatxwait(FAR struct stm32l4_spidev_s *priv);
static inline void spi_dmarxwakeup(FAR struct stm32l4_spidev_s *priv);
static inline void spi_dmatxwakeup(FAR struct stm32l4_spidev_s *priv);
static void spi_dmarxcallback(DMA_HANDLE handle, uint8_t isr,
@@ -640,17 +625,27 @@ static inline bool spi_16bitmode(FAR struct stm32l4_spidev_s *priv)
****************************************************************************/
#ifdef CONFIG_STM32L4_SPI_DMA
-static void spi_dmarxwait(FAR struct stm32l4_spidev_s *priv)
+static int spi_dmarxwait(FAR struct stm32l4_spidev_s *priv)
{
+ int ret;
+
/* Take the semaphore (perhaps waiting). If the result is zero, then the
* DMA must not really have completed???
*/
do
{
- nxsem_wait_uninterruptible(&priv->rxsem);
+ ret = nxsem_wait_uninterruptible(&priv->rxsem);
+
+ /* The only expected error is ECANCELED which would occur if the
+ * calling thread were canceled.
+ */
+
+ DEBUGASSERT(ret == OK || ret == -ECANCELED);
}
- while (priv->rxresult == 0);
+ while (priv->rxresult == 0 && ret == OK);
+
+ return ret;
}
#endif
@@ -663,17 +658,27 @@ static void spi_dmarxwait(FAR struct stm32l4_spidev_s *priv)
****************************************************************************/
#ifdef CONFIG_STM32L4_SPI_DMA
-static void spi_dmatxwait(FAR struct stm32l4_spidev_s *priv)
+static int spi_dmatxwait(FAR struct stm32l4_spidev_s *priv)
{
+ int ret;
+
/* Take the semaphore (perhaps waiting). If the result is zero, then the
* DMA must not really have completed???
*/
do
{
- nxsem_wait_uninterruptible(&priv->txsem);
+ ret = nxsem_wait_uninterruptible(&priv->txsem);
+
+ /* The only expected error is ECANCELED which would occur if the
+ * calling thread were canceled.
+ */
+
+ DEBUGASSERT(ret == OK || ret == -ECANCELED);
}
- while (priv->txresult == 0);
+ while (priv->txresult == 0 && ret == OK);
+
+ return ret;
}
#endif
@@ -1496,8 +1501,12 @@ static void spi_exchange(FAR struct spi_dev_s *dev, FAR const void *txbuffer,
/* Then wait for each to complete */
- spi_dmarxwait(priv);
- spi_dmatxwait(priv);
+ ret = spi_dmarxwait(priv);
+ if (ret >= 0)
+ {
+ ret = spi_dmatxwait(priv);
+ UNUSED(ret);
+ }
#ifdef CONFIG_SPI_TRIGGER
priv->trigarmed = false;
diff --git a/arch/arm/src/tiva/common/tiva_ssi.c b/arch/arm/src/tiva/common/tiva_ssi.c
index 7a10329..3eab257 100644
--- a/arch/arm/src/tiva/common/tiva_ssi.c
+++ b/arch/arm/src/tiva/common/tiva_ssi.c
@@ -1,35 +1,20 @@
/****************************************************************************
* arch/arm/src/tiva/common/tiva_ssi.c
*
- * Copyright (C) 2009-2017 Gregory Nutt. All rights reserved.
- * Author: Gregory Nutt <gn...@nuttx.org>
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in
- * the documentation and/or other materials provided with the
- * distribution.
- * 3. Neither the name NuttX nor the names of its contributors may be
- * used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
- * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
- * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
- * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
- * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
- * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership. The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
*
****************************************************************************/
@@ -239,7 +224,7 @@ static uint32_t ssi_disable(struct tiva_ssidev_s *priv);
static void ssi_enable(struct tiva_ssidev_s *priv, uint32_t enable);
#ifndef CONFIG_SSI_POLLWAIT
-static void ssi_semtake(sem_t *sem);
+static int ssi_semtake(sem_t *sem);
#define ssi_semgive(s) nxsem_post(s);
#endif
@@ -501,9 +486,9 @@ static void ssi_enable(struct tiva_ssidev_s *priv, uint32_t enable)
****************************************************************************/
#ifndef CONFIG_SSI_POLLWAIT
-static void ssi_semtake(sem_t *sem)
+static int ssi_semtake(sem_t *sem)
{
- nxsem_wait_uninterruptible(sem);
+ return nxsem_wait_uninterruptible(sem);
}
#endif
@@ -842,9 +827,9 @@ static int ssi_transfer(struct tiva_ssidev_s *priv, const void *txbuffer,
priv->txbuffer = (uint8_t *)txbuffer; /* Source buffer */
priv->rxbuffer = (uint8_t *)rxbuffer; /* Destination buffer */
- priv->ntxwords = nwords; /* Number of words left to send */
- priv->nrxwords = 0; /* Number of words received */
- priv->nwords = nwords; /* Total number of exchanges */
+ priv->ntxwords = nwords; /* Number of words left to send */
+ priv->nrxwords = 0; /* Number of words received */
+ priv->nwords = nwords; /* Total number of exchanges */
/* Set up the low-level data transfer function pointers */
@@ -905,9 +890,10 @@ static int ssi_transfer(struct tiva_ssidev_s *priv, const void *txbuffer,
leave_critical_section(flags);
do
{
- ssi_semtake(&priv->xfrsem);
+ ret = ssi_semtake(&priv->xfrsem);
}
- while (priv->nrxwords < priv->nwords);
+ while (priv->nrxwords < priv->nwords && ret >= 0);
+
spiinfo("Transfer complete\n");
#else
@@ -1527,12 +1513,11 @@ FAR struct spi_dev_s *tiva_ssibus_initialize(int port)
tiva_ssi0_enablepwr();
tiva_ssi0_enableclk();
- /* Configure SSI0 GPIOs (NOTE that SS is not initialized here, the
- * logic in this file makes no assumptions about chip select)
+ /* Configure SSI0 GPIOs (NOTE that SSI0Fss is not initialized here,
+ * the logic in this file makes no assumptions about chip select).
*/
tiva_configgpio(GPIO_SSI0_CLK); /* PA2: SSI0 clock (SSI0Clk) */
- /* tiva_configgpio(GPIO_SSI0_FSS); PA3: SSI0 frame (SSI0Fss) */
tiva_configgpio(GPIO_SSI0_RX); /* PA4: SSI0 receive (SSI0Rx) */
tiva_configgpio(GPIO_SSI0_TX); /* PA5: SSI0 transmit (SSI0Tx) */
break;
@@ -1559,10 +1544,9 @@ FAR struct spi_dev_s *tiva_ssibus_initialize(int port)
tiva_ssi1_enablepwr();
tiva_ssi1_enableclk();
- /* Configure SSI1 GPIOs */
+ /* Configure SSI1 GPIOs (except for SSI1Fss) */
tiva_configgpio(GPIO_SSI1_CLK); /* PE0: SSI1 clock (SSI1Clk) */
- /* tiva_configgpio(GPIO_SSI1_FSS); PE1: SSI1 frame (SSI1Fss) */
tiva_configgpio(GPIO_SSI1_RX); /* PE2: SSI1 receive (SSI1Rx) */
tiva_configgpio(GPIO_SSI1_TX); /* PE3: SSI1 transmit (SSI1Tx) */
break;
@@ -1589,10 +1573,9 @@ FAR struct spi_dev_s *tiva_ssibus_initialize(int port)
tiva_ssi2_enablepwr();
tiva_ssi2_enableclk();
- /* Configure SSI2 GPIOs */
+ /* Configure SSI2 GPIOs (except for SSI2Fss) */
tiva_configgpio(GPIO_SSI2_CLK); /* PE0: SSI2 clock (SSI2Clk) */
- /* tiva_configgpio(GPIO_SSI2_FSS); PE1: SSI2 frame (SSI2Fss) */
tiva_configgpio(GPIO_SSI2_RX); /* PE2: SSI2 receive (SSI2Rx) */
tiva_configgpio(GPIO_SSI2_TX); /* PE3: SSI2 transmit (SSI2Tx) */
break;
@@ -1619,10 +1602,9 @@ FAR struct spi_dev_s *tiva_ssibus_initialize(int port)
tiva_ssi3_enablepwr();
tiva_ssi3_enableclk();
- /* Configure SSI3 GPIOs */
+ /* Configure SSI3 GPIOs (except for SSI3Fss) */
tiva_configgpio(GPIO_SSI3_CLK); /* PE0: SSI3 clock (SSI3Clk) */
- /* tiva_configgpio(GPIO_SSI3_FSS); PE1: SSI3 frame (SSI3Fss) */
tiva_configgpio(GPIO_SSI3_RX); /* PE2: SSI3 receive (SSI3Rx) */
tiva_configgpio(GPIO_SSI3_TX); /* PE3: SSI3 transmit (SSI3Tx) */
break;