diff options
author | Gregory Nutt <gnutt@nuttx.org> | 2014-02-19 18:48:59 -0600 |
---|---|---|
committer | Gregory Nutt <gnutt@nuttx.org> | 2014-02-19 18:48:59 -0600 |
commit | c7e57eb4b7bb38edfeb53f61bbfc1f16b8ed4a18 (patch) | |
tree | c182d88096741d92ebb754b468efa71dd5e0579b /nuttx/arch/arm/src/samd | |
parent | 59cc45b5ffaa99de068f19ddafa625f8f77deed9 (diff) | |
download | nuttx-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.h | 2 | ||||
-rw-r--r-- | nuttx/arch/arm/src/samd/sam_lowputc.c | 5 | ||||
-rw-r--r-- | nuttx/arch/arm/src/samd/sam_sercom.h | 27 | ||||
-rw-r--r-- | nuttx/arch/arm/src/samd/sam_spi.c | 84 |
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 ****************************************************************************/ |