summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--nuttx/ChangeLog5
-rw-r--r--nuttx/Documentation/NuttX.html7
-rwxr-xr-xnuttx/arch/arm/src/imx/imx_cspi.h2
-rwxr-xr-xnuttx/arch/arm/src/imx/imx_spi.c191
-rwxr-xr-xnuttx/arch/z80/src/ez80/ez80_spi.c35
-rw-r--r--nuttx/configs/mcu123-lpc214x/src/up_spi.c45
-rw-r--r--nuttx/configs/olimex-strp711/src/up_spi.c41
-rw-r--r--nuttx/drivers/mmcsd/mmcsd_spi.c82
-rw-r--r--nuttx/include/nuttx/spi.h29
9 files changed, 269 insertions, 168 deletions
diff --git a/nuttx/ChangeLog b/nuttx/ChangeLog
index d1903f380..4464c8615 100644
--- a/nuttx/ChangeLog
+++ b/nuttx/ChangeLog
@@ -699,3 +699,8 @@
0.4.6 2009-xx-xx Gregory Nutt <spudmonkey@racsa.co.cr>
+ * Change SPI interface so that is can accomodate interfaces where the
+ number of bits per word is greater an 8 (such as with many 9-bit display
+ interfaces). -- this might have broken a few things which will need to
+ be retested!
+
diff --git a/nuttx/Documentation/NuttX.html b/nuttx/Documentation/NuttX.html
index 0f600f2e1..15977d93d 100644
--- a/nuttx/Documentation/NuttX.html
+++ b/nuttx/Documentation/NuttX.html
@@ -8,7 +8,7 @@
<tr align="center" bgcolor="#e4e4e4">
<td>
<h1><big><font color="#3c34ec"><i>NuttX RTOS</i></font></big></h1>
- <p>Last Updated: April 25, 2009</p>
+ <p>Last Updated: April 26, 2009</p>
</td>
</tr>
</table>
@@ -1385,6 +1385,11 @@ buildroot-0.1.5 2009-04-25 &lt;spudmonkey@racsa.co.cr&gt;
<pre><ul>
nuttx-0.4.6 2009-xx-xx Gregory Nutt &lt;spudmonkey@racsa.co.cr&gt;
+ * Change SPI interface so that is can accomodate interfaces where the
+ number of bits per word is greater an 8 (such as with many 9-bit display
+ interfaces). -- this might have broken a few things which will need to
+ be retested!
+
pascal-0.1.3 2009-xx-xx Gregory Nutt &lt;spudmonkey@racsa.co.cr&gt;
buildroot-0.1.6 2009-xx-xx &lt;spudmonkey@racsa.co.cr&gt;
diff --git a/nuttx/arch/arm/src/imx/imx_cspi.h b/nuttx/arch/arm/src/imx/imx_cspi.h
index a42ca296a..71f9ad7cc 100755
--- a/nuttx/arch/arm/src/imx/imx_cspi.h
+++ b/nuttx/arch/arm/src/imx/imx_cspi.h
@@ -131,6 +131,8 @@
#define CSPI_INTCS_ROEN (1 << 14) /* BIT 14: RXFIFO Overflow Interrupt Enable */
#define CSPI_INTCS_BOEN (1 << 15) /* Bit 15: Bit Count Overflow Interrupt Enable */
+#define CSPI_INTCS_ALLINTS 0x0000ff00
+
/* CSPI Sample Period Control Register */
#define CSPI_SPCR_WAIT_SHIFT 0
diff --git a/nuttx/arch/arm/src/imx/imx_spi.c b/nuttx/arch/arm/src/imx/imx_spi.c
index a408ba9b8..b168290e2 100755
--- a/nuttx/arch/arm/src/imx/imx_spi.c
+++ b/nuttx/arch/arm/src/imx/imx_spi.c
@@ -87,12 +87,17 @@
struct imx_spidev_s
{
const struct spi_ops_s *ops; /* Common SPI operations */
+#ifndef CONFIG_SPI_POLLWAIT
+ sem_t sem; /* Wait for transfer to complete */
+#endif
uint32 base; /* SPI register base address */
uint32 frequency; /* Current desired SCLK frequency */
uint32 actual; /* Current actual SCLK frequency */
ubyte mode; /* Current mode */
ubyte nbytes; /* Current number of bits per word */
+#ifndef CONFIG_SPI_POLLWAIT
ubyte irq; /* SPI IRQ number */
+#endif
};
/****************************************************************************
@@ -103,16 +108,20 @@ struct imx_spidev_s
static inline uint32 spi_getreg(struct imx_spidev_s *priv, unsigned int offset);
static inline void spi_putreg(struct imx_spidev_s *priv, unsigned int offset, uint32 value);
-static ubyte spi_waitspif(struct imx_spidev_s *priv);
-static ubyte spi_transfer(struct imx_spidev_s *priv, ubyte ch);
+#ifndef CONFIG_SPI_POLLWAIT
+static inline struct imx_spidev_s *spi_mapirq(int irq);
+static int spi_interrupt(int irq, void *context);
+#endif
+static int spi_transfer(struct imx_spidev_s *priv, const void *txbuffer,
+ void *rxbuffer, unsigned int nwords);
/* SPI methods */
static uint32 spi_setfrequency(FAR struct spi_dev_s *dev, uint32 frequency);
static void spi_setmode(FAR struct spi_dev_s *dev, enum spi_mode_e mode);
-static ubyte spi_sndbyte(FAR struct spi_dev_s *dev, ubyte ch);
-static void spi_sndblock(FAR struct spi_dev_s *dev, FAR const ubyte *buffer, size_t buflen);
-static void spi_recvblock(FAR struct spi_dev_s *dev, FAR ubyte *buffer, size_t buflen);
+static ubyte spi_send(FAR struct spi_dev_s *dev, uint16 wd);
+static void spi_sndblock(FAR struct spi_dev_s *dev, FAR const void *buffer, size_t buflen);
+static void spi_recvblock(FAR struct spi_dev_s *dev, FAR void *buffer, size_t buflen);
/****************************************************************************
* Private Data
@@ -122,13 +131,13 @@ static void spi_recvblock(FAR struct spi_dev_s *dev, FAR ubyte *buffer, size_t
static const struct spi_ops_s g_spiops =
{
- imx_spiselect, /* Provided externally by board logic */
- spi_setfrequency,
- spi_setmode,
- imx_spistatus, /* Provided externally by board logic */
- spi_sndbyte,
- spi_sndblock,
- spi_recvblock,
+ .select = imx_spiselect, /* Provided externally by board logic */
+ .frequency = spi_setfrequency,
+ .setmode = spi_setmode,
+ .status = imx_spistatus, /* Provided externally by board logic */
+ .send = spi_send,
+ .sndblock = spi_sndblock,
+ .recvblock = spi_recvblock,
};
/* This supports is up to two SPI busses/ports */
@@ -139,14 +148,18 @@ static struct imx_spidev_s g_spidev[] =
{
.ops = &g_spiops,
.base = IMX_CSPI1_VBASE
+#ifndef CONFIG_SPI_POLLWAIT
.irq = IMX_IRQ_CSPI1,
+#endif
},
#endif
-#ifndef CONFIG_SPI1_DISABLE
+#ifndef CONFIG_SPI2_DISABLE
{
.ops = &g_spiops,
.base = IMX_CSPI2_VBASE
+#ifndef CONFIG_SPI_POLLWAIT
.irq = IMX_IRQ_CSPI2,
+#endif
},
#endif
};
@@ -201,62 +214,93 @@ static inline void spi_putreg(struct imx_spidev_s *priv, unsigned int offset, ui
}
/****************************************************************************
- * Name: spi_waitspif
+ * Name: spi_mapirq
*
* Description:
- * Wait space available in the Tx FIFO.
+ * Map an IRQ number into the appropriate SPI device
*
* Input Parameters:
- * priv - Device-specific state data
+ * irq - The IRQ number to be mapped
*
* Returned Value:
- * Status register mode bits
+ * On success, a reference to the private data structgure for this IRQ.
+ * NULL on failrue.
*
****************************************************************************/
-static uint32 spi_waitspif(struct imx_spidev_s *priv)
+#ifndef CONFIG_SPI_POLLWAIT
+static inline struct imx_spidev_s *spi_mapirq(int irq)
{
- uint32 status;
-
- /* Wait for the device to be ready to accept another byte (or for an error
- * to be reported).
- */
-#error "Missing logic"
- return status;
+ switch (irq)
+ {
+#ifndef CONFIG_SPI1_DISABLE
+ case IMX_IRQ_CSPI1:
+ return &g_spidev[SPI1_NDX];
+#endif
+#ifndef CONFIG_SPI2_DISABLE
+ case IMX_IRQ_CSPI2:
+ return &g_spidev[SPI2_NDX];
+#endif
+ default:
+ return NULL;
+ }
}
+#endif
/****************************************************************************
* Name: spi_transfer
*
* Description:
- * Send one byte on SPI, return the response
+ * Exchange a block data with the SPI device
*
* Input Parameters:
* priv - Device-specific state data
- * ch - the byte to send
+ * txbuffer - The buffer of data to send to the device (may be NULL).
+ * rxbuffer - The buffer to receive data from the device (may be NULL).
+ * nwords - The total number of words to be exchanged. If the interface
+ * uses <= 8 bits per word, then this is the number of ubytes;
+ * if the interface uses >8 bits per word, then this is the
+ * number of uint16's
*
* Returned Value:
- * response
+ * 0: success, <0:Negated error number on failure
*
****************************************************************************/
-static ubyte spi_transfer(struct imx_spidev_s *priv, ubyte ch)
+#ifndef CONFIG_SPI_POLLWAIT
+static int spi_interrupt(int irq, void *context)
{
- ubyte status;
-
- /* Send the byte, repeating if some error occurs */
-
- for(;;)
- {
-#error "Missing logic"
-
- /* Wait for the device to be ready to accept another byte */
+ struct imx_spidev_s *priv = spi_mapirq(irq);
+ DBGASSERT(priv != NULL);
+# error "Missing logic"
+ return OK;
+}
+#endif
- status = spi_waitspif(oriv);
+/****************************************************************************
+ * Name: spi_transfer
+ *
+ * Description:
+ * Exchange a block data with the SPI device
+ *
+ * Input Parameters:
+ * priv - Device-specific state data
+ * txbuffer - The buffer of data to send to the device (may be NULL).
+ * rxbuffer - The buffer to receive data from the device (may be NULL).
+ * nwords - The total number of words to be exchanged. If the interface
+ * uses <= 8 bits per word, then this is the number of ubytes;
+ * if the interface uses >8 bits per word, then this is the
+ * number of uint16's
+ *
+ * Returned Value:
+ * 0: success, <0:Negated error number on failure
+ *
+ ****************************************************************************/
- /* Return the next byte from the Rx FIFO */
+static int spi_transfer(struct imx_spidev_s *priv, const void *txbuffer,
+ void *rxbuffer, unsigned int nwords)
+{
#error "Missing logic"
- }
}
/****************************************************************************
@@ -396,24 +440,28 @@ static void spi_setmode(FAR struct spi_dev_s *dev, enum spi_mode_e mode)
}
/****************************************************************************
- * Name: spi_sndbyte
+ * Name: spi_send
*
* Description:
- * Send one byte on SPI
+ * Exchange one word on SPI
*
* Input Parameters:
* dev - Device-specific state data
- * ch - The byte to send
+ * wd - The word to send. the size of the data is determined by the
+ * number of bits selected for the SPI interface.
*
* Returned Value:
* response
*
****************************************************************************/
-static ubyte spi_sndbyte(FAR struct spi_dev_s *dev, ubyte ch)
+static uint16 spi_send(FAR struct spi_dev_s *dev, uint16 wd)
{
- struct imx_spidev_s *priv = (struct imx_spidev_s *)dev;
- return spi_transfer(priv, ch);
+ struct imx_spidev_s *priv = (struct imx_spidev_s*)dev;
+ uint16 response = 0;
+
+ (void)spi_transfer(priv, &wd, &response, 1);
+ return response;
}
/*************************************************************************
@@ -425,24 +473,20 @@ static ubyte spi_sndbyte(FAR struct spi_dev_s *dev, ubyte ch)
* Input Parameters:
* dev - Device-specific state data
* buffer - A pointer to the buffer of data to be sent
- * buflen - the length of data to send from the buffer
+ * buflen - the length of data to send from the buffer in number of words.
+ * The wordsize is determined by the number of bits-per-word
+ * selected for the SPI interface. If nbits <= 8, the data is
+ * packed into ubytes; if nbits >8, the data is packed into uint16's
*
* Returned Value:
* None
*
****************************************************************************/
-static void spi_sndblock(FAR struct spi_dev_s *dev, FAR const ubyte *buffer, size_t buflen)
+static void spi_sndblock(FAR struct spi_dev_s *dev, FAR const void *buffer, size_t buflen)
{
struct imx_spidev_s *priv = (struct imx_spidev_s *)dev;
- uint32 response;
-
- /* Loop while thre are bytes remaining to be sent */
-
- while (buflen-- > 0)
- {
- response = spi_transfer(priv, *buffer++);
- }
+ (void)spi_transfer(priv, buffer, NULL, buflen);
}
/****************************************************************************
@@ -454,23 +498,20 @@ static void spi_sndblock(FAR struct spi_dev_s *dev, FAR const ubyte *buffer, siz
* Input Parameters:
* dev - Device-specific state data
* buffer - A pointer to the buffer in which to recieve data
- * buflen - the length of data that can be received in the buffer
+ * buflen - the length of data that can be received in the buffer in number
+ * of words. The wordsize is determined by the number of bits-per-word
+ * selected for the SPI interface. If nbits <= 8, the data is
+ * packed into ubytes; if nbits >8, the data is packed into uint16's
*
* Returned Value:
* None
*
****************************************************************************/
-static void spi_recvblock(FAR struct spi_dev_s *dev, FAR ubyte *buffer, size_t buflen)
+static void spi_recvblock(FAR struct spi_dev_s *dev, FAR void *buffer, size_t buflen)
{
struct imx_spidev_s *priv = (struct imx_spidev_s *)dev;
-
- /* Loop while thre are bytes remaining to be sent */
-
- while (buflen-- > 0)
- {
- *buffer = (ubyte)spi_transfer(prive, 0xff);
- }
+ (void)spi_transfer(priv, NULL, buffer, buflen);
}
/****************************************************************************
@@ -584,7 +625,13 @@ FAR struct spi_dev_s *up_spiinitialize(int port)
/* Disable SPI */
#error "Missing logic"
- /* Initialize control rebistger: min frequency, ignore ready, master mode, mode=0, 8-bit */
+ /* Initialize the state structure */
+
+ifndef CONFIG_SPI_POLLWAIT
+ sem_init(&priv->sem, 0, 0);
+#endif
+
+ /* Initialize control register: min frequency, ignore ready, master mode, mode=0, 8-bit */
spi_putreg(priv, IMX_CSPI_CTRL_OFFSET,
CSPI_CTRL_DIV512 | /* Lowest frequency */
@@ -603,10 +650,14 @@ FAR struct spi_dev_s *up_spiinitialize(int port)
/* Enable interrupts on data ready (and certain error conditions */
+ifndef CONFIG_SPI_POLLWAIT
spi_putreg(priv, CSPI_INTCS_OFFSET,
CSPI_INTCS_RREN | /* RXFIFO Data Ready Interrupt Enable */
CSPI_INTCS_ROEN | /* RXFIFO Overflow Interrupt Enable */
CSPI_INTCS_BOEN); /* Bit Count Overflow Interrupt Enable */
+#else
+ spi_putreg(priv, CSPI_INTCS_OFFSET, 0); /* No interrupts */
+#endif
/* Set the clock source=bit clock and number of clocks inserted between
* transactions = 2.
@@ -620,7 +671,9 @@ FAR struct spi_dev_s *up_spiinitialize(int port)
/* Attach the interrupt */
- irq_attach(priv->irq, (xcpt_t)imx_spinterrupt);
+ifndef CONFIG_SPI_POLLWAIT
+ irq_attach(priv->irq, (xcpt_t)spi_interrupt);
+#endif
/* Enable SPI */
@@ -630,7 +683,9 @@ FAR struct spi_dev_s *up_spiinitialize(int port)
/* Enable SPI interrupts */
+ifndef CONFIG_SPI_POLLWAIT
up_enable_irq(priv->irq);
+#endif
return (FAR struct spi_dev_s *)priv;
}
diff --git a/nuttx/arch/z80/src/ez80/ez80_spi.c b/nuttx/arch/z80/src/ez80/ez80_spi.c
index 87984bf78..20db1035a 100755
--- a/nuttx/arch/z80/src/ez80/ez80_spi.c
+++ b/nuttx/arch/z80/src/ez80/ez80_spi.c
@@ -67,7 +67,7 @@
static uint32 spi_setfrequency(FAR struct spi_dev_s *dev, uint32 frequency);
static void spi_setmode(FAR struct spi_dev_s *dev, enum spi_mode_e mode);
-static ubyte spi_sndbyte(FAR struct spi_dev_s *dev, ubyte ch);
+static uint16 spi_send(FAR struct spi_dev_s *dev, uint16 wd);
static void spi_sndblock(FAR struct spi_dev_s *dev, FAR const ubyte *buffer, size_t buflen);
static void spi_recvblock(FAR struct spi_dev_s *dev, FAR ubyte *buffer, size_t buflen);
@@ -81,7 +81,7 @@ static const struct spi_ops_s g_spiops =
spi_setfrequency,
spi_setmode,
ez80_spistatus, /* Provided externally by board logic */
- spi_sndbyte,
+ spi_send,
spi_sndblock,
spi_recvblock,
};
@@ -268,23 +268,24 @@ static ubyte spi_transfer(ubyte ch)
}
/****************************************************************************
- * Name: spi_sndbyte
+ * Name: spi_send
*
* Description:
- * Send one byte on SPI
+ * Exchange one word on SPI
*
* Input Parameters:
* dev - Device-specific state data
- * ch - The byte to send
+ * wd - The word to send. the size of the data is determined by the
+ * number of bits selected for the SPI interface.
*
* Returned Value:
* response
*
****************************************************************************/
-static ubyte spi_sndbyte(FAR struct spi_dev_s *dev, ubyte ch)
+static uint16 spi_send(FAR struct spi_dev_s *dev, uint16 wd)
{
- return spi_transfer(ch);
+ return spi_transfer((ubyte)wd);
}
/*************************************************************************
@@ -296,22 +297,26 @@ static ubyte spi_sndbyte(FAR struct spi_dev_s *dev, ubyte ch)
* Input Parameters:
* dev - Device-specific state data
* buffer - A pointer to the buffer of data to be sent
- * buflen - the length of data to send from the buffer
+ * buflen - the length of data to send from the buffer in number of words.
+ * The wordsize is determined by the number of bits-per-word
+ * selected for the SPI interface. If nbits <= 8, the data is
+ * packed into ubytes; if nbits >8, the data is packed into uint16's
*
* Returned Value:
* None
*
****************************************************************************/
-static void spi_sndblock(FAR struct spi_dev_s *dev, FAR const ubyte *buffer, size_t buflen)
+static void spi_sndblock(FAR struct spi_dev_s *dev, FAR const void *buffer, size_t buflen)
{
+ FAR const ubyte *ptr = (FAR const ubyte*)buffer;
ubyte response;
/* Loop while thre are bytes remaining to be sent */
while (buflen-- > 0)
{
- response = spi_transfer(*buffer++);
+ response = spi_transfer(*ptr++);
}
}
@@ -324,22 +329,26 @@ static void spi_sndblock(FAR struct spi_dev_s *dev, FAR const ubyte *buffer, siz
* Input Parameters:
* dev - Device-specific state data
* buffer - A pointer to the buffer in which to recieve data
- * buflen - the length of data that can be received in the buffer
+ * buflen - the length of data that can be received in the buffer in number
+ * of words. The wordsize is determined by the number of bits-per-word
+ * selected for the SPI interface. If nbits <= 8, the data is
+ * packed into ubytes; if nbits >8, the data is packed into uint16's
*
* Returned Value:
* None
*
****************************************************************************/
-static void spi_recvblock(FAR struct spi_dev_s *dev, FAR ubyte *buffer, size_t buflen)
+static void spi_recvblock(FAR struct spi_dev_s *dev, FAR void *buffer, size_t buflen)
{
+ FAR ubyte *ptr = (FAR ubyte*)buffer;
ubyte response;
/* Loop while thre are bytes remaining to be sent */
while (buflen-- > 0)
{
- *buffer = spi_transfer(0xff);
+ *ptr++ = spi_transfer(0xff);
}
}
diff --git a/nuttx/configs/mcu123-lpc214x/src/up_spi.c b/nuttx/configs/mcu123-lpc214x/src/up_spi.c
index a33b0ea76..e433a8617 100644
--- a/nuttx/configs/mcu123-lpc214x/src/up_spi.c
+++ b/nuttx/configs/mcu123-lpc214x/src/up_spi.c
@@ -89,9 +89,9 @@
static void spi_select(FAR struct spi_dev_s *dev, enum spi_dev_e devid, boolean selected);
static uint32 spi_setfrequency(FAR struct spi_dev_s *dev, uint32 frequency);
static ubyte spi_status(FAR struct spi_dev_s *dev, enum spi_dev_e devid);
-static ubyte spi_sndbyte(FAR struct spi_dev_s *dev, ubyte ch);
-static void spi_sndblock(FAR struct spi_dev_s *dev, FAR const ubyte *buffer, size_t buflen);
-static void spi_recvblock(FAR struct spi_dev_s *dev, FAR ubyte *buffer, size_t buflen);
+static uint16 spi_send(FAR struct spi_dev_s *dev, uint16 ch);
+static void spi_sndblock(FAR struct spi_dev_s *dev, FAR const void *buffer, size_t buflen);
+static void spi_recvblock(FAR struct spi_dev_s *dev, FAR void *buffer, size_t buflen);
/****************************************************************************
* Private Data
@@ -102,7 +102,7 @@ static const struct spi_ops_s g_spiops =
.select = spi_select,
.setfrequency = spi_setfrequency,
.status = spi_status,
- .sndbyte = spi_sndbyte,
+ .send = spi_send,
.sndblock = spi_sndblock,
.recvblock = spi_recvblock,
};
@@ -232,21 +232,22 @@ static ubyte spi_status(FAR struct spi_dev_s *dev, enum spi_dev_e devid)
}
/****************************************************************************
- * Name: spi_sndbyte
+ * Name: spi_send
*
* Description:
- * Send one byte on SPI
+ * Exchange one word on SPI
*
* Input Parameters:
* dev - Device-specific state data
- * ch - The byte to send
+ * wd - The word to send. the size of the data is determined by the
+ * number of bits selected for the SPI interface.
*
* Returned Value:
* response
*
****************************************************************************/
-static ubyte spi_sndbyte(FAR struct spi_dev_s *dev, ubyte ch)
+static uint16 spi_send(FAR struct spi_dev_s *dev, uint16 wd)
{
/* Wait while the TX FIFO is full */
@@ -254,7 +255,7 @@ static ubyte spi_sndbyte(FAR struct spi_dev_s *dev, ubyte ch)
/* Write the byte to the TX FIFO */
- putreg16(ch, LPC214X_SPI1_DR);
+ putreg16((ubyte)wd, LPC214X_SPI1_DR);
/* Wait for the RX FIFO not empty */
@@ -262,7 +263,7 @@ static ubyte spi_sndbyte(FAR struct spi_dev_s *dev, ubyte ch)
/* Get the value from the RX FIFO and return it */
- return (ubyte)getreg16(LPC214X_SPI1_DR);
+ return (uint16)getreg16(LPC214X_SPI1_DR);
}
/*************************************************************************
@@ -274,15 +275,19 @@ static ubyte spi_sndbyte(FAR struct spi_dev_s *dev, ubyte ch)
* Input Parameters:
* dev - Device-specific state data
* buffer - A pointer to the buffer of data to be sent
- * buflen - the length of data to send from the buffer
+ * buflen - the length of data to send from the buffer in number of words.
+ * The wordsize is determined by the number of bits-per-word
+ * selected for the SPI interface. If nbits <= 8, the data is
+ * packed into ubytes; if nbits >8, the data is packed into uint16's
*
* Returned Value:
* None
*
****************************************************************************/
-static void spi_sndblock(FAR struct spi_dev_s *dev, FAR const ubyte *buffer, size_t buflen)
+static void spi_sndblock(FAR struct spi_dev_s *dev, FAR const void *buffer, size_t buflen)
{
+ FAR const ubyte *ptr = (FAR const ubyte *)buffer;
ubyte sr;
/* Loop while thre are bytes remaining to be sent */
@@ -295,8 +300,8 @@ static void spi_sndblock(FAR struct spi_dev_s *dev, FAR const ubyte *buffer, siz
{
/* Send the data */
- putreg16((uint16)*buffer, LPC214X_SPI1_DR);
- buffer++;
+ putreg16((uint16)*ptr, LPC214X_SPI1_DR);
+ ptr++;
buflen--;
}
}
@@ -339,20 +344,24 @@ static void spi_sndblock(FAR struct spi_dev_s *dev, FAR const ubyte *buffer, siz
* Input Parameters:
* dev - Device-specific state data
* buffer - A pointer to the buffer in which to recieve data
- * buflen - the length of data that can be received in the buffer
+ * buflen - the length of data that can be received in the buffer in number
+ * of words. The wordsize is determined by the number of bits-per-word
+ * selected for the SPI interface. If nbits <= 8, the data is
+ * packed into ubytes; if nbits >8, the data is packed into uint16's
*
* Returned Value:
* None
*
****************************************************************************/
-static void spi_recvblock(FAR struct spi_dev_s *dev, FAR ubyte *buffer, size_t buflen)
+static void spi_recvblock(FAR struct spi_dev_s *dev, FAR const *buffer, size_t buflen)
{
+ FAR ubyte *ptr = (FAR ubyte*)buffer;
uint32 fifobytes = 0;
/* While there is remaining to be sent (and no synchronization error has occurred) */
- while (buflen || fifobytes)
+ while (ptr || fifobytes)
{
/* Fill the transmit FIFO with 0xff...
* Write 0xff to the data register while (1) the TX FIFO is
@@ -372,7 +381,7 @@ static void spi_recvblock(FAR struct spi_dev_s *dev, FAR ubyte *buffer, size_t b
while (getreg8(LPC214X_SPI1_SR) & LPC214X_SPI1SR_RNE)
{
- *buffer++ = (ubyte)getreg16(LPC214X_SPI1_DR);
+ *ptr++ = (ubyte)getreg16(LPC214X_SPI1_DR);
fifobytes--;
}
}
diff --git a/nuttx/configs/olimex-strp711/src/up_spi.c b/nuttx/configs/olimex-strp711/src/up_spi.c
index 33b3a8717..02b68bf72 100644
--- a/nuttx/configs/olimex-strp711/src/up_spi.c
+++ b/nuttx/configs/olimex-strp711/src/up_spi.c
@@ -266,9 +266,9 @@ static inline void spi_putreg(FAR struct str71x_spidev_s *priv, ubyte offset,
static void spi_select(FAR struct spi_dev_s *dev, enum spi_dev_e devid, boolean selected);
static uint32 spi_setfrequency(FAR struct spi_dev_s *dev, uint32 frequency);
static ubyte spi_status(FAR struct spi_dev_s *dev, enum spi_dev_e devid);
-static ubyte spi_sndbyte(FAR struct spi_dev_s *dev, ubyte ch);
-static void spi_sndblock(FAR struct spi_dev_s *dev, FAR const ubyte *buffer, size_t buflen);
-static void spi_recvblock(FAR struct spi_dev_s *dev, FAR ubyte *buffer, size_t buflen);
+static uint16 spi_send(FAR struct spi_dev_s *dev, uint16 wd);
+static void spi_sndblock(FAR struct spi_dev_s *dev, FAR const void *buffer, size_t buflen);
+static void spi_recvblock(FAR struct spi_dev_s *dev, FAR void *buffer, size_t buflen);
/****************************************************************************
* Private Data
@@ -279,7 +279,7 @@ static const struct spi_ops_s g_spiops =
.select = spi_select,
.setfrequency = spi_setfrequency,
.status = spi_status,
- .sndbyte = spi_sndbyte,
+ .send = spi_send,
.sndblock = spi_sndblock,
.recvblock = spi_recvblock,
};
@@ -518,21 +518,22 @@ static ubyte spi_status(FAR struct spi_dev_s *dev, enum spi_dev_e devid)
}
/****************************************************************************
- * Name: spi_sndbyte
+ * Name: spi_send
*
* Description:
- * Send one byte on SPI
+ * Exchange one word on SPI
*
* Input Parameters:
* dev - Device-specific state data
- * ch - The byte to send
+ * wd - The word to send. the size of the data is determined by the
+ * number of bits selected for the SPI interface.
*
* Returned Value:
* response
*
****************************************************************************/
-static ubyte spi_sndbyte(FAR struct spi_dev_s *dev, ubyte ch)
+static uint16 spi_send(FAR struct spi_dev_s *dev, uint16 wd)
{
FAR struct str71x_spidev_s *priv = (FAR struct str71x_spidev_s *)dev;
@@ -550,7 +551,7 @@ static ubyte spi_sndbyte(FAR struct spi_dev_s *dev, ubyte ch)
/* Write the byte to the TX FIFO */
- spi_putreg(priv, STR71X_BSPI_TXR_OFFSET, (uint16)ch << 8);
+ spi_putreg(priv, STR71X_BSPI_TXR_OFFSET, wd << 8);
/* Wait for the RX FIFO not empty */
@@ -570,16 +571,20 @@ static ubyte spi_sndbyte(FAR struct spi_dev_s *dev, ubyte ch)
* Input Parameters:
* dev - Device-specific state data
* buffer - A pointer to the buffer of data to be sent
- * buflen - the length of data to send from the buffer
+ * buflen - the length of data to send from the buffer in number of words.
+ * The wordsize is determined by the number of bits-per-word
+ * selected for the SPI interface. If nbits <= 8, the data is
+ * packed into ubytes; if nbits >8, the data is packed into uint16's
*
* Returned Value:
* None
*
****************************************************************************/
-static void spi_sndblock(FAR struct spi_dev_s *dev, FAR const ubyte *buffer, size_t buflen)
+static void spi_sndblock(FAR struct spi_dev_s *dev, FAR const void *buffer, size_t buflen)
{
FAR struct str71x_spidev_s *priv = (FAR struct str71x_spidev_s *)dev;
+ FAR const ubyte *ptr = (FAR const ubyte *)buffer;
uint16 csr2;
DEBUGASSERT(priv && priv->spibase);
@@ -594,8 +599,8 @@ static void spi_sndblock(FAR struct spi_dev_s *dev, FAR const ubyte *buffer, siz
{
/* Send the data */
- spi_putreg(priv, STR71X_BSPI_TXR_OFFSET, ((uint16)*buffer) << 8);
- buffer++;
+ spi_putreg(priv, STR71X_BSPI_TXR_OFFSET, ((uint16)*ptr) << 8);
+ ptr++;
buflen--;
}
}
@@ -638,16 +643,20 @@ static void spi_sndblock(FAR struct spi_dev_s *dev, FAR const ubyte *buffer, siz
* Input Parameters:
* dev - Device-specific state data
* buffer - A pointer to the buffer in which to recieve data
- * buflen - the length of data that can be received in the buffer
+ * buflen - the length of data that can be received in the buffer in number
+ * of words. The wordsize is determined by the number of bits-per-word
+ * selected for the SPI interface. If nbits <= 8, the data is
+ * packed into ubytes; if nbits >8, the data is packed into uint16's
*
* Returned Value:
* None
*
****************************************************************************/
-static void spi_recvblock(FAR struct spi_dev_s *dev, FAR ubyte *buffer, size_t buflen)
+static void spi_recvblock(FAR struct spi_dev_s *dev, FAR const *buffer, size_t buflen)
{
FAR struct str71x_spidev_s *priv = (FAR struct str71x_spidev_s *)dev;
+ FAR ubyte *ptr = (FAR ubyte*)buffer;
uint32 fifobytes = 0;
DEBUGASSERT(priv && priv->spibase);
@@ -674,7 +683,7 @@ static void spi_recvblock(FAR struct spi_dev_s *dev, FAR ubyte *buffer, size_t b
while ((spi_getreg(priv, STR71X_BSPI_CSR2_OFFSET) & STR71X_BSPICSR2_RFNE) != 0)
{
- *buffer++ = (ubyte)(spi_getreg(priv, STR71X_BSPI_RXR_OFFSET) >> 8);
+ *ptr++ = (ubyte)(spi_getreg(priv, STR71X_BSPI_RXR_OFFSET) >> 8);
fifobytes--;
}
}
diff --git a/nuttx/drivers/mmcsd/mmcsd_spi.c b/nuttx/drivers/mmcsd/mmcsd_spi.c
index b081401cb..da07bb289 100644
--- a/nuttx/drivers/mmcsd/mmcsd_spi.c
+++ b/nuttx/drivers/mmcsd/mmcsd_spi.c
@@ -1,7 +1,7 @@
/****************************************************************************
* drivers/mmcsd/mmcsd_spi.c
*
- * Copyright (C) 2008 Gregory Nutt. All rights reserved.
+ * Copyright (C) 2008-2009 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <spudmonkey@racsa.co.cr>
*
* Redistribution and use in source and binary forms, with or without
@@ -333,7 +333,7 @@ static int mmcsd_waitready(FAR struct mmcsd_slot_s *slot)
for (i = 0; i < slot->twrite; i++)
{
- response = SPI_SNDBYTE(spi, 0xff);
+ response = SPI_SEND(spi, 0xff);
if (response == 0xff)
{
return OK;
@@ -366,23 +366,23 @@ static uint32 mmcsd_sendcmd(FAR struct mmcsd_slot_s *slot,
/* Send command code */
- SPI_SNDBYTE(spi, cmd->cmd);
+ SPI_SEND(spi, cmd->cmd);
/* Send command's arguments */
if (cmd->arg == MMCSD_CMDARG_NONE)
{
- SPI_SNDBYTE(spi, 0x00);
- SPI_SNDBYTE(spi, 0x00);
- SPI_SNDBYTE(spi, 0x00);
- SPI_SNDBYTE(spi, 0x00);
+ SPI_SEND(spi, 0x00);
+ SPI_SEND(spi, 0x00);
+ SPI_SEND(spi, 0x00);
+ SPI_SEND(spi, 0x00);
}
else
{
- SPI_SNDBYTE(spi, arg >> 24);
- SPI_SNDBYTE(spi, arg >> 16);
- SPI_SNDBYTE(spi, arg >> 8);
- SPI_SNDBYTE(spi, arg);
+ SPI_SEND(spi, arg >> 24);
+ SPI_SEND(spi, arg >> 16);
+ SPI_SEND(spi, arg >> 8);
+ SPI_SEND(spi, arg);
}
/* Send CRC if needed. The SPI interface is initialized in non-protected
@@ -392,18 +392,18 @@ static uint32 mmcsd_sendcmd(FAR struct mmcsd_slot_s *slot,
if (cmd->cmd == 0x40)
{
- SPI_SNDBYTE(spi, 0x95);
+ SPI_SEND(spi, 0x95);
}
else
{
- SPI_SNDBYTE(spi, 0xff);
+ SPI_SEND(spi, 0xff);
}
/* Get the response to the command */
for (i = 0; i < 9 && response == 0xff; i++)
{
- response = SPI_SNDBYTE(spi, 0xff);
+ response = SPI_SEND(spi, 0xff);
}
if (i == 0)
@@ -422,7 +422,7 @@ static uint32 mmcsd_sendcmd(FAR struct mmcsd_slot_s *slot,
uint32 busy = 0;
for (i = 0; i < slot->twrite && busy != 0xff; i++)
{
- busy = SPI_SNDBYTE(spi, 0xff);
+ busy = SPI_SEND(spi, 0xff);
}
fvdbg("Return R1B=%02x\n", response);
}
@@ -437,7 +437,7 @@ static uint32 mmcsd_sendcmd(FAR struct mmcsd_slot_s *slot,
case MMCSD_CMDRESP_R2:
{
result = ((uint32) response << 8) & 0x0000ff00;
- result |= SPI_SNDBYTE(spi, 0xff) & 0xff;
+ result |= SPI_SEND(spi, 0xff) & 0xff;
fvdbg("Return R2=%04x\n", result);
}
return result;
@@ -445,10 +445,10 @@ static uint32 mmcsd_sendcmd(FAR struct mmcsd_slot_s *slot,
case MMCSD_CMDRESP_R3:
default:
{
- result = ((uint32) response << 24) & 0xff000000;
- result |= ((uint32) SPI_SNDBYTE(spi, 0xff) << 16) & 0x00ff0000;
- result |= ((uint32) SPI_SNDBYTE(spi, 0xff) << 8) & 0x0000ff00;
- result |= SPI_SNDBYTE(spi, 0xff) & 0xff;
+ result = ((uint32)response << 24) & 0xff000000;
+ result |= ((uint32)SPI_SEND(spi, 0xff) << 16) & 0x00ff0000;
+ result |= ((uint32)SPI_SEND(spi, 0xff) << 8) & 0x0000ff00;
+ result |= SPI_SEND(spi, 0xff) & 0xff;
fvdbg("Return R3=%08x\n", result);
}
return result;
@@ -605,7 +605,7 @@ static int mmcsd_getcardinfo(FAR struct mmcsd_slot_s *slot, ubyte *buffer,
int i;
SPI_SELECT(spi, SPIDEV_MMCSD, FALSE);
- SPI_SNDBYTE(spi, 0xff);
+ SPI_SEND(spi, 0xff);
/* Send the CMD9 or CMD10 */
@@ -620,8 +620,8 @@ static int mmcsd_getcardinfo(FAR struct mmcsd_slot_s *slot, ubyte *buffer,
for (i = 0; i < 8; i++)
{
- response = SPI_SNDBYTE(spi, 0xff);
- fvdbg("%d. SPI sndbyte returned %02x\n", i, response);
+ response = SPI_SEND(spi, 0xff);
+ fvdbg("%d. SPI send returned %02x\n", i, response);
/* If a read operation fails and the card cannot provide the requested
* data, it will send a data error token instead. The 4 least
@@ -637,13 +637,13 @@ static int mmcsd_getcardinfo(FAR struct mmcsd_slot_s *slot, ubyte *buffer,
{
for (i = 0; i < 16; ++i)
{
- *buffer++ = SPI_SNDBYTE(spi, 0xff);
+ *buffer++ = SPI_SEND(spi, 0xff);
}
/* CRC receive */
- (void)SPI_SNDBYTE(spi, 0xff);
- (void)SPI_SNDBYTE(spi, 0xff);
+ SPI_SEND(spi, 0xff);
+ SPI_SEND(spi, 0xff);
SPI_SELECT(spi, SPIDEV_MMCSD, FALSE);
return OK;
}
@@ -791,7 +791,7 @@ static ssize_t mmcsd_read(FAR struct inode *inode, unsigned char *buffer,
mmcsd_semtake(&slot->sem);
SPI_SELECT(spi, SPIDEV_MMCSD, FALSE);
- (void)SPI_SNDBYTE(spi, 0xff);
+ SPI_SEND(spi, 0xff);
/* Send CMD17: Reads a block of the size selected by the SET_BLOCKLEN
* command and verify that good R1 status is returned
@@ -810,8 +810,8 @@ static ssize_t mmcsd_read(FAR struct inode *inode, unsigned char *buffer,
{
/* Synchronize */
- response = SPI_SNDBYTE(spi, 0xff);
- fvdbg("(%d) SPI sndbyte returned %02x\n", i, response);
+ response = SPI_SEND(spi, 0xff);
+ fvdbg("(%d) SPI send returned %02x\n", i, response);
/* If a read operation fails and the card cannot provide the requested
* data, it will send a data error token instead. The 4 least
@@ -831,8 +831,8 @@ static ssize_t mmcsd_read(FAR struct inode *inode, unsigned char *buffer,
/* Receive and ignore the two CRC bytes */
- (void)SPI_SNDBYTE(spi, 0xff);
- (void)SPI_SNDBYTE(spi, 0xff);
+ SPI_SEND(spi, 0xff);
+ SPI_SEND(spi, 0xff);
/* On success, return the number of sectors transfer */
@@ -933,7 +933,7 @@ static ssize_t mmcsd_write(FAR struct inode *inode, const unsigned char *buffer,
mmcsd_semtake(&slot->sem);
SPI_SELECT(spi, SPIDEV_MMCSD, FALSE);
- (void)SPI_SNDBYTE(spi, 0xff);
+ SPI_SEND(spi, 0xff);
/* Send CMD24 (WRITE_BLOCK) and verify that good R1 status is returned */
@@ -952,20 +952,20 @@ static ssize_t mmcsd_write(FAR struct inode *inode, const unsigned char *buffer,
* 3. Followed by the block of data
*/
- (void)SPI_SNDBYTE(spi, 0xff);
- (void)SPI_SNDBYTE(spi, MMCSD_SPIDT_STARTBLKSNGL);
+ SPI_SEND(spi, 0xff);
+ SPI_SEND(spi, MMCSD_SPIDT_STARTBLKSNGL);
(void)SPI_SNDBLOCK(spi, buffer, nbytes);
/* Add the bogus CRC. By default, the SPI interface is initialized in
* non-protected mode. However, we still have to send bogus CRC values
*/
- (void)SPI_SNDBYTE(spi, 0xff);
- (void)SPI_SNDBYTE(spi, 0xff);
+ SPI_SEND(spi, 0xff);
+ SPI_SEND(spi, 0xff);
/* Now get the data response */
- response = SPI_SNDBYTE(spi, 0xff);
+ response = SPI_SEND(spi, 0xff);
if ((response & MMCSD_SPIDR_MASK) != MMCSD_SPIDR_ACCEPTED)
{
fdbg("Bad data response: %02x\n", response);
@@ -1145,7 +1145,7 @@ static int mmcsd_mediainitialize(FAR struct mmcsd_slot_s *slot)
for (j = 10; j; j--)
{
- SPI_SNDBYTE(spi, 0xff);
+ SPI_SEND(spi, 0xff);
}
/* Send CMD0 (GO_TO_IDLE) to put MMC/SD in IDLE/SPI mode */
@@ -1178,13 +1178,13 @@ static int mmcsd_mediainitialize(FAR struct mmcsd_slot_s *slot)
{
fvdbg("%d. Send CMD55\n", i);
SPI_SELECT(spi, SPIDEV_MMCSD, FALSE);
- SPI_SNDBYTE(spi, 0xff);
+ SPI_SEND(spi, 0xff);
result = mmcsd_sendcmd(slot, &g_cmd55, 0);
SPI_SELECT(spi, SPIDEV_MMCSD, FALSE);
fvdbg("%d. Send ACMD41\n", i);
SPI_SELECT(spi, SPIDEV_MMCSD, FALSE);
- SPI_SNDBYTE(spi, 0xff);
+ SPI_SEND(spi, 0xff);
result = mmcsd_sendcmd(slot, &g_acmd41, 0);
SPI_SELECT(spi, SPIDEV_MMCSD, FALSE);
@@ -1199,7 +1199,7 @@ static int mmcsd_mediainitialize(FAR struct mmcsd_slot_s *slot)
{
fvdbg("%d. Send CMD1\n", i);
SPI_SELECT(spi, SPIDEV_MMCSD, FALSE);
- SPI_SNDBYTE(spi, 0xff);
+ SPI_SEND(spi, 0xff);
result = mmcsd_sendcmd(slot, &g_cmd1, 0);
SPI_SELECT(spi, SPIDEV_MMCSD, FALSE);
diff --git a/nuttx/include/nuttx/spi.h b/nuttx/include/nuttx/spi.h
index 636c9323f..7e60a53b3 100644
--- a/nuttx/include/nuttx/spi.h
+++ b/nuttx/include/nuttx/spi.h
@@ -130,21 +130,22 @@
#define SPI_STATUS_WRPROTECTED 0x02 /* Bit 1=1: MMC/SD card write protected */
/****************************************************************************
- * Name: SPI_SNDBYTE
+ * Name: SPI_SEND
*
* Description:
- * Send one byte on SPI. Required.
+ * Exchange one word on SPI. Required.
*
* Input Parameters:
* dev - Device-specific state data
- * ch - The byte to send
+ * wd - The word to send. the size of the data is determined by the
+ * number of bits selected for the SPI interface.
*
* Returned Value:
- * None
+ * Received value
*
****************************************************************************/
-#define SPI_SNDBYTE(d,ch) ((d)->ops->sndbyte(d,ch))
+#define SPI_SEND(d,wd) ((d)->ops->send(d,(uint16)wd))
/****************************************************************************
* Name: SPI_SNDBLOCK
@@ -153,9 +154,12 @@
* Send a block of data on SPI. Required.
*
* Input Parameters:
- * dev - Device-specific state data
+ * dev - Device-specific state data
* buffer - A pointer to the buffer of data to be sent
- * buflen - the length of data to send from the buffer
+ * buflen - the length of data to send from the buffer in number of words.
+ * The wordsize is determined by the number of bits-per-word
+ * selected for the SPI interface. If nbits <= 8, the data is
+ * packed into ubytes; if nbits >8, the data is packed into uint16's
*
* Returned Value:
* None
@@ -173,7 +177,10 @@
* Input Parameters:
* dev - Device-specific state data
* buffer - A pointer to the buffer in which to recieve data
- * buflen - the length of data that can be received in the buffer
+ * buflen - the length of data that can be received in the buffer in number
+ * of words. The wordsize is determined by the number of bits-per-word
+ * selected for the SPI interface. If nbits <= 8, the data is
+ * packed into ubytes; if nbits >8, the data is packed into uint16's
*
* Returned Value:
* None
@@ -241,9 +248,9 @@ struct spi_ops_s
uint32 (*setfrequency)(FAR struct spi_dev_s *dev, uint32 frequency);
void (*setmode)(FAR struct spi_dev_s *dev, enum spi_mode_e mode);
ubyte (*status)(FAR struct spi_dev_s *dev, enum spi_dev_e devid);
- ubyte (*sndbyte)(FAR struct spi_dev_s *dev, ubyte ch);
- void (*sndblock)(FAR struct spi_dev_s *dev, FAR const ubyte *buffer, size_t buflen);
- void (*recvblock)(FAR struct spi_dev_s *dev, FAR ubyte *buffer, size_t buflen);
+ uint16 (*send)(FAR struct spi_dev_s *dev, uint16 wd);
+ void (*sndblock)(FAR struct spi_dev_s *dev, FAR const void *buffer, size_t buflen);
+ void (*recvblock)(FAR struct spi_dev_s *dev, FAR void *buffer, size_t buflen);
int (*registercallback)(FAR struct spi_dev_s *dev, mediachange_t callback, void *arg);
};