From a9e04b3f47df9d7f359ce3b9f905049d385b2fec Mon Sep 17 00:00:00 2001 From: Gregory Nutt Date: Fri, 5 Jul 2013 11:45:17 -0600 Subject: [PATCH] Fix some SPI bit bang timing. I still don't think it is working properly; I am going to need to borrow a logic analyzer --- configs/sure-pic32mx/README.txt | 19 +-- include/nuttx/spi/spi_bitbang.c | 206 +++++++++++++++++++------------- 2 files changed, 133 insertions(+), 92 deletions(-) diff --git a/configs/sure-pic32mx/README.txt b/configs/sure-pic32mx/README.txt index 6a5d6ad3e2..a406d35f61 100644 --- a/configs/sure-pic32mx/README.txt +++ b/configs/sure-pic32mx/README.txt @@ -803,12 +803,14 @@ Where is one of the following: CONFIG_DEBUG_LCD=y : Enable LCD debug output NOTES: - a. I do not have the LCD1602 working. I may just be getting lost in the - tangle of wires or perhaps there is something fundamentally wrong with - the code. - b. At this point in time, testing of the SLCD is very limited because - there is not much in apps/examples/slcd. Basically driver with a working - test setup and ready to be tested and debugged. + 2013-05-27: The LCD1602 has been verified on the DB-DP11212 using + this configuration. It has not been used with the usbnsh configuration + or with the DB-11112 board. It looks to me like the connection to the + LCD1602 is identical on the DB-11112 and so I would expect that to work. + + At this point in time, testing of the SLCD is very limited because + there is not much in apps/examples/slcd. Basically driver with a working + test setup and ready to be tested and debugged. usbnsh: ======= @@ -956,5 +958,8 @@ Where is one of the following: CONFIG_RAMLOG_CONSOLE_BUFSIZE=8192 + STATUS: + 2013-7-4: This configuration was last verified. + 7. See the notes for the nsh configuration. Most also apply to the usbnsh - configuration. + configuration as well. diff --git a/include/nuttx/spi/spi_bitbang.c b/include/nuttx/spi/spi_bitbang.c index 73b36c0ce1..80401bbecf 100755 --- a/include/nuttx/spi/spi_bitbang.c +++ b/include/nuttx/spi/spi_bitbang.c @@ -330,14 +330,19 @@ static void spi_setmode(FAR struct spi_bitbang_s *priv, * 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 + * /CS --+ + * | + * +----------------------------------------------------------------- + * <-hold time-> <-hold time-><-hold time-><-hold time-><-hold time-> + * +------------+ +------------+ + * | | | | + * SCLK ---------------+ +------------+ +------------ + * ` Set MOSI | `- Set MOSI | `- Set MOSI + * | | + * `- Sample MISO `- Sample MISO + * + * MISO <------------X------------><-----------X------------> + * MOSO * * Input Parameters: * dev - Device-specific state data @@ -352,28 +357,33 @@ static void spi_setmode(FAR struct spi_bitbang_s *priv, static uint16_t spi_bitexchange0(uint16_t dataout, uint32_t holdtime) { uint16_t datain; - /* No clock transition before setting MOSI */ + + /* Here the clock is is in the resting set (low). Set MOSI output and wait + * for the hold time + */ + if (dataout != 0) { - SPI_SETMOSI; /* Set MOSI if the bit is set */ + SPI_SETMOSI; } else { - SPI_CLRMOSI; /* Clear MOSI if the bit is not set */ + SPI_CLRMOSI; } - SPI_SETSCK; /* Clock transition before getting MISO */ - datain = (uint16_t)SPI_GETMISO; /* Get bit 0 = MISO value */ - if (holdtime > 0) - { - spi_delay(holdtime); - } + spi_delay(holdtime); - SPI_CLRSCK; /* Return clock to the resting state */ - if (holdtime > 0) - { - spi_delay(holdtime); - } + /* Set the clock high and sample MISO */ + + SPI_SETSCK; + datain = (uint16_t)SPI_GETMISO; + + /* Wait the required amount of hold time then put the clock back in the + * resting state. + */ + + spi_delay(holdtime); + SPI_CLRSCK; return datain; } @@ -389,14 +399,19 @@ static uint16_t spi_bitexchange0(uint16_t dataout, uint32_t holdtime) * 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 + * /CS --+ + * | + * +----------------------------------------------------------------- + * <-hold time-> <-hold time-><-hold time-><-hold time-><-hold time-> + * +------------+ +------------+ + * | | | | + * SCLK -+ +------------+ +------------ + * ` Set MOSI | `- Set MOSI | + * | | + * `- Sample MISO `- Sample MISO + * + * MISO <-----------X-------------><----------X-------------> + * MOSO * * Input Parameters: * dev - Device-specific state data @@ -412,28 +427,31 @@ static uint16_t spi_bitexchange1(uint16_t dataout, uint32_t holdtime) { uint16_t datain; - SPI_SETSCK; /* Clock transition before setting MOSI */ + /* The clock should be in the resting state (low). Set the clock to the + * high state and set MOSI. + */ + + SPI_SETSCK; if (dataout != 0) { - SPI_SETMOSI; /* Set MOSI if the bit is set */ + SPI_SETMOSI; } else { - SPI_CLRMOSI; /* Clear MOSI if the bit is not set */ + SPI_CLRMOSI; } - if (holdtime > 0) - { - spi_delay(holdtime); - } + /* Wait for the required hold time then put the clock back into the + * resting (low) state. + */ - SPI_CLRSCK; /* Clock transition before getting MISO */ - datain = (uint16_t)SPI_GETMISO; /* Get bit 0 = MISO value */ - /* Clock is in resting state */ - if (holdtime > 0) - { - spi_delay(holdtime); - } + spi_delay(holdtime); + SPI_CLRSCK; + + /* Sample MISO on the falling edge and wait for the hold time again */ + + datain = (uint16_t)SPI_GETMISO; + spi_delay(holdtime); return datain; } @@ -449,14 +467,19 @@ static uint16_t spi_bitexchange1(uint16_t dataout, uint32_t holdtime) * 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 + * /CS --+ + * | + * +----------------------------------------------------------------- + * <-hold time-> <-hold time-><-hold time-><-hold time-><-hold time-> + * ---------------+ +------------+ +------------ + * | | | | + * SCLK +------------+ +------------+ + * ` Set MOSI | `- Set MOSI | `- Set MOSI + * | | + * `- Sample MISO `- Sample MISO + * + * MISO <------------X------------><-----------X------------> + * MOSO * * Input Parameters: * dev - Device-specific state data @@ -471,28 +494,33 @@ static uint16_t spi_bitexchange1(uint16_t dataout, uint32_t holdtime) static uint16_t spi_bitexchange2(uint16_t dataout, uint32_t holdtime) { uint16_t datain; - /* No clock transition before setting MOSI */ + + /* Here the clock is is in the resting set (high). Set MOSI output and wait + * for the hold time + */ + if (dataout != 0) { - SPI_SETMOSI; /* Set MOSI if the bit is set */ + SPI_SETMOSI; } else { - SPI_CLRMOSI; /* Clear MOSI if the bit is not set */ + SPI_CLRMOSI; } - SPI_CLRSCK; /* Clock transition before getting MISO */ - datain = (uint16_t)SPI_GETMISO; /* Get bit 0 = MISO value */ - if (holdtime > 0) - { - spi_delay(holdtime); - } + spi_delay(holdtime); - SPI_SETSCK; /* Return clock to the resting state */ - if (holdtime > 0) - { - spi_delay(holdtime); - } + /* Set the clock low and sample MISO */ + + SPI_CLRSCK; + datain = (uint16_t)SPI_GETMISO; + + /* Wait the required amount of hold time then put the clock back in the + * resting state (high). + */ + + spi_delay(holdtime); + SPI_SETSCK; return datain; } @@ -508,14 +536,19 @@ static uint16_t spi_bitexchange2(uint16_t dataout, uint32_t holdtime) * 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 + * /CS --+ + * | + * +----------------------------------------------------------------- + * <-hold time-> <-hold time-><-hold time-><-hold time-><-hold time-> + * -+ +------------+ +------------ + * | | | | + * SCLK +------------+ +------------+ + * ` Set MOSI | `- Set MOSI | + * | | + * `- Sample MISO `- Sample MISO + * + * MISO <-----------X-------------><----------X-------------> + * MOSO * * Input Parameters: * dev - Device-specific state data @@ -531,6 +564,10 @@ static uint16_t spi_bitexchange3(uint16_t dataout, uint32_t holdtime) { uint16_t datain; + /* The clock should be in the resting state (high). Set the clock to the + * low state and set MOSI. + */ + SPI_CLRSCK; /* Clock transition before setting MOSI */ if (dataout != 0) { @@ -541,18 +578,17 @@ static uint16_t spi_bitexchange3(uint16_t dataout, uint32_t holdtime) SPI_CLRMOSI; /* Clear MOSI if the bit is not set */ } - if (holdtime > 0) - { - spi_delay(holdtime); - } + /* Wait for the required hold time then put the clock back into the + * resting (high) state. + */ - SPI_SETSCK; /* Clock transition before getting MISO */ - datain = (uint16_t)SPI_GETMISO; /* Get bit 0 = MISO value */ - /* Clock is in resting state */ - if (holdtime > 0) - { - spi_delay(holdtime); - } + spi_delay(holdtime); + SPI_SETSCK; + + /* Sample MISO on the rising edge and wait for the hold time again */ + + datain = (uint16_t)SPI_GETMISO; + spi_delay(holdtime); return datain; }