clean up of SPI bit bang logic

This commit is contained in:
Gregory Nutt
2013-07-01 17:49:43 -06:00
parent e1dab23711
commit 652c33a53a
4 changed files with 635 additions and 554 deletions
+14 -1
View File
@@ -77,6 +77,17 @@
#define SPI_CLRMOSI putreg32(1 << 7, SAM_PIOD_CODR) #define SPI_CLRMOSI putreg32(1 << 7, SAM_PIOD_CODR)
#define SPI_GETMISO ((getreg32(SAM_PIOD_PDSR) >> 8) & 1) #define SPI_GETMISO ((getreg32(SAM_PIOD_PDSR) >> 8) & 1)
/* Only mode 0 */
#undef SPI_BITBANG_DISABLEMODE0
#define SPI_BITBANG_DISABLEMODE1 1
#define SPI_BITBANG_DISABLEMODE2 1
#define SPI_BITBANG_DISABLEMODE3 1
/* Only 8-bit data width */
#undef SPI_BITBANG_VARWIDTH
/* SPI_PERBIT_NSEC is the minimum time to transfer one bit. This determines /* SPI_PERBIT_NSEC is the minimum time to transfer one bit. This determines
* the maximum frequency and is also used to calculate delays to achieve * the maximum frequency and is also used to calculate delays to achieve
* other SPI frequencies. * other SPI frequencies.
@@ -87,7 +98,9 @@
* I measured a frequency of approximately 305KHz. * I measured a frequency of approximately 305KHz.
* *
* NOTE that there are really only two frequencies possible: hold time=1 * NOTE that there are really only two frequencies possible: hold time=1
* (305KHz) and hold time = 0 (probably around 781KHz) * (305KHz) and hold time = 0 (probably around 781KHz). I believe that
* the code is capable of rates up to around 10MHz, but I think that the
* mere presence of the rate controlling logic slows it down.
*/ */
#define SPI_PERBIT_NSEC 1350 /* Calibrated at 400KHz */ #define SPI_PERBIT_NSEC 1350 /* Calibrated at 400KHz */
+10
View File
@@ -36,4 +36,14 @@ config SPI_BITBANG
Enable support for a generic SPI bit-bang device. Enable support for a generic SPI bit-bang device.
See include/nuttx/spi/spi_bitbang.h for further information. See include/nuttx/spi/spi_bitbang.h for further information.
if SPI_BITBANG
config SPI_BITBANG_VARWIDTH
bool "SPI bit-bang variable width transfers"
default n
---help---
Enable support for a variable dat width transfers. Default: 8-bit
only.
endif
endif endif
+1 -1
View File
@@ -312,7 +312,7 @@ static void spi_setbits(FAR struct spi_dev_s *dev, int nbits)
FAR struct spi_bitbang_s *priv = (FAR struct spi_bitbang_s *)dev; FAR struct spi_bitbang_s *priv = (FAR struct spi_bitbang_s *)dev;
spivdbg("nbits=%d\n", nbits); spivdbg("nbits=%d\n", nbits);
DEBUGASSERT(priv && nbits > 0); DEBUGASSERT(priv && nbits > 0 && nbits <= 16);
priv->nbits = nbits; priv->nbits = nbits;
#else #else
spivdbg("nbits=%d\n", nbits); spivdbg("nbits=%d\n", nbits);
+66 -8
View File
@@ -52,6 +52,11 @@
* - Defines SPI_GETMISO to sample the MISO state * - Defines SPI_GETMISO to sample the MISO state
* - Defines SPI_PERBIT_NSEC which is the minimum time to transfer one bit. * - Defines SPI_PERBIT_NSEC which is the minimum time to transfer one bit.
* This determines the maximum frequency. * This determines the maximum frequency.
* - Other configuration options:
* SPI_BITBANG_DISABLEMODE0 - Define to disable Mode 0 support
* SPI_BITBANG_DISABLEMODE1 - Define to disable Mode 1 support
* SPI_BITBANG_DISABLEMODE2 - Define to disable Mode 2 support
* SPI_BITBANG_DISABLEMODE3 - Define to disable Mode 3 support
* - Provide implementations of spi_select(), spi_status(), and spi_cmddata(). * - Provide implementations of spi_select(), spi_status(), and spi_cmddata().
* - Then include this file * - Then include this file
* - Provide an initialization function that initializes the GPIO pins used * - Provide an initialization function that initializes the GPIO pins used
@@ -225,7 +230,7 @@ static void spi_setmode(FAR struct spi_bitbang_s *priv,
switch (mode) switch (mode)
{ {
case SPIDEV_MODE0: /* CPOL=0; CPHA=0 */ case SPIDEV_MODE0: /* CPOL=0; CPHA=0 */
#ifndef CONFIG_SPI_BITBANG_DISABLEMODE0 #ifndef SPI_BITBANG_DISABLEMODE0
SPI_CLRSCK; /* Resting level of the clock is low */ SPI_CLRSCK; /* Resting level of the clock is low */
priv->exchange = spi_bitexchange0; priv->exchange = spi_bitexchange0;
#else #else
@@ -234,7 +239,7 @@ static void spi_setmode(FAR struct spi_bitbang_s *priv,
break; break;
case SPIDEV_MODE1: /* CPOL=0; CPHA=1 */ case SPIDEV_MODE1: /* CPOL=0; CPHA=1 */
#ifndef CONFIG_SPI_BITBANG_DISABLEMODE1 #ifndef SPI_BITBANG_DISABLEMODE1
SPI_CLRSCK; /* Resting level of the clock is low */ SPI_CLRSCK; /* Resting level of the clock is low */
priv->exchange = spi_bitexchange1; priv->exchange = spi_bitexchange1;
#else #else
@@ -243,7 +248,7 @@ static void spi_setmode(FAR struct spi_bitbang_s *priv,
break; break;
case SPIDEV_MODE2: /* CPOL=1; CPHA=0 */ case SPIDEV_MODE2: /* CPOL=1; CPHA=0 */
#ifndef CONFIG_SPI_BITBANG_DISABLEMODE2 #ifndef SPI_BITBANG_DISABLEMODE2
SPI_SETSCK; /* Resting level of the clock is high */ SPI_SETSCK; /* Resting level of the clock is high */
priv->exchange = spi_bitexchange2; priv->exchange = spi_bitexchange2;
#else #else
@@ -252,7 +257,7 @@ static void spi_setmode(FAR struct spi_bitbang_s *priv,
break; break;
case SPIDEV_MODE3: /* CPOL=1; CPHA=1 */ case SPIDEV_MODE3: /* CPOL=1; CPHA=1 */
#ifndef CONFIG_SPI_BITBANG_DISABLEMODE3 #ifndef SPI_BITBANG_DISABLEMODE3
SPI_SETSCK; /* Resting level of the clock is high */ SPI_SETSCK; /* Resting level of the clock is high */
priv->exchange = spi_bitexchange3; priv->exchange = spi_bitexchange3;
#else #else
@@ -272,6 +277,20 @@ static void spi_setmode(FAR struct spi_bitbang_s *priv,
* Description: * Description:
* Exchange one bit in mode 0 * Exchange one bit in mode 0
* *
* MODE 0: CPOL=0 and CPHA = 0
* The base value of the clock is zero. Data is captured on the clock's
* rising edge and data is propagated on the falling edge (high->low
* transition).
*
* hold time
* +------------+
* | | hold time
* -----+ +------------
* | | `- Propagate to next bit
* | |
* | `- MISO sampled
* ` Set MOSI
*
* Input Parameters: * Input Parameters:
* dev - Device-specific state data * dev - Device-specific state data
* lock - true: Lock spi bus, false: unlock SPI bus * lock - true: Lock spi bus, false: unlock SPI bus
@@ -281,7 +300,7 @@ static void spi_setmode(FAR struct spi_bitbang_s *priv,
* *
****************************************************************************/ ****************************************************************************/
#ifndef CONFIG_SPI_BITBANG_DISABLEMODE0 #ifndef SPI_BITBANG_DISABLEMODE0
static uint16_t spi_bitexchange0(FAR struct spi_bitbang_s *priv, static uint16_t spi_bitexchange0(FAR struct spi_bitbang_s *priv,
uint16_t dataout) uint16_t dataout)
{ {
@@ -319,6 +338,19 @@ static uint16_t spi_bitexchange0(FAR struct spi_bitbang_s *priv,
* Description: * Description:
* Exchange one bit in mode 1 * Exchange one bit in mode 1
* *
* MODE 1: CPOL=0 and CPHA = 1
* The base value of the clock is zero. Data is captured on the clock's
* falling edge and data is propagated on the rising edge
*
* hold time
* +------------+
* | | hold time
* -----+ +------------
* | | `- MISO sampled
* | |
* | `- Propagate to next bit
* ` Set MOSI
*
* Input Parameters: * Input Parameters:
* dev - Device-specific state data * dev - Device-specific state data
* lock - true: Lock spi bus, false: unlock SPI bus * lock - true: Lock spi bus, false: unlock SPI bus
@@ -328,7 +360,7 @@ static uint16_t spi_bitexchange0(FAR struct spi_bitbang_s *priv,
* *
****************************************************************************/ ****************************************************************************/
#ifndef CONFIG_SPI_BITBANG_DISABLEMODE1 #ifndef SPI_BITBANG_DISABLEMODE1
static uint16_t spi_bitexchange1(FAR struct spi_bitbang_s *priv, static uint16_t spi_bitexchange1(FAR struct spi_bitbang_s *priv,
uint16_t dataout) uint16_t dataout)
{ {
@@ -367,6 +399,19 @@ static uint16_t spi_bitexchange1(FAR struct spi_bitbang_s *priv,
* Description: * Description:
* Exchange one bit in mode 2 * Exchange one bit in mode 2
* *
* MODE 2: CPOL=1 and CPHA = 0
* The base value of the clock is one. Data is captured on the clock's
* falling edge and data is propagated on the rising edge.
*
* hold time
* -----+ +------------
* | | hold time
* +------------+
* | | `- Propagate to next bit
* | |
* | `- MISO sampled
* ` Set MOSI
*
* Input Parameters: * Input Parameters:
* dev - Device-specific state data * dev - Device-specific state data
* lock - true: Lock spi bus, false: unlock SPI bus * lock - true: Lock spi bus, false: unlock SPI bus
@@ -376,7 +421,7 @@ static uint16_t spi_bitexchange1(FAR struct spi_bitbang_s *priv,
* *
****************************************************************************/ ****************************************************************************/
#ifndef CONFIG_SPI_BITBANG_DISABLEMODE2 #ifndef SPI_BITBANG_DISABLEMODE2
static uint16_t spi_bitexchange2(FAR struct spi_bitbang_s *priv, static uint16_t spi_bitexchange2(FAR struct spi_bitbang_s *priv,
uint16_t dataout) uint16_t dataout)
{ {
@@ -414,6 +459,19 @@ static uint16_t spi_bitexchange2(FAR struct spi_bitbang_s *priv,
* Description: * Description:
* Exchange one bit in mode 3 * Exchange one bit in mode 3
* *
* MODE 3: CPOL=1 and CPHA = 1
* The base value of the clock is one. Data is captured on the clock's
* rising edge and data is propagated on the falling edge.
*
* hold time
* -----+ +------------
* | | hold time
* +------------+
* | | `- MISO sampled
* | |
* | `- Propagate to next bit
* ` Set MOSI
*
* Input Parameters: * Input Parameters:
* dev - Device-specific state data * dev - Device-specific state data
* lock - true: Lock spi bus, false: unlock SPI bus * lock - true: Lock spi bus, false: unlock SPI bus
@@ -423,7 +481,7 @@ static uint16_t spi_bitexchange2(FAR struct spi_bitbang_s *priv,
* *
****************************************************************************/ ****************************************************************************/
#ifndef CONFIG_SPI_BITBANG_DISABLEMODE3 #ifndef SPI_BITBANG_DISABLEMODE3
static uint16_t spi_bitexchange3(FAR struct spi_bitbang_s *priv, static uint16_t spi_bitexchange3(FAR struct spi_bitbang_s *priv,
uint16_t dataout) uint16_t dataout)
{ {