From aa0dc313ffb4b232bc4bfdd0ae78dedd79ab3b60 Mon Sep 17 00:00:00 2001 From: patacongo Date: Wed, 7 Mar 2012 17:40:23 +0000 Subject: Updates to PIC32 SPI driver git-svn-id: https://nuttx.svn.sourceforge.net/svnroot/nuttx/trunk@4461 7fd9a85b-ad96-42d3-883c-3090e2eb8679 --- nuttx/arch/mips/src/pic32mx/pic32mx-internal.h | 138 +++++++++++------- nuttx/arch/mips/src/pic32mx/pic32mx-spi.c | 190 +++++++++++++++++++------ nuttx/configs/sure-pic32mx/README.txt | 37 ++++- nuttx/configs/sure-pic32mx/nsh/defconfig | 6 +- nuttx/configs/sure-pic32mx/ostest/defconfig | 4 +- nuttx/configs/sure-pic32mx/src/up_buttons.c | 8 +- nuttx/configs/sure-pic32mx/src/up_nsh.c | 2 +- nuttx/configs/sure-pic32mx/src/up_spi.c | 84 ++++++++--- nuttx/configs/sure-pic32mx/src/up_usbdev.c | 2 +- nuttx/configs/sure-pic32mx/usbnsh/defconfig | 2 +- 10 files changed, 340 insertions(+), 133 deletions(-) (limited to 'nuttx') diff --git a/nuttx/arch/mips/src/pic32mx/pic32mx-internal.h b/nuttx/arch/mips/src/pic32mx/pic32mx-internal.h index 190fd8a472..6d9373df87 100644 --- a/nuttx/arch/mips/src/pic32mx/pic32mx-internal.h +++ b/nuttx/arch/mips/src/pic32mx/pic32mx-internal.h @@ -47,6 +47,8 @@ #include #include +#include + #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 d884511e8d..fc81f3d252 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 a9076171b6..4766823ab0 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 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 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 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 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 0d1c7d03fc..d87c5680a2 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 b54151b80f..a214a4f830 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 6a33309b10..9fccedfc1c 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 057b1467e3..1db5e07818 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 67ce64dec5..36ba0844df 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 * * 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 6cc56406a7..667bd18372 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 * * References: diff --git a/nuttx/configs/sure-pic32mx/usbnsh/defconfig b/nuttx/configs/sure-pic32mx/usbnsh/defconfig index 79343e6b74..ab7b6636cc 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 -- cgit v1.2.3