SAMD20: Changes for clean build of SPI driver and SAMD20 Xplained Pro board with the I/O1 module installed

This commit is contained in:
Gregory Nutt 2014-02-20 11:27:59 -06:00
parent 8bbf4f3ec8
commit 8f469d70ed
15 changed files with 244 additions and 167 deletions

View File

@ -6627,5 +6627,5 @@
* arch/arm/src/lm/lm_lowputc.c and lm_serial.c: Several errors
are unmasked with UARTs > UART2 are enabled. From gosha (2014-2-19).
* arch/arm/src/samd/sam_spi.c: The SPI driver is code complete,
but untested (2014-2-19).
but untested (2014-2-20).

View File

@ -257,16 +257,16 @@ choice
depends on SAMD_SERCOM0
config SAMD_SERCOM0_ISI2C
bool "I2C"
select I2C
bool "I2C"
select I2C
config SAMD_SERCOM0_ISSPI
bool "SPI"
select SPI
bool "SPI"
select SAMD_HAVE_SPI
config SAMD_SERCOM0_ISUSART
bool "USART"
select ARCH_HAVE_USART0
bool "USART"
select ARCH_HAVE_USART0
endchoice
@ -276,16 +276,16 @@ choice
depends on SAMD_SERCOM1
config SAMD_SERCOM1_ISI2C
bool "I2C"
select I2C
bool "I2C"
select I2C
config SAMD_SERCOM1_ISSPI
bool "SPI"
select SPI
bool "SPI"
select SAMD_HAVE_SPI
config SAMD_SERCOM1_ISUSART
bool "USART"
select ARCH_HAVE_USART1
bool "USART"
select ARCH_HAVE_USART1
endchoice
@ -295,16 +295,16 @@ choice
depends on SAMD_SERCOM2
config SAMD_SERCOM2_ISI2C
bool "I2C"
select I2C
bool "I2C"
select I2C
config SAMD_SERCOM2_ISSPI
bool "SPI"
select SPI
bool "SPI"
select SAMD_HAVE_SPI
config SAMD_SERCOM2_ISUSART
bool "USART"
select ARCH_HAVE_USART2
bool "USART"
select ARCH_HAVE_USART2
endchoice
@ -314,16 +314,16 @@ choice
depends on SAMD_SERCOM3
config SAMD_SERCOM3_ISI2C
bool "I2C"
select I2C
bool "I2C"
select I2C
config SAMD_SERCOM3_ISSPI
bool "SPI"
select SPI
bool "SPI"
select SAMD_HAVE_SPI
config SAMD_SERCOM3_ISUSART
bool "USART"
select ARCH_HAVE_USART3
bool "USART"
select ARCH_HAVE_USART3
endchoice
@ -333,16 +333,16 @@ choice
depends on SAMD_SERCOM4
config SAMD_SERCOM4_ISI2C
bool "I2C"
select I2C
bool "I2C"
select I2C
config SAMD_SERCOM4_ISSPI
bool "SPI"
select SPI
bool "SPI"
select SAMD_HAVE_SPI
config SAMD_SERCOM4_ISUSART
bool "USART"
select ARCH_HAVE_USART4
bool "USART"
select ARCH_HAVE_USART4
endchoice
@ -352,15 +352,30 @@ choice
depends on SAMD_SERCOM5
config SAMD_SERCOM5_ISI2C
bool "I2C"
select I2C
bool "I2C"
select I2C
config SAMD_SERCOM5_ISSPI
bool "SPI"
select SPI
bool "SPI"
select SAMD_HAVE_SPI
config SAMD_SERCOM5_ISUSART
bool "USART"
select ARCH_HAVE_USART5
bool "USART"
select ARCH_HAVE_USART5
endchoice
config SAMD_HAVE_SPI
bool
select SPI
if SAMD_HAVE_SPI
config SAMA5_SPI_REGDEBUG
bool "SPI egister-Level Debug"
default n
depends on DEBUG_SPI
---help---
Enable very low-level register access debug. Depends on DEBUG_SPI.
endif # SAMD_HAVE_SPI

View File

@ -76,6 +76,10 @@ ifeq ($(CONFIG_NUTTX_KERNEL),y)
CHIP_CSRCS += sam_userspace.c
endif
ifeq ($(CONFIG_SAMD_HAVE_SPI),y)
CHIP_CSRCS += sam_spi.c
endif
ifeq ($(CONFIG_ARCH_IRQPRIO),y)
CHIP_CSRCS += sam_irqprio.c
endif

View File

@ -177,11 +177,11 @@
# define SPI_CTRLB_CHSIZE_8BITS (0 << SPI_CTRLB_CHSIZE_SHIFT) /* 8 bits */
# define SPI_CTRLB_CHSIZE_9BITS (1 << SPI_CTRLB_CHSIZE_SHIFT) /* 9 bits */
#define SPI_CTRLB_PLOADEN (1 << 6) /* Bit 6: Slave Data Preload Enable */
#define SPI_CRLB_AMODE_SHIFT (14) /* Bits 14-15: Address Mode */
#define SPI_CRLB_AMODE_MASK (3 << SPI_CRLB_AMODE_SHIFT)
# define SPI_CRLB_AMODE_MASK (0 << SPI_CRLB_AMODE_SHIFT) /* ADDRMASK used to mask ADDR */
# define SPI_CRLB_AMODE_2ADDRS (1 << SPI_CRLB_AMODE_SHIFT) /* Slave 2 addresses: ADDR & ADDRMASK */
# define SPI_CRLB_AMODE_RANGE (2 << SPI_CRLB_AMODE_SHIFT) /* Slave range of addresses: ADDRMASK-ADDR */
#define SPI_CTRLB_AMODE_SHIFT (14) /* Bits 14-15: Address Mode */
#define SPI_CTRLB_AMODE_MASK (3 << SPI_CTRLB_AMODE_SHIFT)
# define SPI_CTRLB_AMODE_ADDRMASK (0 << SPI_CTRLB_AMODE_SHIFT) /* ADDRMASK used to mask ADDR */
# define SPI_CTRLB_AMODE_2ADDRS (1 << SPI_CTRLB_AMODE_SHIFT) /* Slave 2 addresses: ADDR & ADDRMASK */
# define SPI_CTRLB_AMODE_RANGE (2 << SPI_CTRLB_AMODE_SHIFT) /* Slave range of addresses: ADDRMASK-ADDR */
#define SPI_CTRLB_RXEN (1 << 17) /* Bit 17: Receiver enable */
/* Debug control register */

View File

@ -54,7 +54,6 @@
#include <assert.h>
#include <debug.h>
#include <arch/board/board.h>
#include <nuttx/arch.h>
#include <nuttx/clock.h>
#include <nuttx/spi/spi.h>
@ -65,8 +64,12 @@
#include "chip.h"
#include "chip/sam_port.h"
#include "chip/sam_pinmap.h"
#include "chip/sam_gclk.h"
#include "chip/sam_spi.h"
#include <arch/board/board.h>
#include "sam_port.h"
#include "sam_sercom.h"
#include "sam_spi.h"
@ -135,9 +138,9 @@ struct sam_spidev_s
sem_t spilock; /* Used to managed exclusive access to the bus */
uint32_t frequency; /* Requested clock frequency */
uint32_t actual; /* Actual clock frequency */
uint8_t nbits; /* Width of word in bits (8 to 16) */
uint8_t mode; /* Mode 0,1,2,3 */
#endif
uint8_t nbits; /* Width of word in bits (8 to 16) */
/* Debug stuff */
@ -162,8 +165,10 @@ static bool spi_checkreg(struct sam_spidev_s *priv, bool wr,
# define spi_checkreg(priv,wr,regval,regaddr) (false)
#endif
#if 0 /* Not used */
static uint8_t spi_getreg8(struct sam_spidev_s *priv,
unsigned int offset);
#endif
static void spi_putreg8(struct sam_spidev_s *priv, uint8_t regval,
unsigned int offset);
static uint16_t spi_getreg16(struct sam_spidev_s *priv,
@ -186,22 +191,22 @@ static void spi_dumpregs(struct sam_spidev_s *priv, const char *msg);
#if 0 /* Not used */
static int spi_interrupt(struct sam_spidev_s *dev);
#ifdef SAMD_HAVE_USART0
#ifdef SAMD_HAVE_SPI0
static int spi0_interrupt(int irq, void *context);
#endif
#ifdef SAMD_HAVE_USART1
#ifdef SAMD_HAVE_SPI1
static int spi1_interrupt(int irq, void *context);
#endif
#ifdef SAMD_HAVE_USART2
#ifdef SAMD_HAVE_SPI2
static int spi2_interrupt(int irq, void *context);
#endif
#ifdef SAMD_HAVE_USART3
#ifdef SAMD_HAVE_SPI3
static int spi3_interrupt(int irq, void *context);
#endif
#ifdef SAMD_HAVE_USART4
#ifdef SAMD_HAVE_SPI4
static int spi4_interrupt(int irq, void *context);
#endif
#ifdef SAMD_HAVE_USART5
#ifdef SAMD_HAVE_SPI5
static int spi5_interrupt(int irq, void *context);
#endif
#endif
@ -614,6 +619,7 @@ static bool spi_checkreg(struct sam_spidev_s *priv, bool wr, uint32_t regval,
*
****************************************************************************/
#if 0 /* Not used */
static uint8_t spi_getreg8(struct sam_spidev_s *priv, unsigned int offset)
{
uintptr_t regaddr = priv->base + offset;
@ -628,6 +634,7 @@ static uint8_t spi_getreg8(struct sam_spidev_s *priv, unsigned int offset)
return regval;
}
#endif
/****************************************************************************
* Name: spi_putreg8
@ -781,11 +788,10 @@ static void spi_dumpregs(struct sam_spidev_s *priv, const char *msg)
* Name: spi_interrupt
*
* Description:
* This is the USART interrupt handler. It will be invoked when an
* interrupt received on the 'irq' It should call uart_transmitchars or
* uart_receivechar to perform the appropriate data transfers. The
* interrupt handling logic must be able to map the 'irq' number into the
* approprite sam_spidev_s structure in order to call these functions.
* This is the SPI interrupt handler. It will be invoked when an
* interrupt received on the 'irq' indicating either that the DATA
* register is available for the next transmission (DRE) or that the
* DATA register holds a new incoming work.
*
****************************************************************************/
@ -801,8 +807,8 @@ static int spi_interrupt(struct sam_spidev_s *dev)
* unmasked interrupts).
*/
intflag = sam_serialin8(priv, SAM_USART_INTFLAG_OFFSET);
inten = sam_serialin8(priv, SAM_USART_INTENCLR_OFFSET);
intflag = sam_serialin8(priv, SAM_SPI_INTFLAG_OFFSET);
inten = sam_serialin8(priv, SAM_SPI_INTENCLR_OFFSET);
pending = intflag & inten;
/* Handle an incoming, receive byte. The RXC flag is set when there is
@ -810,7 +816,7 @@ static int spi_interrupt(struct sam_spidev_s *dev)
* register (or by disabling the receiver).
*/
if ((pending & USART_INT_RXC) != 0)
if ((pending & SPI_INT_RXC) != 0)
{
/* Received data ready... process incoming SPI ata */
#warning Missing logic
@ -823,7 +829,7 @@ static int spi_interrupt(struct sam_spidev_s *dev)
* further interrupts until TX interrupts are re-enabled.
*/
if ((pending & USART_INT_DRE) != 0)
if ((pending & SPI_INT_DRE) != 0)
{
/* Transmit data register empty ... process outgoing bytes */
#warning Missing logic
@ -837,48 +843,48 @@ static int spi_interrupt(struct sam_spidev_s *dev)
* Name: spiN_interrupt
*
* Description:
* Handle each SERCOM USART interrupt by calling the common interrupt
* handling logic with the USART-specific state.
* Handle each SERCOM SPI interrupt by calling the common interrupt
* handling logic with the SPI-specific state.
*
****************************************************************************/
#if 0 /* Not used */
#ifdef SAMD_HAVE_USART0
#ifdef SAMD_HAVE_SPI0
static int spi0_interrupt(int irq, void *context)
{
return spi_interrupt(&g_spi0dev);
}
#endif
#ifdef SAMD_HAVE_USART1
#ifdef SAMD_HAVE_SPI1
static int spi1_interrupt(int irq, void *context)
{
return spi_interrupt(&g_spi1dev);
}
#endif
#ifdef SAMD_HAVE_USART2
#ifdef SAMD_HAVE_SPI2
static int spi2_interrupt(int irq, void *context)
{
return spi_interrupt(&g_spi2dev);
}
#endif
#ifdef SAMD_HAVE_USART3
#ifdef SAMD_HAVE_SPI3
static int spi3_interrupt(int irq, void *context)
{
return spi_interrupt(&g_spi3dev);
}
#endif
#ifdef SAMD_HAVE_USART4
#ifdef SAMD_HAVE_SPI4
static int spi4_interrupt(int irq, void *context)
{
return spi_interrupt(&g_spi4dev);
}
#endif
#ifdef SAMD_HAVE_USART5
#ifdef SAMD_HAVE_SPI5
static int spi5_interrupt(int irq, void *context)
{
return spi_interrupt(&g_spi5dev);
@ -1050,7 +1056,7 @@ static void spi_setmode(struct spi_dev_s *dev, enum spi_mode_e mode)
{
/* Yes... Set the mode appropriately */
regval = spi_regetreg(SAM_SPI_CTRLA_OFFSET);
regval = spi_getreg32(priv, SAM_SPI_CTRLA_OFFSET);
regval &= ~(SPI_CTRLA_CPOL | SPI_CTRLA_CPHA);
switch (mode)
@ -1075,7 +1081,7 @@ static void spi_setmode(struct spi_dev_s *dev, enum spi_mode_e mode)
return;
}
spi_putreg32(priv, regval, offset);
spi_putreg32(priv, regval, SAM_SPI_CTRLA_OFFSET);
/* Save the mode so that subsequent re-configurations will be faster */
@ -1104,16 +1110,13 @@ static void spi_setbits(struct spi_dev_s *dev, int nbits)
{
struct sam_spidev_s *priv = (struct sam_spidev_s *)dev;
uint32_t regval;
unsigned int offset;
spivdbg("sercom=%d nbits=%d\n", priv->sercom, nbits);
DEBUGASSERT(priv && nbits > 7 && nbits < 10);
/* Has the number of bits changed? */
#ifndef CONFIG_SPI_OWNBUS
if (nbits != priv->nbits)
#endif
{
/* Yes... Set number of bits appropriately */
@ -1129,9 +1132,7 @@ static void spi_setbits(struct spi_dev_s *dev, int nbits)
/* Save the selection so the subsequence re-configurations will be faster */
#ifndef CONFIG_SPI_OWNBUS
priv->nbits = nbits;
#endif
}
}
@ -1194,19 +1195,20 @@ static void spi_exchange(struct spi_dev_s *dev, const void *txbuffer,
void *rxbuffer, size_t nwords)
{
struct sam_spidev_s *priv = (struct sam_spidev_s *)dev;
const uint16_t *ptx16 = NULL;
const uint8_t *ptx8 = NULL;
uint16_t *prx16 = NULL;
uint8_t *prx8 = NULL;
const uint16_t *ptx16;
const uint8_t *ptx8;
uint16_t *prx16;
uint8_t *prx8;
uint16_t data;
spivdbg("txbuffer=%p rxbuffer=%p nwords=%d\n", txbuffer, rxbuffer, nwords);
/* Set up data receive and transmit pointers */
wide = ;
if (priv->nbits > 8)
{
ptx8 = NULL;
prx8 = NULL;
ptx16 = (const uint16_t *)txbuffer;
prx16 = (uint16_t *)rxbuffer;
}
@ -1214,6 +1216,8 @@ static void spi_exchange(struct spi_dev_s *dev, const void *txbuffer,
{
ptx8 = (const uint8_t *)txbuffer;
prx8 = (uint8_t *)rxbuffer;
ptx16 = NULL;
prx16 = NULL;
}
/* Loop, sending each word in the user-provided data buffer.
@ -1282,13 +1286,13 @@ static void spi_exchange(struct spi_dev_s *dev, const void *txbuffer,
*/
data = spi_getreg16(priv, SAM_SPI_STATUS_OFFSET);
if (data & SPI_STATUS_BUFOVF) != 0)
if ((data & SPI_STATUS_BUFOVF) != 0)
{
spidbg("ERROR: Buffer overflow!\n");
/* Clear the buffer overflow flag */
spi_putreg(priv, data, SAM_SPI_STATUS_OFFSET);
spi_putreg16(priv, data, SAM_SPI_STATUS_OFFSET);
}
/* Read the received data from the SPI DATA Register..
@ -1373,7 +1377,7 @@ static void spi_recvblock(struct spi_dev_s *dev, void *buffer, size_t nwords)
static void spi_wait_synchronization(struct sam_spidev_s *priv)
{
while ((getreg16(priv->base + SAM_USART_STATUS_OFFSET) & USART_STATUS_SYNCBUSY) != 0);
while ((getreg16(priv->base + SAM_SPI_STATUS_OFFSET) & SPI_STATUS_SYNCBUSY) != 0);
}
/****************************************************************************
@ -1432,8 +1436,9 @@ struct spi_dev_s *up_spiinitialize(int port)
struct sam_spidev_s *priv;
irqstate_t flags;
uint32_t regval;
uint32_t baud;
#if 0 /* Not used */
int ret;
#endif
/* Get the port state structure */
@ -1519,20 +1524,18 @@ struct spi_dev_s *up_spiinitialize(int port)
(void)spi_setfrequency((struct spi_dev_s *)priv, 400000);
/* Set MSB first data order and the configured pad mux setting,
* Note that SPI mode 0 are assumed initially.
* Note that SPI mode 0 is assumed initially (CPOL=0 and CPHA=0).
*/
regval = (SPI_DATA_ORDER_MSB | priv->muxconfig);
regval = (SPI_CTRLA_MSBFIRST | priv->muxconfig);
spi_putreg8(priv, regval, SAM_SPI_CTRLA_OFFSET);
/* Enable the receiver. Note that 8-bit data width is assumed initially */
regval = SPI_CTRLB_RXEN;
regval = (SPI_CTRLB_RXEN | SPI_CTRLB_CHSIZE_8BITS);
spi_putreg8(priv, regval, SAM_SPI_CTRLB_OFFSET);
#ifndef CONFIG_SPI_OWNBUS
priv->nbits = nbits;
#endif
priv->nbits = 8;
/* Wait until the synchronization is complete */

View File

@ -146,27 +146,33 @@ enum spi_dev_e;
****************************************************************************/
#ifdef SAMD_HAVE_SPI0
void sam_spi0select(enum spi_dev_e devid, bool selected);
void sam_spi0select(FAR struct spi_dev_s *dev, enum spi_dev_e devid,
bool selected);
#endif
#ifdef SAMD_HAVE_SPI1
void sam_spi1select(enum spi_dev_e devid, bool selected);
void sam_spi1select(FAR struct spi_dev_s *dev, enum spi_dev_e devid,
bool selected);
#endif
#ifdef SAMD_HAVE_SPI2
void sam_spi2select(enum spi_dev_e devid, bool selected);
void sam_spi2select(FAR struct spi_dev_s *dev, enum spi_dev_e devid,
bool selected);
#endif
#ifdef SAMD_HAVE_SPI3
void sam_spi3select(enum spi_dev_e devid, bool selected);
void sam_spi3select(FAR struct spi_dev_s *dev, enum spi_dev_e devid,
bool selected);
#endif
#ifdef SAMD_HAVE_SPI4
void sam_spi4select(enum spi_dev_e devid, bool selected);
void sam_spi4select(FAR struct spi_dev_s *dev, enum spi_dev_e devid,
bool selected);
#endif
#ifdef SAMD_HAVE_SPI5
void sam_spi5select(enum spi_dev_e devid, bool selected);
void sam_spi5select(FAR struct spi_dev_s *dev, enum spi_dev_e devid,
bool selected);
#endif
/****************************************************************************

View File

@ -712,7 +712,14 @@ Configuration sub-directories
4. If the I/O1 module is connected to the SAMD20 Xplained Pro, then
support for the SD card slot can be enabled by making the following
changes to the configuration:
changes to the configuration. These changes assume that the I/O1
modules is connected in EXT1. Most of the modifications necessary
to work with the I/O1 in a different connector are obvious.. except
for the selection of SERCOM SPI support:
EXT1: SPI is provided through SERCOM0
EXT2: SPI is provided through SERCOM1
EXT3: SPI is provided through SERCOM5
File Systems:
CONFIG_FS_FAT=y : Enable the FAT file system
@ -725,7 +732,8 @@ Configuration sub-directories
details.
System Type -> Peripherals:
To be provided : Enable the SAMD20 SPI peripheral
CONFIG_SAMD_SERCOM0=y : Use SERCOM0 if the I/O is in EXT1
CONFIG_SAMD_SERCOM0_ISSPI=y : Configure SERCOM0 as an SPI master
Device Drivers
CONFIG_SPI=y : Enable SPI support
@ -735,6 +743,7 @@ Configuration sub-directories
CONFIG_MMCSD=y : Enable MMC/SD support
CONFIG_MMCSD_NSLOTS=1 : Only one MMC/SD card slot
CONFIG_MMCSD_MULTIBLOCK_DISABLE=n : Should not need to disable multi-block transfers
CONFIG_MMCSD_MMCSUPPORT=n : May interfere with some SD cards
CONFIG_MMCSD_HAVECARDDETECT=y : I/O1 module as a card detect GPIO
CONFIG_MMCSD_SPI=y : Use the SPI interface to the MMC/SD card
CONFIG_MMCSD_SPICLOCK=20000000 : This is a guess for the optimal MMC/SD frequency
@ -742,13 +751,11 @@ Configuration sub-directories
Board Selection -> Common Board Options
CONFIG_NSH_MMCSDSLOTNO=0 : Only one MMC/SD slot, slot 0
CONFIG_NSH_MMCSDSPIPORTNO=0 : Use CS=0 if the I/O1 is in EXT1, OR
CONFIG_NSH_MMCSDSPIPORTNO=2 : Use CS=2 if the I/O1 is in EXT2
CONFIG_NSH_MMCSDSPIPORTNO=0 : Use port=0 -> SERCOM0 if the I/O1 is in EXT1
Board Selection -> SAMD20 Xplained Pro Modules
CONFIG_SAMD20_XPLAINED_IOMODULE=y : I/O1 module is connected
CONFIG_SAMD20_XPLAINED_IOMODULE_EXT1=y : In EXT1, or EXT2
CONFIG_SAMD20_XPLAINED_IOMODULE_EXT2=y
CONFIG_SAMD20_XPLAINED_IOMODULE_EXT1=y : I/O1 modules is in EXT1
Application Configuration -> NSH Library
CONFIG_NSH_ARCHINIT=y : Board has architecture-specific initialization
@ -776,10 +783,18 @@ Configuration sub-directories
5. If the OLED1 module is connected to the SAMD20 Xplained Pro, then
support for the OLED display can be enabled by making the following
changes to the configuration:
changes to the configuration. These changes assume that the I/O1
modules is connected in EXT1. Most of the modifications necessary
to work with the I/O1 in a different connector are obvious.. except
for the selection of SERCOM SPI support:
EXT1: SPI is provided through SERCOM0
EXT2: SPI is provided through SERCOM1
EXT3: SPI is provided through SERCOM5
System Type -> Peripherals:
To be provided : Enable the SAMD20 SPI peripheral
CONFIG_SAMD_SERCOM1=y : Use SERCOM1 if the I/O is in EXT2
CONFIG_SAMD_SERCOM1_ISSPI=y : Configure SERCOM1 as an SPI master
Device Drivers -> SPI
CONFIG_SPI=y : Enable SPI support
@ -797,8 +812,7 @@ Configuration sub-directories
Board Selection -> SAMD20 Xplained Pro Modules
CONFIG_SAMD20_XPLAINED_OLED1MODULE=y : OLED1 module is connected
CONFIG_SAMD20_XPLAINED_OLED1MODULE_EXT1=y : In EXT1, or EXT2
CONFIG_SAMD20_XPLAINED_OLED1MODULE_EXT2=y
CONFIG_SAMD20_XPLAINED_OLED1MODULE_EXT2=y : OLED1 modules is in EXT2
The NX graphics subsystem also needs to be configured:
@ -868,3 +882,9 @@ Configuration sub-directories
appears at different BAUD settings implying that this may not even
be clock related???
- The program seems to be running normally, just producing bad output.
3. The configuration suggests CONFIG_MMCSD_HAVECARDDETECT=y, but as of
this writing, there is no support for EIC pin interrupts.
4. OLED1 module is untested. These intructions were just ported from
the SAM4L Xplained Pro README.txt file.

View File

@ -371,12 +371,14 @@
* 18 PA7 SERCOM0 PAD3 SPI SCK
*/
#define BOARD_SERCOM0_CLKGEN GCLK_CLKCTRL_GEN0
#define BOARD_SERCOM0_MUX_SETTING (SPI_CTRLA_DOPO_DOPAD231 | SPI_CTRLA_DIPAD0)
#define BOARD_SERCOM0_PINMUX_PAD0 PINMUX_PA04D_SERCOM0_PAD0 /* SPI_MISO */
#define BOARD_SERCOM0_PINMUX_PAD1 0 /* microSD_SS */
#define BOARD_SERCOM0_PINMUX_PAD2 PINMUX_PA06D_SERCOM0_PAD2 /* SPI_MOSI */
#define BOARD_SERCOM0_PINMUX_PAD3 PINMUX_PA07D_SERCOM0_PAD3 /* SPI_SCK */
#define BOARD_SERCOM0_GCLKGEN GCLK_CLKCTRL_GEN0
#define BOARD_SERCOM0_MUXCONFIG (SPI_CTRLA_DOPO_DOPAD231 | SPI_CTRLA_DIPAD0)
#define BOARD_SERCOM0_PINMAP_PAD0 PORT_SERCOM0_PAD0_2 /* SPI_MISO */
#define BOARD_SERCOM0_PINMAP_PAD1 0 /* microSD_SS */
#define BOARD_SERCOM0_PINMAP_PAD2 PORT_SERCOM0_PAD2_2 /* SPI_MOSI */
#define BOARD_SERCOM0_PINMAP_PAD3 PORT_SERCOM0_PAD3_2 /* SPI_SCK */
#define BOARD_SERCOM0_FREQUENCY BOARD_GCLK0_FREQUENCY
/* SERCOM1 SPI is available on EXT2
*
@ -388,12 +390,14 @@
* 18 PA19 SERCOM1 PAD3 SPI SCK
*/
#define BOARD_SERCOM1_CLKGEN GCLK_CLKCTRL_GEN0
#define BOARD_SERCOM1_MUX_SETTING (SPI_CTRLA_DOPO_DOPAD231 | SPI_CTRLA_DIPAD0)
#define BOARD_SERCOM1_PINMUX_PAD0 PINMUX_PA16C_SERCOM1_PAD0 /* SPI_MISO */
#define BOARD_SERCOM1_PINMUX_PAD1 0 /* microSD_SS */
#define BOARD_SERCOM1_PINMUX_PAD2 PINMUX_PA18C_SERCOM1_PAD2 /* SPI_MOSI */
#define BOARD_SERCOM1_PINMUX_PAD3 PINMUX_PA19C_SERCOM1_PAD3 /* SPI_SCK */
#define BOARD_SERCOM1_GCLKGEN GCLK_CLKCTRL_GEN0
#define BOARD_SERCOM1_MUXCONFIG (SPI_CTRLA_DOPO_DOPAD231 | SPI_CTRLA_DIPAD0)
#define BOARD_SERCOM1_PINMAP_PAD0 PORT_SERCOM1_PAD0_1 /* SPI_MISO */
#define BOARD_SERCOM1_PINMAP_PAD1 0 /* microSD_SS */
#define BOARD_SERCOM1_PINMAP_PAD2 PORT_SERCOM1_PAD2_1 /* SPI_MOSI */
#define BOARD_SERCOM1_PINMAP_PAD3 PORT_SERCOM1_PAD3_1 /* SPI_SCK */
#define BOARD_SERCOM1_FREQUENCY BOARD_GCLK0_FREQUENCY
/* The SAMD20 Xplained Pro contains an Embedded Debugger (EDBG) that can be
* used to program and debug the ATSAMD20J18A using Serial Wire Debug (SWD).
@ -462,12 +466,14 @@
* 18 PB23 SERCOM5 PAD3 SPI SCK
*/
#define BOARD_SERCOM5_CLKGEN GCLK_CLKCTRL_GEN0
#define BOARD_SERCOM5_MUX_SETTING (SPI_CTRLA_DOPO_DOPAD231 | SPI_CTRLA_DIPAD0)
#define BOARD_SERCOM5_PINMUX_PAD0 PINMUX_PB16C_SERCOM5_PAD0 /* SPI_MISO */
#define BOARD_SERCOM5_PINMUX_PAD1 0 /* microSD_SS */
#define BOARD_SERCOM5_PINMUX_PAD2 PINMUX_PB22D_SERCOM5_PAD2 /* SPI_MOSI */
#define BOARD_SERCOM5_PINMUX_PAD3 PINMUX_PB23D_SERCOM5_PAD3 /* SPI_SCK */
#define BOARD_SERCOM5_GCLKGEN GCLK_CLKCTRL_GEN0
#define BOARD_SERCOM5_MUXCONFIG (SPI_CTRLA_DOPO_DOPAD231 | SPI_CTRLA_DIPAD0)
#define BOARD_SERCOM5_PINMAP_PAD0 PORT_SERCOM5_PAD0_1 /* SPI_MISO */
#define BOARD_SERCOM5_PINMAP_PAD1 0 /* microSD_SS */
#define BOARD_SERCOM5_PINMAP_PAD2 PORT_SERCOM5_PAD2_4 /* SPI_MOSI */
#define BOARD_SERCOM5_PINMAP_PAD3 PORT_SERCOM5_PAD3_4 /* SPI_SCK */
#define BOARD_SERCOM5_FREQUENCY BOARD_GCLK0_FREQUENCY
/* LED definitions ******************************************************************/
/* There are three LEDs on board the SAMD20 Xplained Pro board: The EDBG

View File

@ -64,19 +64,15 @@ ifeq ($(CONFIG_NSH_ARCHINIT),y)
CSRCS += sam_nsh.c
endif
ifeq ($(CONFIG_SAMD_SERCOM0),y)
ifeq ($(CONFIG_SAM4L_XPLAINED_IOMODULE),y)
ifeq ($(CONFIG_SAMD20_XPLAINED_IOMODULE),y)
CSRCS += sam_mmcsd.c
endif
endif
ifeq ($(CONFIG_SAMD_SERCOM0),y)
ifeq ($(CONFIG_SAM4L_XPLAINED_OLED1MODULE),y)
ifeq ($(CONFIG_SAMD20_XPLAINED_OLED1MODULE),y)
ifeq ($(CONFIG_LCD_UG2832HSWEG04),y)
CSRCS += sam_ug2832hsweg04.c
endif
endif
endif
COBJS = $(CSRCS:.c=$(OBJEXT))

View File

@ -72,7 +72,7 @@ void sam_boardinitialize(void)
* sam_spiinitialize() has been brought into the link.
*/
#ifdef SAMD_HAVE_SPI0
#ifdef SAMD_HAVE_SPI
if (sam_spiinitialize)
{
sam_spiinitialize();

View File

@ -49,7 +49,7 @@
#include "sam_config.h"
#include "samd20-xplained.h"
#ifdef CONFIG_SAM4L_XPLAINED_IOMODULE
#ifdef CONFIG_SAMD20_XPLAINED_IOMODULE
/****************************************************************************
* Pre-Processor Definitions
@ -79,48 +79,47 @@
*
* Description:
* Initialize the SPI-based SD card. Requires
* - CONFIG_SAM4L_XPLAINED_IOMODULE=y,
* - CONFIG_SAMD20_XPLAINED_IOMODULE=y,
* - CONFIG_DISABLE_MOUNTPOINT=n,
* - CONFIG_MMCSD=y, and
* - SAMD_HAVE_SPI0=y (CONFIG_SAMD_SERCOM0 && CONFIG_SAMD_SERCOM0_ISSPI)
*
*****************************************************************************/
int sam_sdinitialize(int minor)
int sam_sdinitialize(int port, int minor)
{
FAR struct spi_dev_s *spi;
int ret;
/* Get the SPI driver instance for the SD chip select */
fvdbg("Initializing SPI chip select %d\n", SD_CSNO);
fvdbg("Initializing SERCOM SPI%d\n", port);
spi = up_spiinitialize(SD_CSNO);
spi = up_spiinitialize(port);
if (!spi)
{
fdbg("Failed to initialize SPI chip select %d\n", SD_CSNO);
fdbg("Failed to initialize SPI%d\n", port);
return -ENODEV;
}
fvdbg("Successfully initialized SPI chip select %d\n", SD_CSNO);
fvdbg("Successfully initialized SPI%d\n", port);
/* Bind the SPI device for the chip select to the slot */
fvdbg("Binding SPI chip select %d to MMC/SD slot %d\n",
SD_CSNO, SAMD_MMCSDSLOTNO);
fvdbg("Binding SPI%d to MMC/SD slot %d\n", port, SAMD_MMCSDSLOTNO);
ret = mmcsd_spislotinitialize(minor, SAMD_MMCSDSLOTNO, spi);
if (ret < 0)
{
fdbg("Failed to bind SPI chip select %d to MMC/SD slot %d: %d\n",
SD_CSNO, SAMD_MMCSDSLOTNO, ret);
fdbg("Failed to bind SPI%d to MMC/SD slot %d: %d\n",
port, SAMD_MMCSDSLOTNO, ret);
return ret;
}
fvdbg("Successfuly bound SPI chip select %d to MMC/SD slot %d\n",
SD_CSNO, SAMD_MMCSDSLOTNO);
fvdbg("Successfuly bound SPI%d to MMC/SD slot %d\n",
port, SAMD_MMCSDSLOTNO);
return OK;
}
#endif /* CONFIG_SAM4L_XPLAINED_IOMODULE */
#endif /* CONFIG_SAMD20_XPLAINED_IOMODULE */

View File

@ -48,8 +48,25 @@
/****************************************************************************
* Pre-Processor Definitions
****************************************************************************/
/* Some configuration checks */
#ifdef CONFIG_SAM4L_XPLAINED_IOMODULE
#ifdef CONFIG_SAMD20_XPLAINED_IOMODULE_EXT1
# ifndef SAMD_HAVE_SPI0
# error I/O1 module on EXT1 requires SERCOM SPI0
# undef CONFIG_SAMD20_XPLAINED_IOMODULE
# endif
# define SPI_PORTNO 0
#endif
#ifdef CONFIG_SAMD20_XPLAINED_IOMODULE_EXT2
# ifndef SAMD_HAVE_SPI1
# error I/O1 module on EXT2 requires SERCOM SPI1
# undef CONFIG_SAMD20_XPLAINED_IOMODULE
# endif
# define SPI_PORTNO 1
#endif
#ifdef CONFIG_SAMD20_XPLAINED_IOMODULE
/* Support for the SD card slot on the I/O1 module */
/* Verify NSH PORT and SLOT settings */
@ -57,10 +74,14 @@
# if defined(CONFIG_NSH_MMCSDSLOTNO) && CONFIG_NSH_MMCSDSLOTNO != SAMD_MMCSDSLOTNO
# error Only one MMC/SD slot: Slot 0 (CONFIG_NSH_MMCSDSLOTNO)
# undef CONFIG_NSH_MMCSDSLOTNO
# define CONFIG_NSH_MMCSDSLOTNO SAMD_MMCSDSLOTNO
# endif
# if defined(CONFIG_NSH_MMCSDSPIPORTNO) && CONFIG_NSH_MMCSDSPIPORTNO != SD_CSNO
# error CONFIG_NSH_MMCSDSPIPORTNO must have the same value as SD_CSNO
# if defined(CONFIG_NSH_MMCSDSPIPORTNO) && CONFIG_NSH_MMCSDSPIPORTNO != SPI_PORTNO
# error CONFIG_NSH_MMCSDSPIPORTNO must have the same value as SPI_PORTNO
# undef CONFIG_NSH_MMCSDSPIPORTNO
# define CONFIG_NSH_MMCSDSPIPORTNO SPI_PORTNO
# endif
/* Default MMC/SD minor number */
@ -100,11 +121,11 @@
int nsh_archinitialize(void)
{
#if defined(SAMD_HAVE_SPI0) && defined(CONFIG_SAM4L_XPLAINED_IOMODULE)
#if defined(SAMD_HAVE_SPI0) && defined(CONFIG_SAMD20_XPLAINED_IOMODULE)
/* Initialize the SPI-based MMC/SD slot */
{
int ret = sam_sdinitialize(CONFIG_NSH_MMCSDMINOR);
int ret = sam_sdinitialize(SPI_PORTNO, CONFIG_NSH_MMCSDMINOR);
if (ret < 0)
{
message("nsh_archinitialize: Failed to initialize MMC/SD slot: %d\n",

View File

@ -58,8 +58,8 @@
****************************************************************************/
/* Configuration ************************************************************/
#if defined(CONFIG_SAM4L_XPLAINED_IOMODULE) && \
defined(CONFIG_SAM4L_XPLAINED_OLED1MODULE) && defined(CONFIG_SPI_OWNBUS)
#if defined(CONFIG_SAMD20_XPLAINED_IOMODULE) && \
defined(CONFIG_SAMD20_XPLAINED_OLED1MODULE) && defined(CONFIG_SPI_OWNBUS)
# error CONFIG_SPI_OWNBUS must not defined if using both I/O1 and OLED1 modules
#endif
@ -104,14 +104,14 @@ void weak_function sam_spiinitialize(void)
* it is installed, it may be in connector EXT1 or EXT2.
*/
#ifdef CONFIG_SAM4L_XPLAINED_IOMODULE
#ifdef CONFIG_SAMD20_XPLAINED_IOMODULE
/* TODO: enable interrupt on card detect */
sam_configport(PORT_SD_CD); /* Card detect input */
sam_configport(PORT_SD_CS); /* Chip select output */
#endif
#ifdef CONFIG_SAM4L_XPLAINED_OLED1MODULE
#ifdef CONFIG_SAMD20_XPLAINED_OLED1MODULE
sam_configport(PORT_OLED_DATA); /* Command/data */
sam_configport(PORT_OLED_CS); /* Card detect input */
#endif
@ -180,7 +180,8 @@ void weak_function sam_spiinitialize(void)
****************************************************************************/
#ifdef SAMD_HAVE_SPI0
void sam_spi0select(enum spi_dev_e devid, bool selected)
void sam_spi0select(FAR struct spi_dev_s *dev, enum spi_dev_e devid,
bool selected)
{
#ifdef CONFIG_SAMD20_XPLAINED_IOMODULE_EXT1
/* Select/de-select the SD card */
@ -207,7 +208,8 @@ void sam_spi0select(enum spi_dev_e devid, bool selected)
#endif
#ifdef SAMD_HAVE_SPI1
void sam_spi1select(enum spi_dev_e devid, bool selected)
void sam_spi1select(FAR struct spi_dev_s *dev, enum spi_dev_e devid,
bool selected)
{
#ifdef CONFIG_SAMD20_XPLAINED_IOMODULE_EXT2
/* Select/de-select the SD card */
@ -234,25 +236,29 @@ void sam_spi1select(enum spi_dev_e devid, bool selected)
#endif
#ifdef SAMD_HAVE_SPI2
void sam_spi2select(enum spi_dev_e devid, bool selected)
void sam_spi2select(FAR struct spi_dev_s *dev, enum spi_dev_e devid,
bool selected)
{
}
#endif
#ifdef SAMD_HAVE_SPI3
void sam_spi3select(enum spi_dev_e devid, bool selected)
void sam_spi3select(FAR struct spi_dev_s *dev, enum spi_dev_e devid,
bool selected)
{
}
#endif
#ifdef SAMD_HAVE_SPI4
void sam_spi4select(enum spi_dev_e devid, bool selected)
void sam_spi4select(FAR struct spi_dev_s *dev, enum spi_dev_e devid,
bool selected)
{
}
#endif
#ifdef SAMD_HAVE_SPI5
void sam_spi5select(enum spi_dev_e devid, bool selected)
void sam_spi5select(FAR struct spi_dev_s *dev, enum spi_dev_e devid,
bool selected)
{
}
#endif

View File

@ -117,7 +117,7 @@
#include "sam_port.h"
#include "samd20-xplained.h"
#ifdef CONFIG_SAM4L_XPLAINED_OLED1MODULE
#ifdef CONFIG_SAMD20_XPLAINED_OLED1MODULE
/****************************************************************************
* Pre-Processor Definitions
@ -208,4 +208,4 @@ FAR struct lcd_dev_s *up_nxdrvinit(unsigned int devno)
return NULL;
}
#endif /* CONFIG_SAM4L_XPLAINED_OLED1MODULE */
#endif /* CONFIG_SAMD20_XPLAINED_OLED1MODULE */

View File

@ -127,7 +127,7 @@
# endif
# define PORT_SD_CD (PORT_INTERRUPT | PORT_INT_CHANGE | PORT_PULL_UP | \
PORTF | PORT_PIN5)
PORTB | PORT_PIN5)
# define PORT_SD_CS (PORT_OUTPUT | PORT_PULL_NONE | PORT_OUTPUT_SET | \
PORTA | PORT_PIN5)
@ -139,8 +139,8 @@
# error I/O1 and OLED1 modules cannot both reside in EXT2
# endif
# define PORT_CD (PORT_INTERRUPT | PORT_INT_CHANGE | PORT_PULL_UP | \
PORTB | PORT_PIN15)
# define PORT_SD_CD (PORT_INTERRUPT | PORT_INT_CHANGE | PORT_PULL_UP | \
PORTB | PORT_PIN15)
# define PORT_SD_CS (PORT_OUTPUT | PORT_PULL_NONE | PORT_OUTPUT_SET | \
PORTA | PORT_PIN17)
@ -250,12 +250,13 @@ void weak_function sam_spiinitialize(void);
*
* Description:
* Initialize the SPI-based SD card. Requires CONFIG_SAMD20_XPLAINED_IOMODULE=y,
* CONFIG_DISABLE_MOUNTPOINT=n, CONFIG_MMCSD=y, and SAMD_HAVE_SPI0
* CONFIG_DISABLE_MOUNTPOINT=n, CONFIG_MMCSD=y, and the appropriate SERCOM SPI
* port enabled.
*
************************************************************************************/
#if defined(SAMD_HAVE_SPI0) && defined(CONFIG_SAMD20_XPLAINED_IOMODULE)
int sam_sdinitialize(int minor);
#ifdef CONFIG_SAMD20_XPLAINED_IOMODULE
int sam_sdinitialize(int port, int minor);
#endif
/************************************************************************************