summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorpatacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3>2012-03-07 17:40:23 +0000
committerpatacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3>2012-03-07 17:40:23 +0000
commit52e4f12c798f8e28445af1ec3809364ba39d9000 (patch)
treecd81d113f701d250631b47c306492b74de869d92
parent360fc8ba4b531ca44e553be6259c44afc3862175 (diff)
downloadnuttx-52e4f12c798f8e28445af1ec3809364ba39d9000.tar.gz
nuttx-52e4f12c798f8e28445af1ec3809364ba39d9000.tar.bz2
nuttx-52e4f12c798f8e28445af1ec3809364ba39d9000.zip
Updates to PIC32 SPI driver
git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@4461 42af7a65-404d-4744-a932-0658087f49c3
-rw-r--r--nuttx/arch/mips/src/pic32mx/pic32mx-internal.h138
-rw-r--r--nuttx/arch/mips/src/pic32mx/pic32mx-spi.c190
-rw-r--r--nuttx/configs/sure-pic32mx/README.txt37
-rw-r--r--nuttx/configs/sure-pic32mx/nsh/defconfig6
-rw-r--r--nuttx/configs/sure-pic32mx/ostest/defconfig4
-rw-r--r--nuttx/configs/sure-pic32mx/src/up_buttons.c8
-rw-r--r--nuttx/configs/sure-pic32mx/src/up_nsh.c2
-rw-r--r--nuttx/configs/sure-pic32mx/src/up_spi.c84
-rw-r--r--nuttx/configs/sure-pic32mx/src/up_usbdev.c2
-rw-r--r--nuttx/configs/sure-pic32mx/usbnsh/defconfig2
10 files changed, 340 insertions, 133 deletions
diff --git a/nuttx/arch/mips/src/pic32mx/pic32mx-internal.h b/nuttx/arch/mips/src/pic32mx/pic32mx-internal.h
index 190fd8a47..6d9373df8 100644
--- a/nuttx/arch/mips/src/pic32mx/pic32mx-internal.h
+++ b/nuttx/arch/mips/src/pic32mx/pic32mx-internal.h
@@ -47,6 +47,8 @@
#include <stdint.h>
#include <stdbool.h>
+#include <nuttx/spi.h>
+
#include "up_internal.h"
#include "chip.h"
#include "pic32mx-config.h"
@@ -396,42 +398,48 @@ EXTERN void pic32mx_dumpgpio(uint32_t pinset, const char *msg);
*
************************************************************************************/
-struct spi_dev_s;
-enum spi_dev_e;
-
#ifdef CONFIG_PIC32MX_SPI1
-EXTERN void pic32mx_spi1select(FAR struct spi_dev_s *dev, enum spi_dev_e devid, bool selected);
+EXTERN void pic32mx_spi1select(FAR struct spi_dev_s *dev, enum spi_dev_e devid,
+ bool selected);
EXTERN uint8_t pic32mx_spi1status(FAR struct spi_dev_s *dev, enum spi_dev_e devid);
#ifdef CONFIG_SPI_CMDDATA
-EXTERN int pic32mx_spi1cmddata(FAR struct spi_dev_s *dev, enum spi_dev_e devid, bool cmd);
+EXTERN int pic32mx_spi1cmddata(FAR struct spi_dev_s *dev, enum spi_dev_e devid,
+ bool cmd);
#endif
#endif
#ifdef CONFIG_PIC32MX_SPI2
-EXTERN void pic32mx_spi2select(FAR struct spi_dev_s *dev, enum spi_dev_e devid, bool selected);
+EXTERN void pic32mx_spi2select(FAR struct spi_dev_s *dev, enum spi_dev_e devid,
+ bool selected);
EXTERN uint8_t pic32mx_spi2status(FAR struct spi_dev_s *dev, enum spi_dev_e devid);
#ifdef CONFIG_SPI_CMDDATA
-EXTERN int pic32mx_spi2cmddata(FAR struct spi_dev_s *dev, enum spi_dev_e devid, bool cmd);
+EXTERN int pic32mx_spi2cmddata(FAR struct spi_dev_s *dev, enum spi_dev_e devid,
+ bool cmd);
#endif
#endif
#ifdef CONFIG_PIC32MX_SPI3
-EXTERN void pic32mx_spi3select(FAR struct spi_dev_s *dev, enum spi_dev_e devid, bool selected);
+EXTERN void pic32mx_spi3select(FAR struct spi_dev_s *dev, enum spi_dev_e devid,
+ bool selected);
EXTERN uint8_t pic32mx_spi3status(FAR struct spi_dev_s *dev, enum spi_dev_e devid);
#ifdef CONFIG_SPI_CMDDATA
-EXTERN int pic32mx_spi3cmddata(FAR struct spi_dev_s *dev, enum spi_dev_e devid, bool cmd);
+EXTERN int pic32mx_spi3cmddata(FAR struct spi_dev_s *dev, enum spi_dev_e devid,
+ bool cmd);
#endif
#endif
#ifdef CONFIG_PIC32MX_SPI3
-EXTERN void pic32mx_spi3select(FAR struct spi_dev_s *dev, enum spi_dev_e devid, bool selected);
+EXTERN void pic32mx_spi3select(FAR struct spi_dev_s *dev, enum spi_dev_e devid,
+ bool selected);
EXTERN uint8_t pic32mx_spi3status(FAR struct spi_dev_s *dev, enum spi_dev_e devid);
#ifdef CONFIG_SPI_CMDDATA
-EXTERN int pic32mx_spi3cmddata(FAR struct spi_dev_s *dev, enum spi_dev_e devid, bool cmd);
+EXTERN int pic32mx_spi3cmddata(FAR struct spi_dev_s *dev, enum spi_dev_e devid,
+ bool cmd);
#endif
#endif
-/****************************************************************************
+/************************************************************************************
+
* Name: pic32mx_dmainitialize
*
* Description:
@@ -440,54 +448,60 @@ EXTERN int pic32mx_spi3cmddata(FAR struct spi_dev_s *dev, enum spi_dev_e devid,
* Returned Value:
* None
*
- ****************************************************************************/
+ ************************************************************************************/
+
#ifdef CONFIG_PIC32MX_DMA
EXTERN void pic32mx_dmainitilaize(void);
#endif
-/****************************************************************************
+/************************************************************************************
+
* Name: pic32mx_dmachannel
*
* Description:
- * Allocate a DMA channel. This function sets aside a DMA channel and
- * gives the caller exclusive access to the DMA channel.
+ * Allocate a DMA channel. This function sets aside a DMA channel and gives the
+ * caller exclusive access to the DMA channel.
*
* Returned Value:
- * One success, this function returns a non-NULL, void* DMA channel
- * handle. NULL is returned on any failure. This function can fail only
- * if no DMA channel is available.
+ * One success, this function returns a non-NULL, void* DMA channel handle. NULL
+ * is returned on any failure. This function can fail only if no DMA channel is
+ * available.
*
- ****************************************************************************/
+ ************************************************************************************/
+
#ifdef CONFIG_PIC32MX_DMA
EXTERN DMA_HANDLE pic32mx_dmachannel(void);
#endif
-/****************************************************************************
+/************************************************************************************
+
* Name: pic32mx_dmafree
*
* Description:
- * Release a DMA channel. NOTE: The 'handle' used in this argument must
- * NEVER be used again until pic32mx_dmachannel() is called again to re-gain
- * a valid handle.
+ * Release a DMA channel. NOTE: The 'handle' used in this argument must NEVER be
+ * used again until pic32mx_dmachannel() is called again to re-gain a valid handle.
*
* Returned Value:
* None
*
- ****************************************************************************/
+ ************************************************************************************/
+
#ifdef CONFIG_PIC32MX_DMA
EXTERN void pic32mx_dmafree(DMA_HANDLE handle);
#endif
-/****************************************************************************
+/************************************************************************************
+
* Name: pic32mx_dmasetup
*
* Description:
* Configure DMA for one transfer.
*
- ****************************************************************************/
+ ************************************************************************************/
+
#ifdef CONFIG_PIC32MX_DMA
EXTERN int pic32mx_dmarxsetup(DMA_HANDLE handle,
@@ -496,39 +510,45 @@ EXTERN int pic32mx_dmarxsetup(DMA_HANDLE handle,
size_t nbytes);
#endif
-/****************************************************************************
+/************************************************************************************
+
* Name: pic32mx_dmastart
*
* Description:
* Start the DMA transfer
*
- ****************************************************************************/
+ ************************************************************************************/
+
#ifdef CONFIG_PIC32MX_DMA
EXTERN int pic32mx_dmastart(DMA_HANDLE handle, dma_callback_t callback, void *arg);
#endif
-/****************************************************************************
+/************************************************************************************
+
* Name: pic32mx_dmastop
*
* Description:
- * Cancel the DMA. After pic32mx_dmastop() is called, the DMA channel is
- * reset and pic32mx_dmasetup() must be called before pic32mx_dmastart() can be
- * called again
+ * Cancel the DMA. After pic32mx_dmastop() is called, the DMA channel is reset
+ * and pic32mx_dmasetup() must be called before pic32mx_dmastart() can be called
+ * again
*
- ****************************************************************************/
+ ************************************************************************************/
+
#ifdef CONFIG_PIC32MX_DMA
EXTERN void pic32mx_dmastop(DMA_HANDLE handle);
#endif
-/****************************************************************************
+/************************************************************************************
+
* Name: pic32mx_dmasample
*
* Description:
* Sample DMA register contents
*
- ****************************************************************************/
+ ************************************************************************************/
+
#ifdef CONFIG_PIC32MX_DMA
#ifdef CONFIG_DEBUG_DMA
@@ -538,13 +558,15 @@ EXTERN void pic32mx_dmasample(DMA_HANDLE handle, struct pic32mx_dmaregs_s *regs)
#endif
#endif
-/****************************************************************************
+/************************************************************************************
+
* Name: pic32mx_dmadump
*
* Description:
* Dump previously sampled DMA register contents
*
- ****************************************************************************/
+ ************************************************************************************/
+
#ifdef CONFIG_PIC32MX_DMA
#ifdef CONFIG_DEBUG_DMA
@@ -555,46 +577,52 @@ EXTERN void pic32mx_dmadump(DMA_HANDLE handle, const struct pic32mx_dmaregs_s *r
#endif
#endif
-/****************************************************************************
+/************************************************************************************
+
* Name: pic32mx_usbpullup
*
* Description:
- * If USB is supported and the board supports a pullup via GPIO (for USB
- * software connect and disconnect), then the board software must provide
- * stm32_pullup. See include/nuttx/usb/usbdev.h for additional description
- * of this method. Alternatively, if no pull-up GPIO the following EXTERN
- * can be redefined to be NULL.
+ * If USB is supported and the board supports a pullup via GPIO (for USB software
+ * connect and disconnect), then the board software must provide pic32mx_pullup.
+ * See include/nuttx/usb/usbdev.h for additional description of this method.
+ * Alternatively, if no pull-up GPIO the following EXTERN can be redefined to be
+ * NULL.
*
- ****************************************************************************/
+ ************************************************************************************/
+
#ifdef CONFIG_PIC32MX_USBDEV
struct usbdev_s;
EXTERN int pic32mx_usbpullup(FAR struct usbdev_s *dev, bool enable);
#endif
-/****************************************************************************
+/************************************************************************************
+
* Name: pic32mx_usbsuspend
*
* Description:
- * Board logic must provide the stm32_usbsuspend logic if the USBDEV driver
- * is used. This function is called whenever the USB enters or leaves
- * suspend mode. This is an opportunity for the board logic to shutdown
- * clocks, power, etc. while the USB is suspended.
+ * Board logic must provide the pic32mx_usbsuspend logic if the USBDEV driver is
+ * used. This function is called whenever the USB enters or leaves suspend mode.
+ * This is an opportunity for the board logic to shutdown clocks, power, etc. while
+ * the USB is suspended.
*
- ****************************************************************************/
+ ************************************************************************************/
+
#ifdef CONFIG_PIC32MX_USBDEV
EXTERN void pic32mx_usbsuspend(FAR struct usbdev_s *dev, bool resume);
#endif
-/****************************************************************************
+/************************************************************************************
+
* Name: pic32mx_usbattach and pic32mx_usbdetach
*
* Description:
- * The USB stack must be notified when the device is attached or detached
- * by calling one of these functions.
+ * The USB stack must be notified when the device is attached or detached by
+ * calling one of these functions.
*
- ****************************************************************************/
+ ************************************************************************************/
+
#ifdef CONFIG_PIC32MX_USBDEV
EXTERN void pic32mx_usbattach(void);
diff --git a/nuttx/arch/mips/src/pic32mx/pic32mx-spi.c b/nuttx/arch/mips/src/pic32mx/pic32mx-spi.c
index d884511e8..fc81f3d25 100644
--- a/nuttx/arch/mips/src/pic32mx/pic32mx-spi.c
+++ b/nuttx/arch/mips/src/pic32mx/pic32mx-spi.c
@@ -63,10 +63,15 @@
/****************************************************************************
* Definitions
****************************************************************************/
-/* Enables non-standard debug output from this file */
+/* Enables non-standard debug output from this file.
+ *
+ * CONFIG_SPI_DEBUG && CONFIG_DEBUG - Define to enable basic SPI debug
+ * CONFIG_DEBUG_VERBOSE - Define to enable verbose SPI debug
+ */
#ifndef CONFIG_DEBUG
# undef CONFIG_DEBUG_SPI
+# undef CONFIG_DEBUG_VERBOSE
#endif
#ifdef CONFIG_DEBUG_SPI
@@ -77,7 +82,6 @@
# define spivdbg(x...)
# endif
#else
-# undef CONFIG_DEBUG_VERBOSE
# define spidbg(x...)
# define spivdbg(x...)
#endif
@@ -401,6 +405,13 @@ static uint32_t spi_setfrequency(FAR struct spi_dev_s *dev, uint32_t frequency)
uint32_t actual;
uint32_t regval;
+#ifndef CONFIG_SPI_OWNBUS
+ spivdbg("Old frequency: %d actual: %d New frequency: %d\n",
+ priv->frequency, priv->actual, frequency);
+#else
+ spivdbg("New frequency: %d\n", regval);
+#endif
+
/* Check if the requested frequency is the same as the frequency selection */
#ifndef CONFIG_SPI_OWNBUS
@@ -435,8 +446,10 @@ static uint32_t spi_setfrequency(FAR struct spi_dev_s *dev, uint32_t frequency)
/* Save the new BRG value */
spi_putreg(priv, PIC32MX_SPI_BRG_OFFSET, regval);
+ spivdbg("PBCLOCK: %d frequency: %d divisor: %d BRG: %d\n",
+ BOARD_PBCLOCK, frequency, divisor, regval);
- /* Calculate the new actual frequency"
+ /* Calculate the new actual frequency.
*
* frequency = BOARD_PBCLOCK / (2 * divisor)
*/
@@ -450,7 +463,7 @@ static uint32_t spi_setfrequency(FAR struct spi_dev_s *dev, uint32_t frequency)
priv->actual = actual;
#endif
- spidbg("Frequency %d->%d\n", frequency, actual);
+ spidbg("New frequency: %d Actual: %d\n", frequency, actual);
return actual;
}
@@ -474,16 +487,50 @@ static void spi_setmode(FAR struct spi_dev_s *dev, enum spi_mode_e mode)
FAR struct pic32mx_dev_s *priv = (FAR struct pic32mx_dev_s *)dev;
uint32_t regval;
+#ifndef CONFIG_SPI_OWNBUS
+ spivdbg("Old mode: %d New mode: %d\n", priv->mode, mode);
+#else
+ spivdbg("New mode: %d\n", mode);
+#endif
+
/* Has the mode changed? */
#ifndef CONFIG_SPI_OWNBUS
if (mode != priv->mode)
{
#endif
- /* Yes... Set CR appropriately */
+ /* Yes... Set CON register appropriately.
+ *
+ * Standard terminology is as follows:
+ *
+ * Mode CPOL CPHA
+ * 0 0 0
+ * 1 0 1
+ * 2 1 0
+ * 3 1 1
+ *
+ * CPOL=0: The inactive value of the clock is zero
+ * CPOL=1: The inactive value of the clock is one
+ * CPHA=0: Data is captured on the clock's inactive-to-active edge and
+ * data is propagated on a active-to-inactive edge.
+ * CPHA=1: Data is captured on the clock's active-to-inactive edge and
+ * data is propagated on a active-to-inactive edge.
+ *
+ * CON Register mapping:
+ * CPOL=0 corresponds to CON:CKP=0; CPOL=1 corresponds to CON:CKP=1
+ * CPHA=0 corresponds to CON:CKE=1; CPHA=1 corresponds to CON:CKE=1
+ *
+ * In addition, the CON register supports SMP: SPI Data Input Sample
+ * Phase bit:
+ *
+ * 1 = Input data sampled at end of data output time
+ * 0 = Input data sampled at middle of data output time
+ *
+ * Which is hardcoded to 1.
+ */
regval = spi_getreg(priv, PIC32MX_SPI_CON_OFFSET);
- regval &= ~(SPI_CON_CKP|SPI_CON_SMP);
+ regval &= ~(SPI_CON_CKP|SPI_CON_CKE);
switch (mode)
{
@@ -491,7 +538,7 @@ static void spi_setmode(FAR struct spi_dev_s *dev, enum spi_mode_e mode)
break;
case SPIDEV_MODE1: /* CPOL=0; CPHA=1 */
- regval |= SPI_CON_SMP;
+ regval |= SPI_CON_CKE;
break;
case SPIDEV_MODE2: /* CPOL=1; CPHA=0 */
@@ -499,7 +546,7 @@ static void spi_setmode(FAR struct spi_dev_s *dev, enum spi_mode_e mode)
break;
case SPIDEV_MODE3: /* CPOL=1; CPHA=1 */
- regval |= (SPI_CON_CKP|SPI_CON_SMP);
+ regval |= (SPI_CON_CKP|SPI_CON_CKE);
break;
default:
@@ -508,6 +555,7 @@ static void spi_setmode(FAR struct spi_dev_s *dev, enum spi_mode_e mode)
}
spi_putreg(priv, PIC32MX_SPI_CON_OFFSET, regval);
+ spivdbg("CON: %08x\n", regval);
/* Save the mode so that subsequent re-configuratins will be faster */
@@ -535,9 +583,15 @@ static void spi_setmode(FAR struct spi_dev_s *dev, enum spi_mode_e mode)
static void spi_setbits(FAR struct spi_dev_s *dev, int nbits)
{
FAR struct pic32mx_dev_s *priv = (FAR struct pic32mx_dev_s *)dev;
- uint32_t mode;
+ uint32_t setting;
uint32_t regval;
+#ifndef CONFIG_SPI_OWNBUS
+ spivdbg("Old nbits: %d New nbits: %d\n", priv->nbits, nbits);
+#else
+ spivdbg("New nbits: %d\n", nbits);
+#endif
+
/* Has the number of bits changed? */
DEBUGASSERT(priv && nbits > 7 && nbits < 17);
@@ -549,15 +603,15 @@ static void spi_setbits(FAR struct spi_dev_s *dev, int nbits)
if (nbits == 8)
{
- mode = SPI_CON_MODE_8BIT;
+ setting = SPI_CON_MODE_8BIT;
}
else if (nbits == 16)
{
- mode = SPI_CON_MODE_8BIT;
+ setting = SPI_CON_MODE_8BIT;
}
else if (nbits == 32)
{
- mode = SPI_CON_MODE_8BIT;
+ setting = SPI_CON_MODE_8BIT;
}
else
{
@@ -567,8 +621,9 @@ static void spi_setbits(FAR struct spi_dev_s *dev, int nbits)
regval = spi_getreg(priv, PIC32MX_SPI_CON_OFFSET);
regval &= ~SPI_CON_MODE_MASK;
- regval |= mode;
+ regval |= setting;
regval = spi_getreg(priv, PIC32MX_SPI_CON_OFFSET);
+ spivdbg("CON: %08x\n", regval);
/* Save the selection so the subsequence re-configurations will be faster */
@@ -598,15 +653,26 @@ static uint16_t spi_send(FAR struct spi_dev_s *dev, uint16_t wd)
{
FAR struct pic32mx_dev_s *priv = (FAR struct pic32mx_dev_s *)dev;
+ spivdbg("wd: %04x\n", wd);
+
/* Write the data to transmitted to the SPI Data Register */
spi_putreg(priv, PIC32MX_SPI_BUF_OFFSET, (uint32_t)wd);
- /* Wait for the SPITBE bit in the SPI Status Register to be set to 1. The
- * SPITBE bit will be set when the receive buffer is not empty.
+#ifdef CONFIG_PIC32MX_SPI_ENHBUF
+ /* Wait for the SPIRBE bit in the SPI Status Register to be set to 0. In
+ * enhanced buffer mode, the SPIRBE bit will be cleared in when the
+ * receive buffer is not empty.
+ */
+
+ while ((spi_getreg(priv, PIC32MX_SPI_STAT_OFFSET) & SPI_STAT_SPIRBE) != 0);
+#else
+ /* Wait for the SPIRBF bit in the SPI Status Register to be set to 1. In
+ * normal mode, the SPIRBF bit will be set when receive data is available.
*/
- while ((spi_getreg(priv, PIC32MX_SPI_STAT_OFFSET) & SPI_STAT_SPITBE) == 0);
+ while ((spi_getreg(priv, PIC32MX_SPI_STAT_OFFSET) & SPI_STAT_SPIRBF) == 0);
+#endif
/* Return the SPI data */
@@ -639,7 +705,7 @@ static void spi_sndblock(FAR struct spi_dev_s *dev, FAR const void *buffer, size
uint32_t regval;
uint8_t data;
- spidbg("nwords: %d\n", nwords);
+ spivdbg("nwords: %d\n", nwords);
while (nwords)
{
/* Write the data to transmitted to the SPI Data Register */
@@ -647,11 +713,20 @@ static void spi_sndblock(FAR struct spi_dev_s *dev, FAR const void *buffer, size
data = *ptr++;
spi_putreg(priv, PIC32MX_SPI_BUF_OFFSET, (uint32_t)data);
- /* Wait for the SPITBE bit in the SPI Status Register to be set to 1.
- * The SPITBE bit will be set when the receive buffer is not empty.
+#ifdef CONFIG_PIC32MX_SPI_ENHBUF
+ /* Wait for the SPIRBE bit in the SPI Status Register to be set to 0. In
+ * enhanced buffer mode, the SPIRBE bit will be cleared in when the
+ * receive buffer is not empty.
*/
- while ((spi_getreg(priv, PIC32MX_SPI_STAT_OFFSET) & SPI_STAT_SPITBE) == 0);
+ while ((spi_getreg(priv, PIC32MX_SPI_STAT_OFFSET) & SPI_STAT_SPIRBE) != 0);
+#else
+ /* Wait for the SPIRBF bit in the SPI Status Register to be set to 1. In
+ * normal mode, the SPIRBF bit will be set when receive data is available.
+ */
+
+ while ((spi_getreg(priv, PIC32MX_SPI_STAT_OFFSET) & SPI_STAT_SPIRBF) == 0);
+#endif
/* Read from the buffer register to clear the status bit */
@@ -684,7 +759,7 @@ static void spi_recvblock(FAR struct spi_dev_s *dev, FAR void *buffer, size_t nw
FAR struct pic32mx_dev_s *priv = (FAR struct pic32mx_dev_s *)dev;
FAR uint8_t *ptr = (FAR uint8_t*)buffer;
- spidbg("nwords: %d\n", nwords);
+ spivdbg("nwords: %d\n", nwords);
while (nwords)
{
/* Write some dummy data to the SPI Data Register in order to clock the
@@ -693,11 +768,20 @@ static void spi_recvblock(FAR struct spi_dev_s *dev, FAR void *buffer, size_t nw
spi_putreg(priv, PIC32MX_SPI_BUF_OFFSET, 0xff);
- /* Wait for the SPITBE bit in the SPI Status Register to be set to 1.
- * The SPITBE bit will be set when the receive buffer is not empty.
+#ifdef CONFIG_PIC32MX_SPI_ENHBUF
+ /* Wait for the SPIRBE bit in the SPI Status Register to be set to 0. In
+ * enhanced buffer mode, the SPIRBE bit will be cleared in when the
+ * receive buffer is not empty.
*/
- while ((spi_getreg(priv, PIC32MX_SPI_STAT_OFFSET) & SPI_STAT_SPITBE) == 0);
+ while ((spi_getreg(priv, PIC32MX_SPI_STAT_OFFSET) & SPI_STAT_SPIRBE) != 0);
+#else
+ /* Wait for the SPIRBF bit in the SPI Status Register to be set to 1. In
+ * normal mode, the SPIRBF bit will be set when receive data is available.
+ */
+
+ while ((spi_getreg(priv, PIC32MX_SPI_STAT_OFFSET) & SPI_STAT_SPIRBF) == 0);
+#endif
/* Read the received data from the SPI Data Register */
@@ -730,6 +814,8 @@ FAR struct spi_dev_s *up_spiinitialize(int port)
irqstate_t flags;
uint32_t regval;
+ spivdbg("port: %d\n", port);
+
/* Select the SPI state structure for this port */
#ifdef CONFIG_PIC32MX_SPI1
@@ -782,10 +868,10 @@ FAR struct spi_dev_s *up_spiinitialize(int port)
regval = spi_getreg(priv, PIC32MX_SPI_BUF_OFFSET);
- /* Set the ENHBUF bit if using Enhanced Buffer mode. */
-
#ifdef CONFIG_PIC32MX_SPI_INTERRUPTS
- /* Attach the interrupt vector */
+ /* Attach the interrupt vector. We do this early to make sure that the
+ * resource is available.
+ */
ret = irq_attach(priv->vector, spi_interrupt);
if (ret < 0)
@@ -793,21 +879,6 @@ FAR struct spi_dev_s *up_spiinitialize(int port)
spidbg("Failed to attach vector: %d port: %d\n", priv->vector, port);
goto errout;
}
-
- /* Enable SPI interrupts */
-
- up_enable_irq(priv->eirq);
- up_enable_irq(priv->txirq);
- up_enable_irq(priv->rxirq);
-
- /* Set the interrupt priority */
-
- ret = up_prioritize_irq(priv->vector, CONFIG_PIC32MX_SPI_PRIORITY)
- if (ret < 0)
- {
- spidbg("up_prioritize_irq failed: %d\n", ret);
- goto errout;
- }
#endif
/* Select a default frequency of approx. 400KHz */
@@ -818,13 +889,20 @@ FAR struct spi_dev_s *up_spiinitialize(int port)
spi_putreg(priv, PIC32MX_SPI_STATCLR_OFFSET, SPI_STAT_SPIROV);
- /* Initial settings 8 bit + master mode + mode 0*/
+ /* Initial settings 8 bit + master mode + mode 0. NOTE that MSSEN
+ * not set: The slave select pin must be driven manually via the
+ * board-specific pic32mx_spiNselect() interface.
+ */
- regval = (SPI_CON_MSTEN | SPI_CON_MODE_8BIT | SPI_CON_ON);
-#ifdef CONFIG_PIC32MX_SPI_INTERRUPTS
- regval |= (SPI_CON_RTXISEL_HALF | SPI_CON_STXISEL_HALF);
+ regval = (SPI_CON_MSTEN | SPI_CON_SMP | SPI_CON_MODE_8BIT | SPI_CON_ON);
+
+ /* Set the ENHBUF bit if using Enhanced Buffer mode. */
+
+#ifdef CONFIG_PIC32MX_SPI_ENHBUF
+ regval |= (SPI_CON_ENHBUF | SPI_CON_RTXISEL_HALF | SPI_CON_STXISEL_HALF);
#endif
spi_putreg(priv, PIC32MX_SPI_CON_OFFSET, regval);
+ spivdbg("CON: %08x\n", regval);
/* Set the initial SPI configuration */
@@ -838,6 +916,26 @@ FAR struct spi_dev_s *up_spiinitialize(int port)
#ifndef CONFIG_SPI_OWNBUS
sem_init(&priv->exclsem, 0, 1);
#endif
+
+#ifdef CONFIG_PIC32MX_SPI_INTERRUPTS
+ /* Enable interrupts at the SPI controller */
+
+ up_enable_irq(priv->eirq);
+ up_enable_irq(priv->txirq);
+ up_enable_irq(priv->rxirq);
+
+ /* Set the SPI interrupt priority */
+
+ ret = up_prioritize_irq(priv->vector, CONFIG_PIC32MX_SPI_PRIORITY)
+ if (ret < 0)
+ {
+ spidbg("up_prioritize_irq failed: %d\n", ret);
+ goto errout;
+ }
+#endif
+
+ /* Enable interrupts at the interrupt controller */
+
irqrestore(flags);
return &priv->spidev;
diff --git a/nuttx/configs/sure-pic32mx/README.txt b/nuttx/configs/sure-pic32mx/README.txt
index a9076171b..4766823ab 100644
--- a/nuttx/configs/sure-pic32mx/README.txt
+++ b/nuttx/configs/sure-pic32mx/README.txt
@@ -77,7 +77,7 @@ PIC32MX440F512H Pin Out
21 AN8/U2CTS/C1OUT/RB8 N/C Not connected
22 AN9/C2OUT/PMA7/RB9 N/C Not connected
23 TMS/AN10/CVREFOUT/PMA13/RB10 UTIL_WP FLASH (U1) WP*
- 24 TDO/AN11/PMA12//RB11 SD_CS SD connector CS
+ 24 TDO/AN11/PMA12/RB11 SD_CS SD connector CS
25 Vss Grounded
26 Vdd +3.3V ---
27 TCK/AN12/PMA11/RB12 SD_CD SD connector CD
@@ -452,15 +452,21 @@ selected as follow:
Where <subdir> is one of the following:
ostest:
- -------
+ =======
+ Description.
+ ------------
This configuration directory, performs a simple OS test using
apps/examples/ostest.
nsh:
- ----
+ ====
+ Description.
+ ------------
Configures the NuttShell (nsh) located at apps/examples/nsh. The
Configuration enables only the serial NSH interface.
+ USB Configuations.
+ -----------------
Several USB device configurations can be enabled and included
as NSH built-in built in functions. All require the following
basic setup in your .config to enable USB device support:
@@ -491,8 +497,27 @@ Where <subdir> is one of the following:
to enable the USB mass storage device. However, this device cannot
work until support for the SD card is also incorporated.
+ SD Card Support.
+ ----------------
+ Support for the on-board, SPI-based SD card is available but is
+ not yet functional (at least at the time of this writing). SD
+ card support can be enabled for testing by simply enabling SPI2
+ support in the configuration file:
+
+ -CONFIG_PIC32MX_SPI2=n
+ +CONFIG_PIC32MX_SPI2=y
+
+ Debug output for testing the SD card can be enabled using:
+
+ -CONFIG_DEBUG_FS=n
+ -CONFIG_DEBUG_SPI=n
+ +CONFIG_DEBUG_FS=y
+ +CONFIG_DEBUG_SPI=y
+
usbnsh:
- -------
+ =======
+ Description.
+ ------------
This is another NSH example. If differs from the 'nsh' configuration
above in that this configurations uses a USB serial device for console
I/O. This configuration was created to support the "DB-DP11212 PIC32
@@ -501,6 +526,8 @@ Where <subdir> is one of the following:
"DB_DP11215 PIC32 Storage Demo Board" and has only be testing on that
board.
+ Comparison to nsh
+ -----------------
Below summarizes the key configuration differences between the 'nsh'
and the 'upnsh' configurations:
@@ -511,6 +538,8 @@ Where <subdir> is one of the following:
CONFIG_CDCACM=y : The CDC/ACM serial device class is enabled
CONFIG_CDCACM_CONSOLE=y : The CDC/ACM serial device is the console
+ Using the Prolifics PL2303 Emulation
+ ------------------------------------
You could also use the non-standard PL2303 serial device instead of
the standard CDC/ACM serial device by changing:
diff --git a/nuttx/configs/sure-pic32mx/nsh/defconfig b/nuttx/configs/sure-pic32mx/nsh/defconfig
index 0d1c7d03f..d87c5680a 100644
--- a/nuttx/configs/sure-pic32mx/nsh/defconfig
+++ b/nuttx/configs/sure-pic32mx/nsh/defconfig
@@ -355,6 +355,8 @@ CONFIG_DEBUG_VERBOSE=n
CONFIG_DEBUG_SYMBOLS=n
CONFIG_DEBUG_SCHED=n
CONFIG_DEBUG_USB=n
+CONFIG_DEBUG_FS=n
+CONFIG_DEBUG_SPI=n
CONFIG_HAVE_CXX=n
CONFIG_HAVE_CXXINITIALIZE=n
@@ -910,7 +912,7 @@ CONFIG_NSH_DISABLEBG=n
CONFIG_NSH_ROMFSETC=n
CONFIG_NSH_CONSOLE=y
CONFIG_NSH_TELNET=n
-CONFIG_NSH_ARCHINIT=n
+CONFIG_NSH_ARCHINIT=y
CONFIG_NSH_IOBUFFER_SIZE=512
CONFIG_NSH_DHCPC=n
CONFIG_NSH_NOMAC=n
@@ -929,7 +931,7 @@ CONFIG_NSH_FATMOUNTPT=/tmp
#
# Architecture-specific NSH options
#
-CONFIG_NSH_MMCSDSPIPORTNO=1
+CONFIG_NSH_MMCSDSPIPORTNO=2
CONFIG_NSH_MMCSDSLOTNO=0
CONFIG_NSH_MMCSDMINOR=0
diff --git a/nuttx/configs/sure-pic32mx/ostest/defconfig b/nuttx/configs/sure-pic32mx/ostest/defconfig
index b54151b80..a214a4f83 100644
--- a/nuttx/configs/sure-pic32mx/ostest/defconfig
+++ b/nuttx/configs/sure-pic32mx/ostest/defconfig
@@ -766,7 +766,7 @@ CONFIG_NSH_DISABLEBG=n
CONFIG_NSH_ROMFSETC=n
CONFIG_NSH_CONSOLE=y
CONFIG_NSH_TELNET=n
-CONFIG_NSH_ARCHINIT=n
+CONFIG_NSH_ARCHINIT=y
CONFIG_NSH_IOBUFFER_SIZE=512
CONFIG_NSH_DHCPC=n
CONFIG_NSH_NOMAC=n
@@ -785,7 +785,7 @@ CONFIG_NSH_FATMOUNTPT=/tmp
#
# Architecture-specific NSH options
#
-CONFIG_NSH_MMCSDSPIPORTNO=1
+CONFIG_NSH_MMCSDSPIPORTNO=2
CONFIG_NSH_MMCSDSLOTNO=0
CONFIG_NSH_MMCSDMINOR=0
diff --git a/nuttx/configs/sure-pic32mx/src/up_buttons.c b/nuttx/configs/sure-pic32mx/src/up_buttons.c
index 6a33309b1..9fccedfc1 100644
--- a/nuttx/configs/sure-pic32mx/src/up_buttons.c
+++ b/nuttx/configs/sure-pic32mx/src/up_buttons.c
@@ -69,9 +69,9 @@
* notification will be enabled when pic32mx_gpioattach() is called.
*/
-#define GPIO_SW1 (GPIO_INPUT|GPIO_INT|GPIO_PORTB|GPIO_PIN_3)
-#define GPIO_SW2 (GPIO_INPUT|GPIO_INT|GPIO_PORTB|GPIO_PIN_2)
-#define GPIO_SW3 (GPIO_INPUT|GPIO_INT|GPIO_PORTB|GPIO_PIN_4)
+#define GPIO_SW1 (GPIO_INPUT|GPIO_INT|GPIO_PORTB|GPIO_PIN3)
+#define GPIO_SW2 (GPIO_INPUT|GPIO_INT|GPIO_PORTB|GPIO_PIN2)
+#define GPIO_SW3 (GPIO_INPUT|GPIO_INT|GPIO_PORTB|GPIO_PIN4)
/* Change notification numbers:
* RB3 -> CN5
@@ -91,7 +91,7 @@
static const uint16_t g_buttonset[NUM_BUTTONS] =
{
- BUTTON_SW1 BUTTON_SW2, BUTTON_SW3
+ GPIO_SW1 GPIO_SW2, GPIO_SW3
}
/* Change notification number for each button */
diff --git a/nuttx/configs/sure-pic32mx/src/up_nsh.c b/nuttx/configs/sure-pic32mx/src/up_nsh.c
index 057b1467e..1db5e0781 100644
--- a/nuttx/configs/sure-pic32mx/src/up_nsh.c
+++ b/nuttx/configs/sure-pic32mx/src/up_nsh.c
@@ -63,7 +63,7 @@
#ifdef CONFIG_ARCH_BOARD_SUREPIC32MX
# define CONFIG_NSH_HAVEMMCSD 1
# define CONFIG_NSH_HAVEUSBHOST 1
-# if !defined(CONFIG_NSH_MMCSDSPIPORTNO) || CONFIG_NSH_MMCSDSPIPORTNO != 1
+# if !defined(CONFIG_NSH_MMCSDSPIPORTNO) || CONFIG_NSH_MMCSDSPIPORTNO != 2
# error "The Sure PIC32MX MMC/SD is on SPI2"
# undef CONFIG_NSH_MMCSDSPIPORTNO
# define CONFIG_NSH_MMCSDSPIPORTNO 2
diff --git a/nuttx/configs/sure-pic32mx/src/up_spi.c b/nuttx/configs/sure-pic32mx/src/up_spi.c
index 67ce64dec..36ba0844d 100644
--- a/nuttx/configs/sure-pic32mx/src/up_spi.c
+++ b/nuttx/configs/sure-pic32mx/src/up_spi.c
@@ -2,7 +2,7 @@
* configs/sure-pic32mx/src/up_spi.c
* arch/arm/src/board/up_spi.c
*
- * Copyright (C) 2011 Gregory Nutt. All rights reserved.
+ * Copyright (C) 2011-2012 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* Redistribution and use in source and binary forms, with or without
@@ -57,22 +57,47 @@
/************************************************************************************
* Definitions
************************************************************************************/
+/* The Sure PIC32MX has an SD slot connected on SPI2:
+ *
+ * SPI
+ * SCK2/PMA5/CN8/RG6 SCK SD connector SCK, FLASH (U1) SCK*
+ * SDI2/PMA4/CN9/RG7 SDI SD connector DO, FLASH (U1) SO*
+ * SDO2/PMA3/CN10/RG8 SDO SD connector DI, FLASH (U1) SI*
+ *
+ * Chip Select. Pulled up on-board
+ * TDO/AN11/PMA12/RB11 SD_CS SD connector CS
+ *
+ * Status inputs. All pulled up on-board
+ *
+ * TCK/AN12/PMA11/RB12 SD_CD SD connector CD
+ * TDI/AN13/PMA10/RB13 SD_WD SD connector WD
+ */
+
+#define GPIO_SD_CS (GPIO_OUTPUT|GPIO_VALUE_ONE|GPIO_PORTB|GPIO_PIN11)
+#define GPIO_SD_CD (GPIO_INPUT|GPIO_INT|GPIO_PORTB|GPIO_PIN12)
+#define GPIO_SD_WD (GPIO_INPUT|GPIO_PORTB|GPIO_PIN13)
+
+/* Change notification numbers -- Not available for SD_CD. */
-/* The following enable debug output from this file (needs CONFIG_DEBUG too).
+/* The following enable debug output from this file.
*
- * CONFIG_SPI_DEBUG - Define to enable basic SPI debug
- * CONFIG_SPI_VERBOSE - Define to enable verbose SPI debug
+ * CONFIG_DEBUG_SPI && CONFIG_DEBUG - Define to enable basic SPI debug
+ * CONFIG_DEBUG_VERBOSE - Define to enable verbose SPI debug
*/
-#ifdef CONFIG_SPI_DEBUG
+#ifndef CONFIG_DEBUG
+# undef CONFIG_DEBUG_SPI
+# undef CONFIG_DEBUG_VERBOSE
+#endif
+
+#ifdef CONFIG_DEBUG_SPI
# define spidbg lldbg
-# ifdef CONFIG_SPI_VERBOSE
+# ifdef CONFIG_DEBUG_VERBOSE
# define spivdbg lldbg
# else
# define spivdbg(x...)
# endif
#else
-# undef CONFIG_SPI_VERBOSE
# define spidbg(x...)
# define spivdbg(x...)
#endif
@@ -95,11 +120,13 @@
void weak_function pic32mx_spiinitialize(void)
{
- /* Configure the SPI2 chip select GPIOs */
+ /* Configure the SPI2 chip select (CS) GPIO output, and the card detect (CD) and
+ * write protect (WP) inputs.
+ */
-#ifdef CONFIG_PIC32MX_SPI2
-# warning "Missing logic"
-#endif
+ pic32mx_configgpio(GPIO_SD_CS);
+ pic32mx_configgpio(GPIO_SD_CD);
+ pic32mx_configgpio(GPIO_SD_WD);
}
/************************************************************************************
@@ -128,17 +155,40 @@ void weak_function pic32mx_spiinitialize(void)
************************************************************************************/
#ifdef CONFIG_PIC32MX_SPI2
-void pic32mx_spi2select(FAR struct spi_dev_s *dev, enum spi_dev_e devid, bool selected)
+void pic32mx_spi2select(FAR struct spi_dev_s *dev, enum spi_dev_e devid, bool selected)
{
- spidbg("devid: %d CS: %s\n", (int)devid, selected ? "assert" : "de-assert");
-#warning "Missing logic"
+ spivdbg("devid: %d CS: %s\n", (int)devid, selected ? "assert" : "de-assert");
+
+ /* The SD card chip select is pulled high and active low */
+
+ if (devid == SPIDEV_MMCSD)
+ {
+ pic32mx_gpiowrite(GPIO_SD_CS, !selected);
+ }
}
uint8_t pic32mx_spi2status(FAR struct spi_dev_s *dev, enum spi_dev_e devid)
{
- spidbg("Returning nothing\n");
-#warning "Missing logic"
- return 0;
+ uint8_t ret = 0;
+
+ /* Card detect is pull up on-board. If a low value is sensed then the card must
+ * be present.
+ */
+
+ if (!pic32mx_gpioread(GPIO_SD_CD))
+ {
+ ret = SPI_STATUS_PRESENT;
+
+ /* It seems that a high value indicatest the the card is write protected. */
+
+ if (pic32mx_gpioread(GPIO_SD_WD))
+ {
+ ret |= SPI_STATUS_WRPROTECTED;
+ }
+ }
+
+ spivdbg("Returning %d\n", ret);
+ return ret;
}
#endif
#endif /* CONFIG_PIC32MX_SPI2 */
diff --git a/nuttx/configs/sure-pic32mx/src/up_usbdev.c b/nuttx/configs/sure-pic32mx/src/up_usbdev.c
index 6cc56406a..667bd1837 100644
--- a/nuttx/configs/sure-pic32mx/src/up_usbdev.c
+++ b/nuttx/configs/sure-pic32mx/src/up_usbdev.c
@@ -2,7 +2,7 @@
* configs/sure-pic32mx/src/up_usbdev.c
* arch/arm/src/board/up_usbdev.c
*
- * Copyright (C) 2011 Gregory Nutt. All rights reserved.
+ * Copyright (C) 2011-2012 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* References:
diff --git a/nuttx/configs/sure-pic32mx/usbnsh/defconfig b/nuttx/configs/sure-pic32mx/usbnsh/defconfig
index 79343e6b7..ab7b6636c 100644
--- a/nuttx/configs/sure-pic32mx/usbnsh/defconfig
+++ b/nuttx/configs/sure-pic32mx/usbnsh/defconfig
@@ -929,7 +929,7 @@ CONFIG_NSH_FATMOUNTPT=/tmp
#
# Architecture-specific NSH options
#
-CONFIG_NSH_MMCSDSPIPORTNO=1
+CONFIG_NSH_MMCSDSPIPORTNO=2
CONFIG_NSH_MMCSDSLOTNO=0
CONFIG_NSH_MMCSDMINOR=0