-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

HI Werner:
  I've been interested in your hardware SPI (with DMA enable).
  Conclude from your previous discussion, it's the Hardware
issue (signal integrity?).
  I write a very simple test code in u-boot. My first step is
trying to make SPI controller working, so i choose POLL mode.
Problem, I encounter here is that SPSTA0 transfer ready bit always 0(
not ready). One thing i have to mention, there is no slave SPI
device, and i thought it should be ok just to test the S3C2442 SPI
controller.

   If you are kind to spend a few minutes to review my code,
and give me some suggestions. will be great.

   here is few steps i made in my code.
   1. enbale SPI clock
   2. set SPI pin to function mode.(CLK, MISO, MOSI, CS(GPF3),
      should set nSS0 to function mode?
   3. config SPI controller, baudrate, SPCON0,


Werner Almesberger wrote:
> I wrote:
>> To be continued ...
> 
> After getting nowhere with trying to talk to the prototype board, and
> seeing no end of those short pulses on MISO (*), I decided that my
> suspicion that poor signal integrity was to blame even at this
> moderate clock speed was probably more than a convenient excuse.
> 
> (*) Here's a beautiful one. D5 is the clock, D2 is MISO:
>     http://people.openmoko.org/werner/wlan-spi/3.png
> 
> Then it occurred to me that I could just as well use the WLAN module
> that's already in the device: after turning off the SDIO driver,
> switching to mmc_spi over s3c24xx_spi_gpio, and adapting all the GPIO
> definitions, the mainline SDIO stack happily welcomed the new member
> with SDIO_ID=0271:010A :-)
> 
> I'll just go ahead with s3c24xx_spi_gpio for now, then rework and
> switch to s3c24xx_spi when the Atheros stack talks to the module as
> well.
> 
> I'll give "pure" SPI (G_SPI) a try when the EVB arrives.
> 
> To be continued ...
> 
> - Werner
> 
> 

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v2.0.7 (GNU/Linux)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org

iD8DBQFIszCX28unoHSQkyIRAmWrAJ9G3EMMgDD1sjfwL/Dc8tvFkT+WpgCgjF83
izTYfSNMvhovrTAhkzwOqpk=
=+pkf
-----END PGP SIGNATURE-----
diff --git a/cpu/arm920t/s3c24x0/Makefile b/cpu/arm920t/s3c24x0/Makefile
index 3498e8f..47c15c9 100644
--- a/cpu/arm920t/s3c24x0/Makefile
+++ b/cpu/arm920t/s3c24x0/Makefile
@@ -27,7 +27,7 @@ LIB	= $(obj)lib$(SOC).a
 
 COBJS	= i2c.o interrupts.o serial.o speed.o \
 	  usb.o usb_ohci.o nand_read.o nand.o \
-	  cmd_s3c24xx.o mmc.o
+	  cmd_s3c24xx.o mmc.o spi.o
 
 SRCS	:= $(SOBJS:.o=.S) $(COBJS:.o=.c)
 OBJS	:= $(addprefix $(obj),$(SOBJS) $(COBJS))
diff --git a/cpu/arm920t/s3c24x0/cmd_s3c24xx.c b/cpu/arm920t/s3c24x0/cmd_s3c24xx.c
index 3388c93..2ae487c 100644
--- a/cpu/arm920t/s3c24x0/cmd_s3c24xx.c
+++ b/cpu/arm920t/s3c24x0/cmd_s3c24xx.c
@@ -31,6 +31,7 @@
 #include <s3c2410.h>
 #elif defined(CONFIG_S3C2440) || defined(CONFIG_S3C2442)
 #include <s3c2440.h>
+#include "spi.h"
 #endif
 
 DECLARE_GLOBAL_DATA_PTR;
@@ -264,6 +265,26 @@ int do_s3c24xx ( cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
 				print_cpu_speed();
 		} else
 			goto out_help;
+
+    } else if (!strcmp(argv[1], "spi")) {
+        unsigned short reg, value;
+
+        if (argc < 3)
+            goto out_help;
+        if (!strcmp(argv[2], "init")) {
+            s3c24xx_spi_init();
+        }
+        if (!strcmp(argv[2], "read")) {
+            reg = (unsigned short) simple_strtol(argv[3], NULL, 16);
+            value = s3c24xx_spi_read(reg); 
+            printf("s3c24xx spi read: reg(%x) -> value(%d)\n", reg, value);
+        }
+        if (!strcmp(argv[2], "write")) {
+            reg = (unsigned short) simple_strtol(argv[3], NULL, 16);
+            value = (unsigned short) simple_strtol(argv[4], NULL, 16);
+            s3c24xx_spi_write(reg, value); 
+            printf("s3c24xx spi write: reg(%x) -> value(%d)\n", reg, value);
+        }
 	} else {
 out_help:
 		printf("Usage:\n%s\n", cmdtp->usage);
@@ -277,11 +298,12 @@ out_help:
 
 
 U_BOOT_CMD(
-	s3c24xx,	4,	1,	do_s3c24xx,
+	s3c24xx,	5,	1,	do_s3c24xx,
 	"s3c24xx - SoC  specific commands\n",
 	"speed get - display current PLL speed config\n"
 	"s3c24xx speed list - display supporte PLL speed configs\n"
 	"s3c24xx speed set - set PLL speed\n"
+	"s3c24xx spi (init|read|write) - use spi read or write\n"
 );
 
 #endif
diff --git a/cpu/arm920t/s3c24x0/spi.c b/cpu/arm920t/s3c24x0/spi.c
new file mode 100644
index 0000000..0d26ebe
--- /dev/null
+++ b/cpu/arm920t/s3c24x0/spi.c
@@ -0,0 +1,124 @@
+/*
+ * Functions to access the SPI controller on GTA02 board 
+ *
+ * Copyright (C) 2002 DENX Software Engineering, Wolfgang Denk, [EMAIL PROTECTED]
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+#include <s3c2440.h>
+#include "spi.h"
+
+/* helper function */
+#define abs(value) (((value) < 0) ? ((value)*-1) : (value))
+
+void s3c24xx_spi_init(void)
+{
+	S3C24X0_GPIO * const gpio = S3C24X0_GetBase_GPIO();
+	S3C24X0_SPI * const spi = S3C24X0_GetBase_SPI();
+    S3C24X0_CLOCK_POWER * const clk = S3C24X0_GetBase_CLOCK_POWER();
+	int i;
+
+    printf("spi base addr (0x%x)\n", (unsigned long )spi);
+    /* enable SPI clock */
+    clk->CLKCON = (clk->CLKCON | (1<<18));
+	/* Configure I/O ports. 
+      SPI_SS0   -> GPG2(bit[5:4] -> 0b01 output)
+      SPI_MISO0 -> GPE11(bit[23:22] -> 0b10)
+      SPI_MOSI0 -> GPE12(bit[25:24] -> 0b10)
+      SPI_CLK0  -> GPE13(bit[27:26] -> 0b10)
+     */
+	gpio->GPGCON = (gpio->GPGCON & 0xFFFFFFCF) | 0x030;
+	gpio->GPECON = (gpio->GPECON & 0xFF3FFFFF) | 0x00800000;
+	gpio->GPECON = (gpio->GPECON & 0xFCFFFFFF) | 0x02000000;
+	gpio->GPECON = (gpio->GPECON & 0xF3FFFFFF) | 0x08000000;
+
+	CLR_CS_TOUCH();
+
+	spi->ch[0].SPPRE = 0x4F; /* Baud-rate ca. 514kHz */
+	spi->ch[0].SPPIN = 0x03; /* SPI-MOSI holds Level after last bit */
+	spi->ch[0].SPCON = 0x1B; /* Polling, Prescaler, Master, CPOL=0,
+				    CPHA=1 */
+
+	/* Dummy byte ensures clock to be low. */
+	for (i = 0; i < 10; i++) {
+		spi->ch[0].SPTDAT = 0xFF;
+	}
+	spi_wait_transmit_done();
+}
+
+
+void spi_wait_transmit_done(void)
+{
+	S3C24X0_SPI * const spi = S3C24X0_GetBase_SPI();
+    unsigned int i;
+#define S3C24XX_SPI_TIMEOUT (400)
+    for (i = 0; i < S3C24XX_SPI_TIMEOUT; i++) { 
+	    if (spi->ch[0].SPSTA & 0x01) /* wait until transfer is done */
+            break;
+        udelay(800);
+    }
+    if (i >= S3C24XX_SPI_TIMEOUT)
+        printf("ERR: spi_wait_stransmit timeout\n");
+}
+
+
+void s3c24xx_spi_write(unsigned short reg, unsigned short data)
+{
+	S3C24X0_SPI * const spi = S3C24X0_GetBase_SPI();
+	unsigned int command;
+
+	SET_CS_TOUCH();
+	command = reg;
+	spi->ch[0].SPTDAT = (command & 0xFF00) >> 8;
+	spi_wait_transmit_done();
+	spi->ch[0].SPTDAT = (command & 0x00FF);
+	spi_wait_transmit_done();
+	spi->ch[0].SPTDAT = (data & 0xFF00) >> 8;
+	spi_wait_transmit_done();
+	spi->ch[0].SPTDAT = (data & 0x00FF);
+	spi_wait_transmit_done();
+
+	CLR_CS_TOUCH();
+}
+
+unsigned short s3c24xx_spi_read (unsigned short reg)
+{
+	unsigned short command, data;
+	S3C24X0_SPI * const spi = S3C24X0_GetBase_SPI();
+
+	SET_CS_TOUCH();
+	command = 0x8000 | reg;
+
+	spi->ch[0].SPTDAT = (command & 0xFF00) >> 8;
+	spi_wait_transmit_done();
+	spi->ch[0].SPTDAT = (command & 0x00FF);
+	spi_wait_transmit_done();
+
+	spi->ch[0].SPTDAT = 0xFF;
+	spi_wait_transmit_done();
+	data = spi->ch[0].SPRDAT;
+	spi->ch[0].SPTDAT = 0xFF;
+	spi_wait_transmit_done();
+
+	CLR_CS_TOUCH();
+	return (spi->ch[0].SPRDAT & 0x0FF) | (data << 8);
+}
+
diff --git a/cpu/arm920t/s3c24x0/spi.h b/cpu/arm920t/s3c24x0/spi.h
new file mode 100644
index 0000000..4fbe92c
--- /dev/null
+++ b/cpu/arm920t/s3c24x0/spi.h
@@ -0,0 +1,47 @@
+/*
+ * Functions to access the SPI controller on GTA02 board
+ *
+ * Copyright (C) 2002 DENX Software Engineering, Wolfgang Denk, [EMAIL PROTECTED]
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#ifndef _S3C24XX_SPI_H_
+#define _S3C24XX_SPI_H_
+
+extern void s3c24xx_spi_init(void);
+extern void s3c24xx_spi_write(unsigned short reg, unsigned short data);
+extern unsigned short s3c24xx_spi_read (unsigned short reg);
+extern void spi_wait_transmit_done (void);
+
+static inline void SET_CS_TOUCH(void)
+{
+	S3C24X0_GPIO * const gpio = S3C24X0_GetBase_GPIO();
+
+	gpio->GPFDAT &= 0xFFF7;
+}
+
+static inline void CLR_CS_TOUCH(void)
+{
+	S3C24X0_GPIO * const gpio = S3C24X0_GetBase_GPIO();
+
+	gpio->GPFDAT |= 0x0008;
+}
+#endif	/* _S3C24XX_SPI_H_ */
+
diff --git a/include/s3c2440.h b/include/s3c2440.h
index 89d189c..957f7e1 100644
--- a/include/s3c2440.h
+++ b/include/s3c2440.h
@@ -138,11 +138,12 @@ static inline S3C2440_ADC * S3C2440_GetBase_ADC(void)
 {
 	return (S3C2440_ADC * const)S3C2440_ADC_BASE;
 }
+*/
 static inline S3C24X0_SPI * S3C24X0_GetBase_SPI(void)
 {
 	return (S3C24X0_SPI * const)S3C24X0_SPI_BASE;
 }
-*/
+
 static inline S3C2410_SDI * S3C2410_GetBase_SDI(void)
 {
 	return (S3C2410_SDI * const)S3C2440_SDI_BASE;

Reply via email to