Add ENC28J60 GPIO configuration

git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@2644 42af7a65-404d-4744-a932-0658087f49c3
This commit is contained in:
patacongo 2010-05-02 17:29:37 +00:00
parent 2a17959c7e
commit 34ebc7312c
4 changed files with 420 additions and 132 deletions
configs/olimex-strp711

@ -228,9 +228,33 @@ GENERAL STEPS:
The same commands from the telnet interface can now be accessed through the The same commands from the telnet interface can now be accessed through the
'monitor' command, e.g. 'monitor help' '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 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 Module CON5 QFN ENC2860 Description
--------------- ------------------------------------------------------- --------------- -------------------------------------------------------
1 J8-1 NET CS 5 ~CS Chip select input pin for SPI interface (active low) 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 7 4 CLKOUT 27 CLKOUT Programmable clock output pin
6 5 NET RST 6 ~RESET Active-low device Reset input 6 5 NET RST 6 ~RESET Active-low device Reset input
For the Olimex STR-P711, the ENC28J60 module is placed on SPI1 (with For the Olimex STR-P711, the ENC28J60 module is placed on SPI0 and uses
the MMC slot) and uses P0.0 for CS, P0.1 for an interrupt, and P0.2 as P0.3 for CS, P1.4 for an interrupt, and P1.5 as a reset:
a reset:
Module CON5 Olimex STR-P711 Connection Module CON5 Olimex STR-P711 Connection
--------------- ------------------------------------------------------- --------------- -------------------------------------------------------
1 J8-1 NET CS SPI0-4 P0.0 P0.0/S0.MISO/U3.TX 1 J8-1 NET CS SPI0-2 P0.3 output P0.3/S0.SS/I1.SDA
2 2 SCK SPI1-5 SCLK1 P0.6/S1.SCLK 2 2 SCK SPI0-5 SCLK0 P0.2/S0.SCLK/I1.SCL
3 3 MOSI SPI1-3 MOSI1 P0.5/S1.MOSI 3 3 MOSI SPI0-3 MOSI0 P0.0/S0.MOSI/U3.RX
4 4 MISO SPI1-4 MISO1 P0.4/S1.MISO 4 4 MISO SPI0-4 MISO0 P0.1/S0.MISO/U3.TX
5 5 GND SPI1-1 GND 5 5 GND SPI0-1 GND
10 J9-1 3V3 SPI1-6 3.3V 10 J9-1 3V3 SPI0-6 3.3V
9 2 WOL NC 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 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: Configurations:
--------------- ---------------

@ -115,8 +115,8 @@ CONFIG_STR71X_UART2=n
CONFIG_STR71X_UART3=n CONFIG_STR71X_UART3=n
CONFIG_STR71X_USB=n CONFIG_STR71X_USB=n
CONFIG_STR71X_CAN=n CONFIG_STR71X_CAN=n
CONFIG_STR71X_BSPI0=n CONFIG_STR71X_BSPI0=y
CONFIG_STR71X_BSPI1=y CONFIG_STR71X_BSPI1=n
CONFIG_STR71X_HDLC=n CONFIG_STR71X_HDLC=n
CONFIG_STR71X_XTI=n CONFIG_STR71X_XTI=n
CONFIG_STR71X_GPIO0=y CONFIG_STR71X_GPIO0=y

@ -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 * Included Files
****************************************************************************/ ****************************************************************************/
@ -60,8 +99,22 @@
/* Configuration ************************************************************/ /* Configuration ************************************************************/
#ifndef CONFIG_STR71X_BSPI1 /* We assume that the ENC28J60 is on SPI0 */
# error "Need CONFIG_STR71X_BSP1 in the configuration"
#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 #endif
/* SPI Assumptions **********************************************************/ /* SPI Assumptions **********************************************************/

@ -1,7 +1,7 @@
/**************************************************************************** /****************************************************************************
* config/olimex-strp711/src/up_spi.c * 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> * Author: Gregory Nutt <spudmonkey@racsa.co.cr>
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
@ -116,27 +116,143 @@
* *
****************************************************************************/ ****************************************************************************/
#define BSPI0_GPIO0_MISO (0x0001) /* SPI0 *********************************************************************/
#define BSPI0_GPIO0_MOSI (0x0002)
#define BSPI0_GPIO0_SCLK (0x0004)
#define BSPI0_GPIO0_SS (0x0008)
#define BSPIO_GPIO0_ALT (BSPI0_GPIO0_MISO|BSPI0_GPIO0_MOSI|BSPI0_GPIO0_SCLK) #define BSPI0_GPIO0_MISO (1 << 0)
#define BSPIO_GPIO0_OUT BSPI0_GPIO0_SS #define BSPI0_GPIO0_MOSI (1 << 1)
#define BSPIO_GPIO0_ALL (0x000f) #define BSPI0_GPIO0_SCLK (1 << 2)
#define BSPI0_GPIO0_SS (1 << 3) /* Not used */
#define BSPI1_GPIO0_MISO (0x0010) #define BSPI0_GPIO0_ALT (BSPI0_GPIO0_MISO|BSPI0_GPIO0_MOSI|BSPI0_GPIO0_SCLK)
#define BSPI1_GPIO0_MOSI (0x0020)
#define BSPI1_GPIO0_SCLK (0x0040) /* ENC28J60 Module
#define BSPI1_GPIO0_SS (0x0080) *
* 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_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) /* MMC/SD Pin Usage:
#define MMCSD_GPIO1_CPIN (0x8000) *
#define MMCSD_GPIO1_ALL (MMCSD_GPIO1_WPIN|MMCSD_GPIO1_CPIN) * 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 ******************************************/ /* Configuration register settings ******************************************/
@ -250,11 +366,18 @@
* Private Types * 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 str71x_spidev_s
{ {
struct spi_dev_s spidev; /* Externally visible part of the SPI interface */ struct spi_dev_s spidev; /* Externally visible part of the SPI interface */
uint32_t spibase; /* BSPIn base address */ bool initialized; /* Initialize port only once! */
uint16_t csbit; /* BSPIn SS bit int GPIO0 */ 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 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_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 */ /* SPI methods */
@ -296,7 +420,7 @@ static struct str71x_spidev_s g_spidev0 =
{ {
.spidev = { &g_spiops }, .spidev = { &g_spiops },
.spibase = STR71X_BSPI0_BASE, .spibase = STR71X_BSPI0_BASE,
.csbit = BSPI0_GPIO0_SS .csbit = MMCSD_GPIO0_CS
}; };
#endif #endif
@ -305,7 +429,7 @@ static struct str71x_spidev_s g_spidev1 =
{ {
.spidev = { &g_spiops }, .spidev = { &g_spiops },
.spibase = STR71X_BSPI1_BASE, .spibase = STR71X_BSPI1_BASE,
.csbit = BSPI1_GPIO0_SS .csbit = ENC_GPIO0_CS
}; };
#endif #endif
@ -358,6 +482,52 @@ static inline void spi_putreg(FAR struct str71x_spidev_s *priv, uint8_t offset,
putreg16(value, priv->spibase + offset); putreg16(value, priv->spibase + 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 * Name: spi_select
* *
@ -398,34 +568,9 @@ static void spi_select(FAR struct spi_dev_s *dev, enum spi_dev_e devid, bool sel
reg16 |= priv->csbit; reg16 |= priv->csbit;
spi_putreg(priv, STR71X_GPIO_PD_OFFSET, reg16); spi_putreg(priv, STR71X_GPIO_PD_OFFSET, reg16);
#if CONFIG_STR714X_BSPI0_TXFIFO_DEPTH > 1 /* And drain the FIFOs */
/* Wait while the TX FIFO is full */
while ((spi_getreg(priv, STR71X_BSPI_CSR2_OFFSET) & STR71X_BSPICSR2_TFF) != 0); spi_drain(priv);
#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);
} }
} }
@ -704,7 +849,8 @@ static void spi_recvblock(FAR struct spi_dev_s *dev, FAR void *buffer, size_t bu
* Name: up_spiinitialize * Name: up_spiinitialize
* *
* Description: * 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: * Input Parameter:
* Port number (for hardware that has mutiple SPI interfaces) * 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 #ifdef CONFIG_STR71X_BSPI0
if (port == 0) if (port == 0)
{ {
/* The default, alternate functionality of the GPIO0 pin selections is /* Check if this port has already been initialized */
* 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); if (!g_spidev0.initialized)
reg16 |= STR71X_PCUBOOTCR_BSPIOEN; {
putreg16(reg16, STR71X_PCU_BOOTCR); /* 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.
*/
/* Configure all GPIO pins to their alternate function EXCEPT reg16 = getreg16(STR71X_PCU_BOOTCR);
* for the SS pin .. will will configure that as an output reg16 |= STR71X_PCUBOOTCR_BSPIOEN;
* and control the chip select as a normal GPIO. putreg16(reg16, STR71X_PCU_BOOTCR);
*/
reg16 = getreg16(STR71X_GPIO0_PC0); /* Configure all GPIO pins to their appropriate function:
reg16 |= BSPIO_GPIO0_ALL; *
putreg16(reg16, STR71X_GPIO0_PC0); * 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_PC1); reg16 = getreg16(STR71X_GPIO0_PC0);
reg16 &= ~BSPIO_GPIO0_ALL; reg16 &= ~BSPI0_GPIO0_ALL;
reg16 |= BSPIO_GPIO0_ALT; reg16 |= (BSPI0_GPIO0_ALT|BSPI0_GPIO0_INTTL|BSPI0_GPIO0_OUTPP);
putreg16(reg16, STR71X_GPIO0_PC1); putreg16(reg16, STR71X_GPIO0_PC0);
reg16 = getreg16(STR71X_GPIO0_PC2); reg16 = getreg16(STR71X_GPIO0_PC1);
reg16 |= BSPIO_GPIO0_ALL; reg16 &= ~BSPI0_GPIO0_ALL;
putreg16(reg16, STR71X_GPIO0_PC2); reg16 |= (BSPI0_GPIO0_ALT|BSPI0_GPIO0_INCMOS);
putreg16(reg16, STR71X_GPIO0_PC1);
/* Start with chip slave disabled */ reg16 = getreg16(STR71X_GPIO0_PC2);
reg16 &= ~BSPI0_GPIO0_ALL;
reg16 |= (BSPI0_GPIO0_ALT|BSPI0_GPIO0_OUTPP);
putreg16(reg16, STR71X_GPIO0_PC2);
reg16 = getreg16(STR71X_GPIO0_PD); /* Start with enc28j60 disabled */
reg16 |= BSPI0_GPIO0_SS;
putreg16(reg16, STR71X_GPIO0_PD);
/* Set the clock divider to the maximum */ #ifdef CONFIG_NET_ENC28J60
reg16 = getreg16(STR71X_GPIO0_PD);
reg16 |= ENC_GPIO0_CS;
putreg16(reg16, STR71X_GPIO0_PD);
#endif
putreg16(255, STR71X_BSPI0_CLK); /* Set the clock divider to the maximum */
/* Set FIFO sizes and disable the BSP1. It won't be enabled putreg16(255, STR71X_BSPI0_CLK);
* until the frequency is set.
*/
putreg16(STR71X_BSPI0_CSR1DISABLE, STR71X_BSPI0_CSR1); /* Set FIFO sizes and disable the BSP1. It won't be enabled
putreg16(STR71X_BSPI0_CSR2VALUE, STR71X_BSPI0_CSR2); * until the frequency is set.
*/
putreg16(STR71X_BSPI0_CSR1DISABLE, STR71X_BSPI0_CSR1);
putreg16(STR71X_BSPI0_CSR2VALUE, STR71X_BSPI0_CSR2);
/* 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_GPIO1_PC0);
reg16 &= ~BSPI0_GPIO1_ALL;
reg16 |= (BSPI0_GPIO1_INTTL|BSPI0_GPIO1_OUTPP);
putreg16(reg16, STR71X_GPIO1_PC0);
reg16 = getreg16(STR71X_GPIO1_PC1);
reg16 &= ~BSPI0_GPIO1_ALL;
reg16 |= BSPI0_GPIO0_INCMOS;
putreg16(reg16, STR71X_GPIO1_PC1);
reg16 = getreg16(STR71X_GPIO1_PC2);
reg16 &= ~BSPI0_GPIO1_ALL;
reg16 |= BSPI0_GPIO0_OUTPP;
putreg16(reg16, STR71X_GPIO1_PC2);
g_spidev0.initialized = true;
}
/* Return the SPI device reference */
ret = &g_spidev0.spidev; ret = &g_spidev0.spidev;
} }
@ -775,54 +959,79 @@ FAR struct spi_dev_s *up_spiinitialize(int port)
#ifdef CONFIG_STR71X_BSPI1 #ifdef CONFIG_STR71X_BSPI1
if (port == 1) if (port == 1)
{ {
/* Configure all GPIO pins to their alternate function EXCEPT /* Check if this port has already been initialized */
* 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); if (!g_spidev1.initialized)
reg16 |= BSPI1_GPIO0_ALL; {
putreg16(reg16, STR71X_GPIO0_PC0); /* 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_PC1); reg16 = getreg16(STR71X_GPIO0_PC0);
reg16 &= ~BSPI1_GPIO0_ALL; reg16 &= ~BSPI1_GPIO0_ALL;
reg16 |= BSPI1_GPIO0_ALT; reg16 |= (BSPI1_GPIO0_ALT|BSPI1_GPIO0_INTTL|BSPI1_GPIO0_OUTPP);
putreg16(reg16, STR71X_GPIO0_PC1); putreg16(reg16, STR71X_GPIO0_PC0);
reg16 = getreg16(STR71X_GPIO0_PC2); reg16 = getreg16(STR71X_GPIO0_PC1);
reg16 |= BSPI1_GPIO0_ALL; reg16 &= ~BSPI1_GPIO0_ALL;
putreg16(reg16, STR71X_GPIO0_PC2); reg16 |= (BSPI1_GPIO0_ALT|BSPI1_GPIO0_INCMOS);
putreg16(reg16, STR71X_GPIO0_PC1);
/* Start with chip slave disabled */ reg16 = getreg16(STR71X_GPIO0_PC2);
reg16 &= ~BSPI1_GPIO0_ALL;
reg16 |= (BSPI1_GPIO0_ALT|BSPI1_GPIO0_OUTPP);
putreg16(reg16, STR71X_GPIO0_PC2);
reg16 = getreg16(STR71X_GPIO0_PD); /* Start with MMC/SD disabled */
reg16 |= BSPI1_GPIO0_SS;
putreg16(reg16, STR71X_GPIO0_PD);
/* Set the clock divider to the maximum */ reg16 = getreg16(STR71X_GPIO0_PD);
reg16 |= MMCSD_GPIO0_CS;
putreg16(reg16, STR71X_GPIO0_PD);
putreg16(255, STR71X_BSPI1_CLK); /* Set the clock divider to the maximum */
/* Set FIFO sizes and disable the BSP1. It won't be enabled putreg16(255, STR71X_BSPI1_CLK);
* until the frequency is set.
*/
putreg16(STR71X_BSPI1_CSR1DISABLE, STR71X_BSPI1_CSR1); /* Set FIFO sizes and disable the BSP1. It won't be enabled
putreg16(STR71X_BSPI1_CSR2VALUE, STR71X_BSPI1_CSR2); * until the frequency is set.
*/
/* Configure GPIO1 pins for WP/CP input */ putreg16(STR71X_BSPI1_CSR1DISABLE, STR71X_BSPI1_CSR1);
putreg16(STR71X_BSPI1_CSR2VALUE, STR71X_BSPI1_CSR2);
reg16 = getreg16(STR71X_GPIO1_PC0); /* Configure GPIO1 pins for WP/CP input
reg16 |= MMCSD_GPIO1_ALL; *
putreg16(reg16, STR71X_GPIO1_PC0); * 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_GPIO1_PC1); #ifdef BSPI1_GPIO1_ALL
reg16 &= ~MMCSD_GPIO1_ALL; reg16 = getreg16(STR71X_GPIO1_PC0);
putreg16(reg16, STR71X_GPIO1_PC1); reg16 &= ~BSPI1_GPIO1_ALL;
reg16 |= (BSPI1_GPIO1_INTTL|BSPI1_GPIO1_OUTPP);
putreg16(reg16, STR71X_GPIO1_PC0);
reg16 = getreg16(STR71X_GPIO1_PC2); reg16 = getreg16(STR71X_GPIO1_PC1);
reg16 &= ~MMCSD_GPIO1_ALL; reg16 &= ~BSPI1_GPIO1_ALL;
putreg16(reg16, STR71X_GPIO1_PC2); 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;
}
/* Return the SPI device reference */
ret = &g_spidev1.spidev; ret = &g_spidev1.spidev;
} }