summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorpatacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3>2010-05-02 17:29:37 +0000
committerpatacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3>2010-05-02 17:29:37 +0000
commit08b4a61636f1289a773ac4cb67f07a758f852c19 (patch)
tree776aaaa6630bda6e4c4737421449892b924083b1
parent0a6c1fff8a08287f4053eeef680e4f13123f9b80 (diff)
downloadnuttx-08b4a61636f1289a773ac4cb67f07a758f852c19.tar.gz
nuttx-08b4a61636f1289a773ac4cb67f07a758f852c19.tar.bz2
nuttx-08b4a61636f1289a773ac4cb67f07a758f852c19.zip
Add ENC28J60 GPIO configuration
git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@2644 42af7a65-404d-4744-a932-0658087f49c3
-rw-r--r--nuttx/configs/olimex-strp711/README.txt48
-rwxr-xr-xnuttx/configs/olimex-strp711/nettest/defconfig4
-rwxr-xr-xnuttx/configs/olimex-strp711/src/up_enc28j60.c57
-rw-r--r--nuttx/configs/olimex-strp711/src/up_spi.c465
4 files changed, 431 insertions, 143 deletions
diff --git a/nuttx/configs/olimex-strp711/README.txt b/nuttx/configs/olimex-strp711/README.txt
index 2f7431a03..8eaf3224e 100644
--- a/nuttx/configs/olimex-strp711/README.txt
+++ b/nuttx/configs/olimex-strp711/README.txt
@@ -228,9 +228,33 @@ GENERAL STEPS:
The same commands from the telnet interface can now be accessed through the
'monitor' command, e.g. 'monitor help'
+MMC/SD Slot
+^^^^^^^^^^^
+
+ STR-P711 PIN MMC/SD USAGE PIN CONFIGURATION
+ ------------ ---------------- -----------------------
+ P0.7/S1.SS 1 CD/DAT3/CS P.07 output
+ P0.5/S1.MOSI 2 CMD/DI MOSI1
+ --- 3 VSS1 ---
+ --- 4 VDD ---
+ P0.6/S1.SCLK 5 CLK/SCLK SLCK1
+ --- 6 VSS2 ---
+ P0.4/S1.MISO 7 DAT0/D0 MISO1
+ --- 8 DAT1/RES (Pulled up)
+ --- 9 DAT2/RES (Pulled up)
+
+ P1.10/USBCLK 10/14 WP P1.10 input
+ P1.15/HTXD 13/15 CP P1.15 input
+
+ Use of SPI1 doesn't conflict with anything. WP conflicts USB; CP conflicts
+ with NTXD.
+
ENC28J60 Module
^^^^^^^^^^^^^^^
+ The ENC28J60 module does not come on the Olimex-STR-P711, but this describes
+ how I have connected it:
+
Module CON5 QFN ENC2860 Description
--------------- -------------------------------------------------------
1 J8-1 NET CS 5 ~CS Chip select input pin for SPI interface (active low)
@@ -244,22 +268,24 @@ ENC28J60 Module
7 4 CLKOUT 27 CLKOUT Programmable clock output pin
6 5 NET RST 6 ~RESET Active-low device Reset input
- For the Olimex STR-P711, the ENC28J60 module is placed on SPI1 (with
- the MMC slot) and uses P0.0 for CS, P0.1 for an interrupt, and P0.2 as
- a reset:
+ For the Olimex STR-P711, the ENC28J60 module is placed on SPI0 and uses
+ P0.3 for CS, P1.4 for an interrupt, and P1.5 as a reset:
Module CON5 Olimex STR-P711 Connection
--------------- -------------------------------------------------------
- 1 J8-1 NET CS SPI0-4 P0.0 P0.0/S0.MISO/U3.TX
- 2 2 SCK SPI1-5 SCLK1 P0.6/S1.SCLK
- 3 3 MOSI SPI1-3 MOSI1 P0.5/S1.MOSI
- 4 4 MISO SPI1-4 MISO1 P0.4/S1.MISO
- 5 5 GND SPI1-1 GND
- 10 J9-1 3V3 SPI1-6 3.3V
+ 1 J8-1 NET CS SPI0-2 P0.3 output P0.3/S0.SS/I1.SDA
+ 2 2 SCK SPI0-5 SCLK0 P0.2/S0.SCLK/I1.SCL
+ 3 3 MOSI SPI0-3 MOSI0 P0.0/S0.MOSI/U3.RX
+ 4 4 MISO SPI0-4 MISO0 P0.1/S0.MISO/U3.TX
+ 5 5 GND SPI0-1 GND
+ 10 J9-1 3V3 SPI0-6 3.3V
9 2 WOL NC
- 8 3 NET INT SPI0-3 P0.1 P0.1/S0.MOSI/U3.RX
+ 8 3 NET INT TMR1_EXT-5 P1.4 input P1.4/T1.ICAPA/T1.EXTCLK
7 4 CLKOUT NC
- 6 5 NET RST SPI0-5 P0.2 P0.2/S0
+ 6 5 NET RST TMR1_EXT_4 P1.5 output P1.5/T1.ICAPB
+
+ UART3, I2C cannot be used with SPI0. The GPIOs selected for the ENC28J60
+ interrupt conflict with TIM1.
Configurations:
---------------
diff --git a/nuttx/configs/olimex-strp711/nettest/defconfig b/nuttx/configs/olimex-strp711/nettest/defconfig
index 9088ec8f7..80c48d7ac 100755
--- a/nuttx/configs/olimex-strp711/nettest/defconfig
+++ b/nuttx/configs/olimex-strp711/nettest/defconfig
@@ -115,8 +115,8 @@ CONFIG_STR71X_UART2=n
CONFIG_STR71X_UART3=n
CONFIG_STR71X_USB=n
CONFIG_STR71X_CAN=n
-CONFIG_STR71X_BSPI0=n
-CONFIG_STR71X_BSPI1=y
+CONFIG_STR71X_BSPI0=y
+CONFIG_STR71X_BSPI1=n
CONFIG_STR71X_HDLC=n
CONFIG_STR71X_XTI=n
CONFIG_STR71X_GPIO0=y
diff --git a/nuttx/configs/olimex-strp711/src/up_enc28j60.c b/nuttx/configs/olimex-strp711/src/up_enc28j60.c
index 4bccb572f..cc285a3dc 100755
--- a/nuttx/configs/olimex-strp711/src/up_enc28j60.c
+++ b/nuttx/configs/olimex-strp711/src/up_enc28j60.c
@@ -33,6 +33,45 @@
*
****************************************************************************/
+/*
+ * ENC28J60 Module
+ *
+ * The ENC28J60 module does not come on the Olimex-STR-P711, but this describes
+ * how I have connected it:
+ *
+ * Module CON5 QFN ENC2860 Description
+ * --------------- -------------------------------------------------------
+ * 1 J8-1 NET CS 5 ~CS Chip select input pin for SPI interface (active low)
+ * 2 2 SCK 4 SCK Clock in pin for SPI interface
+ * 3 3 MOSI 3 SI Data in pin for SPI interface
+ * 4 4 MISO 2 SO Data out pin for SPI interface
+ * 5 5 GND -- --- ---
+ * 10 J9-1 3V3 -- --- ---
+ * 9 2 WOL 1 ~WOL Unicast WOL filter
+ * 8 3 NET INT 28 ~INT Interrupt output pin (active low)
+ * 7 4 CLKOUT 27 CLKOUT Programmable clock output pin
+ * 6 5 NET RST 6 ~RESET Active-low device Reset input
+ *
+ * For the Olimex STR-P711, the ENC28J60 module is placed on SPI0 and uses
+ * P0.3 for CS, P1.4 for an interrupt, and P1.5 as a reset:
+ *
+ * Module CON5 Olimex STR-P711 Connection
+ * --------------- -------------------------------------------------------
+ * 1 J8-1 NET CS SPI0-2 P0.3 output P0.3/S0.SS/I1.SDA
+ * 2 2 SCK SPI0-5 SCLK0 P0.2/S0.SCLK/I1.SCL
+ * 3 3 MOSI SPI0-3 MOSI0 P0.0/S0.MOSI/U3.RX
+ * 4 4 MISO SPI0-4 MISO0 P0.1/S0.MISO/U3.TX
+ * 5 5 GND SPI0-1 GND
+ * 10 J9-1 3V3 SPI0-6 3.3V
+ * 9 2 WOL NC
+ * 8 3 NET INT TMR1_EXT-5 P1.4 input P1.4/T1.ICAPA/T1.EXTCLK
+ * 7 4 CLKOUT NC
+ * 6 5 NET RST TMR1_EXT_4 P1.5 output P1.5/T1.ICAPB
+ *
+ * UART3, I2C cannot be used with SPI0. The GPIOs selected for the ENC28J60
+ * interrupt conflict with TMR1.
+ */
+
/****************************************************************************
* Included Files
****************************************************************************/
@@ -60,8 +99,22 @@
/* Configuration ************************************************************/
-#ifndef CONFIG_STR71X_BSPI1
-# error "Need CONFIG_STR71X_BSP1 in the configuration"
+/* We assume that the ENC28J60 is on SPI0 */
+
+#ifndef CONFIG_STR71X_BSPI0
+# error "Need CONFIG_STR71X_BSPI0 in the configuration"
+#endif
+
+/* UART3, I2C cannot be used with SPI0. The GPIOs selected for the ENC28J60
+ * interrupt conflict with TIM1.
+ */
+
+#ifdef CONFIG_STR71X_UART3
+# error "CONFIG_STR71X_UART3 cannot be used in this configuration"
+#endif
+
+#ifdef CONFIG_STR71X_TIM1
+# error "CONFIG_STR71X_TIM1 cannot be used in this configuration"
#endif
/* SPI Assumptions **********************************************************/
diff --git a/nuttx/configs/olimex-strp711/src/up_spi.c b/nuttx/configs/olimex-strp711/src/up_spi.c
index 4f6036c3f..cfddffeef 100644
--- a/nuttx/configs/olimex-strp711/src/up_spi.c
+++ b/nuttx/configs/olimex-strp711/src/up_spi.c
@@ -1,7 +1,7 @@
/****************************************************************************
* config/olimex-strp711/src/up_spi.c
*
- * Copyright (C) 2008-2009 Gregory Nutt. All rights reserved.
+ * Copyright (C) 2008-2010 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <spudmonkey@racsa.co.cr>
*
* Redistribution and use in source and binary forms, with or without
@@ -116,27 +116,143 @@
*
****************************************************************************/
-#define BSPI0_GPIO0_MISO (0x0001)
-#define BSPI0_GPIO0_MOSI (0x0002)
-#define BSPI0_GPIO0_SCLK (0x0004)
-#define BSPI0_GPIO0_SS (0x0008)
+/* SPI0 *********************************************************************/
-#define BSPIO_GPIO0_ALT (BSPI0_GPIO0_MISO|BSPI0_GPIO0_MOSI|BSPI0_GPIO0_SCLK)
-#define BSPIO_GPIO0_OUT BSPI0_GPIO0_SS
-#define BSPIO_GPIO0_ALL (0x000f)
+#define BSPI0_GPIO0_MISO (1 << 0)
+#define BSPI0_GPIO0_MOSI (1 << 1)
+#define BSPI0_GPIO0_SCLK (1 << 2)
+#define BSPI0_GPIO0_SS (1 << 3) /* Not used */
-#define BSPI1_GPIO0_MISO (0x0010)
-#define BSPI1_GPIO0_MOSI (0x0020)
-#define BSPI1_GPIO0_SCLK (0x0040)
-#define BSPI1_GPIO0_SS (0x0080)
+#define BSPI0_GPIO0_ALT (BSPI0_GPIO0_MISO|BSPI0_GPIO0_MOSI|BSPI0_GPIO0_SCLK)
+
+/* ENC28J60 Module
+ *
+ * The ENC28J60 module does not come on the Olimex-STR-P711, but this describes
+ * how I have connected it:
+ *
+ * STR-P711 PIN PIN CONFIGURATION ENC28J60 CONNECTION
+ * ----------------------- ----------------- -----------------------
+ * P0.3/S0.SS/I1.SDA P0.3 output CON5 1 J8-1 NET CS
+ * P0.2/S0.SCLK/I1.SCL SCLK0 2 2 SCK
+ * P0.0/S0.MOSI/U3.RX MOSI0 3 3 MOSI
+ * P0.1/S0.MISO/U3.TX MISO0 4 4 MISO
+ * GND GND 5 5 GND
+ * 3.3V 3.3V 10 J9-1 3V3
+ * NC NC 9 2 WOL
+ * P1.4/T1.ICAPA/T1.EXTCLK P1.4 input 8 3 NET INT
+ * NC NC 7 4 CLKOUT
+ * P1.5/T1.ICAPB P1.5 output 6 5 NET RST
+ */
+
+#ifdef CONFIG_NET_ENC28J60
+
+/* UART3, I2C cannot be used with SPI0. The GPIOs selected for the ENC28J60
+ * interrupt conflict with TMR1.
+ */
+
+# ifdef CONFIG_STR71X_UART3
+# error "CONFIG_STR71X_UART3 cannot be used in this configuration"
+# endif
+
+# ifdef CONFIG_STR71X_TIM3
+# error "CONFIG_STR71X_TIM3 cannot be used in this configuration"
+# endif
+
+/* ENC28J60 additional pins
+ *
+ * NOTE: The ENC28J60 is a 3.3V part; however, it was designed to be
+ * easily integrated into 5V systems. The SPI CS, SCK and SI inputs,
+ * as well as the RESET pin, are all 5V tolerant. On the other hand,
+ * if the host controller is operated at 5V, it quite likely will
+ * not be within specifications when its SPI and interrupt inputs
+ * are driven by the 3.3V CMOS outputs on the ENC28J60. A
+ * unidirectional level translator would be necessary.
+ */
+
+# define ENC_GPIO0_CS (1 << 3)
+# define ENC_GPIO0_INTTL (0)
+# define ENC_GPIO0_INCMOS (0)
+# define ENC_GPIO0_OUTPP ENC_GPIO0_CS
+# define ENC_GPIO0_ALL ENC_GPIO0_CS
+
+# define ENC_GPIO1_NETINT ( 1 << 4)
+# define ENC_GPIO1_NETRST (1 << 5)
+# define ENC_GPIO1_INTTL (0)
+# define ENC_GPIO1_INCMOS ENC_GPIO1_NETINT
+# define ENC_GPIO1_OUTPP ENC_GPIO1_NETRST
+# define ENC_GPIO1_ALL (ENC_GPIO1_NETINT|ENC_GPIO1_NETRST)
+
+# define BSPI0_GPIO0_INTTL ENC_GPIO0_INTTL
+# define BSPI0_GPIO0_INCMOS ENC_GPIO0_INCMOS
+# define BSPI0_GPIO0_OUTPP ENC_GPIO0_OUTPP
+# define BSPI0_GPIO0_ALL (BSPI0_GPIO0_ALT|ENC_GPIO0_ALL)
+
+# define BSPI0_GPIO1_INTTL ENC_GPIO1_INTTL
+# define BSPI0_GPIO1_INCMOS ENC_GPIO1_INCMOS
+# define BSPI0_GPIO1_OUTPP ENC_GPIO1_OUTPP
+# define BSPI0_GPIO1_ALL ENC_GPIO1_ALL
+
+#else
+# define BSPI0_GPIO0_INTTL (0)
+# define BSPI0_GPIO0_INCMOS (0)
+# define BSPI0_GPIO0_OUTPP (0)
+# define BSPI0_GPIO0_ALL BSPI0_GPIO0_ALT
+#endif
+
+/* SPI1 *********************************************************************/
+
+#define BSPI1_GPIO0_MISO (1 << 4)
+#define BSPI1_GPIO0_MOSI (1 << 5)
+#define BSPI1_GPIO0_SCLK (1 << 6)
+#define BSPI1_GPIO0_SS (1 << 7) /* Not used */
#define BSPI1_GPIO0_ALT (BSPI1_GPIO0_MISO|BSPI1_GPIO0_MOSI|BSPI1_GPIO0_SCLK)
-#define BSPI1_GPIO0_OUT BSPI1_GPIO0_SS
-#define BSPI1_GPIO0_ALL (0x00f0)
-#define MMCSD_GPIO1_WPIN (0x0400)
-#define MMCSD_GPIO1_CPIN (0x8000)
-#define MMCSD_GPIO1_ALL (MMCSD_GPIO1_WPIN|MMCSD_GPIO1_CPIN)
+/* MMC/SD Pin Usage:
+ *
+ * STR-P711 PIN MMC/SD USAGE PIN CONFIGURATION
+ * ------------ ---------------- -----------------------
+ * P0.7/S1.SS 1 CD/DAT3/CS P0.7 output
+ * P0.5/S1.MOSI 2 CMD/DI MOSI1
+ * --- 3 VSS1 ---
+ * --- 4 VDD ---
+ * P0.6/S1.SCLK 5 CLK/SCLK SLCK1
+ * --- 6 VSS2 ---
+ * P0.4/S1.MISO 7 DAT0/D0 MISO1
+ * --- 8 DAT1/RES (Pulled up)
+ * --- 9 DAT2/RES (Pulled up)
+ *
+ * P1.10/USBCLK 10/14 WP P1.10 input
+ * P1.15/HTXD 13/15 CP P1.15 input
+ *
+ * Use of SPI1 doesn't conflict with anything. WP conflicts USB; CP conflicts
+ * with NTXD.
+ */
+
+/* MMC/SD additional pins */
+
+#define MMCSD_GPIO0_CS (1 << 7)
+#define MMCSD_GPIO0_INTTL (0)
+#define MMCSD_GPIO0_INCMOS (0)
+#define MMCSD_GPIO0_OUTPP MMCSD_GPIO0_CS
+#define MMCSD_GPIO0_ALL MMCSD_GPIO0_CS
+
+#define MMCSD_GPIO1_WPIN (1 << 10)
+#define MMCSD_GPIO1_CPIN (1 << 15)
+#define MMCSD_GPIO1_INTTL (MMCSD_GPIO1_WPIN|MMCSD_GPIO1_CPIN)
+#define MMCSD_GPIO1_INCMOS (0)
+#define MMCSD_GPIO1_OUTPP (0)
+#define MMCSD_GPIO1_ALL (MMCSD_GPIO1_WPIN|MMCSD_GPIO1_CPIN)
+
+#define BSPI1_GPIO0_INTTL MMCSD_GPIO0_INTTL
+#define BSPI1_GPIO0_INCMOS MMCSD_GPIO0_INCMOS
+#define BSPI1_GPIO0_OUTPP MMCSD_GPIO0_OUTPP
+#define BSPI1_GPIO0_ALL (BSPI1_GPIO0_ALT|MMCSD_GPIO0_ALL)
+
+#define BSPI1_GPIO1_INTTL MMCSD_GPIO1_INTTL
+#define BSPI1_GPIO1_INCMOS MMCSD_GPIO1_INCMOS
+#define BSPI1_GPIO1_OUTPP MMCSD_GPIO1_OUTPP
+#define BSPI1_GPIO1_ALL MMCSD_GPIO1_ALL
/* Configuration register settings ******************************************/
@@ -250,11 +366,18 @@
* Private Types
****************************************************************************/
+/* NOTE: As implemented here, this driver will support only one device per
+ * SPI bus: Only one chip select, csbit, per bus; no locking, not mode or
+ * bits-per-word settings. To support multiple devices per but, spi_select
+ * would also require some logic changes.
+ */
+
struct str71x_spidev_s
{
- struct spi_dev_s spidev; /* Externally visible part of the SPI interface */
- uint32_t spibase; /* BSPIn base address */
- uint16_t csbit; /* BSPIn SS bit int GPIO0 */
+ struct spi_dev_s spidev; /* Externally visible part of the SPI interface */
+ bool initialized; /* Initialize port only once! */
+ uint32_t spibase; /* BSPIn base address */
+ uint16_t csbit; /* BSPIn SS bit int GPIO0 */
};
/****************************************************************************
@@ -265,6 +388,7 @@ struct str71x_spidev_s
static inline uint16_t spi_getreg(FAR struct str71x_spidev_s *priv, uint8_t offset);
static inline void spi_putreg(FAR struct str71x_spidev_s *priv, uint8_t offset, uint16_t value);
+static inline void spi_drain(FAR struct str71x_spidev_s *priv);
/* SPI methods */
@@ -296,7 +420,7 @@ static struct str71x_spidev_s g_spidev0 =
{
.spidev = { &g_spiops },
.spibase = STR71X_BSPI0_BASE,
- .csbit = BSPI0_GPIO0_SS
+ .csbit = MMCSD_GPIO0_CS
};
#endif
@@ -305,7 +429,7 @@ static struct str71x_spidev_s g_spidev1 =
{
.spidev = { &g_spiops },
.spibase = STR71X_BSPI1_BASE,
- .csbit = BSPI1_GPIO0_SS
+ .csbit = ENC_GPIO0_CS
};
#endif
@@ -359,6 +483,52 @@ static inline void spi_putreg(FAR struct str71x_spidev_s *priv, uint8_t offset,
}
/****************************************************************************
+ * Name: spi_drain
+ *
+ * Description:
+ * Drain any bytes left in the fifos.
+ *
+ * Input Parameters:
+ * dev - Device-specific state data
+ *
+ * Returned Value:
+ * None
+ *
+ ****************************************************************************/
+
+static inline void spi_drain(FAR struct str71x_spidev_s *priv)
+{
+#if CONFIG_STR714X_BSPI0_TXFIFO_DEPTH > 1
+ /* Wait while the TX FIFO is full */
+
+ while ((spi_getreg(priv, STR71X_BSPI_CSR2_OFFSET) & STR71X_BSPICSR2_TFF) != 0);
+#else
+ /* Wait until the TX FIFO is empty */
+
+ while ((spi_getreg(priv, STR71X_BSPI_CSR2_OFFSET) & STR71X_BSPICSR2_TFE) == 0);
+#endif
+ /* Write 0xff to the TX FIFO */
+
+ spi_putreg(priv, STR71X_BSPI_TXR_OFFSET, 0xff00);
+
+ /* Wait for the TX FIFO empty */
+
+ while ((spi_getreg(priv, STR71X_BSPI_CSR2_OFFSET) & STR71X_BSPICSR2_TFNE) != 0);
+
+ /* Wait for the RX FIFO not empty */
+
+ while ((spi_getreg(priv, STR71X_BSPI_CSR2_OFFSET) & STR71X_BSPICSR2_RFNE) == 0);
+
+ /* Then read and discard bytes until the RX FIFO is empty */
+
+ do
+ {
+ (void)spi_getreg(priv, STR71X_BSPI_RXR_OFFSET);
+ }
+ while (spi_getreg(priv, STR71X_BSPI_CSR2_OFFSET & STR71X_BSPICSR2_RFNE) != 0);
+}
+
+/****************************************************************************
* Name: spi_select
*
* Description:
@@ -398,34 +568,9 @@ static void spi_select(FAR struct spi_dev_s *dev, enum spi_dev_e devid, bool sel
reg16 |= priv->csbit;
spi_putreg(priv, STR71X_GPIO_PD_OFFSET, reg16);
-#if CONFIG_STR714X_BSPI0_TXFIFO_DEPTH > 1
- /* Wait while the TX FIFO is full */
-
- while ((spi_getreg(priv, STR71X_BSPI_CSR2_OFFSET) & STR71X_BSPICSR2_TFF) != 0);
-#else
- /* Wait until the TX FIFO is empty */
-
- while ((spi_getreg(priv, STR71X_BSPI_CSR2_OFFSET) & STR71X_BSPICSR2_TFE) == 0);
-#endif
- /* Write 0xff to the TX FIFO */
-
- spi_putreg(priv, STR71X_BSPI_TXR_OFFSET, 0xff00);
-
- /* Wait for the TX FIFO empty */
-
- while ((spi_getreg(priv, STR71X_BSPI_CSR2_OFFSET) & STR71X_BSPICSR2_TFNE) != 0);
+ /* And drain the FIFOs */
- /* Wait for the RX FIFO not empty */
-
- while ((spi_getreg(priv, STR71X_BSPI_CSR2_OFFSET) & STR71X_BSPICSR2_RFNE) == 0);
-
- /* Then read and discard bytes until the RX FIFO is empty */
-
- do
- {
- (void)spi_getreg(priv, STR71X_BSPI_RXR_OFFSET);
- }
- while (spi_getreg(priv, STR71X_BSPI_CSR2_OFFSET & STR71X_BSPICSR2_RFNE) != 0);
+ spi_drain(priv);
}
}
@@ -704,7 +849,8 @@ static void spi_recvblock(FAR struct spi_dev_s *dev, FAR void *buffer, size_t bu
* Name: up_spiinitialize
*
* Description:
- * Initialize the selected SPI port
+ * Initialize the selected SPI port. This function could get called
+ * multiple times for each STR7 devices that needs an SPI reference.
*
* Input Parameter:
* Port number (for hardware that has mutiple SPI interfaces)
@@ -724,49 +870,87 @@ FAR struct spi_dev_s *up_spiinitialize(int port)
#ifdef CONFIG_STR71X_BSPI0
if (port == 0)
{
- /* The default, alternate functionality of the GPIO0 pin selections is
- * UART3/I2C1. In order to have BSP0 functionality, we also have to
- * set the BSPI0 enable bit in the PCU BOOTCR register.
- */
+ /* Check if this port has already been initialized */
- reg16 = getreg16(STR71X_PCU_BOOTCR);
- reg16 |= STR71X_PCUBOOTCR_BSPIOEN;
- putreg16(reg16, STR71X_PCU_BOOTCR);
+ if (!g_spidev0.initialized)
+ {
+ /* The default, alternate functionality of the GPIO0 pin selections is
+ * UART3/I2C1. In order to have BSP0 functionality, we also have to
+ * set the BSPI0 enable bit in the PCU BOOTCR register.
+ */
+
+ reg16 = getreg16(STR71X_PCU_BOOTCR);
+ reg16 |= STR71X_PCUBOOTCR_BSPIOEN;
+ putreg16(reg16, STR71X_PCU_BOOTCR);
+
+ /* Configure all GPIO pins to their appropriate function:
+ *
+ * PC0=1 PC1=1 PC2=1: Alternate function, push-pull
+ * PC0=1 PC1=0 PC2=0: In, TTL
+ * PC0=0 PC1=1 PC2=0: In, CMOS
+ * PC0=1 PC1=0 PC2=1: Output, push pull
+ */
+
+ reg16 = getreg16(STR71X_GPIO0_PC0);
+ reg16 &= ~BSPI0_GPIO0_ALL;
+ reg16 |= (BSPI0_GPIO0_ALT|BSPI0_GPIO0_INTTL|BSPI0_GPIO0_OUTPP);
+ putreg16(reg16, STR71X_GPIO0_PC0);
+
+ reg16 = getreg16(STR71X_GPIO0_PC1);
+ reg16 &= ~BSPI0_GPIO0_ALL;
+ reg16 |= (BSPI0_GPIO0_ALT|BSPI0_GPIO0_INCMOS);
+ putreg16(reg16, STR71X_GPIO0_PC1);
+
+ reg16 = getreg16(STR71X_GPIO0_PC2);
+ reg16 &= ~BSPI0_GPIO0_ALL;
+ reg16 |= (BSPI0_GPIO0_ALT|BSPI0_GPIO0_OUTPP);
+ putreg16(reg16, STR71X_GPIO0_PC2);
+
+ /* Start with enc28j60 disabled */
+
+#ifdef CONFIG_NET_ENC28J60
+ reg16 = getreg16(STR71X_GPIO0_PD);
+ reg16 |= ENC_GPIO0_CS;
+ putreg16(reg16, STR71X_GPIO0_PD);
+#endif
- /* Configure all GPIO pins to their alternate function EXCEPT
- * for the SS pin .. will will configure that as an output
- * and control the chip select as a normal GPIO.
- */
+ /* Set the clock divider to the maximum */
- reg16 = getreg16(STR71X_GPIO0_PC0);
- reg16 |= BSPIO_GPIO0_ALL;
- putreg16(reg16, STR71X_GPIO0_PC0);
+ putreg16(255, STR71X_BSPI0_CLK);
- reg16 = getreg16(STR71X_GPIO0_PC1);
- reg16 &= ~BSPIO_GPIO0_ALL;
- reg16 |= BSPIO_GPIO0_ALT;
- putreg16(reg16, STR71X_GPIO0_PC1);
+ /* Set FIFO sizes and disable the BSP1. It won't be enabled
+ * until the frequency is set.
+ */
- reg16 = getreg16(STR71X_GPIO0_PC2);
- reg16 |= BSPIO_GPIO0_ALL;
- putreg16(reg16, STR71X_GPIO0_PC2);
+ putreg16(STR71X_BSPI0_CSR1DISABLE, STR71X_BSPI0_CSR1);
+ putreg16(STR71X_BSPI0_CSR2VALUE, STR71X_BSPI0_CSR2);
- /* Start with chip slave disabled */
+ /* Configure GPIO1 pins for ENC28J60 inputs and outputs.
+ *
+ * PC0=1 PC1=0 PC2=0: In, TTL
+ * PC0=0 PC1=1 PC2=0: In, CMOS
+ * PC0=1 PC1=0 PC2=1: Output, push pull
+ */
- reg16 = getreg16(STR71X_GPIO0_PD);
- reg16 |= BSPI0_GPIO0_SS;
- putreg16(reg16, STR71X_GPIO0_PD);
+ reg16 = getreg16(STR71X_GPIO1_PC0);
+ reg16 &= ~BSPI0_GPIO1_ALL;
+ reg16 |= (BSPI0_GPIO1_INTTL|BSPI0_GPIO1_OUTPP);
+ putreg16(reg16, STR71X_GPIO1_PC0);
- /* Set the clock divider to the maximum */
+ reg16 = getreg16(STR71X_GPIO1_PC1);
+ reg16 &= ~BSPI0_GPIO1_ALL;
+ reg16 |= BSPI0_GPIO0_INCMOS;
+ putreg16(reg16, STR71X_GPIO1_PC1);
- putreg16(255, STR71X_BSPI0_CLK);
+ reg16 = getreg16(STR71X_GPIO1_PC2);
+ reg16 &= ~BSPI0_GPIO1_ALL;
+ reg16 |= BSPI0_GPIO0_OUTPP;
+ putreg16(reg16, STR71X_GPIO1_PC2);
- /* Set FIFO sizes and disable the BSP1. It won't be enabled
- * until the frequency is set.
- */
+ g_spidev0.initialized = true;
+ }
- putreg16(STR71X_BSPI0_CSR1DISABLE, STR71X_BSPI0_CSR1);
- putreg16(STR71X_BSPI0_CSR2VALUE, STR71X_BSPI0_CSR2);
+ /* Return the SPI device reference */
ret = &g_spidev0.spidev;
}
@@ -775,54 +959,79 @@ FAR struct spi_dev_s *up_spiinitialize(int port)
#ifdef CONFIG_STR71X_BSPI1
if (port == 1)
{
- /* Configure all GPIO pins to their alternate function EXCEPT
- * for the SS pin .. will will configure that as an output
- * and control the chip select as a normal GPIO.
- */
-
- reg16 = getreg16(STR71X_GPIO0_PC0);
- reg16 |= BSPI1_GPIO0_ALL;
- putreg16(reg16, STR71X_GPIO0_PC0);
-
- reg16 = getreg16(STR71X_GPIO0_PC1);
- reg16 &= ~BSPI1_GPIO0_ALL;
- reg16 |= BSPI1_GPIO0_ALT;
- putreg16(reg16, STR71X_GPIO0_PC1);
-
- reg16 = getreg16(STR71X_GPIO0_PC2);
- reg16 |= BSPI1_GPIO0_ALL;
- putreg16(reg16, STR71X_GPIO0_PC2);
-
- /* Start with chip slave disabled */
-
- reg16 = getreg16(STR71X_GPIO0_PD);
- reg16 |= BSPI1_GPIO0_SS;
- putreg16(reg16, STR71X_GPIO0_PD);
+ /* Check if this port has already been initialized */
- /* Set the clock divider to the maximum */
-
- putreg16(255, STR71X_BSPI1_CLK);
-
- /* Set FIFO sizes and disable the BSP1. It won't be enabled
- * until the frequency is set.
- */
-
- putreg16(STR71X_BSPI1_CSR1DISABLE, STR71X_BSPI1_CSR1);
- putreg16(STR71X_BSPI1_CSR2VALUE, STR71X_BSPI1_CSR2);
-
- /* Configure GPIO1 pins for WP/CP input */
-
- reg16 = getreg16(STR71X_GPIO1_PC0);
- reg16 |= MMCSD_GPIO1_ALL;
- putreg16(reg16, STR71X_GPIO1_PC0);
-
- reg16 = getreg16(STR71X_GPIO1_PC1);
- reg16 &= ~MMCSD_GPIO1_ALL;
- putreg16(reg16, STR71X_GPIO1_PC1);
+ if (!g_spidev1.initialized)
+ {
+ /* Configure all GPIO pins to their alternate function EXCEPT for
+ * the CS pin .. we will configure that as an push-pull output
+ * and control the chip select as a normal GPIO.
+ *
+ * PC0=1 PC1=1 PC2=1: Alternate function, push-pull
+ * PC0=1 PC1=0 PC2=0: In, TTL
+ * PC0=0 PC1=1 PC2=0: In, CMOS
+ * PC0=1 PC1=0 PC2=1: Output, push pull
+ */
+
+ reg16 = getreg16(STR71X_GPIO0_PC0);
+ reg16 &= ~BSPI1_GPIO0_ALL;
+ reg16 |= (BSPI1_GPIO0_ALT|BSPI1_GPIO0_INTTL|BSPI1_GPIO0_OUTPP);
+ putreg16(reg16, STR71X_GPIO0_PC0);
+
+ reg16 = getreg16(STR71X_GPIO0_PC1);
+ reg16 &= ~BSPI1_GPIO0_ALL;
+ reg16 |= (BSPI1_GPIO0_ALT|BSPI1_GPIO0_INCMOS);
+ putreg16(reg16, STR71X_GPIO0_PC1);
+
+ reg16 = getreg16(STR71X_GPIO0_PC2);
+ reg16 &= ~BSPI1_GPIO0_ALL;
+ reg16 |= (BSPI1_GPIO0_ALT|BSPI1_GPIO0_OUTPP);
+ putreg16(reg16, STR71X_GPIO0_PC2);
+
+ /* Start with MMC/SD disabled */
+
+ reg16 = getreg16(STR71X_GPIO0_PD);
+ reg16 |= MMCSD_GPIO0_CS;
+ putreg16(reg16, STR71X_GPIO0_PD);
+
+ /* Set the clock divider to the maximum */
+
+ putreg16(255, STR71X_BSPI1_CLK);
+
+ /* Set FIFO sizes and disable the BSP1. It won't be enabled
+ * until the frequency is set.
+ */
+
+ putreg16(STR71X_BSPI1_CSR1DISABLE, STR71X_BSPI1_CSR1);
+ putreg16(STR71X_BSPI1_CSR2VALUE, STR71X_BSPI1_CSR2);
+
+ /* Configure GPIO1 pins for WP/CP input
+ *
+ * PC0=1 PC1=0 PC2=0: In, TTL
+ * PC0=0 PC1=1 PC2=0: In, CMOS
+ * PC0=1 PC1=0 PC2=1: Output, push pull
+ */
+
+#ifdef BSPI1_GPIO1_ALL
+ reg16 = getreg16(STR71X_GPIO1_PC0);
+ reg16 &= ~BSPI1_GPIO1_ALL;
+ reg16 |= (BSPI1_GPIO1_INTTL|BSPI1_GPIO1_OUTPP);
+ putreg16(reg16, STR71X_GPIO1_PC0);
+
+ reg16 = getreg16(STR71X_GPIO1_PC1);
+ reg16 &= ~BSPI1_GPIO1_ALL;
+ reg16 |= BSPI1_GPIO0_INCMOS;
+ putreg16(reg16, STR71X_GPIO1_PC1);
+
+ reg16 = getreg16(STR71X_GPIO1_PC2);
+ reg16 &= ~BSPI1_GPIO1_ALL;
+ reg16 |= BSPI1_GPIO0_OUTPP;
+ putreg16(reg16, STR71X_GPIO1_PC2);
+#endif
+ g_spidev1.initialized = true;
+ }
- reg16 = getreg16(STR71X_GPIO1_PC2);
- reg16 &= ~MMCSD_GPIO1_ALL;
- putreg16(reg16, STR71X_GPIO1_PC2);
+ /* Return the SPI device reference */
ret = &g_spidev1.spidev;
}