EFM32: Integrate Pierre's SPI driver

This commit is contained in:
Gregory Nutt 2014-10-26 09:27:55 -06:00
parent 2c85b0e85f
commit cd004832d1
7 changed files with 1481 additions and 45 deletions

View File

@ -111,6 +111,10 @@ CHIP_CSRCS += efm32_serial.c
endif
endif
ifeq ($(CONFIG_EFM32_USART_ISSPI),y)
CHIP_CSRCS += efm32_spi.c
endif
ifeq ($(CONFIG_EFM32_LEUART),y)
CHIP_CSRCS += efm32_leserial.c
endif

View File

@ -1,4 +1,4 @@
/************************************************************************************
/****************************************************************************
* arch/arm/src/efm32/efm32_config.h
*
* Copyright (C) 2014 Gregory Nutt. All rights reserved.
@ -31,23 +31,23 @@
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
************************************************************************************/
****************************************************************************/
#ifndef __ARCH_ARM_SRC_EFM32_EFM32_CONFIG_H
#define __ARCH_ARM_SRC_EFM32_EFM32_CONFIG_H
/************************************************************************************
/****************************************************************************
* Included Files
************************************************************************************/
****************************************************************************/
#include <nuttx/config.h>
/************************************************************************************
/****************************************************************************
* Pre-processor Definitions
************************************************************************************/
/* Configuration *******************************************************************/
/* Make sure that the configuration does not enable UARTs that the MCU does not
* have
****************************************************************************/
/* Configuration ************************************************************/
/* Make sure that the configuration does not enable UARTs that the MCU does
* not have.
*/
#ifndef CONFIG_EFM32_HAVE_USART2
@ -196,19 +196,19 @@
# undef CONFIG_LEUART1_SERIAL_CONSOLE
#endif
/************************************************************************************
/****************************************************************************
* Public Types
************************************************************************************/
****************************************************************************/
/************************************************************************************
/****************************************************************************
* Inline Functions
************************************************************************************/
****************************************************************************/
#ifndef __ASSEMBLY__
/************************************************************************************
/****************************************************************************
* Public Data
************************************************************************************/
****************************************************************************/
#if defined(__cplusplus)
extern "C"

View File

@ -281,7 +281,7 @@ void efm32_lowsetup(void)
uint32_t regval;
#endif
#ifdef HAVE_UART_DEVICE
#if defined(HAVE_UART_DEVICE) || defined(HAVE_SPI_DEVICE)
/* Enable clocking to configured UART/USART interfaces */
regval = getreg32(EFM32_CMU_HFPERCLKEN0);
@ -348,18 +348,27 @@ void efm32_lowsetup(void)
#ifdef CONFIG_EFM32_USART0
regval = (USART_ROUTE_RXPEN | USART_ROUTE_TXPEN |
(BOARD_USART0_ROUTE_LOCATION << _USART_ROUTE_LOCATION_SHIFT));
#ifdef CONFIG_EFM32_USART0_ISSPI
regval |= USART_ROUTE_CLKPEN;
#endif
putreg32(regval, EFM32_USART0_ROUTE);
#endif
#ifdef CONFIG_EFM32_USART1
regval = (USART_ROUTE_RXPEN | USART_ROUTE_TXPEN |
(BOARD_USART1_ROUTE_LOCATION << _USART_ROUTE_LOCATION_SHIFT));
#ifdef CONFIG_EFM32_USART1_ISSPI
regval |= USART_ROUTE_CLKPEN;
#endif
putreg32(regval, EFM32_USART1_ROUTE);
#endif
#ifdef CONFIG_EFM32_USART2
regval = (USART_ROUTE_RXPEN | USART_ROUTE_TXPEN |
(BOARD_USART2_ROUTE_LOCATION << _USART_ROUTE_LOCATION_SHIFT));
#ifdef CONFIG_EFM32_USART2_ISSPI
regval |= USART_ROUTE_CLKPEN;
#endif
putreg32(regval, EFM32_USART2_ROUTE);
#endif
@ -650,7 +659,7 @@ void efm32_leuartconfigure(uintptr_t base, uint32_t baud, unsigned int parity,
*
*****************************************************************************/
#ifdef HAVE_UART_DEVICE
#if defined(HAVE_UART_DEVICE) || defined(HAVE_SPI_DEVICE)
void efm32_uart_reset(uintptr_t base)
{
putreg32(USART_CMD_RXDIS | USART_CMD_TXDIS | USART_CMD_MASTERDIS |

View File

@ -111,7 +111,7 @@ void efm32_leuartconfigure(uintptr_t base, uint32_t baud, unsigned int parity,
*
*****************************************************************************/
#ifdef HAVE_UART_DEVICE
#if defined(HAVE_UART_DEVICE) || defined(HAVE_SPI_DEVICE)
void efm32_uart_reset(uintptr_t base);
#endif

View File

@ -107,13 +107,13 @@
# define UART1_ASSIGNED 1
#else
# undef CONSOLE_DEV /* No console */
# if defined(CONFIG_EFM32_USART0)
# if defined(CONFIG_EFM32_USART0_ISUART)
# define TTYS0_DEV g_usart0port /* USART0 is ttyS0 */
# define USART0_ASSIGNED 1
# elif defined(CONFIG_EFM32_USART1)
# elif defined(CONFIG_EFM32_USART1_ISUART)
# define TTYS0_DEV g_usart1port /* USART1 is ttyS0 */
# define USART1_ASSIGNED 1
# elif defined(CONFIG_EFM32_USART2)
# elif defined(CONFIG_EFM32_USART2_ISUART)
# define TTYS0_DEV g_usart2port /* USART2 is ttyS0 */
# define USART2_ASSIGNED 1
# elif defined(CONFIG_EFM32_UART0)
@ -129,13 +129,13 @@
* console UART. There are really only 4 unassigned.
*/
#if defined(CONFIG_EFM32_USART0) && !defined(USART0_ASSIGNED)
#if defined(CONFIG_EFM32_USART0_ISUART) && !defined(USART0_ASSIGNED)
# define TTYS1_DEV g_usart0port /* USART0 is ttyS1 */
# define USART0_ASSIGNED 1
#elif defined(CONFIG_EFM32_USART1) && !defined(USART1_ASSIGNED)
#elif defined(CONFIG_EFM32_USART1_ISUART) && !defined(USART1_ASSIGNED)
# define TTYS1_DEV g_usart1port /* USART1 is ttyS1 */
# define USART1_ASSIGNED 1
#elif defined(CONFIG_EFM32_USART2) && !defined(USART2_ASSIGNED)
#elif defined(CONFIG_EFM32_USART2_ISUART) && !defined(USART2_ASSIGNED)
# define TTYS1_DEV g_usart2port /* USART2 is ttyS1 */
# define USART2_ASSIGNED 1
#elif defined(CONFIG_EFM32_UART0) && !defined(UART0_ASSIGNED)
@ -151,10 +151,10 @@
* also be the console. There are really only 3 unassigned.
*/
#if defined(CONFIG_EFM32_USART1) && !defined(USART1_ASSIGNED)
#if defined(CONFIG_EFM32_USART1_ISUART) && !defined(USART1_ASSIGNED)
# define TTYS2_DEV g_usart1port /* USART1 is ttyS2 */
# define USART1_ASSIGNED 1
#elif defined(CONFIG_EFM32_USART2) && !defined(USART2_ASSIGNED)
#elif defined(CONFIG_EFM32_USART2_ISUART) && !defined(USART2_ASSIGNED)
# define TTYS2_DEV g_usart2port /* USART2 is ttyS2 */
# define USART2_ASSIGNED 1
#elif defined(CONFIG_EFM32_UART0) && !defined(UART0_ASSIGNED)
@ -170,7 +170,7 @@
* these could also be the console. There are really only 2 unassigned.
*/
#if defined(CONFIG_EFM32_USART2) && !defined(USART2_ASSIGNED)
#if defined(CONFIG_EFM32_USART2_ISUART) && !defined(USART2_ASSIGNED)
# define TTYS3_DEV g_usart2port /* USART2 is ttyS3 */
# define USART2_ASSIGNED 1
#elif defined(CONFIG_EFM32_UART0) && !defined(UART0_ASSIGNED)
@ -247,13 +247,13 @@ static void efm32_shutdown(struct uart_dev_s *dev);
static int efm32_attach(struct uart_dev_s *dev);
static void efm32_detach(struct uart_dev_s *dev);
static int efm32_rxinterrupt(struct uart_dev_s *dev);
#if defined(CONFIG_EFM32_USART0)
#if defined(CONFIG_EFM32_USART0_ISUART)
static int efm32_usart0_rxinterrupt(int irq, void *context);
#endif
#if defined(CONFIG_EFM32_USART1)
#if defined(CONFIG_EFM32_USART1_ISUART)
static int efm32_usart1_rxinterrupt(int irq, void *context);
#endif
#if defined(CONFIG_EFM32_USART2)
#if defined(CONFIG_EFM32_USART2_ISUART)
static int efm32_usart2_rxinterrupt(int irq, void *context);
#endif
#if defined(CONFIG_EFM32_UART0)
@ -263,13 +263,13 @@ static int efm32_uart0_rxinterrupt(int irq, void *context);
static int efm32_uart1_rxinterrupt(int irq, void *context);
#endif
static int efm32_txinterrupt(struct uart_dev_s *dev);
#if defined(CONFIG_EFM32_USART0)
#if defined(CONFIG_EFM32_USART0_ISUART)
static int efm32_usart0_txinterrupt(int irq, void *context);
#endif
#if defined(CONFIG_EFM32_USART1)
#if defined(CONFIG_EFM32_USART1_ISUART)
static int efm32_usart1_txinterrupt(int irq, void *context);
#endif
#if defined(CONFIG_EFM32_USART2)
#if defined(CONFIG_EFM32_USART2_ISUART)
static int efm32_usart2_txinterrupt(int irq, void *context);
#endif
#if defined(CONFIG_EFM32_UART0)
@ -312,15 +312,15 @@ static const struct uart_ops_s g_uart_ops =
/* I/O buffers */
#ifdef CONFIG_EFM32_USART0
#ifdef CONFIG_EFM32_USART0_ISUART
static char g_usart0rxbuffer[CONFIG_USART0_RXBUFSIZE];
static char g_usart0txbuffer[CONFIG_USART0_TXBUFSIZE];
#endif
#ifdef CONFIG_EFM32_USART1
#ifdef CONFIG_EFM32_USART1_ISUART
static char g_usart1rxbuffer[CONFIG_USART1_RXBUFSIZE];
static char g_usart1txbuffer[CONFIG_USART1_TXBUFSIZE];
#endif
#ifdef CONFIG_EFM32_USART2
#ifdef CONFIG_EFM32_USART2_ISUART
static char g_usart2rxbuffer[CONFIG_USART2_RXBUFSIZE];
static char g_usart2txbuffer[CONFIG_USART2_TXBUFSIZE];
#endif
@ -335,7 +335,7 @@ static char g_uart1txbuffer[CONFIG_UART1_TXBUFSIZE];
/* This describes the state of the EFM32 USART0 port. */
#ifdef CONFIG_EFM32_USART0
#ifdef CONFIG_EFM32_USART0_ISUART
static const struct efm32_usart_s g_usart0config =
{
.uartbase = EFM32_USART0_BASE,
@ -373,7 +373,7 @@ static struct uart_dev_s g_usart0port =
/* This describes the state of the EFM32 USART1 port. */
#ifdef CONFIG_EFM32_USART1
#ifdef CONFIG_EFM32_USART1_ISUART
static struct efm32_config_s g_usart1config =
{
.uartbase = EFM32_USART1_BASE,
@ -411,7 +411,7 @@ static struct uart_dev_s g_usart1port =
/* This describes the state of the EFM32 USART2 port. */
#ifdef CONFIG_EFM32_USART2
#ifdef CONFIG_EFM32_USART2_ISUART
static struct efm32_config_s g_usart2config =
{
.uartbase = EFM32_USART2_BASE,
@ -774,21 +774,21 @@ static int efm32_rxinterrupt(struct uart_dev_s *dev)
return OK;
}
#if defined(CONFIG_EFM32_USART0)
#if defined(CONFIG_EFM32_USART0_ISUART)
static int efm32_usart0_rxinterrupt(int irq, void *context)
{
return efm32_rxinterrupt(&g_usart0port);
}
#endif
#if defined(CONFIG_EFM32_USART1)
#if defined(CONFIG_EFM32_USART1_ISUART)
static int efm32_usart1_rxinterrupt(int irq, void *context)
{
return efm32_rxinterrupt(&g_usart1port);
}
#endif
#if defined(CONFIG_EFM32_USART2)
#if defined(CONFIG_EFM32_USART2_ISUART)
static int efm32_usart2_rxinterrupt(int irq, void *context)
{
return efm32_rxinterrupt(&g_usart2port);
@ -857,21 +857,21 @@ static int efm32_txinterrupt(struct uart_dev_s *dev)
return OK;
}
#if defined(CONFIG_EFM32_USART0)
#if defined(CONFIG_EFM32_USART0_ISUART)
static int efm32_usart0_txinterrupt(int irq, void *context)
{
return efm32_txinterrupt(&g_usart0port);
}
#endif
#if defined(CONFIG_EFM32_USART1)
#if defined(CONFIG_EFM32_USART1_ISUART)
static int efm32_usart1_txinterrupt(int irq, void *context)
{
return efm32_txinterrupt(&g_usart1port);
}
#endif
#if defined(CONFIG_EFM32_USART2)
#if defined(CONFIG_EFM32_USART2_ISUART)
static int efm32_usart2_txinterrupt(int irq, void *context)
{
return efm32_txinterrupt(&g_usart2port);

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,118 @@
/************************************************************************************
* arm/arm/src/efm32/efm32_spi.h
*
* Copyright (C) 2009-2013 Bouteville Pierre-Noel. All rights reserved.
* Author: Bouteville Pierre-Noel <pnb990@gmail.com>
*
* 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 __ARCH_ARM_EFM32_EFM32_SPI_H
#define __ARCH_ARM_EFM32_EFM32_SPI_H
/************************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include "efm32_config.h"
/************************************************************************************
* Pre-processor Definitions
****************************************************************************/
/************************************************************************************
* Public Function Prototypes
****************************************************************************/
/************************************************************************************
* Name: efm32_spi_initialize
*
* Description:
* Initialize the selected SPI port
*
* Input Parameter:
* port - SPI port number to initialize. One of {0,1,2}
*
* Returned Value:
* Valid SPI device structure reference on success; a NULL on failure
*
****************************************************************************/
struct spi_dev_s;
struct spi_dev_s *efm32_spi_initialize(int port);
/************************************************************************************
* Name: efm32_spi[n]_select, efm32_spi[n]_status, and efm32_spi[n]_cmddata
*
* Description:
* The external functions, efm32_spi[n]_select, efm32_spi[n]_status, and
* efm32_spi[n]_cmddata must be provided by board-specific logic. These are
* implementations of the select, status, and cmddata methods of the SPI interface
* defined by struct spi_ops_s (see include/nuttx/spi/spi.h). All other methods
* (including up_spiinitialize()) are provided by common EFM32 logic. To use this
* common SPI logic on your board:
*
* 1. Provide logic in efm32_boardinitialize() to configure SPI chip select
* pins.
* 2. Provide efm32_spi[n]_select() and efm32_spi[n]_status() functions in your
* board-specific logic. These functions will perform chip selection and
* status operations using GPIOs in the way your board is configured.
* 3. If CONFIG_SPI_CMDDATA is defined in your NuttX configuration file, then
* provide efm32_spi[n]_cmddata() functions in your board-specific logic.
* These functions will perform cmd/data selection operations using GPIOs in the
* way your board is configured.
* 4. Add a calls to up_spiinitialize() in your low level application
* initialization logic
* 5. The handle returned by up_spiinitialize() may then be used to bind the
* SPI driver to higher level logic (e.g., calling
* mmcsd_spislotinitialize(), for example, will bind the SPI driver to
* the SPI MMC/SD driver).
*
****************************************************************************/
#ifdef CONFIG_EFM32_USART0_ISSPI
void efm32_spi0_select(FAR struct spi_dev_s *dev, enum spi_dev_e devid, bool selected);
uint8_t efm32_spi0_status(FAR struct spi_dev_s *dev, enum spi_dev_e devid);
int efm32_spi0_cmddata(FAR struct spi_dev_s *dev, enum spi_dev_e devid, bool cmd);
#endif
#ifdef CONFIG_EFM32_USART1_ISSPI
void efm32_spi1_select(FAR struct spi_dev_s *dev, enum spi_dev_e devid, bool selected);
uint8_t efm32_spi1_status(FAR struct spi_dev_s *dev, enum spi_dev_e devid);
int efm32_spi1_cmddata(FAR struct spi_dev_s *dev, enum spi_dev_e devid, bool cmd);
#endif
#ifdef CONFIG_EFM32_USART2_ISSPI
void efm32_spi2_select(FAR struct spi_dev_s *dev, enum spi_dev_e devid, bool selected);
uint8_t efm32_spi2_status(FAR struct spi_dev_s *dev, enum spi_dev_e devid);
int efm32_spi2_cmddata(FAR struct spi_dev_s *dev, enum spi_dev_e devid, bool cmd);
#endif
#endif /* __ARCH_ARM_EFM32_EFM32_SPI_H */