summaryrefslogtreecommitdiff
path: root/nuttx/arch/arm/src/samd
diff options
context:
space:
mode:
authorGregory Nutt <gnutt@nuttx.org>2014-02-19 18:48:59 -0600
committerGregory Nutt <gnutt@nuttx.org>2014-02-19 18:48:59 -0600
commitc7e57eb4b7bb38edfeb53f61bbfc1f16b8ed4a18 (patch)
treec182d88096741d92ebb754b468efa71dd5e0579b /nuttx/arch/arm/src/samd
parent59cc45b5ffaa99de068f19ddafa625f8f77deed9 (diff)
downloadnuttx-c7e57eb4b7bb38edfeb53f61bbfc1f16b8ed4a18.tar.gz
nuttx-c7e57eb4b7bb38edfeb53f61bbfc1f16b8ed4a18.tar.bz2
nuttx-c7e57eb4b7bb38edfeb53f61bbfc1f16b8ed4a18.zip
SAMD: A little more SPI logic
Diffstat (limited to 'nuttx/arch/arm/src/samd')
-rw-r--r--nuttx/arch/arm/src/samd/chip/sam_spi.h2
-rw-r--r--nuttx/arch/arm/src/samd/sam_lowputc.c5
-rw-r--r--nuttx/arch/arm/src/samd/sam_sercom.h27
-rw-r--r--nuttx/arch/arm/src/samd/sam_spi.c84
4 files changed, 89 insertions, 29 deletions
diff --git a/nuttx/arch/arm/src/samd/chip/sam_spi.h b/nuttx/arch/arm/src/samd/chip/sam_spi.h
index e5b54e5e7..c5d78a90d 100644
--- a/nuttx/arch/arm/src/samd/chip/sam_spi.h
+++ b/nuttx/arch/arm/src/samd/chip/sam_spi.h
@@ -202,6 +202,8 @@
#define SPI_STATUS_BUFOVF (1 << 2) /* Bit 2: Buffer overflow */
#define SPI_STATUS_SYNCBUSY (1 << 15) /* Bit 15: Synchronization busy */
+#define SPI_STATUS_CLRALL SPI_STATUS_BUFOVF
+
/* Address register */
#define SPI_ADDR_SHIFT (0) /* Bits 0-7: Address */
diff --git a/nuttx/arch/arm/src/samd/sam_lowputc.c b/nuttx/arch/arm/src/samd/sam_lowputc.c
index f80a3bb43..1b22d558b 100644
--- a/nuttx/arch/arm/src/samd/sam_lowputc.c
+++ b/nuttx/arch/arm/src/samd/sam_lowputc.c
@@ -292,14 +292,11 @@ sam_pad_configure(const struct sam_usart_config_s * const config)
#ifdef SAMD_HAVE_USART
int sam_usart_internal(const struct sam_usart_config_s * const config)
{
- uint32_t regval;
int ret;
/* Enable clocking to the SERCOM module in PM */
- regval = getreg32(SAM_PM_APBCMASK);
- regval |= PM_APBCMASK_SERCOM(config->sercom);
- putreg32(regval, SAM_PM_APBCMASK);
+ sercom_enable(config->sercom);
/* Configure the GCLKs for the SERCOM module */
diff --git a/nuttx/arch/arm/src/samd/sam_sercom.h b/nuttx/arch/arm/src/samd/sam_sercom.h
index 2d935ce14..77dd9363c 100644
--- a/nuttx/arch/arm/src/samd/sam_sercom.h
+++ b/nuttx/arch/arm/src/samd/sam_sercom.h
@@ -72,6 +72,33 @@ extern "C"
/****************************************************************************
* Public Function Prototypes
****************************************************************************/
+
+/****************************************************************************
+ * Name: sercom_enable
+ *
+ * Description:
+ * Enable clocking to a SERCOM module in PM
+ *
+ * Assumptions/Limitation:
+ * This operation is global and non-atomic. The caller should disable
+ * interrupts prior to calling this function.
+ *
+ ****************************************************************************/
+
+static inline int sercom_enable(int sercom)
+{
+ uint32_t regval;
+
+ /* Enable clocking to the SERCOM module in PM */
+
+ regval = getreg32(SAM_PM_APBCMASK);
+ regval |= PM_APBCMASK_SERCOM(sercom);
+ putreg32(regval, SAM_PM_APBCMASK);
+}
+
+/****************************************************************************
+ * Public Function Prototypes
+ ****************************************************************************/
/****************************************************************************
* Name: sercom_coreclk_configure
*
diff --git a/nuttx/arch/arm/src/samd/sam_spi.c b/nuttx/arch/arm/src/samd/sam_spi.c
index ebde7bbcf..58be9f423 100644
--- a/nuttx/arch/arm/src/samd/sam_spi.c
+++ b/nuttx/arch/arm/src/samd/sam_spi.c
@@ -121,7 +121,7 @@ struct sam_spidev_s
port_pinset_t pad2; /* Pin configuration for PAD2 */
port_pinset_t pad3; /* Pin configuration for PAD3 */
uint32_t muxconfig; /* Pad multiplexing configuration */
- uint32_t frequency; /* Source clock frequency */
+ uint32_t srcfreq; /* Source clock frequency */
uintptr_t base; /* SERCOM base address */
/* Dynamic configuration */
@@ -157,17 +157,17 @@ static bool spi_checkreg(struct sam_spidev_s *spi, bool wr,
# define spi_checkreg(spi,wr,regval,regaddr) (false)
#endif
-static inline uint8_t spi_getreg8(struct sam_spidev_s *spi,
+static uint8_t spi_getreg8(struct sam_spidev_s *spi,
unsigned int offset);
-static inline void spi_putreg8(struct sam_spidev_s *spi, uint8_t regval,
+static void spi_putreg8(struct sam_spidev_s *spi, uint8_t regval,
unsigned int offset);
-static inline uint16_t spi_getreg16(struct sam_spidev_s *spi,
+static uint16_t spi_getreg16(struct sam_spidev_s *spi,
unsigned int offset);
-static inline void spi_putreg16(struct sam_spidev_s *spi, uint16_t regval,
+static void spi_putreg16(struct sam_spidev_s *spi, uint16_t regval,
unsigned int offset);
-static inline uint32_t spi_getreg32(struct sam_spidev_s *spi,
+static uint32_t spi_getreg32(struct sam_spidev_s *spi,
unsigned int offset);
-static inline void spi_putreg32(struct sam_spidev_s *spi, uint32_t regval,
+static void spi_putreg32(struct sam_spidev_s *spi, uint32_t regval,
unsigned int offset);
#if defined(CONFIG_DEBUG_SPI) && defined(CONFIG_DEBUG_VERBOSE)
@@ -194,6 +194,10 @@ static void spi_recvblock(struct spi_dev_s *dev, void *buffer,
size_t nwords);
#endif
+/* Initialization */
+
+static void spi_pad_configure(struct sam_spidev_s *priv);
+
/****************************************************************************
* Private Data
****************************************************************************/
@@ -237,7 +241,7 @@ static struct sam_spidev_s g_spi0dev =
.pad2 = BOARD_SERCOM0_PINMAP_PAD2,
.pad3 = BOARD_SERCOM0_PINMAP_PAD3,
.muxconfig = BOARD_SERCOM0_MUXCONFIG,
- .frequency = BOARD_SERCOM0_FREQUENCY,
+ .srcfreq = BOARD_SERCOM0_FREQUENCY,
.base = SAM_SERCOM0_BASE,
#ifndef CONFIG_SPI_OWNBUS
.spilock = SEM_INITIALIZER(1),
@@ -284,7 +288,7 @@ static struct sam_spidev_s g_spi1dev =
.pad2 = BOARD_SERCOM1_PINMAP_PAD2,
.pad3 = BOARD_SERCOM1_PINMAP_PAD3,
.muxconfig = BOARD_SERCOM1_MUXCONFIG,
- .frequency = BOARD_SERCOM1_FREQUENCY,
+ .srcfreq = BOARD_SERCOM1_FREQUENCY,
.base = SAM_SERCOM1_BASE,
#ifndef CONFIG_SPI_OWNBUS
.spilock = SEM_INITIALIZER(1),
@@ -331,7 +335,7 @@ static struct sam_spidev_s g_spi2dev =
.pad2 = BOARD_SERCOM2_PINMAP_PAD2,
.pad3 = BOARD_SERCOM2_PINMAP_PAD3,
.muxconfig = BOARD_SERCOM2_MUXCONFIG,
- .frequency = BOARD_SERCOM2_FREQUENCY,
+ .srcfreq = BOARD_SERCOM2_FREQUENCY,
.base = SAM_SERCOM2_BASE,
#ifndef CONFIG_SPI_OWNBUS
.spilock = SEM_INITIALIZER(1),
@@ -378,7 +382,7 @@ static struct sam_spidev_s g_spi3dev =
.pad2 = BOARD_SERCOM3_PINMAP_PAD2,
.pad3 = BOARD_SERCOM3_PINMAP_PAD3,
.muxconfig = BOARD_SERCOM3_MUXCONFIG,
- .frequency = BOARD_SERCOM3_FREQUENCY,
+ .srcfreq = BOARD_SERCOM3_FREQUENCY,
.base = SAM_SERCOM3_BASE,
#ifndef CONFIG_SPI_OWNBUS
.spilock = SEM_INITIALIZER(1),
@@ -425,7 +429,7 @@ static struct sam_spidev_s g_spi4dev =
.pad2 = BOARD_SERCOM4_PINMAP_PAD2,
.pad3 = BOARD_SERCOM4_PINMAP_PAD3,
.muxconfig = BOARD_SERCOM4_MUXCONFIG,
- .frequency = BOARD_SERCOM4_FREQUENCY,
+ .srcfreq = BOARD_SERCOM4_FREQUENCY,
.base = SAM_SERCOM4_BASE,
#ifndef CONFIG_SPI_OWNBUS
.spilock = SEM_INITIALIZER(1),
@@ -472,7 +476,7 @@ static struct sam_spidev_s g_spi5dev =
.pad2 = BOARD_SERCOM5_PINMAP_PAD2,
.pad3 = BOARD_SERCOM5_PINMAP_PAD3,
.muxconfig = BOARD_SERCOM5_MUXCONFIG,
- .frequency = BOARD_SERCOM5_FREQUENCY,
+ .srcfreq = BOARD_SERCOM5_FREQUENCY,
.base = SAM_SERCOM5_BASE,
#ifndef CONFIG_SPI_OWNBUS
.spilock = SEM_INITIALIZER(1),
@@ -550,8 +554,7 @@ static bool spi_checkreg(struct sam_spidev_s *priv, bool wr, uint32_t regval,
*
****************************************************************************/
-static inline uint8_t spi_getreg8(struct sam_spidev_s *priv,
- unsigned int offset)
+static uint8_t spi_getreg8(struct sam_spidev_s *priv, unsigned int offset)
{
uintptr_t regaddr = priv->base + offset;
uint8_t regval = getreg8(regaddr);
@@ -574,8 +577,8 @@ static inline uint8_t spi_getreg8(struct sam_spidev_s *priv,
*
****************************************************************************/
-static inline void spi_putreg8(struct sam_spidev_s *priv, uint8_t regval,
- unsigned int offset)
+static void spi_putreg8(struct sam_spidev_s *priv, uint8_t regval,
+ unsigned int offset)
{
uintptr_t regaddr = priv->base + offset;
@@ -597,8 +600,7 @@ static inline void spi_putreg8(struct sam_spidev_s *priv, uint8_t regval,
*
****************************************************************************/
-static inline uint16_t spi_getreg16(struct sam_spidev_s *priv,
- unsigned int offset)
+static uint16_t spi_getreg16(struct sam_spidev_s *priv, unsigned int offset)
{
uintptr_t regaddr = priv->base + offset;
uint16_t regval = getreg16(regaddr);
@@ -621,8 +623,8 @@ static inline uint16_t spi_getreg16(struct sam_spidev_s *priv,
*
****************************************************************************/
-static inline void spi_putreg16(struct sam_spidev_s *priv, uint16_t regval,
- unsigned int offset)
+static void spi_putreg16(struct sam_spidev_s *priv, uint16_t regval,
+ unsigned int offset)
{
uintptr_t regaddr = priv->base + offset;
@@ -644,8 +646,7 @@ static inline void spi_putreg16(struct sam_spidev_s *priv, uint16_t regval,
*
****************************************************************************/
-static inline uint32_t spi_getreg32(struct sam_spidev_s *priv,
- unsigned int offset)
+static uint32_t spi_getreg32(struct sam_spidev_s *priv, unsigned int offset)
{
uintptr_t regaddr = priv->base + offset;
uint32_t regval = getreg32(regaddr);
@@ -668,8 +669,8 @@ static inline uint32_t spi_getreg32(struct sam_spidev_s *priv,
*
****************************************************************************/
-static inline void spi_putreg32(struct sam_spidev_s *priv, uint32_t regval,
- unsigned int offset)
+static void spi_putreg32(struct sam_spidev_s *priv, uint32_t regval,
+ unsigned int offset)
{
uintptr_t regaddr = priv->base + offset;
@@ -1131,6 +1132,39 @@ static void spi_recvblock(struct spi_dev_s *dev, void *buffer, size_t nwords)
#endif
/****************************************************************************
+ * Name: spi_pad_configure
+ *
+ * Description:
+ * Configure the SERCOM SPI pads.
+ *
+ ****************************************************************************/
+
+static void spi_pad_configure(struct sam_spidev_s *priv)
+{
+ /* Configure SERCOM pads */
+
+ if (priv->pad0 != 0)
+ {
+ sam_configport(priv->pad0);
+ }
+
+ if (priv->pad1 != 0)
+ {
+ sam_configport(priv->pad1);
+ }
+
+ if (priv->pad2 != 0)
+ {
+ sam_configport(priv->pad2);
+ }
+
+ if (priv->pad3 != 0)
+ {
+ sam_configport(priv->pad3);
+ }
+}
+
+/****************************************************************************
* Public Functions
****************************************************************************/