diff --git a/ChangeLog b/ChangeLog index 2e57c8f868..e33278154c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -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). diff --git a/arch/arm/src/samd/Kconfig b/arch/arm/src/samd/Kconfig index 0b8ed7a5b9..281f51aec1 100644 --- a/arch/arm/src/samd/Kconfig +++ b/arch/arm/src/samd/Kconfig @@ -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 diff --git a/arch/arm/src/samd/Make.defs b/arch/arm/src/samd/Make.defs index 569d31b572..602a0fbed3 100644 --- a/arch/arm/src/samd/Make.defs +++ b/arch/arm/src/samd/Make.defs @@ -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 diff --git a/arch/arm/src/samd/chip/sam_spi.h b/arch/arm/src/samd/chip/sam_spi.h index 71202790ec..f64be7c88a 100644 --- a/arch/arm/src/samd/chip/sam_spi.h +++ b/arch/arm/src/samd/chip/sam_spi.h @@ -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 */ diff --git a/arch/arm/src/samd/sam_spi.c b/arch/arm/src/samd/sam_spi.c index 2b81ee7976..18dc33bb5e 100644 --- a/arch/arm/src/samd/sam_spi.c +++ b/arch/arm/src/samd/sam_spi.c @@ -54,7 +54,6 @@ #include #include -#include #include #include #include @@ -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 + +#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 */ diff --git a/arch/arm/src/samd/sam_spi.h b/arch/arm/src/samd/sam_spi.h index db4c6b133c..51e2496176 100644 --- a/arch/arm/src/samd/sam_spi.h +++ b/arch/arm/src/samd/sam_spi.h @@ -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 /**************************************************************************** diff --git a/configs/samd20-xplained/README.txt b/configs/samd20-xplained/README.txt index 81962e5907..bd307879f5 100644 --- a/configs/samd20-xplained/README.txt +++ b/configs/samd20-xplained/README.txt @@ -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. diff --git a/configs/samd20-xplained/include/board.h b/configs/samd20-xplained/include/board.h index a17d630ad3..13eed94674 100644 --- a/configs/samd20-xplained/include/board.h +++ b/configs/samd20-xplained/include/board.h @@ -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 diff --git a/configs/samd20-xplained/src/Makefile b/configs/samd20-xplained/src/Makefile index 6be9b5e5e0..75fa61457c 100644 --- a/configs/samd20-xplained/src/Makefile +++ b/configs/samd20-xplained/src/Makefile @@ -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)) diff --git a/configs/samd20-xplained/src/sam_boot.c b/configs/samd20-xplained/src/sam_boot.c index 082638fbb6..06f038eb78 100644 --- a/configs/samd20-xplained/src/sam_boot.c +++ b/configs/samd20-xplained/src/sam_boot.c @@ -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(); diff --git a/configs/samd20-xplained/src/sam_mmcsd.c b/configs/samd20-xplained/src/sam_mmcsd.c index 0cb4ddef37..d3005e7f1b 100644 --- a/configs/samd20-xplained/src/sam_mmcsd.c +++ b/configs/samd20-xplained/src/sam_mmcsd.c @@ -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 */ diff --git a/configs/samd20-xplained/src/sam_nsh.c b/configs/samd20-xplained/src/sam_nsh.c index b26955f32c..e781b51b76 100644 --- a/configs/samd20-xplained/src/sam_nsh.c +++ b/configs/samd20-xplained/src/sam_nsh.c @@ -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", diff --git a/configs/samd20-xplained/src/sam_spi.c b/configs/samd20-xplained/src/sam_spi.c index 8042002223..e13f19395f 100644 --- a/configs/samd20-xplained/src/sam_spi.c +++ b/configs/samd20-xplained/src/sam_spi.c @@ -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 diff --git a/configs/samd20-xplained/src/sam_ug2832hsweg04.c b/configs/samd20-xplained/src/sam_ug2832hsweg04.c index 46f1dc7343..a031179c8d 100644 --- a/configs/samd20-xplained/src/sam_ug2832hsweg04.c +++ b/configs/samd20-xplained/src/sam_ug2832hsweg04.c @@ -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 */ diff --git a/configs/samd20-xplained/src/samd20-xplained.h b/configs/samd20-xplained/src/samd20-xplained.h index 14f32d3327..b64459eac1 100644 --- a/configs/samd20-xplained/src/samd20-xplained.h +++ b/configs/samd20-xplained/src/samd20-xplained.h @@ -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 /************************************************************************************