[U-Boot-Users] Soft SPI support for all SPI modes

Zach Sadecki Zach.Sadecki at ripcode.com
Mon Aug 6 22:36:16 CEST 2007


Here is a patch that will allow the soft SPI driver to support all
different SPI modes (CPOL=0/1, CPHA=0/1).

Signed-off-by: Zach Sadecki <zach.sadecki at ripcode.com>


===================================================================
--- common/soft_spi.c
+++ common/soft_spi.c
@@ -39,7 +39,33 @@
 #define PRINTD(fmt,args...)
 #endif

+#ifndef CONFIG_SPI_CPOL
+#define CONFIG_SPI_CPOL        0
+#endif

+#ifndef CONFIG_SPI_CPHA
+#define CONFIG_SPI_CPHA        0
+#endif
+
+#if (CONFIG_SPI_CPOL == 0)
+#define SPI_CLOCK_IDLE         0
+#define SPI_CLOCK_ACTIVE       1
+#else
+#define SPI_CLOCK_IDLE         1
+#define SPI_CLOCK_ACTIVE       0
+#endif
+
+#if (CONFIG_SPI_CPHA == 0)
+/* Read on active (1st) edge */
+#define SPI_CLOCK_WRITE        SPI_CLOCK_IDLE
+#define SPI_CLOCK_READ         SPI_CLOCK_ACTIVE
+#else
+/* Read on idle (2nd) edge */
+#define SPI_CLOCK_WRITE        SPI_CLOCK_ACTIVE
+#define SPI_CLOCK_READ         SPI_CLOCK_IDLE
+#endif
+
+
 
/*=====================================================================*
/
 /*                         Public Functions
*/
 
/*=====================================================================*
/
@@ -87,10 +113,12 @@
        PRINTD("spi_xfer: chipsel %08X dout %08X din %08X bitlen %d\n",
                (int)chipsel, *(uint *)dout, *(uint *)din, bitlen);

+       SPI_SCL(SPI_CLOCK_IDLE); /* Ensure SPI clock starts in idle
state */
        if(chipsel != NULL) {
                (*chipsel)(1);  /* select the target chip */
        }
-
+       SPI_DELAY; /* half clock delay after SS */
+
        for(j = 0; j < bitlen; j++) {
                /*
                 * Check if it is time to work on a new byte.
@@ -102,14 +130,14 @@
                        }
                        tmpdin  = 0;
                }
-               SPI_SCL(0);
+               SPI_SCL(SPI_CLOCK_WRITE);
                SPI_SDA(tmpdout & 0x80);
                SPI_DELAY;
-               SPI_SCL(1);
-               SPI_DELAY;
+               SPI_SCL(SPI_CLOCK_READ);
                tmpdin  <<= 1;
                tmpdin   |= SPI_READ;
                tmpdout <<= 1;
+               SPI_DELAY;
        }
        /*
         * If the number of bits isn't a multiple of 8, shift the last
@@ -120,7 +148,7 @@
                tmpdin <<= 8 - (bitlen % 8);
        *din++ = tmpdin;

-       SPI_SCL(0);             /* SPI wants the clock left low for idle
*/
+       SPI_SCL(SPI_CLOCK_IDLE); /* Leave SPI clock in idle state */

        if(chipsel != NULL) {
                (*chipsel)(0);  /* deselect the target chip */




More information about the U-Boot mailing list