diff options
Diffstat (limited to 'nuttx')
-rw-r--r-- | nuttx/ChangeLog | 3 | ||||
-rw-r--r-- | nuttx/configs/arduino-due/Kconfig | 9 | ||||
-rw-r--r-- | nuttx/configs/arduino-due/README.txt | 26 | ||||
-rw-r--r-- | nuttx/configs/arduino-due/nsh/defconfig | 1 | ||||
-rw-r--r-- | nuttx/configs/arduino-due/src/Makefile | 17 | ||||
-rw-r--r-- | nuttx/configs/arduino-due/src/arduino-due.h | 157 | ||||
-rw-r--r-- | nuttx/drivers/Makefile | 3 | ||||
-rw-r--r-- | nuttx/drivers/input/Make.defs | 2 | ||||
-rw-r--r-- | nuttx/drivers/spi/Kconfig | 19 | ||||
-rwxr-xr-x | nuttx/drivers/spi/spi_bitbang.c | 544 | ||||
-rwxr-xr-x | nuttx/include/nuttx/spi/spi_bitbang.h | 176 |
11 files changed, 934 insertions, 23 deletions
diff --git a/nuttx/ChangeLog b/nuttx/ChangeLog index d19bb86c8..dcc7d15cf 100644 --- a/nuttx/ChangeLog +++ b/nuttx/ChangeLog @@ -5096,4 +5096,7 @@ SPI-related files. includes/nuttx/spi.h moved to include/nuttx/spi/.; SPI-related Kconfig info moved from drivers/Kconfig to drivers/spi/kconfig (2013-7-1). + * drivers/spi/spi_bitbang.c and include/nuttx/spi/spi_bitbang.h: Add + support for a generic bit-bang SPI driver. This checkout is the + common upper-half logic. Still missing the lower half (2013-7-1). diff --git a/nuttx/configs/arduino-due/Kconfig b/nuttx/configs/arduino-due/Kconfig index 8a0550d91..5330ae2a4 100644 --- a/nuttx/configs/arduino-due/Kconfig +++ b/nuttx/configs/arduino-due/Kconfig @@ -4,4 +4,13 @@ # if ARCH_BOARD_ARDUINO_DUE + +config ARDUINO_ITHEAD_TFT + bool "ITEAD 2.4 inch TFT w/Touch" + default n + ---help--- + Select this option if you have the ITEAD 2.4" TFT module installed. + This will enable support for the peripherals on that module + including the SD card, TFT LCD, and touchscreen controller. + endif diff --git a/nuttx/configs/arduino-due/README.txt b/nuttx/configs/arduino-due/README.txt index 4e9a304d5..35b9b20f3 100644 --- a/nuttx/configs/arduino-due/README.txt +++ b/nuttx/configs/arduino-due/README.txt @@ -122,19 +122,22 @@ ITEAD 2.4" TFT with Touch The Arduino 2.4" TFT Touch shield uses the S6D1121 controller , it supports 8-bit data interface. The touch IC is TSC2046. - Arduino ATSAM3X Due ITHEAD - Due PIN GPIO FUNCTION SIGNAL PIN SIGNAL NOTES + ---------- --------------------------- ----------- ----- ---------- ------------------ + Arduino ATSAM3X Due ITHEAD + Due PIN GPIO FUNCTION SIGNAL PIN SIGNAL NOTES + ---------- ---- ---------------------- ----------- ----- ---------- ------------------ PWMH 10 SCL1 PA18 TWCK0/A20/WKUP9 SCL1 --- --- SCL not available 9 SDA1 PA17 TWD0SPCK0 SDA1 --- --- SDA not available 8 Aref --- --- AREF Vref --- --- 7 GND --- --- GND GND --- --- - 6 PWM13 PB27 SPI0_SPCK/A20/WKUP10 PWM13 D13 SD_SCK SCK, also LED "L" + 6 PWM13 PB27 SPI0_SPCK/A20/WKUP10 PWM13 D13 SD_SCK SCK, also LED "L", Pulled low on-board 5 PWM12 PD8 A21/NANDALE/TIOB8 PWM12 D12 SD_MISO MISO not available - 4 PWM11 PD7 A17/BA1/TIOA8 PWM11 D11 SD_MOSI MOSI not available - 3 PWM10 ??? ??? SS0/PWM10 D10 SD_CS ??? - 2 PWM9 PC21 A0/NBS0/PWML4 PWM9 D9 Touch_IRQ --- - 1 PWM8 PC22 A1/PWML5 PWM8 D8 Touch_Dout --- + 4 PWM11 PD7 A17/BA1/TIOA8 PWM11 D11 SD_MOSI MOSI not available, Pulled low on-board + 3 PWM10 ??? ??? SS0/PWM10 D10 SD_CS Pulled low on-board + 2 PWM9 PC21 A0/NBS0/PWML4 PWM9 D9 Touch_Dout --- + 1 PWM8 PC22 A1/PWML5 PWM8 D8 Touch_IRQ --- + PWML 8 PWM7 PC23 A2/PWML6 PWM7 D7 DB15 --- 7 PWM6 PC24 A3/PWML7 PWM6 D6 DB14 --- @@ -144,7 +147,7 @@ ITEAD 2.4" TFT with Touch 3 PWM2 PB25 RTS0/TIOA0 PWM2 D2 DB10 --- 2 PWM1 PA9 UTXD/PWMH3 TX D1 DB9 UART0 TX 1 PWM0 PA8 URXD/PWMH0/WKUP4 RX D0 DB8 UART0 RX - + ---------- ---- ---------------------- ----------- ----- ---------- ------------------ POWER 1 --- --- --- --- --- --- --- 2 IOref --- --- IOREF +3V3 --- --- --- @@ -163,14 +166,15 @@ ITEAD 2.4" TFT with Touch 6 A5 PA4 TCLK1/NWAIT/AD2 AD5 A5 TFT_RS --- 7 A6 PA3 TIOB1/PWMFI1/AD1/WKUP1 AD6 --- --- --- 8 A7 PA2 TIOA1/NANDRDY/AD0 AD7 --- --- --- + ---------- ---- ---------------------- ----------- ----- ---------- ------------------ - NOTE: + NOTES: 1. It is not possible to use any of the SPI devices on the Shield unless a bit-bang SPI interface is used. This includes the touch controller and the SD card. - 2. UART0 cannot be used - 3. Parallel data is not contiguous in any PIO register + 2. UART0 cannot be used. USARTs on the COMM connector should be available. + 3. Parallel data is not contiguous in the PIO register 4. 3.3V and 5V are reversed. Development Environment diff --git a/nuttx/configs/arduino-due/nsh/defconfig b/nuttx/configs/arduino-due/nsh/defconfig index 2e0f4387b..01e2dfe16 100644 --- a/nuttx/configs/arduino-due/nsh/defconfig +++ b/nuttx/configs/arduino-due/nsh/defconfig @@ -245,6 +245,7 @@ CONFIG_NSH_MMCSDMINOR=0 # # Board-Specific Options # +# CONFIG_ARDUINO_ITHEAD_TFT is not set # # RTOS Features diff --git a/nuttx/configs/arduino-due/src/Makefile b/nuttx/configs/arduino-due/src/Makefile index a3ad76c45..3e09e46af 100644 --- a/nuttx/configs/arduino-due/src/Makefile +++ b/nuttx/configs/arduino-due/src/Makefile @@ -52,6 +52,23 @@ else CSRCS += sam_userleds.c endif +ifeq ($(CONFIG_ARDUINO_ITHEAD_TFT),y) + +ifeq ($(CONFIG_SPI_BITBANG),y) +ifeq ($(CONFIG_MMC_SPI),y) +CSRCS += sam_mmcsd.c +endif + +ifeq ($(CONFIG_INPUT),y) +CSRCS += sam_touchscreen.c +endif +endif + +ifeq ($(CONFIG_LCD),y) +CSRCS += sam_lcd.c +endif +endif + COBJS = $(CSRCS:.c=$(OBJEXT)) SRCS = $(ASRCS) $(CSRCS) diff --git a/nuttx/configs/arduino-due/src/arduino-due.h b/nuttx/configs/arduino-due/src/arduino-due.h index 71a5d3c12..4be9a7963 100644 --- a/nuttx/configs/arduino-due/src/arduino-due.h +++ b/nuttx/configs/arduino-due/src/arduino-due.h @@ -97,6 +97,163 @@ #define GPIO_LED_TX (GPIO_OUTPUT | GPIO_CFG_PULLUP | GPIO_OUTPUT_SET | \ GPIO_PORT_PIOA | GPIO_PIN21) +/* ITEAD 2.4" TFT with Touch + * + * The Arduino 2.4" TFT Touch Shield is designed for all the Arduino + * compatible boards. It works in 3.3V voltage level. It can be directly + * plugged on the Arduino and other compatible boards. It will offer + * display, touch and storage functions for the Arduino board + * + * Features: + * + * 1. Compatible with 3.3/5V operation voltage level + * 2. Compatible with UTFT library + * 3. With SD Card Socket + * + * The Arduino 2.4" TFT Touch shield uses the S6D1121 controller , it + * supports 8-bit data interface. The touch IC is TSC2046. + * + * ---------- --------------------------- ----------- ----- ---------- ------------------ + * Arduino ATSAM3X Due ITHEAD + * Due PIN GPIO FUNCTION SIGNAL PIN SIGNAL NOTES + * ---------- ---- ---------------------- ----------- ----- ---------- ------------------ + * PWMH + * 10 SCL1 PA18 TWCK0/A20/WKUP9 SCL1 --- --- SCL not available + * 9 SDA1 PA17 TWD0SPCK0 SDA1 --- --- SDA not available + * 8 Aref --- --- AREF Vref --- --- + * 7 GND --- --- GND GND --- --- + * 6 PWM13 PB27 SPI0_SPCK/A20/WKUP10 PWM13 D13 SD_SCK SCK, also LED "L", Pulled low on-board + * 5 PWM12 PD8 A21/NANDALE/TIOB8 PWM12 D12 SD_MISO MISO not available + * 4 PWM11 PD7 A17/BA1/TIOA8 PWM11 D11 SD_MOSI MOSI not available, Pulled low on-board + * 3 PWM10 ??? ??? SS0/PWM10 D10 SD_CS Pulled low on-board + * 2 PWM9 PC21 A0/NBS0/PWML4 PWM9 D9 Touch_Dout --- + * 1 PWM8 PC22 A1/PWML5 PWM8 D8 Touch_IRQ --- + * PWML + * 8 PWM7 PC23 A2/PWML6 PWM7 D7 DB15 --- + * 7 PWM6 PC24 A3/PWML7 PWM6 D6 DB14 --- + * 6 PWM5 PC25 A4/TIOA6 PWM5 D5 DB13 --- + * 5 PWM4 PC26 A5/TIOB6 SS1/PWM4 D4 DB12 --- + * 4 PWM3 PC28 A7/TIOA7 PWM3 D3 DB11 --- + * 3 PWM2 PB25 RTS0/TIOA0 PWM2 D2 DB10 --- + * 2 PWM1 PA9 UTXD/PWMH3 TX D1 DB9 UART0 TX + * 1 PWM0 PA8 URXD/PWMH0/WKUP4 RX D0 DB8 UART0 RX + * ---------- ---- ---------------------- ----------- ----- ---------- ------------------ + * POWER + * 1 --- --- --- --- --- --- --- + * 2 IOref --- --- IOREF +3V3 --- --- --- + * 3 RESET --- --- MASTER_RESET RST --- --- + * 4 3.3V --- --- +3V3 5V --- --- + * 5 5V --- --- +5V 3.3V --- --- + * 6 GND --- --- GND GND --- --- + * 7 GND --- --- GND GND --- --- + * 8 Vin --- --- VIN Vin --- --- + * ADCL + * 1 A0 PA16 SPCK1/TD/AD7 AD0 A0 Touch_Din --- + * 2 A1 PA24 MCDA3/PCK1/AD6 AD1 A1 Touch_CLK --- + * 3 A2 PA23 MCDA2/TCLK4/AD5 AD2 A2 --- --- + * 4 A3 PA22 MCDA1/TCLK3/AD4 AD3 A3 TFT_CS --- + * 5 A4 PA6 TIOB2/NCS0/AD3 AD4 A4 TFT_WR --- + * 6 A5 PA4 TCLK1/NWAIT/AD2 AD5 A5 TFT_RS --- + * 7 A6 PA3 TIOB1/PWMFI1/AD1/WKUP1 AD6 --- --- --- + * 8 A7 PA2 TIOA1/NANDRDY/AD0 AD7 --- --- --- + * ---------- ---- ---------------------- ----------- ----- ---------- ------------------ + * + * NOTES: + * + * 1. It is not possible to use any of the SPI devices on the Shield unless + * a bit-bang SPI interface is used. This includes the touch controller + * and the SD card. + * 2. UART0 cannot be used. USARTs on the COMM connector should be available. + * 3. Parallel data is not contiguous in the PIO register + * 4. 3.3V and 5V are reversed. + */ + +#ifdef CONFIG_ARDUINO_ITHEAD_TFT + /* In order to use the SD card on the ITEAD shield, you must enable the + * SPI bit-bang driver as well as support for SPI-based MMC/SD cards. + */ + +# if defined(CONFIG_SPI_BITBANG) && defined(CONFIG_MMC_SPI) + + /* The SD slot shares the pin with LED "L" so LED support must be disabled + * to use the MMC/SD card on the ITEAD shield. + */ + +# ifdef CONFIG_ARCH_LEDs +# error LEDs may not be used with the ITEAD SD card +# endif + +# define GPIO_SD_SCK (GPIO_OUTPUT | GPIO_CFG_DEFAULT | GPIO_OUTPUT_CLR | \ + GPIO_PORT_PIOB | GPIO_PIN27) +# define GPIO_SD_MISO (GPIO_OUTPUT | GPIO_CFG_DEFAULT | GPIO_OUTPUT_CLR | \ + GPIO_PORT_PIOD | GPIO_PIN8) +# define GPIO_SD_MOSI (GPIO_OUTPUT | GPIO_CFG_DEFAULT | GPIO_OUTPUT_CLR | \ + GPIO_PORT_PIOD | GPIO_PIN7) +# define GPIO_SD_CS (GPIO_OUTPUT | GPIO_CFG_PULLUP | GPIO_OUTPUT_CLR | \ + GPIO_PORT_PIO? | GPIO_PIN?) +# endif + + /* In order to use the touchscreen on the ITEAD shield, you must enable the + * SPI bit-bang driver and INPUT device support. + */ + +# if defined(CONFIG_SPI_BITBANG) && defined(CONFIG_INPUT) +# define GPIO_TSC_SCK (GPIO_OUTPUT | GPIO_CFG_DEFAULT | GPIO_OUTPUT_CLR | \ + GPIO_PORT_PIOA | GPIO_PIN24) +# define GPIO_TSC_MISO (GPIO_OUTPUT | GPIO_CFG_DEFAULT | GPIO_OUTPUT_CLR | \ + GPIO_PORT_PIOC | GPIO_PIN21) +# define GPIO_TSC_MOSI (GPIO_OUTPUT | GPIO_CFG_DEFAULT | GPIO_OUTPUT_CLR | \ + GPIO_PORT_PIOA | GPIO_PIN16) +# define GPIO_TSC_CS (GPIO_OUTPUT | GPIO_CFG_PULLUP | GPIO_OUTPUT_CLR | \ + GPIO_PORT_PIO? | GPIO_PIN?) +# define GPIO_TSC_IRQ (GPIO_INPUT | GPIO_CFG_PULLUP | GPIO_INT_BOTHEDGES | \ + GPIO_PORT_PIOC | GPIO_PIN22) +# define SAM_TCS_IRQ SAM_IRQ_PC21 +# endif + + /* Only CONFIG_LCD is expected to enable the TFT LCD */ + +# ifdef CONFIG_LCD + + /* UART0 cannot be used with the LCD because the UART0 pins are used + * by the LCD. + */ + +# ifdef CONFIG_SAM34_UART0 +# error "UART0 cannot be used with the ITEAD LCD" +# endif + + /* Data pins are initially configured but may be switched dynamically to + * either inputs or outputs as needed. + */ + +# define GPIO_LCD_D0IN (GPIO_OUTPUT | GPIO_CFG_DEFAULT | GPIO_OUTPUT_CLR | \ + GPIO_PORT_PIOA | GPIO_PIN8) +# define GPIO_LCD_D1IN (GPIO_OUTPUT | GPIO_CFG_DEFAULT | GPIO_OUTPUT_CLR | \ + GPIO_PORT_PIOA | GPIO_PIN9) +# define GPIO_LCD_D2IN (GPIO_OUTPUT | GPIO_CFG_DEFAULT | GPIO_OUTPUT_CLR | \ + GPIO_PORT_PIOB | GPIO_PIN25) +# define GPIO_LCD_D3IN (GPIO_OUTPUT | GPIO_CFG_DEFAULT | GPIO_OUTPUT_CLR | \ + GPIO_PORT_PIOC | GPIO_PIN28) +# define GPIO_LCD_D4IN (GPIO_OUTPUT | GPIO_CFG_DEFAULT | GPIO_OUTPUT_CLR | \ + GPIO_PORT_PIOC | GPIO_PIN26) +# define GPIO_LCD_D5IN (GPIO_OUTPUT | GPIO_CFG_DEFAULT | GPIO_OUTPUT_CLR | \ + GPIO_PORT_PIOC | GPIO_PIN25) +# define GPIO_LCD_D6IN (GPIO_OUTPUT | GPIO_CFG_DEFAULT | GPIO_OUTPUT_CLR | \ + GPIO_PORT_PIOC | GPIO_PIN24) +# define GPIO_LCD_D7IN (GPIO_OUTPUT | GPIO_CFG_DEFAULT | GPIO_OUTPUT_CLR | \ + GPIO_PORT_PIOC | GPIO_PIN23) +# define GPIO_LCD_D7IN (GPIO_OUTPUT | GPIO_CFG_DEFAULT | GPIO_OUTPUT_CLR | \ + GPIO_PORT_PIOC | GPIO_PIN23) +# define GPIO_LCD_CS (GPIO_OUTPUT | GPIO_CFG_DEFAULT | GPIO_OUTPUT_CLR | \ + GPIO_PORT_PIOA | GPIO_PIN22) +# define GPIO_LCD_WR (GPIO_OUTPUT | GPIO_CFG_DEFAULT | GPIO_OUTPUT_CLR | \ + GPIO_PORT_PIOA | GPIO_PIN6) +# define GPIO_LCD_RS (GPIO_OUTPUT | GPIO_CFG_DEFAULT | GPIO_OUTPUT_CLR | \ + GPIO_PORT_PIOA | GPIO_PIN4) +# endif +#endif + /************************************************************************************ * Public Types ************************************************************************************/ diff --git a/nuttx/drivers/Makefile b/nuttx/drivers/Makefile index c91870ec9..cce03cad0 100644 --- a/nuttx/drivers/Makefile +++ b/nuttx/drivers/Makefile @@ -1,7 +1,7 @@ ############################################################################ # drivers/Makefile # -# Copyright (C) 2007-2012 Gregory Nutt. All rights reserved. +# Copyright (C) 2007-2013 Gregory Nutt. All rights reserved. # Author: Gregory Nutt <gnutt@nuttx.org> # # Redistribution and use in source and binary forms, with or without @@ -62,6 +62,7 @@ include power$(DELIM)Make.defs include sensors$(DELIM)Make.defs include sercomm$(DELIM)Make.defs include serial$(DELIM)Make.defs +include spi$(DELIM)Make.defs include syslog$(DELIM)Make.defs include usbdev$(DELIM)Make.defs include usbhost$(DELIM)Make.defs diff --git a/nuttx/drivers/input/Make.defs b/nuttx/drivers/input/Make.defs index 10e6db62f..81cf2f696 100644 --- a/nuttx/drivers/input/Make.defs +++ b/nuttx/drivers/input/Make.defs @@ -33,7 +33,7 @@ # ############################################################################ -# Don't build anything if there is no NX support for input devices +# Don't build anything if there is no support for input devices ifeq ($(CONFIG_INPUT),y) diff --git a/nuttx/drivers/spi/Kconfig b/nuttx/drivers/spi/Kconfig index 645f4017b..fbba4e253 100644 --- a/nuttx/drivers/spi/Kconfig +++ b/nuttx/drivers/spi/Kconfig @@ -3,22 +3,15 @@ # see misc/tools/kconfig-language.txt. # -config SPI - bool "SPI Driver Support" - default n - ---help--- - This selection enables selection of common SPI options. This option - should be enabled by all platforms that support SPI interfaces. - See include/nuttx/spi/spi.h for further SPI driver information. - if SPI + config SPI_OWNBUS bool "SPI single device" default n ---help--- Set if there is only one active device on the SPI bus. No locking or SPI configuration will be performed. It is not necessary for clients to - lock, re-configure, etc.. + lock, re-configure, etc. config SPI_EXCHANGE bool "SPI exchange" @@ -36,5 +29,11 @@ config SPI_CMDDATA either 9-bit SPI (yech) or 8-bit SPI and a GPIO output that selects between command and data. -endif +config SPI_BITBANG + bool "SPI bit-bang device" + default n + ---help--- + Enable support for a generic SPI bit-bang device. + See include/nuttx/spi/spi_bitbang.h for further information. +endif diff --git a/nuttx/drivers/spi/spi_bitbang.c b/nuttx/drivers/spi/spi_bitbang.c new file mode 100755 index 000000000..27022c375 --- /dev/null +++ b/nuttx/drivers/spi/spi_bitbang.c @@ -0,0 +1,544 @@ +/**************************************************************************** + * drivers/spi/spi_bitbang.c + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt <gnutt@nuttx.org> + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include <nuttx/config.h> + +#include <stdlib.h> +#include <semaphore.h> +#include <assert.h> +#include <errno.h> + +#include <nuttx/spi/spi.h> +#include <nuttx/spi/spi_bitbang.h> + +#ifdef CONFIG_SPI_BITBANG + + /**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ +/* This file holds the static, device-independ portion of the generica SPI- + * bit-bang driver. The full driver consists of 5 files: + * + * 1. drivers/spi/spi_bitbang.c: This file. This file holds the basic + * SPI driver framework and not perform any direct bit-bang operations. + * Rather, it will could out to board-specific logic to perform the + * low level data transfers. + * 2. include/nuttx/spi/spi_bitbang.h: This header file provides the + * data types and function prototypes needed to utilize the logic in + * this file. + * 3. configs/<board>/src/<file>: The implementation of the low-level + * bit-bang logic resides in some file in the board source directory. + * This board-specific logic includes the bit-bang skeleton logic + * provided in include/nuttx/spi/spi_bitband.c. + * 4. include/nuttx/spi/spi_bitband.c. Despite the .c extension, this + * really an included file. It is used in this way: 1) The board- + * specific logic in configs/<board>/src/<file> provides some definitions + * then 2) includes include/nuttx/spi/spi_bitband.c. That file will + * then use those definitions to implement the low-level bit-bang + * logic. the board-specific logic then calls spi_create_bitbang() + * in this file to instantiate the complete SPI driver. + * + * See include/nuttx/spi/spi_bitband.c for more detailed usage + * information. + */ + +/* Debug ********************************************************************/ +/* Check if SPI debut is enabled (non-standard.. no support in + * include/debug.h + */ + +#ifndef CONFIG_DEBUG +# undef CONFIG_DEBUG_VERBOSE +# undef CONFIG_DEBUG_SPI +#endif + +#ifdef CONFIG_DEBUG_SPI +# define spidbg lldbg +# ifdef CONFIG_DEBUG_VERBOSE +# define spivdbg lldbg +# else +# define spivdbg(x...) +# endif +#else +# define spidbg(x...) +# define spivdbg(x...) +#endif + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/* SPI methods */ + +#ifndef CONFIG_SPI_OWNBUS +static int spi_lock(FAR struct spi_dev_s *dev, bool lock); +#endif +static void spi_select(FAR struct spi_dev_s *dev, enum spi_dev_e devid, + bool selected); +static uint32_t spi_setfrequency(FAR struct spi_dev_s *dev, + uint32_t frequency); +static void spi_setmode(FAR struct spi_dev_s *dev, + enum spi_mode_e mode); +static void spi_setbits(FAR struct spi_dev_s *dev, int nbits); +static uint16_t spi_send(FAR struct spi_dev_s *dev, uint16_t ch); +static void spi_exchange(FAR struct spi_dev_s *dev, + FAR const void *txbuffer, FAR void *rxbuffer, + size_t nwords); +static uint8_t spi_status(FAR struct spi_dev_s *dev, enum spi_dev_e devid); +#ifdef CONFIG_SPI_CMDDATA +static int spi_cmddata(FAR struct spi_dev_s *dev, enum spi_dev_e devid, + bool cmd); +#endif +#ifndef CONFIG_SPI_EXCHANGE +static void spi_sndblock(FAR struct spi_dev_s *dev, + FAR const void *buffer, size_t nwords); +static void spi_recvblock(FAR struct spi_dev_s *dev, FAR void *buffer, + size_t nwords); +#endif + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/* SPI driver operations */ + +static const struct spi_ops_s g_spiops = +{ +#ifndef CONFIG_SPI_OWNBUS + .lock = spi_lock, +#endif + .select = spi_select, + .setfrequency = spi_setfrequency, + .setmode = spi_setmode, + .setbits = spi_setbits, + .status = spi_status, +#ifdef CONFIG_SPI_CMDDATA + .cmddata = spi_cmddata, +#endif + .send = spi_send, +#ifdef CONFIG_SPI_EXCHANGE + .exchange = spi_exchange, +#else + .sndblock = spi_sndblock, + .recvblock = spi_recvblock, +#endif + .registercallback = 0, /* Not implemented */ +}; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: spi_lock + * + * Description: + * On SPI busses where there are multiple devices, it will be necessary to + * lock SPI to have exclusive access to the busses for a sequence of + * transfers. The bus should be locked before the chip is selected. After + * locking the SPI bus, the caller should then also call the setfrequency, + * setbits, and setmode methods to make sure that the SPI is properly + * configured for the device. If the SPI buss is being shared, then it + * may have been left in an incompatible state. + * + * Input Parameters: + * dev - Device-specific state data + * lock - true: Lock spi bus, false: unlock SPI bus + * + * Returned Value: + * None + * + ****************************************************************************/ + +#ifndef CONFIG_SPI_OWNBUS +static int spi_lock(FAR struct spi_dev_s *dev, bool lock) +{ + FAR struct spi_bitbang_s *priv = (FAR struct spi_bitbang_s *)dev; + + spivdbg("lock=%d\n", lock); + if (lock) + { + /* Take the semaphore (perhaps waiting) */ + + while (sem_wait(&priv->exclsem) != 0) + { + /* The only case that an error should occur here is if the wait was awakened + * by a signal. + */ + + ASSERT(errno == EINTR); + } + } + else + { + (void)sem_post(&priv->exclsem); + } + + return OK; +} +#endif + +/**************************************************************************** + * Name: spi_select + * + * Description: + * Set/clear the chip select line for the selected device. + * + * Input Parameters: + * dev - Device-specific state data + * devid - Identifies the device to be selected + * selected - select or de-select device + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void spi_select(FAR struct spi_dev_s *dev, enum spi_dev_e devid, + bool selected) +{ + FAR struct spi_bitbang_s *priv = (FAR struct spi_bitbang_s *)dev; + DEBUGASSERT(priv && priv->low->select); + priv->low->select(priv, devid, selected); +} + +/**************************************************************************** + * Name: spi_setfrequency + * + * Description: + * Set the SPI frequency. + * + * Input Parameters: + * dev - Device-specific state data + * frequency - The SPI frequency requested + * + * Returned Value: + * Returns the actual frequency selected + * + ****************************************************************************/ + +static uint32_t spi_setfrequency(FAR struct spi_dev_s *dev, uint32_t frequency) +{ + FAR struct spi_bitbang_s *priv = (FAR struct spi_bitbang_s *)dev; + + /* SPI frequency cannot be precisely controlled with a bit-bang interface. + * Freqency corresponds to delay in toggle the SPI clock line: Set high, + * wait, set low, wait, set high, wait, etc. + * + * Here we calcalute the half period of the frequency in nanoseconds (i.e., + * the amount of time that the clock should remain in the high or low state). + * + * frequency = psec / 1 sec - psec = full period in seconds + * psec = 1 sec / frequency + * hpsec = 1 sec / (2 * frequency) - hpsec = half period in seconds + * hpnsec = 1000000000 / (2 * frequency) - hpnsec = half period in nanoseconds + */ + + priv->hpnsec = (1000000000ul + frequency) / (frequency << 2); + return frequency; +} + +/**************************************************************************** + * Name: spi_setmode + * + * Description: + * Set the SPI mode. Optional. See enum spi_mode_e for mode definitions + * + * Input Parameters: + * dev - Device-specific state data + * mode - The SPI mode requested + * + * Returned Value: + * none + * + ****************************************************************************/ + +static void spi_setmode(FAR struct spi_dev_s *dev, enum spi_mode_e mode) +{ + FAR struct spi_bitbang_s *priv = (FAR struct spi_bitbang_s *)dev; + DEBUGASSERT(priv && priv->low->setmode); + priv->low->setmode(priv, mode); +} + +/**************************************************************************** + * Name: spi_setbits + * + * Description: + * Set the number if bits per word. + * + * Input Parameters: + * dev - Device-specific state data + * nbits - The number of bits requests + * + * Returned Value: + * none + * + ****************************************************************************/ + +static void spi_setbits(FAR struct spi_dev_s *dev, int nbits) +{ +#ifdef CONFIG_SPI_BITBANG_VARWIDTH + FAR struct spi_bitbang_s *priv = (FAR struct spi_bitbang_s *)dev; + + spivdbg("nbits=%d\n", nbits); + DEBUGASSERT(priv && nbits > 0); + priv->nbits = nbits; +#else + spivdbg("nbits=%d\n", nbits); + DEBUGASSERT(nbits == 8); +#endif +} +/**************************************************************************** + * Name: spi_send + * + * Description: + * Exchange one word on SPI + * + * Input Parameters: + * dev - Device-specific state data + * wd - The word to send. the size of the data is determined by the + * number of bits selected for the SPI interface. + * + * Returned Value: + * response + * + ****************************************************************************/ + +static uint16_t spi_send(FAR struct spi_dev_s *dev, uint16_t wd) +{ + FAR struct spi_bitbang_s *priv = (FAR struct spi_bitbang_s *)dev; + DEBUGASSERT(priv && priv->low && priv->low->exchange); + + return priv->low->exchange(priv, wd); +} + +/**************************************************************************** + * Name: spi_exchange + * + * Description: + * Exahange a block of data from SPI. Required. + * + * Input Parameters: + * dev - Device-specific state data + * txbuffer - A pointer to the buffer of data to be sent + * rxbuffer - A pointer to the buffer in which to recieve data + * nwords - the length of data that to be exchanged in units of words. + * The wordsize is determined by the number of bits-per-word + * selected for the SPI interface. If nbits <= 8, the data is + * packed into uint8_t's; if nbits >8, the data is packed into + * uint16_t's + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void spi_exchange(FAR struct spi_dev_s *dev, + FAR const void *txbuffer, FAR void *rxbuffer, + size_t nwords) +{ + FAR struct spi_bitbang_s *priv = (FAR struct spi_bitbang_s *)dev; + FAR const uint8_t *src = (FAR const uint8_t *)txbuffer; + FAR uint8_t *dest = (FAR uint8_t *)rxbuffer; + uint16_t dataout; + uint16_t datain; + + DEBUGASSERT(priv && priv->low && priv->low->exchange); + + /* If there is no data source, send 0xff */ + + if (!src) + { + dataout = 0xff; + } + + /* Exchange each word */ + + while (nwords-- > 0) + { + /* If there is source data, get the next word from the source */ + + if (src) + { + dataout = (uint16_t)*src++; + +#ifdef CONFIG_SPI_BITBANG_VARWIDTH + if (priv->nbits > 8) + { +#ifdef CONFIG_ENDIAN_BIG + dataout <<= 8; + dataout |= *src++; +#else + dataout |= (uint16_t)(*src++) << 8; +#endif + } +#endif + } + + /* Exchange the word of data */ + + datain = priv->low->exchange(priv, dataout); + + /* If there is a data sink, transfer the data to the receive buffer */ + + if (dest) + { +#ifdef CONFIG_SPI_BITBANG_VARWIDTH + if (priv->nbits > 8) + { +#ifdef CONFIG_ENDIAN_BIG + *dest++ = (uint8_t)(datain >> 8); + *dest++ = (uint8_t)datain; +#else + *dest++ = (uint8_t)datain; + *dest++ = (uint8_t)(datain >> 8); +#endif + } +#else + *dest++ = (uint8_t)datain; +#endif + } + } +} + +/*************************************************************************** + * Name: spi_sndblock + * + * Description: + * Send a block of data on SPI + * + * Input Parameters: + * dev - Device-specific state data + * buffer - A pointer to the buffer of data to be sent + * nwords - the length of data to send from the buffer in number of words. + * The wordsize is determined by the number of bits-per-word + * selected for the SPI interface. If nbits <= 8, the data is + * packed into uint8_t's; if nbits >8, the data is packed into uint16_t's + * + * Returned Value: + * None + * + ****************************************************************************/ + +#ifndef CONFIG_SPI_EXCHANGE +static void spi_sndblock(FAR struct spi_dev_s *dev, FAR const void *buffer, size_t nwords) +{ + /* spi_exchange can do this. */ + + spi_exchange(dev, buffer, NULL, nwords); +} +#endif + +/**************************************************************************** + * Name: spi_recvblock + * + * Description: + * Revice a block of data from SPI + * + * Input Parameters: + * dev - Device-specific state data + * buffer - A pointer to the buffer in which to recieve data + * nwords - the length of data that can be received in the buffer in number + * of words. The wordsize is determined by the number of bits-per-word + * selected for the SPI interface. If nbits <= 8, the data is + * packed into uint8_t's; if nbits >8, the data is packed into uint16_t's + * + * Returned Value: + * None + * + ****************************************************************************/ + +#ifndef CONFIG_SPI_EXCHANGE +static void spi_recvblock(FAR struct spi_dev_s *dev, FAR void *buffer, size_t nwords) +{ + /* spi_exchange can do this. */ + + spi_exchange(dev, NULL, buffer, nwords); +} +#endif + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: spi_create_bitbang + * + * Descripton: + * Create an instance of the SPI bit-bang driver. + * + ****************************************************************************/ + +FAR struct spi_dev_s *spi_create_bitbang(FAR const struct spi_bitbang_ops_s *low) +{ + FAR struct spi_bitbang_s *priv; + + DEBUGASSERT(low); + + /* Allocate an instance of the SPI bit bang structure */ + + priv = (FAR struct spi_bitbang_s *)zalloc(sizeof(struct spi_bitbang_s)); + if (!priv) + { + spidbg("Failed to allocate the device structure\n"); + return NULL; + } + + /* Initialize the driver structure */ + + priv->dev.ops = &g_spiops; + priv->low = low; +#ifdef CONFIG_SPI_BITBANG_VARWIDTH + priv->nbits = 8; +#endif + + /* Select an initial state of mode 0, 8-bits, and 400KHz */ + + low->setmode(priv, SPIDEV_MODE0); + spi_setfrequency(&priv->dev, 400000); + + /* And return the initialized driver structure */ + + return &priv->dev; +} + +#endif /* CONFIG_SPI_BITBANG */ diff --git a/nuttx/include/nuttx/spi/spi_bitbang.h b/nuttx/include/nuttx/spi/spi_bitbang.h new file mode 100755 index 000000000..22a44494b --- /dev/null +++ b/nuttx/include/nuttx/spi/spi_bitbang.h @@ -0,0 +1,176 @@ +/**************************************************************************** + * include/nuttx/spi/spi_bitbang.h + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt <gnutt@nuttx.org> + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#ifndef __INCLUDE_NUTTX_SPI_SPI_BITBANG_H +#define __INCLUDE_NUTTX_SPI_SPI_BITBANG_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include <nuttx/config.h> + +#include <nuttx/spi/spi.h> + +#ifdef CONFIG_SPI_BITBANG + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ +/* Configuration ************************************************************/ +#ifndef SPI_BITBANG_MODE <<< NOOOO.. Needs to be programmable +# define SPI_BITBANG_MODE SPI_MODE0 +#endif + +#ifndef CONFIG_SPI_BITBANG_FREQUENCY <<< NOOOO.. Needs to be programmable +# define CONFIG_SPI_BITBANG_FREQUENCY 1000000 +#endif + +/* Debug ********************************************************************/ +/* Check if SPI debut is enabled (non-standard.. no support in + * include/debug.h + */ + +#ifndef CONFIG_DEBUG +# undef CONFIG_DEBUG_VERBOSE +# undef CONFIG_DEBUG_SPI +#endif + +#ifdef CONFIG_DEBUG_SPI +# define spidbg lldbg +# ifdef CONFIG_DEBUG_VERBOSE +# define spivdbg lldbg +# else +# define spivdbg(x...) +# endif +#else +# define spidbg(x...) +# define spivdbg(x...) +#endif + +/**************************************************************************** + * Private Types + ****************************************************************************/ +#ifndef __ASSEMBLY__ + +/* These are the lower-half handlers that perform the level-level, platform- + * specific bit-bang operations. + */ + +struct spi_bitbang_s; /* Forward reference */ +struct spi_bitbang_ops_s +{ + /* Platform specific chip select logic */ + + void (*select)(FAR struct spi_bitbang_s *priv, enum spi_dev_e devid, + bool selected); + + /* Platform-specific, SPI mode function */ + + void (*setmode)(FAR struct spi_bitbang_s *priv, enum spi_mode_e mode); + + /* Platform-specific word exchange function */ + + uint16_t (*exchange)(FAR struct spi_bitbang_s *priv, uint16_t dataout); + + /* Platform-specific word exchange function */ + + uint8_t (*status)(FAR struct spi_bitbang_s *priv, enum spi_dev_e devid); + +#ifdef CONFIG_SPI_CMDDATA + /* Platform-specific CMD/DATA function */ + + int (*cmddata)(FAR struct spi_bitbang_s *priv, enum spi_dev_e devid, + bool cmd); +#endif +}; + +/* This structure provides the state of the SPI bit-bang driver */ + +struct spi_bitbang_s +{ + struct spi_dev_s dev; /* Publicly visible version of SPI driver */ + FAR const struct spi_bitbang_ops_s *low; /* Low-level operations */ + uint32_t hpnsec; /* Number of microseconds in a half cycle */ +#ifndef CONFIG_SPI_OWNBUS + sem_t exclsem; /* Supports mutually exclusive access to SPI */ +#endif +#ifdef CONFIG_SPI_BITBANG_VARWIDTH + uint8_t nbits; /* Number of bits in the transfer */ +#endif + FAR void *priv; /* For use by the lower half driver */ +}; + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Name: spi_create_bitbang + * + * Descripton: + * Create an instance of the SPI bit-bang driver. + * + * Input Parameters: + * low - Low-level, platform specific device operations. + * + * Returned Value: + * On success a non-NULL, initialized SPI driver instance is returned. + * + ****************************************************************************/ + +FAR struct spi_dev_s *spi_create_bitbang(FAR const struct spi_bitbang_ops_s *low); + +#undef EXTERN +#if defined(__cplusplus) +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* CONFIG_SPI_BITBANG */ +#endif /* __INCLUDE_NUTTX_SPI_SPI_BITBANG_H */ |