From 301fe2c02ef0ca779d11dcedc2a081436360fbe3 Mon Sep 17 00:00:00 2001 From: Marti Bolivar Date: Tue, 10 Apr 2012 16:05:42 -0400 Subject: 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 --- libmaple/stm32f1/include/series/spi.h | 70 +++++++++++++++++++++++++++++++++++ 1 file changed, 70 insertions(+) create mode 100644 libmaple/stm32f1/include/series/spi.h (limited to 'libmaple/stm32f1/include/series/spi.h') 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 + * @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 -- cgit v1.2.3 From f5c37f28fd9be3bd8e2c7159a09891d5e571bc43 Mon Sep 17 00:00:00 2001 From: Marti Bolivar Date: Sun, 3 Jun 2012 02:11:07 -0400 Subject: Globally switch style for GPIO config routines. Stupidly, spi_gpio_cfg() didn't take a spi_dev* argument on F1, because it doesn't matter there. On F2, where we need to set an alternate function when configuring GPIOs for SPI, we need to know the dev. We can't add break backwards compatibility, so we need a new function. However, we've since added a bunch of foo_gpio_cfg() routines, and we don't want confusing asymmetry in the names. So a global style change is needed. (Fortunately, the new functions weren't part of a release, so it's no problem to change their names). Change all foo_gpio_cfg() routines to foo_config_gpios() (or foo_config_gpio(), if there's only one GPIO to configure). For backwards compatibility, make spi_gpio_cfg() on F1 an __always_inline call to spi_config_gpios(). Signed-off-by: Marti Bolivar --- examples/test-timers.cpp | 2 +- libmaple/include/libmaple/adc.h | 6 +++++- libmaple/include/libmaple/spi.h | 15 ++++++++------- libmaple/include/libmaple/usart.h | 19 ++++++++++++++----- libmaple/stm32f1/adc.c | 2 +- libmaple/stm32f1/include/series/spi.h | 32 ++++++++++++++++++++++++++++++++ libmaple/stm32f1/spi.c | 15 ++++++++------- libmaple/stm32f1/usart.c | 8 ++++---- libmaple/stm32f2/adc.c | 2 +- libmaple/stm32f2/usart.c | 8 ++++---- wirish/HardwareSPI.cpp | 10 +++------- wirish/HardwareSerial.cpp | 8 ++++---- 12 files changed, 85 insertions(+), 42 deletions(-) (limited to 'libmaple/stm32f1/include/series/spi.h') diff --git a/examples/test-timers.cpp b/examples/test-timers.cpp index 1f376b7..e646916 100644 --- a/examples/test-timers.cpp +++ b/examples/test-timers.cpp @@ -389,7 +389,7 @@ static void _delay(uint32 msec) { } static void init_usart(usart_dev *dev, gpio_dev *gdev, uint8 tx, uint8 rx) { - usart_async_gpio_cfg(dev, gdev, rx, gdev, tx, 0); + usart_config_gpios_async(dev, gdev, rx, gdev, tx, 0); usart_init(dev); usart_set_baud_rate(dev, USART_USE_PCLK, COMM_USART_BAUD); usart_enable(dev); diff --git a/libmaple/include/libmaple/adc.h b/libmaple/include/libmaple/adc.h index ff9a5e4..a500af7 100644 --- a/libmaple/include/libmaple/adc.h +++ b/libmaple/include/libmaple/adc.h @@ -262,10 +262,14 @@ extern void adc_foreach(void (*fn)(const adc_dev*)); struct gpio_dev; /** * @brief Configure a GPIO pin for ADC conversion. + * @param dev ADC device to use for conversion (currently ignored on + * all targets). * @param gdev GPIO device to configure. * @param bit Bit on gdev to configure for ADC conversion. */ -extern void adc_gpio_cfg(struct gpio_dev *gdev, uint8 bit); +extern void adc_config_gpio(const struct adc_dev *dev, + struct gpio_dev *gdev, + uint8 bit); /** * @brief Enable an ADC and configure it for single conversion mode. diff --git a/libmaple/include/libmaple/spi.h b/libmaple/include/libmaple/spi.h index 3805b2e..90e2036 100644 --- a/libmaple/include/libmaple/spi.h +++ b/libmaple/include/libmaple/spi.h @@ -224,13 +224,14 @@ struct gpio_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, - struct gpio_dev *nss_dev, - uint8 nss_bit, - struct gpio_dev *comm_dev, - uint8 sck_bit, - uint8 miso_bit, - uint8 mosi_bit); +extern void spi_config_gpios(spi_dev *dev, + uint8 as_master, + struct gpio_dev *nss_dev, + uint8 nss_bit, + struct gpio_dev *comm_dev, + uint8 sck_bit, + uint8 miso_bit, + uint8 mosi_bit); /** * @brief SPI mode configuration. diff --git a/libmaple/include/libmaple/usart.h b/libmaple/include/libmaple/usart.h index 293d59e..26a64d3 100644 --- a/libmaple/include/libmaple/usart.h +++ b/libmaple/include/libmaple/usart.h @@ -395,12 +395,21 @@ typedef struct usart_dev { void usart_init(usart_dev *dev); -/* FIXME document this function */ struct gpio_dev; /* forward declaration */ -void usart_async_gpio_cfg(usart_dev *udev, - struct gpio_dev *rx_dev, uint8 rx, - struct gpio_dev *tx_dev, uint8 tx, - unsigned flags); +/* FIXME [PRE 0.0.13] decide if flags are necessary */ +/** + * @brief Configure GPIOs for use as USART TX/RX. + * @param udev USART device to use + * @param rx_dev RX pin gpio_dev + * @param rx RX pin bit on rx_dev + * @param tx_dev TX pin gpio_dev + * @param tx TX pin bit on tx_dev + * @param flags Currently ignored + */ +extern void usart_config_gpios_async(usart_dev *udev, + struct gpio_dev *rx_dev, uint8 rx, + struct gpio_dev *tx_dev, uint8 tx, + unsigned flags); #define USART_USE_PCLK 0 void usart_set_baud_rate(usart_dev *dev, uint32 clock_speed, uint32 baud); diff --git a/libmaple/stm32f1/adc.c b/libmaple/stm32f1/adc.c index facc6bd..ecfbc1c 100644 --- a/libmaple/stm32f1/adc.c +++ b/libmaple/stm32f1/adc.c @@ -99,7 +99,7 @@ void adc_foreach(void (*fn)(const adc_dev*)) { #endif } -void adc_gpio_cfg(gpio_dev *gdev, uint8 bit) { +void adc_config_gpio(const adc_dev *ignored, gpio_dev *gdev, uint8 bit) { gpio_set_mode(gdev, bit, GPIO_INPUT_ANALOG); } diff --git a/libmaple/stm32f1/include/series/spi.h b/libmaple/stm32f1/include/series/spi.h index 167df0c..8cc4c4d 100644 --- a/libmaple/stm32f1/include/series/spi.h +++ b/libmaple/stm32f1/include/series/spi.h @@ -34,6 +34,8 @@ #ifndef _LIBMAPLE_STM32F1_SPI_H_ #define _LIBMAPLE_STM32F1_SPI_H_ +#include + #ifdef __cplusplus extern "C" { #endif @@ -63,6 +65,36 @@ extern struct spi_dev *SPI2; extern struct spi_dev *SPI3; #endif +/* + * Routines + */ + +/* spi_gpio_cfg(): Backwards compatibility shim to spi_config_gpios() */ +struct gpio_dev; +extern void spi_config_gpios(struct spi_dev*, uint8, + struct gpio_dev*, uint8, + struct gpio_dev*, uint8, uint8, uint8); +/** + * @brief Deprecated. Use spi_config_gpios() instead. + * @see spi_config_gpios() + */ +static __always_inline void spi_gpio_cfg(uint8 as_master, + struct gpio_dev *nss_dev, + uint8 nss_bit, + struct gpio_dev *comm_dev, + uint8 sck_bit, + uint8 miso_bit, + uint8 mosi_bit) { + /* We switched style globally to foo_config_gpios() and always + * taking a foo_dev* argument (that last bit is the important + * part) after this function was written. + * + * However, spi_config_gpios() just ignores the spi_dev* on F1, so + * we can still keep this around for older code. */ + spi_config_gpios(NULL, as_master, nss_dev, nss_bit, + comm_dev, sck_bit, miso_bit, mosi_bit); +} + #ifdef __cplusplus } #endif diff --git a/libmaple/stm32f1/spi.c b/libmaple/stm32f1/spi.c index 8b6e495..72f2ef4 100644 --- a/libmaple/stm32f1/spi.c +++ b/libmaple/stm32f1/spi.c @@ -69,13 +69,14 @@ spi_dev *SPI3 = &spi3; * 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) { +void spi_config_gpios(spi_dev *ignored, + 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); diff --git a/libmaple/stm32f1/usart.c b/libmaple/stm32f1/usart.c index eed420e..b3b849f 100644 --- a/libmaple/stm32f1/usart.c +++ b/libmaple/stm32f1/usart.c @@ -101,10 +101,10 @@ usart_dev *UART5 = &uart5; * Routines */ -void usart_async_gpio_cfg(usart_dev *udev, - gpio_dev *rx_dev, uint8 rx, - gpio_dev *tx_dev, uint8 tx, - unsigned flags) { +void usart_config_gpios_async(usart_dev *udev, + gpio_dev *rx_dev, uint8 rx, + gpio_dev *tx_dev, uint8 tx, + unsigned flags) { gpio_set_mode(rx_dev, rx, GPIO_INPUT_FLOATING); gpio_set_mode(tx_dev, tx, GPIO_AF_OUTPUT_PP); } diff --git a/libmaple/stm32f2/adc.c b/libmaple/stm32f2/adc.c index 0380736..a400d7b 100644 --- a/libmaple/stm32f2/adc.c +++ b/libmaple/stm32f2/adc.c @@ -74,7 +74,7 @@ void adc_foreach(void (*fn)(const adc_dev*)) { fn(ADC3); } -void adc_gpio_cfg(gpio_dev *gdev, uint8 bit) { +void adc_config_gpio(const adc_dev *ignored, gpio_dev *gdev, uint8 bit) { gpio_set_modef(gdev, bit, GPIO_MODE_ANALOG, GPIO_MODEF_PUPD_NONE); } diff --git a/libmaple/stm32f2/usart.c b/libmaple/stm32f2/usart.c index 2dd3afc..9a1acf3 100644 --- a/libmaple/stm32f2/usart.c +++ b/libmaple/stm32f2/usart.c @@ -107,10 +107,10 @@ usart_dev *USART6 = &usart6; * Routines */ -void usart_async_gpio_cfg(usart_dev *udev, - gpio_dev *rx_dev, uint8 rx, - gpio_dev *tx_dev, uint8 tx, - unsigned flags) { +void usart_config_gpios_async(usart_dev *udev, + gpio_dev *rx_dev, uint8 rx, + gpio_dev *tx_dev, uint8 tx, + unsigned flags) { gpio_af af; /* TODO: break this out into a user-facing function. */ switch (udev->clk_id) { diff --git a/wirish/HardwareSPI.cpp b/wirish/HardwareSPI.cpp index e1f186e..120cd67 100644 --- a/wirish/HardwareSPI.cpp +++ b/wirish/HardwareSPI.cpp @@ -283,13 +283,9 @@ static void configure_gpios(spi_dev *dev, bool as_master) { disable_pwm(misoi); disable_pwm(mosii); - spi_gpio_cfg(as_master, - nssi->gpio_device, - nssi->gpio_bit, - scki->gpio_device, - scki->gpio_bit, - misoi->gpio_bit, - mosii->gpio_bit); + spi_config_gpios(dev, as_master, nssi->gpio_device, nssi->gpio_bit, + scki->gpio_device, scki->gpio_bit, misoi->gpio_bit, + mosii->gpio_bit); } static const spi_baud_rate baud_rates[MAX_SPI_FREQS] __FLASH__ = { diff --git a/wirish/HardwareSerial.cpp b/wirish/HardwareSerial.cpp index 75f5bbb..7dccccf 100644 --- a/wirish/HardwareSerial.cpp +++ b/wirish/HardwareSerial.cpp @@ -100,10 +100,10 @@ void HardwareSerial::begin(uint32 baud) { disable_timer_if_necessary(txi->timer_device, txi->timer_channel); - usart_async_gpio_cfg(this->usart_device, - rxi->gpio_device, rxi->gpio_bit, - txi->gpio_device, txi->gpio_bit, - 0); + usart_config_gpios_async(this->usart_device, + rxi->gpio_device, rxi->gpio_bit, + txi->gpio_device, txi->gpio_bit, + 0); usart_init(this->usart_device); usart_set_baud_rate(this->usart_device, USART_USE_PCLK, baud); usart_enable(this->usart_device); -- cgit v1.2.3 From a52fe9205cbb8f8a2e458e300c2048d889b26b54 Mon Sep 17 00:00:00 2001 From: Marti Bolivar Date: Thu, 7 Jun 2012 21:41:50 -0400 Subject: Bring back . Add a spi_private.h with a SPI_DEV(), for convenience. Use it in the F1 and F2 implementations. We could probably unify these with an STM32_HAVE_SPI(n) macro, but we'll leave that for the future. Most everything from F1 is portable; F2 has some additional bit definitions and a spi_get_af() routine, but that's about it. Signed-off-by: Marti Bolivar --- libmaple/include/libmaple/spi.h | 2 +- libmaple/rules.mk | 2 +- libmaple/spi_private.h | 37 +++++++++++++++ libmaple/stm32f1/include/series/spi.h | 3 -- libmaple/stm32f1/spi.c | 25 ++-------- libmaple/stm32f2/include/series/spi.h | 88 +++++++++++++++++++++++++++++++++++ libmaple/stm32f2/rules.mk | 1 + libmaple/stm32f2/spi.c | 88 +++++++++++++++++++++++++++++++++++ 8 files changed, 221 insertions(+), 25 deletions(-) create mode 100644 libmaple/spi_private.h create mode 100644 libmaple/stm32f2/include/series/spi.h create mode 100644 libmaple/stm32f2/spi.c (limited to 'libmaple/stm32f1/include/series/spi.h') diff --git a/libmaple/include/libmaple/spi.h b/libmaple/include/libmaple/spi.h index 90e2036..45dc5a2 100644 --- a/libmaple/include/libmaple/spi.h +++ b/libmaple/include/libmaple/spi.h @@ -307,7 +307,7 @@ 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*)); +extern 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 649e4c8..be93d2e 100644 --- a/libmaple/rules.mk +++ b/libmaple/rules.mk @@ -21,7 +21,7 @@ cSRCS_$(d) += iwdg.c cSRCS_$(d) += nvic.c cSRCS_$(d) += pwr.c cSRCS_$(d) += rcc.c -# cSRCS_$(d) += spi.c +cSRCS_$(d) += spi.c cSRCS_$(d) += systick.c cSRCS_$(d) += timer.c cSRCS_$(d) += usart.c diff --git a/libmaple/spi_private.h b/libmaple/spi_private.h new file mode 100644 index 0000000..f0e0bd1 --- /dev/null +++ b/libmaple/spi_private.h @@ -0,0 +1,37 @@ +/****************************************************************************** + * The MIT License + * + * Copyright (c) 2012 LeafLabs, LLC. + * + * 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. + *****************************************************************************/ + +#ifndef _LIBMAPLE_SPI_PRIVATE_H_ +#define _LIBMAPLE_SPI_PRIVATE_H_ + +#define SPI_DEV(num) \ + { \ + .regs = SPI##num##_BASE, \ + .clk_id = RCC_SPI##num, \ + .irq_num = NVIC_SPI##num, \ + } + +#endif diff --git a/libmaple/stm32f1/include/series/spi.h b/libmaple/stm32f1/include/series/spi.h index 8cc4c4d..d288a0c 100644 --- a/libmaple/stm32f1/include/series/spi.h +++ b/libmaple/stm32f1/include/series/spi.h @@ -46,11 +46,8 @@ extern "C" { 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) /* diff --git a/libmaple/stm32f1/spi.c b/libmaple/stm32f1/spi.c index 72f2ef4..1c78cc3 100644 --- a/libmaple/stm32f1/spi.c +++ b/libmaple/stm32f1/spi.c @@ -33,35 +33,20 @@ #include #include +#include "spi_private.h" /* * Devices */ -static spi_dev spi1 = { - .regs = SPI1_BASE, - .clk_id = RCC_SPI1, - .irq_num = NVIC_SPI1, -}; -static spi_dev spi2 = { - .regs = SPI2_BASE, - .clk_id = RCC_SPI2, - .irq_num = NVIC_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, -}; -#endif +static spi_dev spi1 = SPI_DEV(1); +static spi_dev spi2 = SPI_DEV(2); -/** SPI device 1 */ spi_dev *SPI1 = &spi1; -/** SPI device 2 */ spi_dev *SPI2 = &spi2; + #if defined(STM32_HIGH_DENSITY) || defined(STM32_XL_DENSITY) -/** SPI device 3 */ +static spi_dev spi3 = SPI_DEV(3); spi_dev *SPI3 = &spi3; #endif diff --git a/libmaple/stm32f2/include/series/spi.h b/libmaple/stm32f2/include/series/spi.h new file mode 100644 index 0000000..7b9f94a --- /dev/null +++ b/libmaple/stm32f2/include/series/spi.h @@ -0,0 +1,88 @@ +/****************************************************************************** + * The MIT License + * + * Copyright (c) 2012 LeafLabs, LLC. + * + * 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/stm32f2/include/series/spi.h + * @author Marti Bolivar + * @brief STM32F2 SPI/I2S series header. + */ + +#ifndef _LIBMAPLE_STM32F2_SPI_H_ +#define _LIBMAPLE_STM32F2_SPI_H_ + +#include /* for gpio_af */ + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * Register map base pointers + */ + +struct spi_reg_map; + +#define SPI1_BASE ((struct spi_reg_map*)0x40013000) +#define SPI2_BASE ((struct spi_reg_map*)0x40003800) +#define SPI3_BASE ((struct spi_reg_map*)0x40003C00) + +/* + * Register bit definitions + */ + +/* Control register 2 */ + +#define SPI_CR2_FRF_BIT 4 + +#define SPI_CR2_FRF (1U << SPI_CR2_FRF_BIT) + +/* Status register */ + +#define SPI_SR_TIFRFE_BIT 8 + +#define SPI_SR_TIFRFE (1U << SPI_SR_TIFRFE_BIT) + +/* + * Device pointers + */ + +struct spi_dev; + +extern struct spi_dev *SPI1; +extern struct spi_dev *SPI2; +extern struct spi_dev *SPI3; + +/* + * Routines + */ + +gpio_af spi_get_af(struct spi_dev *dev); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/libmaple/stm32f2/rules.mk b/libmaple/stm32f2/rules.mk index fd6b933..759f905 100644 --- a/libmaple/stm32f2/rules.mk +++ b/libmaple/stm32f2/rules.mk @@ -16,6 +16,7 @@ cSRCS_$(d) += exti.c cSRCS_$(d) += fsmc.c cSRCS_$(d) += gpio.c cSRCS_$(d) += rcc.c +cSRCS_$(d) += spi.c cSRCS_$(d) += syscfg.c cSRCS_$(d) += timer.c cSRCS_$(d) += usart.c diff --git a/libmaple/stm32f2/spi.c b/libmaple/stm32f2/spi.c new file mode 100644 index 0000000..cfd9995 --- /dev/null +++ b/libmaple/stm32f2/spi.c @@ -0,0 +1,88 @@ +/****************************************************************************** + * The MIT License + * + * Copyright (c) 2012 LeafLabs, LLC. + * + * 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/stm32f2/spi.c + * @author Marti Bolivar + * @brief STM32F2 SPI/I2S. + */ + +#include +#include "spi_private.h" + +/* + * Devices + */ + +static spi_dev spi1 = SPI_DEV(1); +static spi_dev spi2 = SPI_DEV(2); +static spi_dev spi3 = SPI_DEV(3); + +spi_dev *SPI1 = &spi1; +spi_dev *SPI2 = &spi2; +spi_dev *SPI3 = &spi3; + +/* + * Routines + */ + +void spi_config_gpios(spi_dev *dev, + uint8 as_master, + gpio_dev *nss_dev, + uint8 nss_bit, + gpio_dev *comm_dev, + uint8 sck_bit, + uint8 miso_bit, + uint8 mosi_bit) { + gpio_af dev_af = spi_get_af(dev); + gpio_set_mode(nss_dev, nss_bit, GPIO_MODE_AF); + gpio_set_mode(comm_dev, sck_bit, GPIO_MODE_AF); + gpio_set_mode(comm_dev, miso_bit, GPIO_MODE_AF); + gpio_set_mode(comm_dev, mosi_bit, GPIO_MODE_AF); + gpio_set_af(nss_dev, nss_bit, dev_af); + gpio_set_af(comm_dev, sck_bit, dev_af); + gpio_set_af(comm_dev, miso_bit, dev_af); + gpio_set_af(comm_dev, mosi_bit, dev_af); +} + +void spi_foreach(void (*fn)(spi_dev*)) { + fn(SPI1); + fn(SPI2); + fn(SPI3); +} + +gpio_af spi_get_af(spi_dev *dev) { + switch (dev->clk_id) { + case RCC_SPI1: /* Fall through */ + case RCC_SPI2: + return GPIO_AF_SPI_1_2; + case RCC_SPI3: + return GPIO_AF_SPI3; + default: + ASSERT(0); /* Can't happen */ + return (gpio_af)-1; + } +} -- cgit v1.2.3