[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