diff options
Diffstat (limited to 'nuttx')
-rw-r--r-- | nuttx/ChangeLog | 5 | ||||
-rw-r--r-- | nuttx/Documentation/NuttX.html | 7 | ||||
-rwxr-xr-x | nuttx/arch/arm/src/imx/imx_cspi.h | 2 | ||||
-rwxr-xr-x | nuttx/arch/arm/src/imx/imx_spi.c | 191 | ||||
-rwxr-xr-x | nuttx/arch/z80/src/ez80/ez80_spi.c | 35 | ||||
-rw-r--r-- | nuttx/configs/mcu123-lpc214x/src/up_spi.c | 45 | ||||
-rw-r--r-- | nuttx/configs/olimex-strp711/src/up_spi.c | 41 | ||||
-rw-r--r-- | nuttx/drivers/mmcsd/mmcsd_spi.c | 82 | ||||
-rw-r--r-- | nuttx/include/nuttx/spi.h | 29 |
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 <spudmonkey@racsa.co.cr> <pre><ul> nuttx-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! + pascal-0.1.3 2009-xx-xx Gregory Nutt <spudmonkey@racsa.co.cr> buildroot-0.1.6 2009-xx-xx <spudmonkey@racsa.co.cr> 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); }; |