diff options
author | Marti Bolivar <mbolivar@leaflabs.com> | 2012-04-10 16:05:42 -0400 |
---|---|---|
committer | Marti Bolivar <mbolivar@leaflabs.com> | 2012-04-11 16:56:57 -0400 |
commit | 301fe2c02ef0ca779d11dcedc2a081436360fbe3 (patch) | |
tree | 4da6bc1d69906ed20720cc21adc57d20c945b266 | |
parent | c114022b2599fc7024c771d13b24a2119bee2208 (diff) | |
download | librambutan-301fe2c02ef0ca779d11dcedc2a081436360fbe3.tar.gz librambutan-301fe2c02ef0ca779d11dcedc2a081436360fbe3.zip |
libmaple/spi: Fixups, move nonportable bits into libmaple/stm32f1.
Standard family support refactoring: add STM32F1 series spi.h, spi.c,
and move anything that won't port to STM32F2 there.
As part of a general effort to be cleaner, remove the dependency on
libmaple/util.h from libmaple/spi.h by not using BIT(). Also forward
declare struct gpio_dev for spi_gpio_cfg() to remove that include.
Signed-off-by: Marti Bolivar <mbolivar@leaflabs.com>
-rw-r--r-- | libmaple/include/libmaple/spi.h | 118 | ||||
-rw-r--r-- | libmaple/rules.mk | 2 | ||||
-rw-r--r-- | libmaple/spi.c | 77 | ||||
-rw-r--r-- | libmaple/stm32f1/include/series/spi.h | 70 | ||||
-rw-r--r-- | libmaple/stm32f1/rules.mk | 1 | ||||
-rw-r--r-- | libmaple/stm32f1/spi.c | 97 |
6 files changed, 231 insertions, 134 deletions
diff --git a/libmaple/include/libmaple/spi.h b/libmaple/include/libmaple/spi.h index 7a665db..5b045a9 100644 --- a/libmaple/include/libmaple/spi.h +++ b/libmaple/include/libmaple/spi.h @@ -44,8 +44,7 @@ extern "C" { #include <libmaple/libmaple_types.h> #include <libmaple/rcc.h> #include <libmaple/nvic.h> -#include <libmaple/gpio.h> -#include <libmaple/util.h> +#include <series/spi.h> /* * Register maps @@ -64,13 +63,6 @@ typedef struct spi_reg_map { __io uint32 I2SPR; /**< I2S prescaler register */ } spi_reg_map; -/** SPI1 register map base pointer */ -#define SPI1_BASE ((struct spi_reg_map*)0x40013000) -/** SPI2 register map base pointer */ -#define SPI2_BASE ((struct spi_reg_map*)0x40003800) -/** SPI3 register map base pointer */ -#define SPI3_BASE ((struct spi_reg_map*)0x40003C00) - /* * Register bit definitions */ @@ -91,20 +83,20 @@ typedef struct spi_reg_map { #define SPI_CR1_CPOL_BIT 1 #define SPI_CR1_CPHA_BIT 0 -#define SPI_CR1_BIDIMODE BIT(SPI_CR1_BIDIMODE_BIT) +#define SPI_CR1_BIDIMODE (1U << SPI_CR1_BIDIMODE_BIT) #define SPI_CR1_BIDIMODE_2_LINE (0x0 << SPI_CR1_BIDIMODE_BIT) #define SPI_CR1_BIDIMODE_1_LINE (0x1 << SPI_CR1_BIDIMODE_BIT) -#define SPI_CR1_BIDIOE BIT(SPI_CR1_BIDIOE_BIT) -#define SPI_CR1_CRCEN BIT(SPI_CR1_CRCEN_BIT) -#define SPI_CR1_CRCNEXT BIT(SPI_CR1_CRCNEXT_BIT) -#define SPI_CR1_DFF BIT(SPI_CR1_DFF_BIT) +#define SPI_CR1_BIDIOE (1U << SPI_CR1_BIDIOE_BIT) +#define SPI_CR1_CRCEN (1U << SPI_CR1_CRCEN_BIT) +#define SPI_CR1_CRCNEXT (1U << SPI_CR1_CRCNEXT_BIT) +#define SPI_CR1_DFF (1U << SPI_CR1_DFF_BIT) #define SPI_CR1_DFF_8_BIT (0x0 << SPI_CR1_DFF_BIT) #define SPI_CR1_DFF_16_BIT (0x1 << SPI_CR1_DFF_BIT) -#define SPI_CR1_RXONLY BIT(SPI_CR1_RXONLY_BIT) -#define SPI_CR1_SSM BIT(SPI_CR1_SSM_BIT) -#define SPI_CR1_SSI BIT(SPI_CR1_SSI_BIT) -#define SPI_CR1_LSBFIRST BIT(SPI_CR1_LSBFIRST_BIT) -#define SPI_CR1_SPE BIT(SPI_CR1_SPE_BIT) +#define SPI_CR1_RXONLY (1U << SPI_CR1_RXONLY_BIT) +#define SPI_CR1_SSM (1U << SPI_CR1_SSM_BIT) +#define SPI_CR1_SSI (1U << SPI_CR1_SSI_BIT) +#define SPI_CR1_LSBFIRST (1U << SPI_CR1_LSBFIRST_BIT) +#define SPI_CR1_SPE (1U << SPI_CR1_SPE_BIT) #define SPI_CR1_BR (0x7 << 3) #define SPI_CR1_BR_PCLK_DIV_2 (0x0 << 3) #define SPI_CR1_BR_PCLK_DIV_4 (0x1 << 3) @@ -114,17 +106,14 @@ typedef struct spi_reg_map { #define SPI_CR1_BR_PCLK_DIV_64 (0x5 << 3) #define SPI_CR1_BR_PCLK_DIV_128 (0x6 << 3) #define SPI_CR1_BR_PCLK_DIV_256 (0x7 << 3) -#define SPI_CR1_MSTR BIT(SPI_CR1_MSTR_BIT) -#define SPI_CR1_CPOL BIT(SPI_CR1_CPOL_BIT) +#define SPI_CR1_MSTR (1U << SPI_CR1_MSTR_BIT) +#define SPI_CR1_CPOL (1U << SPI_CR1_CPOL_BIT) #define SPI_CR1_CPOL_LOW (0x0 << SPI_CR1_CPOL_BIT) #define SPI_CR1_CPOL_HIGH (0x1 << SPI_CR1_CPOL_BIT) -#define SPI_CR1_CPHA BIT(SPI_CR1_CPHA_BIT) +#define SPI_CR1_CPHA (1U << SPI_CR1_CPHA_BIT) /* Control register 2 */ -/* RM0008-ism: SPI CR2 has "TXDMAEN" and "RXDMAEN" bits, while the - * USARTs have CR3 "DMAR" and "DMAT" bits. */ - #define SPI_CR2_TXEIE_BIT 7 #define SPI_CR2_RXNEIE_BIT 6 #define SPI_CR2_ERRIE_BIT 5 @@ -132,12 +121,12 @@ typedef struct spi_reg_map { #define SPI_CR2_TXDMAEN_BIT 1 #define SPI_CR2_RXDMAEN_BIT 0 -#define SPI_CR2_TXEIE BIT(SPI_CR2_TXEIE_BIT) -#define SPI_CR2_RXNEIE BIT(SPI_CR2_RXNEIE_BIT) -#define SPI_CR2_ERRIE BIT(SPI_CR2_ERRIE_BIT) -#define SPI_CR2_SSOE BIT(SPI_CR2_SSOE_BIT) -#define SPI_CR2_TXDMAEN BIT(SPI_CR2_TXDMAEN_BIT) -#define SPI_CR2_RXDMAEN BIT(SPI_CR2_RXDMAEN_BIT) +#define SPI_CR2_TXEIE (1U << SPI_CR2_TXEIE_BIT) +#define SPI_CR2_RXNEIE (1U << SPI_CR2_RXNEIE_BIT) +#define SPI_CR2_ERRIE (1U << SPI_CR2_ERRIE_BIT) +#define SPI_CR2_SSOE (1U << SPI_CR2_SSOE_BIT) +#define SPI_CR2_TXDMAEN (1U << SPI_CR2_TXDMAEN_BIT) +#define SPI_CR2_RXDMAEN (1U << SPI_CR2_RXDMAEN_BIT) /* Status register */ @@ -150,37 +139,35 @@ typedef struct spi_reg_map { #define SPI_SR_TXE_BIT 1 #define SPI_SR_RXNE_BIT 0 -#define SPI_SR_BSY BIT(SPI_SR_BSY_BIT) -#define SPI_SR_OVR BIT(SPI_SR_OVR_BIT) -#define SPI_SR_MODF BIT(SPI_SR_MODF_BIT) -#define SPI_SR_CRCERR BIT(SPI_SR_CRCERR_BIT) -#define SPI_SR_UDR BIT(SPI_SR_UDR_BIT) -#define SPI_SR_CHSIDE BIT(SPI_SR_CHSIDE_BIT) +#define SPI_SR_BSY (1U << SPI_SR_BSY_BIT) +#define SPI_SR_OVR (1U << SPI_SR_OVR_BIT) +#define SPI_SR_MODF (1U << SPI_SR_MODF_BIT) +#define SPI_SR_CRCERR (1U << SPI_SR_CRCERR_BIT) +#define SPI_SR_UDR (1U << SPI_SR_UDR_BIT) +#define SPI_SR_CHSIDE (1U << SPI_SR_CHSIDE_BIT) #define SPI_SR_CHSIDE_LEFT (0x0 << SPI_SR_CHSIDE_BIT) #define SPI_SR_CHSIDE_RIGHT (0x1 << SPI_SR_CHSIDE_BIT) -#define SPI_SR_TXE BIT(SPI_SR_TXE_BIT) -#define SPI_SR_RXNE BIT(SPI_SR_RXNE_BIT) +#define SPI_SR_TXE (1U << SPI_SR_TXE_BIT) +#define SPI_SR_RXNE (1U << SPI_SR_RXNE_BIT) /* I2S configuration register */ -/* RM0008-ism: CR1 has "CPOL", I2SCFGR has "CKPOL". */ - #define SPI_I2SCFGR_I2SMOD_BIT 11 #define SPI_I2SCFGR_I2SE_BIT 10 #define SPI_I2SCFGR_PCMSYNC_BIT 7 #define SPI_I2SCFGR_CKPOL_BIT 3 #define SPI_I2SCFGR_CHLEN_BIT 0 -#define SPI_I2SCFGR_I2SMOD BIT(SPI_I2SCFGR_I2SMOD_BIT) +#define SPI_I2SCFGR_I2SMOD (1U << SPI_I2SCFGR_I2SMOD_BIT) #define SPI_I2SCFGR_I2SMOD_SPI (0x0 << SPI_I2SCFGR_I2SMOD_BIT) #define SPI_I2SCFGR_I2SMOD_I2S (0x1 << SPI_I2SCFGR_I2SMOD_BIT) -#define SPI_I2SCFGR_I2SE BIT(SPI_I2SCFGR_I2SE_BIT) +#define SPI_I2SCFGR_I2SE (1U << SPI_I2SCFGR_I2SE_BIT) #define SPI_I2SCFGR_I2SCFG (0x3 << 8) #define SPI_I2SCFGR_I2SCFG_SLAVE_TX (0x0 << 8) #define SPI_I2SCFGR_I2SCFG_SLAVE_RX (0x1 << 8) #define SPI_I2SCFGR_I2SCFG_MASTER_TX (0x2 << 8) #define SPI_I2SCFGR_I2SCFG_MASTER_RX (0x3 << 8) -#define SPI_I2SCFGR_PCMSYNC BIT(SPI_I2SCFGR_PCMSYNC_BIT) +#define SPI_I2SCFGR_PCMSYNC (1U << SPI_I2SCFGR_PCMSYNC_BIT) #define SPI_I2SCFGR_PCMSYNC_SHORT (0x0 << SPI_I2SCFGR_PCMSYNC_BIT) #define SPI_I2SCFGR_PCMSYNC_LONG (0x1 << SPI_I2SCFGR_PCMSYNC_BIT) #define SPI_I2SCFGR_I2SSTD (0x3 << 4) @@ -188,17 +175,26 @@ typedef struct spi_reg_map { #define SPI_I2SCFGR_I2SSTD_MSB (0x1 << 4) #define SPI_I2SCFGR_I2SSTD_LSB (0x2 << 4) #define SPI_I2SCFGR_I2SSTD_PCM (0x3 << 4) -#define SPI_I2SCFGR_CKPOL BIT(SPI_I2SCFGR_CKPOL_BIT) +#define SPI_I2SCFGR_CKPOL (1U << SPI_I2SCFGR_CKPOL_BIT) #define SPI_I2SCFGR_CKPOL_LOW (0x0 << SPI_I2SCFGR_CKPOL_BIT) #define SPI_I2SCFGR_CKPOL_HIGH (0x1 << SPI_I2SCFGR_CKPOL_BIT) #define SPI_I2SCFGR_DATLEN (0x3 << 1) #define SPI_I2SCFGR_DATLEN_16_BIT (0x0 << 1) #define SPI_I2SCFGR_DATLEN_24_BIT (0x1 << 1) #define SPI_I2SCFGR_DATLEN_32_BIT (0x2 << 1) -#define SPI_I2SCFGR_CHLEN BIT(SPI_I2SCFGR_CHLEN_BIT) +#define SPI_I2SCFGR_CHLEN (1U << SPI_I2SCFGR_CHLEN_BIT) #define SPI_I2SCFGR_CHLEN_16_BIT (0x0 << SPI_I2SCFGR_CHLEN_BIT) #define SPI_I2SCFGR_CHLEN_32_BIT (0x1 << SPI_I2SCFGR_CHLEN_BIT) +/* I2S prescaler register */ + +#define SPI_I2SPR_MCKOE_BIT 9 +#define SPI_I2SPR_ODD_BIT 8 + +#define SPI_I2SPR_MCKOE (1U << SPI_I2SPR_MCKOE_BIT) +#define SPI_I2SPR_ODD (1U << SPI_I2SPR_ODD_BIT) +#define SPI_I2SPR_I2SDIV 0xFF + /* * Devices */ @@ -210,22 +206,28 @@ typedef struct spi_dev { nvic_irq_num irq_num; /**< NVIC interrupt number */ } spi_dev; -extern spi_dev *SPI1; -extern spi_dev *SPI2; -#ifdef STM32_HIGH_DENSITY -extern spi_dev *SPI3; -#endif - /* * SPI Convenience functions */ void spi_init(spi_dev *dev); +struct gpio_dev; +/** + * @brief Configure GPIO bit modes for use as a SPI port's pins. + * @param as_master If true, configure bits for use as a bus master. + * Otherwise, configure bits for use as slave. + * @param nss_dev NSS pin's GPIO device + * @param comm_dev SCK, MISO, MOSI pins' GPIO device + * @param nss_bit NSS pin's GPIO bit on nss_dev + * @param sck_bit SCK pin's GPIO bit on comm_dev + * @param miso_bit MISO pin's GPIO bit on comm_dev + * @param mosi_bit MOSI pin's GPIO bit on comm_dev + */ void spi_gpio_cfg(uint8 as_master, - gpio_dev *nss_dev, + struct gpio_dev *nss_dev, uint8 nss_bit, - gpio_dev *comm_dev, + struct gpio_dev *comm_dev, uint8 sck_bit, uint8 miso_bit, uint8 mosi_bit); @@ -244,7 +246,7 @@ typedef enum spi_mode { clock transition */ SPI_MODE_2, /**< Clock line idles high (1), data capture on first clock transition. */ - SPI_MODE_3 /**< Clock line idles high (1), data capture on + SPI_MODE_3, /**< Clock line idles high (1), data capture on second clock transition. */ } spi_mode; @@ -300,7 +302,11 @@ void spi_slave_enable(spi_dev *dev, uint32 spi_tx(spi_dev *dev, const void *buf, uint32 len); -void spi_foreach(void (*fn)(spi_dev (*dev))); +/** + * @brief Call a function on each SPI port + * @param fn Function to call. + */ +void spi_foreach(void (*fn)(spi_dev*)); void spi_peripheral_enable(spi_dev *dev); void spi_peripheral_disable(spi_dev *dev); diff --git a/libmaple/rules.mk b/libmaple/rules.mk index 2f5e066..93716d2 100644 --- a/libmaple/rules.mk +++ b/libmaple/rules.mk @@ -18,6 +18,7 @@ cSRCS_$(d) += iwdg.c cSRCS_$(d) += nvic.c cSRCS_$(d) += pwr.c cSRCS_$(d) += rcc.c +cSRCS_$(d) += spi.c cSRCS_$(d) += syscalls.c cSRCS_$(d) += systick.c cSRCS_$(d) += timer.c @@ -29,7 +30,6 @@ cSRCS_$(d) += util.c # cSRCS_$(d) += dma.c # cSRCS_$(d) += exti.c # cSRCS_$(d) += i2c.c -# cSRCS_$(d) += spi.c sSRCS_$(d) := exc.S diff --git a/libmaple/spi.c b/libmaple/spi.c index 00b7ce2..194a82e 100644 --- a/libmaple/spi.c +++ b/libmaple/spi.c @@ -38,36 +38,6 @@ static void spi_reconfigure(spi_dev *dev, uint32 cr1_config); /* - * SPI devices - */ - -static spi_dev spi1 = { - .regs = SPI1_BASE, - .clk_id = RCC_SPI1, - .irq_num = NVIC_SPI1, -}; -/** SPI device 1 */ -spi_dev *SPI1 = &spi1; - -static spi_dev spi2 = { - .regs = SPI2_BASE, - .clk_id = RCC_SPI2, - .irq_num = NVIC_SPI2, -}; -/** SPI device 2 */ -spi_dev *SPI2 = &spi2; - -#ifdef STM32_HIGH_DENSITY -static spi_dev spi3 = { - .regs = SPI3_BASE, - .clk_id = RCC_SPI3, - .irq_num = NVIC_SPI3, -}; -/** SPI device 3 */ -spi_dev *SPI3 = &spi3; -#endif - -/* * SPI convenience routines */ @@ -81,37 +51,6 @@ void spi_init(spi_dev *dev) { } /** - * @brief Configure GPIO bit modes for use as a SPI port's pins. - * @param as_master If true, configure bits for use as a bus master. - * Otherwise, configure bits for use as slave. - * @param nss_dev NSS pin's GPIO device - * @param comm_dev SCK, MISO, MOSI pins' GPIO device - * @param nss_bit NSS pin's GPIO bit on nss_dev - * @param sck_bit SCK pin's GPIO bit on comm_dev - * @param miso_bit MISO pin's GPIO bit on comm_dev - * @param mosi_bit MOSI pin's GPIO bit on comm_dev - */ -void spi_gpio_cfg(uint8 as_master, - gpio_dev *nss_dev, - uint8 nss_bit, - gpio_dev *comm_dev, - uint8 sck_bit, - uint8 miso_bit, - uint8 mosi_bit) { - if (as_master) { - gpio_set_mode(nss_dev, nss_bit, GPIO_AF_OUTPUT_PP); - gpio_set_mode(comm_dev, sck_bit, GPIO_AF_OUTPUT_PP); - gpio_set_mode(comm_dev, miso_bit, GPIO_INPUT_FLOATING); - gpio_set_mode(comm_dev, mosi_bit, GPIO_AF_OUTPUT_PP); - } else { - gpio_set_mode(nss_dev, nss_bit, GPIO_INPUT_FLOATING); - gpio_set_mode(comm_dev, sck_bit, GPIO_INPUT_FLOATING); - gpio_set_mode(comm_dev, miso_bit, GPIO_AF_OUTPUT_PP); - gpio_set_mode(comm_dev, mosi_bit, GPIO_INPUT_FLOATING); - } -} - -/** * @brief Configure and enable a SPI device as bus master. * * The device's peripheral will be disabled before being reconfigured. @@ -166,18 +105,6 @@ uint32 spi_tx(spi_dev *dev, const void *buf, uint32 len) { } /** - * @brief Call a function on each SPI port - * @param fn Function to call. - */ -void spi_foreach(void (*fn)(spi_dev*)) { - fn(SPI1); - fn(SPI2); -#ifdef STM32_HIGH_DENSITY - fn(SPI3); -#endif -} - -/** * @brief Enable a SPI peripheral * @param dev Device to enable */ @@ -235,7 +162,3 @@ static void spi_reconfigure(spi_dev *dev, uint32 cr1_config) { dev->regs->CR1 = cr1_config; spi_peripheral_enable(dev); } - -/* - * IRQ handlers (TODO) - */ diff --git a/libmaple/stm32f1/include/series/spi.h b/libmaple/stm32f1/include/series/spi.h new file mode 100644 index 0000000..167df0c --- /dev/null +++ b/libmaple/stm32f1/include/series/spi.h @@ -0,0 +1,70 @@ +/****************************************************************************** + * The MIT License + * + * Copyright (c) 2011, 2012 LeafLabs, LLC. + * Copyright (c) 2010 Perry Hung. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + *****************************************************************************/ + +/** + * @file libmaple/stm32f1/include/series/spi.h + * @author Marti Bolivar <mbolivar@leaflabs.com> + * @brief STM32F1 SPI/I2S series header. + */ + +#ifndef _LIBMAPLE_STM32F1_SPI_H_ +#define _LIBMAPLE_STM32F1_SPI_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * Register map base pointers + */ + +struct spi_reg_map; + +/** SPI1 register map base pointer */ +#define SPI1_BASE ((struct spi_reg_map*)0x40013000) +/** SPI2 register map base pointer */ +#define SPI2_BASE ((struct spi_reg_map*)0x40003800) +/** SPI3 register map base pointer */ +#define SPI3_BASE ((struct spi_reg_map*)0x40003C00) + +/* + * Device pointers + */ + +struct spi_dev; + +extern struct spi_dev *SPI1; +extern struct spi_dev *SPI2; +#if defined(STM32_HIGH_DENSITY) || defined(STM32_XL_DENSITY) +extern struct spi_dev *SPI3; +#endif + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/libmaple/stm32f1/rules.mk b/libmaple/stm32f1/rules.mk index 03fddb3..52ceea6 100644 --- a/libmaple/stm32f1/rules.mk +++ b/libmaple/stm32f1/rules.mk @@ -16,6 +16,7 @@ cSRCS_$(d) += bkp.c cSRCS_$(d) += fsmc.c cSRCS_$(d) += gpio.c cSRCS_$(d) += rcc.c +cSRCS_$(d) += spi.c cSRCS_$(d) += timer.c cSRCS_$(d) += usart.c diff --git a/libmaple/stm32f1/spi.c b/libmaple/stm32f1/spi.c new file mode 100644 index 0000000..b860918 --- /dev/null +++ b/libmaple/stm32f1/spi.c @@ -0,0 +1,97 @@ +/****************************************************************************** + * The MIT License + * + * Copyright (c) 2011, 2012 LeafLabs, LLC. + * Copyright (c) 2010 Perry Hung. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + *****************************************************************************/ + +/** + * @file libmaple/stm32f1/spi.c + * @author Marti Bolivar <mbolivar@leaflabs.com> + * @brief STM32F1 SPI/I2S support. + */ + +#include <libmaple/spi.h> +#include <libmaple/gpio.h> + +/* + * Devices + */ + +static spi_dev spi1 = { + .regs = SPI1_BASE, + .clk_id = RCC_SPI1, + .irq_num = NVIC_SPI1, +}; +/** SPI device 1 */ +spi_dev *SPI1 = &spi1; + +static spi_dev spi2 = { + .regs = SPI2_BASE, + .clk_id = RCC_SPI2, + .irq_num = NVIC_SPI2, +}; +/** SPI device 2 */ +spi_dev *SPI2 = &spi2; + +#if defined(STM32_HIGH_DENSITY) || defined(STM32_XL_DENSITY) +static spi_dev spi3 = { + .regs = SPI3_BASE, + .clk_id = RCC_SPI3, + .irq_num = NVIC_SPI3, +}; +/** SPI device 3 */ +spi_dev *SPI3 = &spi3; +#endif + +/* + * Routines + */ + +void spi_gpio_cfg(uint8 as_master, + gpio_dev *nss_dev, + uint8 nss_bit, + gpio_dev *comm_dev, + uint8 sck_bit, + uint8 miso_bit, + uint8 mosi_bit) { + if (as_master) { + gpio_set_mode(nss_dev, nss_bit, GPIO_AF_OUTPUT_PP); + gpio_set_mode(comm_dev, sck_bit, GPIO_AF_OUTPUT_PP); + gpio_set_mode(comm_dev, miso_bit, GPIO_INPUT_FLOATING); + gpio_set_mode(comm_dev, mosi_bit, GPIO_AF_OUTPUT_PP); + } else { + gpio_set_mode(nss_dev, nss_bit, GPIO_INPUT_FLOATING); + gpio_set_mode(comm_dev, sck_bit, GPIO_INPUT_FLOATING); + gpio_set_mode(comm_dev, miso_bit, GPIO_AF_OUTPUT_PP); + gpio_set_mode(comm_dev, mosi_bit, GPIO_INPUT_FLOATING); + } +} + +void spi_foreach(void (*fn)(spi_dev*)) { + fn(SPI1); + fn(SPI2); +#if defined(STM32_HIGH_DENSITY) || defined(STM32_XL_DENSITY) + fn(SPI3); +#endif +} |