summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorpatacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3>2009-05-24 13:25:43 +0000
committerpatacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3>2009-05-24 13:25:43 +0000
commite2a24a1500e26a3c53a64238bd249f512ca736f1 (patch)
treedbace1acc66d280a7f0e7601d3afc510d7e8948f
parent2bec7f89cc1a4246ef3f0ed18525faef2482419d (diff)
downloadpx4-nuttx-e2a24a1500e26a3c53a64238bd249f512ca736f1.tar.gz
px4-nuttx-e2a24a1500e26a3c53a64238bd249f512ca736f1.tar.bz2
px4-nuttx-e2a24a1500e26a3c53a64238bd249f512ca736f1.zip
Initial SSI debug
git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@1822 42af7a65-404d-4744-a932-0658087f49c3
-rwxr-xr-xnuttx/arch/arm/src/lm3s/lm3s_ssi.c94
1 files changed, 77 insertions, 17 deletions
diff --git a/nuttx/arch/arm/src/lm3s/lm3s_ssi.c b/nuttx/arch/arm/src/lm3s/lm3s_ssi.c
index 4fbc83a7d..7c91a0709 100755
--- a/nuttx/arch/arm/src/lm3s/lm3s_ssi.c
+++ b/nuttx/arch/arm/src/lm3s/lm3s_ssi.c
@@ -60,6 +60,20 @@
* Definitions
****************************************************************************/
+/* Enables debug output from this file (needs CONFIG_DEBUG with
+ * CONFIG_DEBUG_VERBOSE too)
+ */
+
+#undef SSI_DEBUG /* Define to enable debug */
+
+#ifdef SSI_DEBUG
+# define ssidbg lldbg
+# define ssivdbg llvdbg
+#else
+# define ssidbg(x...)
+# define ssivdbg(x...)
+#endif
+
/* How many SSI modules does this chip support? The LM3S6918 supports 2 SSI
* modules (others may support more -- in such case, the following must be
* expanded).
@@ -181,7 +195,7 @@ static void ssi_rxnull(struct lm32_ssidev_s *priv);
static void ssi_rxuint16(struct lm32_ssidev_s *priv);
static void ssi_rxubyte(struct lm32_ssidev_s *priv);
static inline boolean ssi_txfifofull(struct lm32_ssidev_s *priv);
-static inline boolean ssi_rxfifonotempty(struct lm32_ssidev_s *priv);
+static inline boolean ssi_rxfifoempty(struct lm32_ssidev_s *priv);
static int ssi_performtx(struct lm32_ssidev_s *priv);
static inline void ssi_performrx(struct lm32_ssidev_s *priv);
static int ssi_transfer(struct lm32_ssidev_s *priv, const void *txbuffer,
@@ -341,6 +355,7 @@ static uint32 ssi_disable(struct lm32_ssidev_s *priv)
retval = ssi_getreg(priv, LM3S_SSI_CR1_OFFSET);
regval = (retval & ~SSI_CR1_SSE);
ssi_putreg(priv, LM3S_SSI_CR1_OFFSET, regval);
+ ssivdbg("CR1: %08x\n", regval);
return retval;
}
@@ -364,6 +379,7 @@ static void ssi_enable(struct lm32_ssidev_s *priv, uint32 enable)
regval &= ~SSI_CR1_SSE;
regval |= (enable & SSI_CR1_SSE);
ssi_putreg(priv, LM3S_SSI_CR1_OFFSET, regval);
+ ssivdbg("CR1: %08x\n", regval);
}
/****************************************************************************
@@ -467,7 +483,7 @@ static void ssi_rxubyte(struct lm32_ssidev_s *priv)
* Name: ssi_txfifofull
*
* Description:
- * Return TRUE if the Tx FIFO is not full
+ * Return TRUE if the Tx FIFO is full
*
* Input Parameters:
* priv - Device-specific state data
@@ -479,14 +495,14 @@ static void ssi_rxubyte(struct lm32_ssidev_s *priv)
static inline boolean ssi_txfifofull(struct lm32_ssidev_s *priv)
{
- return (ssi_getreg(priv, LM3S_SSI_SR_OFFSET) & SSI_SR_TNF) != 0;
+ return (ssi_getreg(priv, LM3S_SSI_SR_OFFSET) & SSI_SR_TNF) == 0;
}
/****************************************************************************
- * Name: ssi_rxfifonotempty
+ * Name: ssi_rxfifoempty
*
* Description:
- * Return TRUE if the Rx FIFO is not empty
+ * Return TRUE if the Rx FIFO is empty
*
* Input Parameters:
* priv - Device-specific state data
@@ -496,9 +512,9 @@ static inline boolean ssi_txfifofull(struct lm32_ssidev_s *priv)
*
****************************************************************************/
-static inline boolean ssi_rxfifonotempty(struct lm32_ssidev_s *priv)
+static inline boolean ssi_rxfifoempty(struct lm32_ssidev_s *priv)
{
- return (ssi_getreg(priv, LM3S_SSI_SR_OFFSET) & SSI_SR_RNE) != 0;
+ return (ssi_getreg(priv, LM3S_SSI_SR_OFFSET) & SSI_SR_RNE) == 0;
}
/****************************************************************************
@@ -555,7 +571,7 @@ static int ssi_performtx(struct lm32_ssidev_s *priv)
*/
#ifdef CONFIG_DEBUG
- regval |= (SSI_IM_TX|SSI_RIS_ROR)
+ regval |= (SSI_IM_TX|SSI_RIS_ROR);
#else
regval |= SSI_IM_TX;
#endif
@@ -597,7 +613,7 @@ static inline void ssi_performrx(struct lm32_ssidev_s *priv)
/* Loop while data is available in the Rx FIFO */
- while (ssi_rxfifonotempty(priv))
+ while (!ssi_rxfifoempty(priv))
{
/* Have all of the requested words been transferred from the Rx FIFO? */
@@ -671,6 +687,7 @@ static int ssi_transfer(struct lm32_ssidev_s *priv, const void *txbuffer,
#endif
int ntxd;
+ ssidbg("txbuffer: %p rxbuffer: %p nwords: %d\n", txbuffer, rxbuffer, nwords);
ssi_semtake(&priv->exclsem);
/* Set up to perform the transfer */
@@ -707,24 +724,40 @@ static int ssi_transfer(struct lm32_ssidev_s *priv, const void *txbuffer,
/* Prime the Tx FIFO to start the sequence (saves one interrupt).
* At this point, all SSI interrupts should be disabled, but the
* operation of ssi_performtx() will set up the interrupts
- * approapriately.
+ * approapriately (if nwords > TxFIFO size).
*/
#ifndef CONFIG_SSI_POLLWAIT
flags = irqsave();
+ ssivdbg("ntxwords: %d nrxwords: %d nwords: %d SR: %08x\n",
+ priv->ntxwords, priv->nrxwords, priv->nwords,
+ ssi_getreg(priv, LM3S_SSI_SR_OFFSET));
ntxd = ssi_performtx(priv);
+ /* For the case where nwords < Tx FIFO size, ssi_performrx will
+ * configure interrupts correctly for the final phase of the
+ * the transfer.
+ */
+
+ ssi_performrx(priv);
+ ssivdbg("ntxwords: %d nrxwords: %d nwords: %d SR: %08x IM: %08x\n",
+ priv->ntxwords, priv->nrxwords, priv->nwords,
+ ssi_getreg(priv, LM3S_SSI_SR_OFFSET),
+ ssi_getreg(priv, LM3S_SSI_IM_OFFSET));
+
/* Wait for the transfer to complete. Since there is no handshake
* with SPI, the following should complete even if there are problems
* with the transfer, so it should be safe with no timeout.
*/
+ ssivdbg("Waiting for transfer complete\n");
irqrestore(flags);
do
{
ssi_semtake(&priv->xfrsem);
}
while (priv->nrxwords < priv->nwords);
+ ssidbg("Transfer complete\n");
#else
/* Perform the transfer using polling logic. This will totally
@@ -832,6 +865,10 @@ static int ssi_interrupt(int irq, void *context)
}
#endif
+ ssivdbg("ntxwords: %d nrxwords: %d nwords: %d SR: %08x\n",
+ priv->ntxwords, priv->nrxwords, priv->nwords,
+ ssi_getreg(priv, LM3S_SSI_SR_OFFSET));
+
/* Handle outgoing Tx FIFO transfers */
ntxd = ssi_performtx(priv);
@@ -840,6 +877,11 @@ static int ssi_interrupt(int irq, void *context)
ssi_performrx(priv);
+ ssivdbg("ntxwords: %d nrxwords: %d nwords: %d SR: %08x IM: %08x\n",
+ priv->ntxwords, priv->nrxwords, priv->nwords,
+ ssi_getreg(priv, LM3S_SSI_SR_OFFSET),
+ ssi_getreg(priv, LM3S_SSI_IM_OFFSET));
+
/* Check if the transfer is complete */
if (priv->nrxwords >= priv->nwords)
@@ -850,6 +892,7 @@ static int ssi_interrupt(int irq, void *context)
/* Wake up the waiting thread */
+ ssidbg("Transfer complete\n");
ssi_semgive(&priv->xfrsem);
}
return OK;
@@ -878,6 +921,7 @@ static void ssi_setfrequencyinternal(struct lm32_ssidev_s *priv, uint32 frequenc
uint32 regval;
uint32 scr;
+ ssidbg("frequency: %d\n", frequency);
if (priv && frequency != priv->frequency)
{
/* "The serial bit rate is derived by dividing down the input clock
@@ -934,7 +978,7 @@ static void ssi_setfrequencyinternal(struct lm32_ssidev_s *priv, uint32 frequenc
/* Set CPDVSR */
- DEBUGASSERT(cpdvsr < 255);
+ DEBUGASSERT(cpsdvsr < 255);
ssi_putreg(priv, LM3S_SSI_CPSR_OFFSET, cpsdvsr);
/* Set SCR */
@@ -943,6 +987,7 @@ static void ssi_setfrequencyinternal(struct lm32_ssidev_s *priv, uint32 frequenc
regval &= ~SSI_CR0_SCR_MASK;
regval |= (scr << SSI_CR0_SCR_SHIFT);
ssi_putreg(priv, LM3S_SSI_CR0_OFFSET, regval);
+ ssivdbg("CR0: %08x CPSR: %08x\n", regval, cpsdvsr);
/* Calcluate the actual frequency */
@@ -985,7 +1030,7 @@ static void ssi_setmodeinternal(struct lm32_ssidev_s *priv, enum spi_mode_e mode
uint32 modebits;
uint32 regval;
- ssi_semtake(&priv->exclsem);
+ ssidbg("mode: %d\n", mode);
if (priv && mode != priv->mode)
{
/* Select the CTL register bits based on the selected mode */
@@ -1018,6 +1063,7 @@ static void ssi_setmodeinternal(struct lm32_ssidev_s *priv, enum spi_mode_e mode
regval &= ~SSI_CR0_FRF_MASK;
regval |= modebits;
ssi_putreg(priv, LM3S_SSI_CR0_OFFSET, regval);
+ ssivdbg("CR0: %08x\n", regval);
}
}
@@ -1054,13 +1100,14 @@ static void ssi_setbitsinternal(struct lm32_ssidev_s *priv, int nbits)
{
uint32 regval;
- ssi_semtake(&priv->exclsem);
+ ssidbg("nbits: %d\n", nbits);
if (priv && nbits != priv->nbits && nbits >=4 && nbits <= 16)
{
regval = ssi_getreg(priv, LM3S_SSI_CR0_OFFSET);
regval &= ~SSI_CR0_DSS_MASK;
regval |= ((nbits - 1) << SSI_CR0_DSS_SHIFT);
ssi_putreg(priv, LM3S_SSI_CR0_OFFSET, regval);
+ ssivdbg("CR0: %08x\n", regval);
priv->nbits = nbits;
}
@@ -1220,6 +1267,8 @@ FAR struct spi_dev_s *up_spiinitialize(int port)
irqstate_t flags;
ubyte regval;
+ ssidbg("port: %d\n", port);
+
/* Set up for the selected port */
flags = irqsave();
@@ -1236,6 +1285,7 @@ FAR struct spi_dev_s *up_spiinitialize(int port)
regval = getreg32(LM3S_SYSCON_RCGC1);
regval |= SYSCON_RCGC1_SSI0;
putreg32(regval, LM3S_SYSCON_RCGC1);
+ ssivdbg("RCGC1: %08x\n", regval);
/* Configure SSI0 GPIOs (NOTE that SS is not initialized here, the
* logic in this file makes no assumptions about chip select)
@@ -1259,6 +1309,7 @@ FAR struct spi_dev_s *up_spiinitialize(int port)
regval = getreg32(LM3S_SYSCON_RCGC1);
regval |= SYSCON_RCGC1_SSI1;
putreg32(regval, LM3S_SYSCON_RCGC1);
+ ssivdbg("RCGC1: %08x\n", regval);
/* Configure SSI1 GPIOs */
@@ -1289,19 +1340,28 @@ FAR struct spi_dev_s *up_spiinitialize(int port)
ssi_putreg(priv, LM3S_SSI_CR0_OFFSET, 0);
- /* Set the initial mode to mode 0 */
+ /* Set the initial mode to mode 0. The application may override
+ * this initial setting using the setmode() method.
+ */
ssi_setmodeinternal(priv, SPIDEV_MODE0);
- /* Set the initial data width to 8-bits */
+ /* Set the initial data width to 8-bits. The application may
+ * override this initial setting using the setbits() method.
+ */
ssi_setbitsinternal(priv, 8);
- /* Set the initialize clock frequency for detection */
+ /* Pick some initialize clock frequency. 400,000Hz is the startup
+ * MMC/SD frequency used for card detection. The application may
+ * override this setting using the setfrequency() method.
+ */
ssi_setfrequencyinternal(priv, 400000);
- /* Disable all SSI interrupt sources */
+ /* Disable all SSI interrupt sources. They will be enabled only
+ * while there is an SSI transfer in progress.
+ */
ssi_putreg(priv, LM3S_SSI_IM_OFFSET, 0);