Initial check-in for STM32 board

This commit is contained in:
Ben Lye
2017-11-27 21:19:49 +00:00
parent 9bf5b0c9a7
commit e557155b17
893 changed files with 106516 additions and 34 deletions

View File

@@ -0,0 +1,62 @@
/******************************************************************************
* 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_DMA_PRIVATE_H_
#define _LIBMAPLE_DMA_PRIVATE_H_
#include <libmaple/dma.h>
#include <libmaple/libmaple_types.h>
/*
* IRQ handling
*/
/* Wrap this in an ifdef to shut up GCC. (We provide DMA_GET_HANDLER
* in the series support files, which need dma_irq_handler().) */
#ifdef DMA_GET_HANDLER
static inline __always_inline void dma_irq_handler(dma_dev *dev, dma_tube tube) {
void (*handler)(void) = DMA_GET_HANDLER(dev, tube);
if (handler) {
handler();
dma_clear_isr_bits(dev, tube); /* in case handler doesn't */
}
}
#endif
/*
* Conveniences for dealing with tube sources/destinations
*/
enum dma_atype {
DMA_ATYPE_MEM,
DMA_ATYPE_PER,
DMA_ATYPE_OTHER,
};
enum dma_atype _dma_addr_type(__io void *addr);
#endif

View File

@@ -0,0 +1,34 @@
/******************************************************************************
* 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_EXTI_PRIVATE_H_
#define _LIBMAPLE_EXTI_PRIVATE_H_
#include <libmaple/exti.h>
void exti_do_select(__io uint32 *exti_cr, exti_num num, exti_cfg port);
#endif

View File

@@ -0,0 +1,79 @@
/******************************************************************************
* 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_I2C_PRIVATE_H_
#define _LIBMAPLE_I2C_PRIVATE_H_
#include <libmaple/i2c_common.h>
/* For old-style definitions (SDA/SCL on same GPIO device) */
#define I2C_DEV_OLD(num, port, sda, scl) \
{ \
.regs = I2C##num##_BASE, \
.gpio_port = port, \
.scl_port = NULL, \
.sda_port = NULL, \
.sda_pin = sda, \
.scl_pin = scl, \
.clk_id = RCC_I2C##num, \
.ev_nvic_line = NVIC_I2C##num##_EV, \
.er_nvic_line = NVIC_I2C##num##_ER, \
.state = I2C_STATE_DISABLED, \
}
/* For new-style definitions (SDA/SCL may be on different GPIO devices) */
#define I2C_DEV_NEW(num, sdaport, sdabit, sclport, sclbit) \
{ \
.regs = I2C##num##_BASE, \
.gpio_port = NULL, \
.scl_port = sclport, \
.scl_pin = sclbit, \
.sda_port = sdaport, \
.sda_pin = sdabit, \
.clk_id = RCC_I2C##num, \
.ev_nvic_line = NVIC_I2C##num##_EV, \
.er_nvic_line = NVIC_I2C##num##_ER, \
.state = I2C_STATE_DISABLED, \
}
void _i2c_irq_handler(i2c_dev *dev);
void _i2c_irq_error_handler(i2c_dev *dev);
struct gpio_dev;
static inline struct gpio_dev* scl_port(const i2c_dev *dev) {
return (dev->gpio_port == NULL) ? dev->scl_port : dev->gpio_port;
}
static inline struct gpio_dev* sda_port(const i2c_dev *dev) {
return (dev->gpio_port == NULL) ? dev->sda_port : dev->gpio_port;
}
/* Auxiliary procedure for enabling an I2C peripheral; `flags' as for
* i2c_master_enable(). */
void _i2c_set_ccr_trise(i2c_dev *dev, uint32 flags);
#endif /* _LIBMAPLE_I2C_PRIVATE_H_ */

View File

@@ -0,0 +1,351 @@
/******************************************************************************
* The MIT License
*
* Copyright (c) 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/include/libmaple/adc.h
* @author Marti Bolivar <mbolivar@leaflabs.com>,
* Perry Hung <perry@leaflabs.com>
* @brief Analog-to-Digital Conversion (ADC) header.
*/
#ifndef _LIBMAPLE_ADC_H_
#define _LIBMAPLE_ADC_H_
#ifdef __cplusplus
extern "C"{
#endif
#include <libmaple/libmaple.h>
#include <libmaple/bitband.h>
#include <libmaple/rcc.h>
#include <libmaple/nvic.h>
/* We include the series header below, after defining the register map
* and device structs. */
/*
* Register map
*/
/** ADC register map type. */
typedef struct adc_reg_map {
__io uint32 SR; ///< Status register
__io uint32 CR1; ///< Control register 1
__io uint32 CR2; ///< Control register 2
__io uint32 SMPR1; ///< Sample time register 1
__io uint32 SMPR2; ///< Sample time register 2
__io uint32 JOFR1; ///< Injected channel data offset register 1
__io uint32 JOFR2; ///< Injected channel data offset register 2
__io uint32 JOFR3; ///< Injected channel data offset register 3
__io uint32 JOFR4; ///< Injected channel data offset register 4
__io uint32 HTR; ///< Watchdog high threshold register
__io uint32 LTR; ///< Watchdog low threshold register
__io uint32 SQR1; ///< Regular sequence register 1
__io uint32 SQR2; ///< Regular sequence register 2
__io uint32 SQR3; ///< Regular sequence register 3
__io uint32 JSQR; ///< Injected sequence register
__io uint32 JDR1; ///< Injected data register 1
__io uint32 JDR2; ///< Injected data register 2
__io uint32 JDR3; ///< Injected data register 3
__io uint32 JDR4; ///< Injected data register 4
__io uint32 DR; ///< Regular data register
} adc_reg_map;
/** ADC device type. */
typedef struct adc_dev {
adc_reg_map *regs; /**< Register map */
rcc_clk_id clk_id; /**< RCC clock information */
nvic_irq_num irq_num; /* Added by bubulindo */
voidFuncPtr handlers[]; /* Added by bubulindo EOC, JEOC, AWD Interrupts*/
} adc_dev;
//Added by bubulindo - Interrupt ID's for ADC
typedef enum adc_interrupt_id {
ADC_EOC, /**< Update interrupt. */
ADC_AWD , /**< Capture/compare 1 interrupt. */
ADC_JEOC,
//ADC_JSTRT,
//ADC_STRT, /**Analog WatchDog interrupt */
} adc_interrupt_id;
//Added by bubulindo
void adc_enable_irq(adc_dev* dev, uint8 interrupt);
void adc_attach_interrupt(adc_dev *dev, uint8 interrupt, voidFuncPtr handler);
/* Pull in the series header (which may need the above struct
* definitions).
*
* IMPORTANT: The series header must define the following:
*
* - enum adc_extsel_event (and typedef to adc_extsel_event): One per
* external event used to trigger start of conversion of a regular
* group. If two different series support the same event as a
* trigger, they must use the same token for the enumerator for that
* event. (The value of the enumerator is of course allowed to be
* different).
*
* - enum adc_smp_rate (and typedef to adc_smp_rate): One per
* available sampling time. These must be in the form ADC_SMPR_X_Y
* for X.Y cycles (e.g. ADC_SMPR_1_5 means 1.5 cycles), or
* ADC_SMPR_X for X cycles (e.g. ADC_SMPR_3 means 3 cycles).
*
* - enum adc_prescaler (and typedef): One per available prescaler,
* suitable for adc_set_prescaler. Series which have the same
* prescaler dividers (e.g. STM32F1 and STM32F2 both divide PCLK2 by
* 2, 4, 6, or 8) must provide the same tokens as enumerators, for
* portability.
*/
/* Roger clark. Replaced with line below #include <series/adc.h>*/
#include "stm32f1/include/series/adc.h"
/*
* Register bit definitions
*/
/* Status register */
#define ADC_SR_AWD_BIT 0
#define ADC_SR_EOC_BIT 1
#define ADC_SR_JEOC_BIT 2
#define ADC_SR_JSTRT_BIT 3
#define ADC_SR_STRT_BIT 4
#define ADC_SR_AWD BIT(ADC_SR_AWD_BIT)
#define ADC_SR_EOC BIT(ADC_SR_EOC_BIT)
#define ADC_SR_JEOC BIT(ADC_SR_JEOC_BIT)
#define ADC_SR_JSTRT BIT(ADC_SR_JSTRT_BIT)
#define ADC_SR_STRT BIT(ADC_SR_STRT_BIT)
/* Control register 1 */
#define ADC_CR1_EOCIE_BIT 5
#define ADC_CR1_AWDIE_BIT 6
#define ADC_CR1_JEOCIE_BIT 7
#define ADC_CR1_SCAN_BIT 8
#define ADC_CR1_AWDSGL_BIT 9
#define ADC_CR1_JAUTO_BIT 10
#define ADC_CR1_DISCEN_BIT 11
#define ADC_CR1_JDISCEN_BIT 12
#define ADC_CR1_JAWDEN_BIT 22
#define ADC_CR1_AWDEN_BIT 23
#define ADC_CR1_AWDCH (0x1F)
#define ADC_CR1_EOCIE BIT(ADC_CR1_EOCIE_BIT)
#define ADC_CR1_AWDIE BIT(ADC_CR1_AWDIE_BIT)
#define ADC_CR1_JEOCIE BIT(ADC_CR1_JEOCIE_BIT)
#define ADC_CR1_SCAN BIT(ADC_CR1_SCAN_BIT)
#define ADC_CR1_AWDSGL BIT(ADC_CR1_AWDSGL_BIT)
#define ADC_CR1_JAUTO BIT(ADC_CR1_JAUTO_BIT)
#define ADC_CR1_DISCEN BIT(ADC_CR1_DISCEN_BIT)
#define ADC_CR1_JDISCEN BIT(ADC_CR1_JDISCEN_BIT)
#define ADC_CR1_DISCNUM (0xE000)
#define ADC_CR1_JAWDEN BIT(ADC_CR1_JAWDEN_BIT)
#define ADC_CR1_AWDEN BIT(ADC_CR1_AWDEN_BIT)
/* Control register 2 */
/* Because this register varies significantly by series (e.g. some
* bits moved and others disappeared in the F1->F2 transition), its
* definitions are in the series headers. */
/* Sample time register 1 */
#define ADC_SMPR1_SMP17 (0x7 << 21)
#define ADC_SMPR1_SMP16 (0x7 << 18)
#define ADC_SMPR1_SMP15 (0x7 << 15)
#define ADC_SMPR1_SMP14 (0x7 << 12)
#define ADC_SMPR1_SMP13 (0x7 << 9)
#define ADC_SMPR1_SMP12 (0x7 << 6)
#define ADC_SMPR1_SMP11 (0x7 << 3)
#define ADC_SMPR1_SMP10 0x7
/* Sample time register 2 */
#define ADC_SMPR2_SMP9 (0x7 << 27)
#define ADC_SMPR2_SMP8 (0x7 << 24)
#define ADC_SMPR2_SMP7 (0x7 << 21)
#define ADC_SMPR2_SMP6 (0x7 << 18)
#define ADC_SMPR2_SMP5 (0x7 << 15)
#define ADC_SMPR2_SMP4 (0x7 << 12)
#define ADC_SMPR2_SMP3 (0x7 << 9)
#define ADC_SMPR2_SMP2 (0x7 << 6)
#define ADC_SMPR2_SMP1 (0x7 << 3)
#define ADC_SMPR2_SMP0 0x7
/* Injected channel data offset register */
#define ADC_JOFR_JOFFSET 0x3FF
/* Watchdog high threshold register */
#define ADC_HTR_HT 0x3FF
/* Watchdog low threshold register */
#define ADC_LTR_LT 0x3FF
/* Regular sequence register 1 */
#define ADC_SQR1_L (0x1F << 20)
#define ADC_SQR1_SQ16 (0x1F << 15)
#define ADC_SQR1_SQ15 (0x1F << 10)
#define ADC_SQR1_SQ14 (0x1F << 5)
#define ADC_SQR1_SQ13 0x1F
/* Regular sequence register 2 */
#define ADC_SQR2_SQ12 (0x1F << 25)
#define ADC_SQR2_SQ11 (0x1F << 20)
#define ADC_SQR2_SQ10 (0x1F << 16)
#define ADC_SQR2_SQ9 (0x1F << 10)
#define ADC_SQR2_SQ8 (0x1F << 5)
#define ADC_SQR2_SQ7 0x1F
/* Regular sequence register 3 */
#define ADC_SQR3_SQ6 (0x1F << 25)
#define ADC_SQR3_SQ5 (0x1F << 20)
#define ADC_SQR3_SQ4 (0x1F << 16)
#define ADC_SQR3_SQ3 (0x1F << 10)
#define ADC_SQR3_SQ2 (0x1F << 5)
#define ADC_SQR3_SQ1 0x1F
/* Injected sequence register */
#define ADC_JSQR_JL (0x3 << 20)
#define ADC_JSQR_JL_1CONV (0x0 << 20)
#define ADC_JSQR_JL_2CONV (0x1 << 20)
#define ADC_JSQR_JL_3CONV (0x2 << 20)
#define ADC_JSQR_JL_4CONV (0x3 << 20)
#define ADC_JSQR_JSQ4 (0x1F << 15)
#define ADC_JSQR_JSQ3 (0x1F << 10)
#define ADC_JSQR_JSQ2 (0x1F << 5)
#define ADC_JSQR_JSQ1 0x1F
/* Injected data registers */
#define ADC_JDR_JDATA 0xFFFF
/* Regular data register */
#define ADC_DR_ADC2DATA (0xFFFF << 16)
#define ADC_DR_DATA 0xFFFF
/*
* Routines
*/
void adc_init(adc_dev *dev);
void adc_set_extsel(adc_dev *dev, adc_extsel_event event);
void adc_set_sample_rate(adc_dev *dev, adc_smp_rate smp_rate);
uint16 adc_read(adc_dev *dev, uint8 channel);
/**
* @brief Set the ADC prescaler.
*
* This determines the ADC clock for all devices.
*/
extern void adc_set_prescaler(adc_prescaler pre);
/**
* @brief Call a function on all ADC devices.
* @param fn Function to call on each ADC device.
*/
extern void adc_foreach(void (*fn)(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_config_gpio(struct adc_dev *dev,
struct gpio_dev *gdev,
uint8 bit);
/**
* @brief Enable an ADC and configure it for single conversion mode.
*
* This function performs any initialization necessary to allow the
* ADC device to perform a single synchronous regular software
* triggered conversion, using adc_read().
*
* @param dev Device to enable.
* @see adc_read()
*/
extern void adc_enable_single_swstart(adc_dev* dev);
/**
* @brief Set the regular channel sequence length.
*
* Defines the total number of conversions in the regular channel
* conversion sequence.
*
* @param dev ADC device.
* @param length Regular channel sequence length, from 1 to 16.
*/
static inline void adc_set_reg_seqlen(adc_dev *dev, uint8 length) {
uint32 tmp = dev->regs->SQR1;
tmp &= ~ADC_SQR1_L;
tmp |= (length - 1) << 20;
dev->regs->SQR1 = tmp;
}
/**
* @brief Enable an adc peripheral
* @param dev ADC device to enable
*/
static inline void adc_enable(adc_dev *dev) {
*bb_perip(&dev->regs->CR2, ADC_CR2_ADON_BIT) = 1;
}
/**
* @brief Disable an ADC peripheral
* @param dev ADC device to disable
*/
static inline void adc_disable(adc_dev *dev) {
*bb_perip(&dev->regs->CR2, ADC_CR2_ADON_BIT) = 0;
}
/**
* @brief Disable all ADC peripherals.
*/
static inline void adc_disable_all(void) {
adc_foreach(adc_disable);
}
#ifdef __cplusplus
} // extern "C"
#endif
#endif

View File

@@ -0,0 +1,128 @@
/******************************************************************************
* The MIT License
*
* Copyright (c) 2011 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/include/libmaple/bitband.h
*
* @brief Bit-banding utility functions
*/
#ifndef _LIBMAPLE_BITBAND_H_
#define _LIBMAPLE_BITBAND_H_
#ifdef __cplusplus
extern "C" {
#endif
#include <libmaple/libmaple_types.h>
#define BB_SRAM_REF 0x20000000
#define BB_SRAM_BASE 0x22000000
#define BB_PERI_REF 0x40000000
#define BB_PERI_BASE 0x42000000
static inline volatile uint32* __bb_addr(volatile void*,
uint32,
uint32,
uint32);
/**
* @brief Obtain a pointer to the bit-band address corresponding to a
* bit in a volatile SRAM address.
* @param address Address in the bit-banded SRAM region
* @param bit Bit in address to bit-band
*/
static inline volatile uint32* bb_sramp(volatile void *address, uint32 bit) {
return __bb_addr(address, bit, BB_SRAM_BASE, BB_SRAM_REF);
}
/**
* @brief Get a bit from an address in the SRAM bit-band region.
* @param address Address in the SRAM bit-band region to read from
* @param bit Bit in address to read
* @return bit's value in address.
*/
static inline uint8 bb_sram_get_bit(volatile void *address, uint32 bit) {
return *bb_sramp(address, bit);
}
/**
* @brief Set a bit in an address in the SRAM bit-band region.
* @param address Address in the SRAM bit-band region to write to
* @param bit Bit in address to write to
* @param val Value to write for bit, either 0 or 1.
*/
static inline void bb_sram_set_bit(volatile void *address,
uint32 bit,
uint8 val) {
*bb_sramp(address, bit) = val;
}
/**
* @brief Obtain a pointer to the bit-band address corresponding to a
* bit in a peripheral address.
* @param address Address in the bit-banded peripheral region
* @param bit Bit in address to bit-band
*/
static inline volatile uint32* bb_perip(volatile void *address, uint32 bit) {
return __bb_addr(address, bit, BB_PERI_BASE, BB_PERI_REF);
}
/**
* @brief Get a bit from an address in the peripheral bit-band region.
* @param address Address in the peripheral bit-band region to read from
* @param bit Bit in address to read
* @return bit's value in address.
*/
static inline uint8 bb_peri_get_bit(volatile void *address, uint32 bit) {
return *bb_perip(address, bit);
}
/**
* @brief Set a bit in an address in the peripheral bit-band region.
* @param address Address in the peripheral bit-band region to write to
* @param bit Bit in address to write to
* @param val Value to write for bit, either 0 or 1.
*/
static inline void bb_peri_set_bit(volatile void *address,
uint32 bit,
uint8 val) {
*bb_perip(address, bit) = val;
}
static inline volatile uint32* __bb_addr(volatile void *address,
uint32 bit,
uint32 bb_base,
uint32 bb_ref) {
return (volatile uint32*)(bb_base + ((uint32)address - bb_ref) * 32 +
bit * 4);
}
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -0,0 +1,166 @@
/******************************************************************************
* The MIT License
*
* Copyright (c) 2010 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/include/libmaple/bkp.h
* @brief Backup register support (STM32F1 only).
*/
#ifndef _LIBMAPLE_BKP_H_
#define _LIBMAPLE_BKP_H_
#ifdef __cplusplus
extern "C" {
#endif
#include <libmaple/libmaple.h>
#if defined(STM32_MEDIUM_DENSITY)
#define BKP_NR_DATA_REGS 10
#elif defined(STM32_HIGH_DENSITY)
#define BKP_NR_DATA_REGS 42
#endif
/** Backup peripheral register map type. */
typedef struct bkp_reg_map {
const uint32 RESERVED1; ///< Reserved
__io uint32 DR1; ///< Data register 1
__io uint32 DR2; ///< Data register 2
__io uint32 DR3; ///< Data register 3
__io uint32 DR4; ///< Data register 4
__io uint32 DR5; ///< Data register 5
__io uint32 DR6; ///< Data register 6
__io uint32 DR7; ///< Data register 7
__io uint32 DR8; ///< Data register 8
__io uint32 DR9; ///< Data register 9
__io uint32 DR10; ///< Data register 10
__io uint32 RTCCR; ///< RTC control register
__io uint32 CR; ///< Control register
__io uint32 CSR; ///< Control and status register
#if defined(STM32_HIGH_DENSITY) || defined(STM32_XL_DENSITY)
const uint32 RESERVED2; ///< Reserved
const uint32 RESERVED3; ///< Reserved
__io uint32 DR11; ///< Data register 11
__io uint32 DR12; ///< Data register 12
__io uint32 DR13; ///< Data register 13
__io uint32 DR14; ///< Data register 14
__io uint32 DR15; ///< Data register 15
__io uint32 DR16; ///< Data register 16
__io uint32 DR17; ///< Data register 17
__io uint32 DR18; ///< Data register 18
__io uint32 DR19; ///< Data register 19
__io uint32 DR20; ///< Data register 20
__io uint32 DR21; ///< Data register 21
__io uint32 DR22; ///< Data register 22
__io uint32 DR23; ///< Data register 23
__io uint32 DR24; ///< Data register 24
__io uint32 DR25; ///< Data register 25
__io uint32 DR26; ///< Data register 26
__io uint32 DR27; ///< Data register 27
__io uint32 DR28; ///< Data register 28
__io uint32 DR29; ///< Data register 29
__io uint32 DR30; ///< Data register 30
__io uint32 DR31; ///< Data register 31
__io uint32 DR32; ///< Data register 32
__io uint32 DR33; ///< Data register 33
__io uint32 DR34; ///< Data register 34
__io uint32 DR35; ///< Data register 35
__io uint32 DR36; ///< Data register 36
__io uint32 DR37; ///< Data register 37
__io uint32 DR38; ///< Data register 38
__io uint32 DR39; ///< Data register 39
__io uint32 DR40; ///< Data register 40
__io uint32 DR41; ///< Data register 41
__io uint32 DR42; ///< Data register 42
#endif
} bkp_reg_map;
/** Backup peripheral register map base pointer. */
#define BKP_BASE ((struct bkp_reg_map*)0x40006C00)
/** Backup peripheral device type. */
typedef struct bkp_dev {
bkp_reg_map *regs; /**< Register map */
} bkp_dev;
extern const bkp_dev *BKP;
/*
* Register bit definitions
*/
/* Data Registers */
#define BKP_DR_D 0xFFFF
/* RTC Clock Calibration Register */
#define BKP_RTCCR_ASOS_BIT 9
#define BKP_RTCCR_ASOE_BIT 8
#define BKP_RTCCR_CCO_BIT 7
#define BKP_RTCCR_ASOS BIT(BKP_RTCCR_ASOS_BIT)
#define BKP_RTCCR_ASOE BIT(BKP_RTCCR_ASOE_BIT)
#define BKP_RTCCR_CCO BIT(BKP_RTCCR_CCO_BIT)
#define BKP_RTCCR_CAL 0x7F
/* Backup control register */
#define BKP_CR_TPAL_BIT 1
#define BKP_CR_TPE_BIT 0
#define BKP_CR_TPAL BIT(BKP_CR_TPAL_BIT)
#define BKP_CR_TPE BIT(BKP_CR_TPE_BIT)
/* Backup control/status register */
#define BKP_CSR_TIF_BIT 9
#define BKP_CSR_TEF_BIT 8
#define BKP_CSR_TPIE_BIT 2
#define BKP_CSR_CTI_BIT 1
#define BKP_CSR_CTE_BIT 0
#define BKP_CSR_TIF BIT(BKP_CSR_TIF_BIT)
#define BKP_CSR_TEF BIT(BKP_CSR_TEF_BIT)
#define BKP_CSR_TPIE BIT(BKP_CSR_TPIE_BIT)
#define BKP_CSR_CTI BIT(BKP_CSR_CTI_BIT)
#define BKP_CSR_CTE BIT(BKP_CSR_CTE_BIT)
/*
* Convenience functions
*/
void bkp_init(void);
void bkp_enable_writes(void);
void bkp_disable_writes(void);
uint16 bkp_read(uint8 reg);
void bkp_write(uint8 reg, uint16 val);
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif

View File

@@ -0,0 +1,162 @@
/******************************************************************************
* The MIT License
*
* Copyright (c) 2011, 2012 LeafLabs, LLC.
* Copyright (c) 2010 Bryan Newbold.
*
* 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/include/libmaple/dac.h
* @brief Digital to analog converter support.
*/
/* See notes/dac.txt for more info */
#ifndef _LIBMAPLE_DAC_H_
#define _LIBMAPLE_DAC_H_
#ifdef __cplusplus
extern "C"{
#endif
/* Roger clark. Replaced with line below #include <series/dac.h>*/
#include "stm32f1/include/series/dac.h"
#include <libmaple/libmaple_types.h>
#include <libmaple/rcc.h>
#include <libmaple/stm32.h>
/*
* Register map base and device pointers.
*
* The DACs are the same on all supported targets, so it's not worth
* repeating these in the series headers.
*/
#define DAC_BASE ((struct dac_reg_map*)0x40007400)
/** DAC device type. */
typedef struct dac_dev {
dac_reg_map *regs; /**< Register map */
} dac_dev;
#if STM32_HAVE_DAC
extern const dac_dev *DAC;
#endif
/*
* Register bit definitions
*/
/* Control register */
/* Channel 1 control */
#define DAC_CR_EN1 (1U << 0) /* Enable */
#define DAC_CR_BOFF1 (1U << 1) /* Output buffer disable */
#define DAC_CR_TEN1 (1U << 2) /* Trigger enable */
#define DAC_CR_TSEL1 (0x7 << 3) /* Trigger selection */
#define DAC_CR_WAVE1 (0x3 << 6) /* Noise/triangle wave */
#define DAC_CR_MAMP1 (0xF << 8) /* Mask/amplitude selector */
#define DAC_CR_DMAEN1 (1U << 12) /* DMA enable */
/* Channel 2 control */
#define DAC_CR_EN2 (1U << 16) /* Enable */
#define DAC_CR_BOFF2 (1U << 17) /* Output buffer disable */
#define DAC_CR_TEN2 (1U << 18) /* Trigger enable */
#define DAC_CR_TSEL2 (0x7 << 19) /* Trigger selection */
#define DAC_CR_WAVE2 (0x3 << 22) /* Noise/triangle wave */
#define DAC_CR_MAMP2 (0xF << 24) /* Mask/amplitude selector */
#define DAC_CR_DMAEN2 (1U << 28) /* DMA enable */
/* Software trigger register */
#define DAC_SWTRIGR_SWTRIG1 (1U << 0) /* Channel 1 software trigger */
#define DAC_SWTRIGR_SWTRIG2 (1U << 1) /* Channel 2 software trigger */
/* Channel 1 12-bit right-aligned data holding register */
#define DAC_DHR12R1_DACC1DHR 0x00000FFF
/* Channel 1 12-bit left-aligned data holding register */
#define DAC_DHR12L1_DACC1DHR 0x0000FFF0
/* Channel 1 8-bit left-aligned data holding register */
#define DAC_DHR8R1_DACC1DHR 0x000000FF
/* Channel 2 12-bit right-aligned data holding register */
#define DAC_DHR12R2_DACC2DHR 0x00000FFF
/* Channel 2 12-bit left-aligned data holding register */
#define DAC_DHR12L2_DACC2DHR 0x0000FFF0
/* Channel 2 8-bit left-aligned data holding register */
#define DAC_DHR8R2_DACC2DHR 0x000000FF
/* Dual DAC 12-bit right-aligned data holding register */
#define DAC_DHR12RD_DACC1DHR 0x00000FFF
#define DAC_DHR12RD_DACC2DHR 0x0FFF0000
/* Dual DAC 12-bit left-aligned data holding register */
#define DAC_DHR12LD_DACC1DHR 0x0000FFF0
#define DAC_DHR12LD_DACC2DHR 0xFFF00000
/* Dual DAC 8-bit left-aligned data holding register */
#define DAC_DHR8RD_DACC1DHR 0x000000FF
#define DAC_DHR8RD_DACC2DHR 0x0000FF00
/* Channel 1 data output register */
#define DAC_DOR1_DACC1DOR 0x00000FFF
/* Channel 1 data output register */
#define DAC_DOR2_DACC2DOR 0x00000FFF
/*
* Routines
*/
/* We take the dev argument in these for future-proofing */
#define DAC_CH1 0x1
#define DAC_CH2 0x2
void dac_init(const dac_dev *dev, uint32 flags);
void dac_write_channel(const dac_dev *dev, uint8 channel, uint16 val);
void dac_enable_channel(const dac_dev *dev, uint8 channel);
void dac_disable_channel(const dac_dev *dev, uint8 channel);
#define dac_write_channel1(val) ( DAC->regs->DHR12R1 = DAC_DHR12R1_DACC1DHR & val )
#define dac_write_channel2(val) ( DAC->regs->DHR12R2 = DAC_DHR12R2_DACC2DHR & val )
#ifdef __cplusplus
} // extern "C"
#endif
#endif

View File

@@ -0,0 +1,65 @@
/******************************************************************************
* The MIT License
*
* Copyright (c) 2010 Perry Hung.
* Copyright (c) 2011 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/include/libmaple/delay.h
* @brief Delay implementation
*/
#ifndef _LIBMAPLE_DELAY_H_
#define _LIBMAPLE_DELAY_H_
#ifdef __cplusplus
extern "C" {
#endif
#include <libmaple/libmaple_types.h>
#include <libmaple/stm32.h>
/**
* @brief Delay the given number of microseconds.
*
* @param us Number of microseconds to delay.
*/
static inline void delay_us(uint32 us) {
us *= STM32_DELAY_US_MULT;
/* fudge for function call overhead */
us--;
asm volatile(" mov r0, %[us] \n\t"
"1: subs r0, #1 \n\t"
" bhi 1b \n\t"
:
: [us] "r" (us)
: "r0");
}
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -0,0 +1,447 @@
/******************************************************************************
* The MIT License
*
* Copyright (c) 2010 Michael Hope.
* 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/include/libmaple/dma.h
*
* @author Marti Bolivar <mbolivar@leaflabs.com>;
* Original implementation by Michael Hope
*
* @brief Direct Memory Access peripheral support
*/
#ifndef _LIBMAPLE_DMA_H_
#define _LIBMAPLE_DMA_H_
#ifdef __cplusplus
extern "C"{
#endif
/* <series/dma.h> provides:
*
* - An opaque dma_tube type, and predefined rvalues for each tube
* supported by the series.
*
* A "DMA tube" is a series-specific (hopefully integer) datatype
* that abstracts the conduit through which DMA-ed data flow.
*
* Examples: On STM32F1, dma_tube is just an alias for dma_channel,
* and the tube values are just DMA_CH1 (=1), DMA_CH2 (=2), etc.
*
* Note that a dma_tube doesn't have to be an enum, and its values
* don't have to be integral. They _do_ need to be cheap to pass as
* arguments, though.
*
* - struct dma_tube_reg_map (and typedef to dma_tube_reg_map). DMA
* register maps tend to be split into global registers and per-tube
* registers. It's convenient to pass around pointers to a tube's
* registers, since that makes it possible to configure or otherwise
* mess with a tube without knowing which one you're dealing with.
*
* - Base pointers to the various dma_tube_reg_maps.
*
* Examples: On STM32F1, these are DMAxCHy_BASE. You can access
* registers like DMAxCHy_BASE->CPAR, etc.
*
* - enum dma_request_src (and typedef to dma_request_src). This
* specifies the peripheral DMA request sources (e.g. USART TX DMA
* requests, etc.).
*
* - enum dma_mode_flags (and typedef to dma_mode_flags). Used in
* dma_tube_config. If two series both support the same mode flags,
* they must use the same enumerator names for those flags (the
* values of those enumerators are of course allowed to differ).
*
* - Normal stuff: dma_reg_map and base pointers, register bit
* definitions, dma_dev pointer declarations, and any other
* convenience functions useful for the series. */
/* Roger clark. Replaced with line below #include <series/dma.h>*/
#include "stm32f1/include/series/dma.h"
/* <libmaple/dma_common.h> buys us dma_dev and other necessities. */
#include <libmaple/dma_common.h>
#include <libmaple/libmaple_types.h>
/*
* Declarations/documentation for some of the series-provided types.
*/
/**
* @brief (Series-dependent) DMA request sources.
*
* These specify the various pieces of peripheral functionality which
* may make DMA requests. Use them to set up a DMA transfer (see
* struct dma_tube_config, dma_tube_cfg()).
*/
enum dma_request_src;
/**
* @brief (Series-dependent) DMA tube configuration flags.
* These specify miscellaneous bits of configuration for a DMA tube.
* @see struct dma_mode_config
*/
enum dma_cfg_flags;
/**
* @brief (Series-dependent) DMA tube register map type.
* This allows you to access a tube's registers as a group.
* @see dma_tube_regs()
*/
struct dma_tube_reg_map;
/*
* Convenience functions
*/
/* Initialization */
void dma_init(dma_dev *dev);
/* dma_tube configuration
*
* Use these types and functions to set up DMA transfers, handle
* interrupts, etc. The main function of interest is dma_tube_cfg(),
* which the various series implement separately. */
/**
* @brief Specifies a DMA tube configuration.
*
* Use one of these to set up a DMA transfer by passing it to
* dma_tube_cfg().
*
* @see dma_tube_cfg()
* @see dma_xfer_size
*/
typedef struct dma_tube_config {
/** Source of data */
__io void *tube_src;
/** Source transfer size */
dma_xfer_size tube_src_size;
/** Destination of data */
__io void *tube_dst;
/** Destination transfer size */
dma_xfer_size tube_dst_size;
/**
* Number of data to transfer (0 to 65,535).
*
* Note that this is NOT measured in bytes; it's measured in
* number of data, which occur in multiples of tube_src_size. For
* example, if tube_src_size is DMA_SIZE_32BITS and tube_nr_xfers
* is 2, then 8 total bytes will be transferred.
*/
unsigned tube_nr_xfers;
/**
* Target-specific configuration flags.
*
* These are an OR of series-specific enum dma_mode_flags values.
* Consult the documentation for your target for what flags you
* can use here.
*
* Typical flag examples: DMA_CFG_SRC_INC, DMA_CFG_DST_INC,
* DMA_CFG_CIRC, DMA_CFG_CMPLT_IE, etc.
*/
unsigned tube_flags;
/**
* Currently unused. You must set this to 0 or something valid for
* your target. */
void *target_data;
/**
* Hardware DMA request source.
*
* This is ignored for memory-to-memory transfers.
*/
enum dma_request_src tube_req_src;
} dma_tube_config;
#define DMA_TUBE_CFG_SUCCESS 0
#define DMA_TUBE_CFG_EREQ 1
#define DMA_TUBE_CFG_ENDATA 2
#define DMA_TUBE_CFG_EDEV 3
#define DMA_TUBE_CFG_ESRC 4
#define DMA_TUBE_CFG_EDST 5
#define DMA_TUBE_CFG_EDIR 6
#define DMA_TUBE_CFG_ESIZE 7
#define DMA_TUBE_CFG_ECFG 0xFF
/**
* @brief Configure a DMA tube.
*
* Use this function to set up a DMA transfer. The tube will be
* disabled before being reconfigured. The transfer will have low
* priority by default. You can choose another priority before the
* transfer begins using dma_set_priority(). You can manage your
* interrupt handlers for the tube using dma_attach_interrupt() and
* dma_detach_interrupt().
*
* After calling dma_tube_cfg() and performing any other desired
* configuration, start the transfer using dma_enable().
*
* @param dev DMA device.
* @param tube DMA tube to configure.
* @param cfg Configuration to apply to tube.
*
* @return DMA_TUBE_CFG_SUCCESS (0) on success, <0 on failure. On
* failure, returned value will be the opposite (-) of one of:
*
* - DMA_TUBE_CFG_EREQ: tube doesn't work with cfg->tube_req_src
* - DMA_TUBE_CFG_ENDATA: cfg->tube_[src,dst]_size are
* incompatible with cfg->tube_nr_xfers, or cfg->tube_nr_xfers
* is out of bounds.
* - DMA_TUBE_CFG_EDEV: dev does not support cfg
* - DMA_TUBE_CFG_ESRC: bad cfg->tube_src
* - DMA_TUBE_CFG_EDST: bad cfg->tube_dst
* - DMA_TUBE_CFG_EDIR: dev can't transfer from cfg->tube_src to
* cfg->tube_dst
* - DMA_TUBE_CFG_ESIZE: something ended up wrong due to MSIZE/PSIZE
* - DMA_TUBE_CFG_ECFG: generic "something's wrong"
*
* @sideeffect Disables tube. May alter tube's registers even when an
* error occurs.
* @see struct dma_tube_config
* @see dma_attach_interrupt()
* @see dma_detach_interrupt()
* @see dma_enable()
*/
extern int dma_tube_cfg(dma_dev *dev, dma_tube tube, dma_tube_config *cfg);
/* Other tube configuration functions. You can use these if
* dma_tube_cfg() isn't enough, or to adjust parts of an existing tube
* configuration. */
/** DMA transfer priority. */
typedef enum dma_priority {
DMA_PRIORITY_LOW = 0, /**< Low priority */
DMA_PRIORITY_MEDIUM = 1, /**< Medium priority */
DMA_PRIORITY_HIGH = 2, /**< High priority */
DMA_PRIORITY_VERY_HIGH = 3, /**< Very high priority */
} dma_priority;
/**
* @brief Set the priority of a DMA transfer.
*
* You may not call this function while the tube is enabled.
*
* @param dev DMA device
* @param tube DMA tube
* @param priority priority to set.
*/
extern void dma_set_priority(dma_dev *dev, dma_tube tube,
dma_priority priority);
/**
* @brief Set the number of data transfers on a DMA tube.
*
* You may not call this function while the tube is enabled.
*
* @param dev DMA device
* @param tube Tube through which the transfer will occur.
* @param num_transfers Number of DMA transactions to set.
*/
extern void dma_set_num_transfers(dma_dev *dev, dma_tube tube,
uint16 num_transfers);
/**
* @brief Set the base memory address where data will be read from or
* written to.
*
* You must not call this function while the tube is enabled.
*
* If the DMA memory size is 16 bits, the address is automatically
* aligned to a half-word. If the DMA memory size is 32 bits, the
* address is aligned to a word.
*
* @param dev DMA Device
* @param tube Tube whose base memory address to set.
* @param address Memory base address to use.
*/
extern void dma_set_mem_addr(dma_dev *dev, dma_tube tube, __io void *address);
/**
* @brief Set the base peripheral address where data will be read from
* or written to.
*
* You must not call this function while the channel is enabled.
*
* If the DMA peripheral size is 16 bits, the address is automatically
* aligned to a half-word. If the DMA peripheral size is 32 bits, the
* address is aligned to a word.
*
* @param dev DMA Device
* @param tube Tube whose peripheral data register base address to set.
* @param address Peripheral memory base address to use.
*/
extern void dma_set_per_addr(dma_dev *dev, dma_tube tube, __io void *address);
/* Interrupt handling */
/**
* @brief Attach an interrupt to a DMA transfer.
*
* Interrupts are enabled using series-specific mode flags in
* dma_tube_cfg().
*
* @param dev DMA device
* @param tube Tube to attach handler to
* @param handler Interrupt handler to call when tube interrupt fires.
* @see dma_tube_cfg()
* @see dma_get_irq_cause()
* @see dma_detach_interrupt()
*/
extern void dma_attach_interrupt(dma_dev *dev, dma_tube tube,
void (*handler)(void));
/**
* @brief Detach a DMA transfer interrupt handler.
*
* After calling this function, the given tube's interrupts will be
* disabled.
*
* @param dev DMA device
* @param tube Tube whose handler to detach
* @sideeffect Clears the tube's interrupt enable bits.
* @see dma_attach_interrupt()
*/
extern void dma_detach_interrupt(dma_dev *dev, dma_tube tube);
/* Tube enable/disable */
/**
* @brief Enable a DMA tube.
*
* If the tube has been properly configured, calling this function
* allows it to start serving DMA requests.
*
* @param dev DMA device
* @param tube Tube to enable
* @see dma_tube_cfg()
*/
extern void dma_enable(dma_dev *dev, dma_tube tube);
/**
* @brief Disable a DMA channel.
*
* Calling this function makes the tube stop serving DMA requests.
*
* @param dev DMA device
* @param tube Tube to disable
*/
extern void dma_disable(dma_dev *dev, dma_tube tube);
/**
* @brief Check if a DMA tube is enabled.
* @param dev DMA device.
* @param tube Tube to check.
* @return 0 if the tube is disabled, >0 if it is enabled.
*/
static inline uint8 dma_is_enabled(dma_dev *dev, dma_tube tube);
/* Other conveniences */
/**
* @brief Obtain a pointer to an individual DMA tube's registers.
*
* Examples:
*
* - On STM32F1, dma_channel_regs(DMA1, DMA_CH1)->CCR is DMA1_BASE->CCR1.
*
* @param dev DMA device.
* @param tube DMA tube whose register map to obtain.
* @return (Series-specific) tube register map.
*/
static inline dma_tube_reg_map* dma_tube_regs(dma_dev *dev, dma_tube tube);
/**
* Encodes the reason why a DMA interrupt was called.
* @see dma_get_irq_cause()
*/
typedef enum dma_irq_cause {
DMA_TRANSFER_COMPLETE, /**< Transfer is complete. */
DMA_TRANSFER_HALF_COMPLETE, /**< Transfer is half complete. */
DMA_TRANSFER_ERROR, /**< Error occurred during transfer. */
DMA_TRANSFER_DME_ERROR, /**<
* @brief Direct mode error occurred during
* transfer. */
DMA_TRANSFER_FIFO_ERROR, /**< FIFO error occurred during transfer. */
} dma_irq_cause;
/**
* @brief Discover the reason why a DMA interrupt was called.
*
* You may only call this function within an attached interrupt
* handler for the given channel.
*
* This function resets the internal DMA register state which encodes
* the cause of the interrupt; consequently, it can only be called
* once per interrupt handler invocation.
*
* @param dev DMA device
* @param tube Tube whose interrupt is being handled.
* @return Reason why the interrupt fired.
* @sideeffect Clears flags in dev's interrupt status registers.
* @see dma_attach_interrupt()
* @see dma_irq_cause
*/
extern dma_irq_cause dma_get_irq_cause(dma_dev *dev, dma_tube tube);
/**
* @brief Get the ISR status bits for a DMA channel.
*
* The bits are returned right-aligned, in the order they appear in
* the corresponding ISR register.
*
* If you're trying to figure out why a DMA interrupt fired, you may
* find dma_get_irq_cause() more convenient.
*
* @param dev DMA device
* @param tube Tube whose ISR bits to return.
* @see dma_get_irq_cause().
*/
static inline uint8 dma_get_isr_bits(dma_dev *dev, dma_tube tube);
/**
* @brief Clear the ISR status bits for a given DMA tube.
*
* If you're trying to clean up after yourself in a DMA interrupt, you
* may find dma_get_irq_cause() more convenient.
*
* @param dev DMA device
* @param tube Tube whose ISR bits to clear.
* @see dma_get_irq_cause()
*/
static inline void dma_clear_isr_bits(dma_dev *dev, dma_tube tube);
#ifdef __cplusplus
} // extern "C"
#endif
#endif

View File

@@ -0,0 +1,112 @@
/******************************************************************************
* 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/include/libmaple/dma_common.h
* @author Marti Bolivar <mbolivar@leaflabs.com>
* @brief Common DMA sub-header for <series/dma.h> and <libmaple/dma.h>.
*
* CONTENTS UNSTABLE. The existence of this file is an implementation
* detail. Never include it directly. If you need something from
* here, include <libmaple/dma.h> instead.
*/
/*
* There's a fair amount of common DMA functionality needed by each
* <series/dma.h> and <libmaple/dma.h>. This header exists in order
* to provide it to both, avoiding some hacks and circular
* dependencies.
*/
#ifndef _LIBMAPLE_DMA_COMMON_H_
#define _LIBMAPLE_DMA_COMMON_H_
#ifdef __cplusplus
extern "C"{
#endif
#include <libmaple/libmaple_types.h>
#include <libmaple/nvic.h>
#include <libmaple/rcc.h>
/*
* Devices
*/
struct dma_reg_map;
/* Encapsulates state related to user interrupt handlers. You
* shouldn't touch these directly; use dma_attach_interrupt() and
* dma_detach_interupt() instead. */
typedef struct dma_handler_config {
void (*handler)(void); /* User handler */
nvic_irq_num irq_line; /* IRQ line for interrupt */
} dma_handler_config;
/** DMA device type */
typedef struct dma_dev {
struct dma_reg_map *regs; /**< Register map */
rcc_clk_id clk_id; /**< Clock ID */
struct dma_handler_config handlers[]; /**< For internal use */
} dma_dev;
/**
* @brief DMA channels
*
* Notes:
* - This is also the dma_tube type for STM32F1.
* - Channel 0 is not available on all STM32 series.
*
* @see dma_tube
*/
typedef enum dma_channel {
DMA_CH0 = 0, /**< Channel 0 */
DMA_CH1 = 1, /**< Channel 1 */
DMA_CH2 = 2, /**< Channel 2 */
DMA_CH3 = 3, /**< Channel 3 */
DMA_CH4 = 4, /**< Channel 4 */
DMA_CH5 = 5, /**< Channel 5 */
DMA_CH6 = 6, /**< Channel 6 */
DMA_CH7 = 7, /**< Channel 7 */
} dma_channel;
/**
* @brief Source and destination transfer sizes.
* Use these when initializing a struct dma_tube_config.
* @see struct dma_tube_config
* @see dma_tube_cfg
*/
typedef enum dma_xfer_size {
DMA_SIZE_8BITS = 0, /**< 8-bit transfers */
DMA_SIZE_16BITS = 1, /**< 16-bit transfers */
DMA_SIZE_32BITS = 2, /**< 32-bit transfers */
} dma_xfer_size;
#ifdef __cplusplus
} // extern "C"
#endif
#endif

View File

@@ -0,0 +1,144 @@
/******************************************************************************
* The MIT License
*
* 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/include/libmaple/exti.h
* @brief External interrupt control
*/
/* See notes/exti.txt for more info */
#ifndef _LIBMAPLE_EXTI_H_
#define _LIBMAPLE_EXTI_H_
#ifdef __cplusplus
extern "C"{
#endif
/* Roger clark. replaced by line below #include <series/exti.h> */ /* provides EXTI_BASE */
#include "stm32f1/include/series/exti.h"
#include <libmaple/libmaple_types.h>
/*
* Register map and base pointer.
*/
/** EXTI register map type */
typedef struct exti_reg_map {
__io uint32 IMR; /**< Interrupt mask register */
__io uint32 EMR; /**< Event mask register */
__io uint32 RTSR; /**< Rising trigger selection register */
__io uint32 FTSR; /**< Falling trigger selection register */
__io uint32 SWIER; /**< Software interrupt event register */
__io uint32 PR; /**< Pending register */
} exti_reg_map;
/*
* Types: exti_num, exti_cfg, exti_trigger_mode.
*
* A combination of these three specifies an external interrupt
* configuration (see exti_attach_interrupt()).
*/
/** EXTI line. */
typedef enum exti_num {
EXTI0, /**< EXTI line 0 */
EXTI1, /**< EXTI line 1 */
EXTI2, /**< EXTI line 2 */
EXTI3, /**< EXTI line 3 */
EXTI4, /**< EXTI line 4 */
EXTI5, /**< EXTI line 5 */
EXTI6, /**< EXTI line 6 */
EXTI7, /**< EXTI line 7 */
EXTI8, /**< EXTI line 8 */
EXTI9, /**< EXTI line 9 */
EXTI10, /**< EXTI line 10 */
EXTI11, /**< EXTI line 11 */
EXTI12, /**< EXTI line 12 */
EXTI13, /**< EXTI line 13 */
EXTI14, /**< EXTI line 14 */
EXTI15, /**< EXTI line 15 */
} exti_num;
/**
* @brief EXTI port configuration
*
* These specify which GPIO port an external interrupt line should be
* connected to.
*/
typedef enum exti_cfg {
EXTI_PA, /**< Use PAx pin */
EXTI_PB, /**< Use PBx pin */
EXTI_PC, /**< Use PCx pin */
EXTI_PD, /**< Use PDx pin */
EXTI_PE, /**< Use PEx pin */
EXTI_PF, /**< Use PFx pin */
EXTI_PG, /**< Use PGx pin */
EXTI_PH, /**< Use PHx pin */
EXTI_PI, /**< Use PIx pin */
} exti_cfg;
/** External interrupt trigger mode */
typedef enum exti_trigger_mode {
EXTI_RISING, /**< Trigger on the rising edge */
EXTI_FALLING, /**< Trigger on the falling edge */
EXTI_RISING_FALLING /**< Trigger on both the rising and falling edges */
} exti_trigger_mode;
/*
* Routines
*/
void exti_attach_interrupt(exti_num num,
exti_cfg port,
voidFuncPtr handler,
exti_trigger_mode mode);
void exti_attach_callback(exti_num num,
exti_cfg port,
voidArgumentFuncPtr handler,
void *arg,
exti_trigger_mode mode);
void exti_detach_interrupt(exti_num num);
/**
* @brief Set the GPIO port for an EXTI line.
*
* This is a low-level routine that most users will not
* need. exti_attach_interrupt() handles calling this function
* appropriately.
*
* @param num EXTI line
* @param port EXTI configuration for GPIO port to connect to num.
* @see exti_num
* @see exti_cfg
*/
extern void exti_select(exti_num num, exti_cfg port);
#ifdef __cplusplus
} // extern "C"
#endif
#endif

View File

@@ -0,0 +1,107 @@
/******************************************************************************
* The MIT License
*
* 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/include/libmaple/flash.h
* @brief Flash support.
*/
#ifndef _LIBMAPLE_FLASH_H_
#define _LIBMAPLE_FLASH_H_
#ifdef __cplusplus
extern "C"{
#endif
#include <libmaple/libmaple_types.h>
#define FLASH_WAIT_STATE_0 0x0
#define FLASH_WAIT_STATE_1 0x1
#define FLASH_WAIT_STATE_2 0x2
#define FLASH_WAIT_STATE_3 0x3
#define FLASH_WAIT_STATE_4 0x4
#define FLASH_WAIT_STATE_5 0x5
#define FLASH_WAIT_STATE_6 0x6
#define FLASH_WAIT_STATE_7 0x7
/* The series header must define:
*
* - FLASH_SAFE_WAIT_STATES, the smallest number of wait states that
* it is safe to use when SYSCLK is at its fastest documented rate
* and the MCU is powered at 3.3V (i.e. this doesn't consider
* overclocking or low voltage operation).
*
* - The following bit flags, for flash_enable_features():
*
* -- FLASH_PREFETCH: prefetcher
* -- FLASH_ICACHE: instruction cache
* -- FLASH_DCACHE: data cache
*
* See that function's Doxygen for more restrictions.
*/
/* Roger clark. Replaced with line below #include <series/flash.h>*/
#include "stm32f1/include/series/flash.h"
#ifdef __DOXYGEN__
/** Flash register map base pointer. */
#define FLASH_BASE
#endif
/*
* Flash routines
*/
void flash_set_latency(uint32 wait_states);
/**
* @brief Enable Flash memory features
*
* If the target MCU doesn't provide a feature (e.g. instruction and
* data caches on the STM32F1), the flag will be ignored. This allows
* using these flags unconditionally, with the desired effect taking
* place on targets that support them.
*
* @param feature_flags Bitwise OR of the following:
* FLASH_PREFETCH (turns on prefetcher),
* FLASH_ICACHE (turns on instruction cache),
* FLASH_DCACHE (turns on data cache).
*/
static inline void flash_enable_features(uint32 feature_flags) {
FLASH_BASE->ACR |= feature_flags;
}
/**
* @brief Deprecated. Use flash_enable_features(FLASH_PREFETCH) instead.
*/
static inline void flash_enable_prefetch(void) {
flash_enable_features(FLASH_PREFETCH);
}
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -0,0 +1,340 @@
/******************************************************************************
* The MIT License
*
* Copyright (c) 2010 Bryan Newbold.
*
* 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/include/libmaple/fsmc.h
* @brief Flexible static memory controller support.
*/
/*
* See ../notes/fsmc.txt for more info
*/
#ifndef _LIBMAPLE_FSMC_H_
#define _LIBMAPLE_FSMC_H_
#ifdef __cplusplus
extern "C"{
#endif
#include <libmaple/libmaple_types.h>
#include <libmaple/stm32.h>
#if !STM32_HAVE_FSMC
#error "FSMC is unavailable on your MCU"
#endif
/*
* Register maps and devices
*/
/** FSMC register map type */
typedef struct fsmc_reg_map {
__io uint32 BCR1; /**< SRAM/NOR-Flash chip-select control register 1 */
__io uint32 BTR1; /**< SRAM/NOR-Flash chip-select timing register 1 */
__io uint32 BCR2; /**< SRAM/NOR-Flash chip-select control register 2 */
__io uint32 BTR2; /**< SRAM/NOR-Flash chip-select timing register 2 */
__io uint32 BCR3; /**< SRAM/NOR-Flash chip-select control register 3 */
__io uint32 BTR3; /**< SRAM/NOR-Flash chip-select timing register 3 */
__io uint32 BCR4; /**< SRAM/NOR-Flash chip-select control register 4 */
__io uint32 BTR4; /**< SRAM/NOR-Flash chip-select timing register 4 */
const uint8 RESERVED1[64]; /**< Reserved */
__io uint32 PCR2; /**< PC Card/NAND Flash control register 2 */
__io uint32 SR2; /**< FIFO status and interrupt register 2 */
__io uint32 PMEM2; /**< Common memory space timing register 2 */
__io uint32 PATT2; /**< Attribute memory space timing register 2 */
const uint8 RESERVED2[4]; /**< Reserved */
__io uint32 ECCR2; /**< ECC result register 2 */
const uint8 RESERVED3[2];
__io uint32 PCR3; /**< PC Card/NAND Flash control register 3 */
__io uint32 SR3; /**< FIFO status and interrupt register 3 */
__io uint32 PMEM3; /**< Common memory space timing register 3 */
__io uint32 PATT3; /**< Attribute memory space timing register 3 */
const uint32 RESERVED4; /**< Reserved */
__io uint32 ECCR3; /**< ECC result register 3 */
const uint8 RESERVED5[8]; /**< Reserved */
__io uint32 PCR4; /**< PC Card/NAND Flash control register 4 */
__io uint32 SR4; /**< FIFO status and interrupt register 4 */
__io uint32 PMEM4; /**< Common memory space timing register 4 */
__io uint32 PATT4; /**< Attribute memory space timing register 4 */
__io uint32 PIO4; /**< I/O space timing register 4 */
const uint8 RESERVED6[80]; /**< Reserved */
__io uint32 BWTR1; /**< SRAM/NOR-Flash write timing register 1 */
const uint32 RESERVED7; /**< Reserved */
__io uint32 BWTR2; /**< SRAM/NOR-Flash write timing register 2 */
const uint32 RESERVED8; /**< Reserved */
__io uint32 BWTR3; /**< SRAM/NOR-Flash write timing register 3 */
const uint32 RESERVED9; /**< Reserved */
__io uint32 BWTR4; /**< SRAM/NOR-Flash write timing register 4 */
} __attribute__((packed)) fsmc_reg_map;
#define __FSMCB 0xA0000000
/** FSMC register map base pointer */
#define FSMC_BASE ((struct fsmc_reg_map*)__FSMCB)
/** FSMC NOR/PSRAM register map type */
typedef struct fsmc_nor_psram_reg_map {
__io uint32 BCR; /**< Chip-select control register */
__io uint32 BTR; /**< Chip-select timing register */
const uint8 RESERVED[252]; /**< Reserved */
__io uint32 BWTR; /**< Write timing register */
} fsmc_nor_psram_reg_map;
/** FSMC NOR/PSRAM base pointer 1 */
#define FSMC_NOR_PSRAM1_BASE ((struct fsmc_nor_psram_reg_map*)__FSMCB)
/** FSMC NOR/PSRAM base pointer 2 */
#define FSMC_NOR_PSRAM2_BASE ((struct fsmc_nor_psram_reg_map*)(__FSMCB + 0x8))
/** FSMC NOR/PSRAM base pointer 3 */
#define FSMC_NOR_PSRAM3_BASE ((struct fsmc_nor_psram_reg_map*)(__FSMCB + 0x10))
/** FSMC NOR/PSRAM base pointer 4 */
#define FSMC_NOR_PSRAM4_BASE ((struct fsmc_nor_psram_reg_map*)(__FSMCB + 0x18))
/*
* Register bit definitions
*/
/* NOR/PSRAM chip-select control registers */
#define FSMC_BCR_CBURSTRW_BIT 19
#define FSMC_BCR_ASYNCWAIT_BIT 15
#define FSMC_BCR_EXTMOD_BIT 14
#define FSMC_BCR_WAITEN_BIT 13
#define FSMC_BCR_WREN_BIT 12
#define FSMC_BCR_WAITCFG_BIT 11
#define FSMC_BCR_WRAPMOD_BIT 10
#define FSMC_BCR_WAITPOL_BIT 9
#define FSMC_BCR_BURSTEN_BIT 8
#define FSMC_BCR_FACCEN_BIT 6
#define FSMC_BCR_MUXEN_BIT 1
#define FSMC_BCR_MBKEN_BIT 0
#define FSMC_BCR_CBURSTRW (1U << FSMC_BCR_CBURSTRW_BIT)
#define FSMC_BCR_ASYNCWAIT (1U << FSMC_BCR_ASYNCWAIT_BIT)
#define FSMC_BCR_EXTMOD (1U << FSMC_BCR_EXTMOD_BIT)
#define FSMC_BCR_WAITEN (1U << FSMC_BCR_WAITEN_BIT)
#define FSMC_BCR_WREN (1U << FSMC_BCR_WREN_BIT)
#define FSMC_BCR_WAITCFG (1U << FSMC_BCR_WAITCFG_BIT)
#define FSMC_BCR_WRAPMOD (1U << FSMC_BCR_WRAPMOD_BIT)
#define FSMC_BCR_WAITPOL (1U << FSMC_BCR_WAITPOL_BIT)
#define FSMC_BCR_BURSTEN (1U << FSMC_BCR_BURSTEN_BIT)
#define FSMC_BCR_FACCEN (1U << FSMC_BCR_FACCEN_BIT)
#define FSMC_BCR_MWID (0x3 << 4)
#define FSMC_BCR_MWID_8BITS (0x0 << 4)
#define FSMC_BCR_MWID_16BITS (0x1 << 4)
#define FSMC_BCR_MTYP (0x3 << 2)
#define FSMC_BCR_MTYP_SRAM (0x0 << 2)
#define FSMC_BCR_MTYP_PSRAM (0x1 << 2)
#define FSMC_BCR_MTYP_NOR_FLASH (0x2 << 2)
#define FSMC_BCR_MUXEN (1U << FSMC_BCR_MUXEN_BIT)
#define FSMC_BCR_MBKEN (1U << FSMC_BCR_MBKEN_BIT)
/* SRAM/NOR-Flash chip-select timing registers */
#define FSMC_BTR_ACCMOD (0x3 << 28)
#define FSMC_BTR_ACCMOD_A (0x0 << 28)
#define FSMC_BTR_ACCMOD_B (0x1 << 28)
#define FSMC_BTR_ACCMOD_C (0x2 << 28)
#define FSMC_BTR_ACCMOD_D (0x3 << 28)
#define FSMC_BTR_DATLAT (0xF << 24)
#define FSMC_BTR_CLKDIV (0xF << 20)
#define FSMC_BTR_BUSTURN (0xF << 16)
#define FSMC_BTR_DATAST (0xFF << 8)
#define FSMC_BTR_ADDHLD (0xF << 4)
#define FSMC_BTR_ADDSET 0xF
/* SRAM/NOR-Flash write timing registers */
#define FSMC_BWTR_ACCMOD (0x3 << 28)
#define FSMC_BWTR_ACCMOD_A (0x0 << 28)
#define FSMC_BWTR_ACCMOD_B (0x1 << 28)
#define FSMC_BWTR_ACCMOD_C (0x2 << 28)
#define FSMC_BWTR_ACCMOD_D (0x3 << 28)
#define FSMC_BWTR_DATLAT (0xF << 24)
#define FSMC_BWTR_CLKDIV (0xF << 20)
#define FSMC_BWTR_DATAST (0xFF << 8)
#define FSMC_BWTR_ADDHLD (0xF << 4)
#define FSMC_BWTR_ADDSET 0xF
/* NAND Flash/PC Card controller registers */
#define FSMC_PCR_ECCEN_BIT 6
#define FSMC_PCR_PTYP_BIT 3
#define FSMC_PCR_PBKEN_BIT 2
#define FSMC_PCR_PWAITEN_BIT 1
#define FSMC_PCR_ECCPS (0x7 << 17)
#define FSMC_PCR_ECCPS_256B (0x0 << 17)
#define FSMC_PCR_ECCPS_512B (0x1 << 17)
#define FSMC_PCR_ECCPS_1024B (0x2 << 17)
#define FSMC_PCR_ECCPS_2048B (0x3 << 17)
#define FSMC_PCR_ECCPS_4096B (0x4 << 17)
#define FSMC_PCR_ECCPS_8192B (0x5 << 17)
#define FSMC_PCR_TAR (0xF << 13)
#define FSMC_PCR_TCLR (0xF << 9)
#define FSMC_PCR_ECCEN (1U << FSMC_PCR_ECCEN_BIT)
#define FSMC_PCR_PWID (0x3 << 4)
#define FSMC_PCR_PWID_8BITS (0x0 << 4)
#define FSMC_PCR_PWID_16BITS (0x1 << 4)
#define FSMC_PCR_PTYP (1U << FSMC_PCR_PTYP_BIT)
#define FSMC_PCR_PTYP_PC_CF_PCMCIA (0x0 << FSMC_PCR_PTYP_BIT)
#define FSMC_PCR_PTYP_NAND (0x1 << FSMC_PCR_PTYP_BIT)
#define FSMC_PCR_PBKEN (1U << FSMC_PCR_PBKEN_BIT)
#define FSMC_PCR_PWAITEN (1U << FSMC_PCR_PWAITEN_BIT)
/* FIFO status and interrupt registers */
#define FSMC_SR_FEMPT_BIT 6
#define FSMC_SR_IFEN_BIT 5
#define FSMC_SR_ILEN_BIT 4
#define FSMC_SR_IREN_BIT 3
#define FSMC_SR_IFS_BIT 2
#define FSMC_SR_ILS_BIT 1
#define FSMC_SR_IRS_BIT 0
#define FSMC_SR_FEMPT (1U << FSMC_SR_FEMPT_BIT)
#define FSMC_SR_IFEN (1U << FSMC_SR_IFEN_BIT)
#define FSMC_SR_ILEN (1U << FSMC_SR_ILEN_BIT)
#define FSMC_SR_IREN (1U << FSMC_SR_IREN_BIT)
#define FSMC_SR_IFS (1U << FSMC_SR_IFS_BIT)
#define FSMC_SR_ILS (1U << FSMC_SR_ILS_BIT)
#define FSMC_SR_IRS (1U << FSMC_SR_IRS_BIT)
/* Common memory space timing registers */
#define FSMC_PMEM_MEMHIZ (0xFF << 24)
#define FSMC_PMEM_MEMHOLD (0xFF << 16)
#define FSMC_PMEM_MEMWAIT (0xFF << 8)
#define FSMC_PMEM_MEMSET 0xFF
/* Attribute memory space timing registers */
#define FSMC_PATT_ATTHIZ (0xFF << 24)
#define FSMC_PATT_ATTHOLD (0xFF << 16)
#define FSMC_PATT_ATTWAIT (0xFF << 8)
#define FSMC_PATT_ATTSET 0xFF
/* I/O space timing register 4 */
#define FSMC_PIO_IOHIZ (0xFF << 24)
#define FSMC_PIO_IOHOLD (0xFF << 16)
#define FSMC_PIO_IOWAIT (0xFF << 8)
#define FSMC_PIO_IOSET 0xFF
/*
* Memory bank boundary addresses
*/
/**
* @brief Void pointer to base address of FSMC memory bank 1 (NOR/PSRAM).
*
* This bank is split into 4 regions. Each region supports interfacing
* with 1 NOR Flash, SRAM, or PSRAM chip. The base addresses of these
* regions are FSMC_NOR_PSRAM_REGIONx, for x = 1, 2, 3, 4.
*/
#define FSMC_BANK1 ((void*)0x60000000)
/**
* @brief Void pointer to base address of FSMC memory bank 1, region 1
* (NOR/PSRAM).
*/
#define FSMC_NOR_PSRAM_REGION1 FSMC_BANK1
/**
* @brief Void pointer to base address of FSMC memory bank 1, region 2
* (NOR/PSRAM).
*/
#define FSMC_NOR_PSRAM_REGION2 ((void*)0x64000000)
/**
* @brief Void pointer to base address of FSMC memory bank 1, region 3
* (NOR/PSRAM).
*/
#define FSMC_NOR_PSRAM_REGION3 ((void*)0x68000000)
/**
* @brief Void pointer to base address of FSMC memory bank 1, region 4
* (NOR/PSRAM).
*/
#define FSMC_NOR_PSRAM_REGION4 ((void*)0x6C000000)
/** Void pointer to base address of FSMC memory bank 2 (NAND Flash). */
#define FSMC_BANK2 ((void*)0x70000000)
/** Void pointer to base address of FSMC memory bank 3 (NAND Flash). */
#define FSMC_BANK3 ((void*)0x80000000)
/**
* @brief Void pointer to base address of FSMC memory bank 4 (PC card
* devices).
*/
#define FSMC_BANK4 ((void*)0x90000000)
/*
* SRAM/NOR Flash routines
*/
/**
* @brief Configure FSMC GPIOs for use with SRAM.
*/
void fsmc_sram_init_gpios(void);
/**
* Set the DATAST bits in the given NOR/PSRAM register map's
* chip-select timing register (FSMC_BTR).
*
* @param regs NOR Flash/PSRAM register map whose chip-select timing
* register to set.
* @param datast Value to use for DATAST bits.
*/
static inline void fsmc_nor_psram_set_datast(fsmc_nor_psram_reg_map *regs,
uint8 datast) {
regs->BTR &= ~FSMC_BTR_DATAST;
regs->BTR |= datast << 8;
}
/**
* Set the ADDHLD bits in the given NOR/PSRAM register map's chip
* select timing register (FSMC_BTRx).
*
* @param regs NOR Flash/PSRAM register map whose chip-select timing
* register to set.
* @param addset Value to use for ADDSET bits.
*/
static inline void fsmc_nor_psram_set_addset(fsmc_nor_psram_reg_map *regs,
uint8 addset) {
regs->BTR &= ~FSMC_BTR_ADDSET;
regs->BTR |= addset & 0xF;
}
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif

View File

@@ -0,0 +1,123 @@
/******************************************************************************
* The MIT License
*
* Copyright (c) 2010 Perry Hung.
* Copyright (c) 2011, 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/include/libmaple/gpio.h
* @brief General Purpose I/O (GPIO) interace.
*/
#ifndef _LIBMAPLE_GPIO_H_
#define _LIBMAPLE_GPIO_H_
#ifdef __cplusplus
extern "C"{
#endif
/*
* Note: Series header must define:
* - enum gpio_pin_mode (TODO think harder about portability here)
*/
// roger clark. replaced with line below #include <series/gpio.h>
#include "stm32f1/include/series/gpio.h"
#include <libmaple/libmaple_types.h>
#include <libmaple/rcc.h>
#include <libmaple/exti.h>
/*
* Device type
*/
/** GPIO device type */
typedef struct gpio_dev {
gpio_reg_map *regs; /**< Register map */
rcc_clk_id clk_id; /**< RCC clock information */
/**
* @brief (Deprecated) External interrupt port.
* Instead of dev->exti_port, use gpio_exti_port(dev).
*/
exti_cfg exti_port;
} gpio_dev;
/*
* Portable routines
*/
void gpio_init(gpio_dev *dev);
void gpio_init_all(void);
/* TODO flags argument version? */
void gpio_set_mode(gpio_dev *dev, uint8 pin, gpio_pin_mode mode);
gpio_pin_mode gpio_get_mode(gpio_dev *dev, uint8 pin);
/**
* @brief Get a GPIO port's corresponding EXTI port configuration.
* @param dev GPIO port whose exti_cfg to return.
*/
static inline exti_cfg gpio_exti_port(gpio_dev *dev) {
return (exti_cfg)(EXTI_PA + (dev->clk_id - RCC_GPIOA));
}
/**
* Set or reset a GPIO pin.
*
* Pin must have previously been configured to output mode.
*
* @param dev GPIO device whose pin to set.
* @param pin Pin on to set or reset
* @param val If true, set the pin. If false, reset the pin.
*/
static inline void gpio_write_bit(gpio_dev *dev, uint8 pin, uint8 val) {
val = !val; /* "set" bits are lower than "reset" bits */
dev->regs->BSRR = (1U << pin) << (16 * val);
}
/**
* Determine whether or not a GPIO pin is set.
*
* Pin must have previously been configured to input mode.
*
* @param dev GPIO device whose pin to test.
* @param pin Pin on dev to test.
* @return True if the pin is set, false otherwise.
*/
static inline uint32 gpio_read_bit(gpio_dev *dev, uint8 pin) {
return dev->regs->IDR & (1U << pin);
}
/**
* Toggle a pin configured as output push-pull.
* @param dev GPIO device.
* @param pin Pin on dev to toggle.
*/
static inline void gpio_toggle_bit(gpio_dev *dev, uint8 pin) {
dev->regs->ODR = dev->regs->ODR ^ (1U << pin);
}
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -0,0 +1,414 @@
/******************************************************************************
* The MIT License
*
* Copyright (c) 2010 Perry Hung.
* 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/include/libmaple/i2c.h
* @brief Inter-Integrated Circuit (I2C) peripheral support
*
* Currently master-only. Usage notes:
*
* - Enable an I2C device with i2c_master_enable().
* - Initialize an array of struct i2c_msg to suit the bus
* transactions (reads/writes) you wish to perform.
* - Call i2c_master_xfer() to do the work.
*/
#ifndef _LIBMAPLE_I2C_H_
#define _LIBMAPLE_I2C_H_
#ifdef __cplusplus
extern "C" {
#endif
/*
* Series header must provide:
*
* - uint32 _i2c_bus_clk(i2c_dev*): Clock frequency of dev's bus, in
* MHz. (This is for internal use only).
*
* - (optional) _I2C_HAVE_IRQ_FIXUP: Leave undefined, or define to 1.
* This is for internal use only. It's a hack to work around a
* silicon bug related to I2C IRQ pre-emption on some targets. If 1,
* the series header must also declare and implement a routine with
* this signature (it may also be provided as a macro):
*
* void _i2c_irq_priority_fixup(i2c_dev*)
*
* This will be called by i2c_enable_irq() before actually enabling
* I2C interrupts.
*
* - Reg. map base pointers, device pointer declarations.
*/
/* Roger clark. Replaced with line below #include <series/i2c.h>*/
#include "stm32f1/include/series/i2c.h"
#include <libmaple/i2c_common.h>
#include <libmaple/libmaple_types.h>
#include <libmaple/rcc.h>
#include <libmaple/nvic.h>
#include <libmaple/gpio.h>
/** I2C register map type */
typedef struct i2c_reg_map {
__io uint32 CR1; /**< Control register 1 */
__io uint32 CR2; /**< Control register 2 */
__io uint32 OAR1; /**< Own address register 1 */
__io uint32 OAR2; /**< Own address register 2 */
__io uint32 DR; /**< Data register */
__io uint32 SR1; /**< Status register 1 */
__io uint32 SR2; /**< Status register 2 */
__io uint32 CCR; /**< Clock control register */
__io uint32 TRISE; /**< TRISE (rise time) register */
} i2c_reg_map;
/**
* @brief I2C message type
*/
typedef struct i2c_msg {
uint16 addr; /**< Address */
#define I2C_MSG_READ 0x1
#define I2C_MSG_10BIT_ADDR 0x2
/**
* Bitwise OR of:
* - I2C_MSG_READ (write is default)
* - I2C_MSG_10BIT_ADDR (7-bit is default) */
uint16 flags;
uint16 length; /**< Message length */
uint16 xferred; /**< Messages transferred */
uint8 *data; /**< Data */
} i2c_msg;
/*
* Register bit definitions
*/
/* Control register 1 */
#define I2C_CR1_SWRST (1U << 15) // Software reset
#define I2C_CR1_ALERT (1U << 13) // SMBus alert
#define I2C_CR1_PEC (1U << 12) // Packet error checking
#define I2C_CR1_POS (1U << 11) // Acknowledge/PEC position
#define I2C_CR1_ACK (1U << 10) // Acknowledge enable
#define I2C_CR1_STOP (1U << 9) // Stop generation
#define I2C_CR1_START (1U << 8) // Start generation
#define I2C_CR1_NOSTRETCH (1U << 7) // Clock stretching disable
#define I2C_CR1_ENGC (1U << 6) // General call enable
#define I2C_CR1_ENPEC (1U << 5) // PEC enable
#define I2C_CR1_ENARP (1U << 4) // ARP enable
#define I2C_CR1_SMBTYPE (1U << 3) // SMBus type
#define I2C_CR1_SMBTYPE_DEVICE (0U << 3) // SMBus type: device
#define I2C_CR1_SMBTYPE_HOST (1U << 3) // SMBus type: host
#define I2C_CR1_SMBUS (1U << 1) // SMBus mode
#define I2C_CR1_SMBUS_I2C (0U << 1) // SMBus mode: I2C
#define I2C_CR1_SMBUS_SMBUS (1U << 1) // SMBus mode: SMBus
#define I2C_CR1_PE (1U << 0) // Peripheral Enable
/* Control register 2 */
#define I2C_CR2_LAST (1U << 12) // DMA last transfer
#define I2C_CR2_DMAEN (1U << 11) // DMA requests enable
#define I2C_CR2_ITBUFEN (1U << 10) // Buffer interrupt enable
#define I2C_CR2_ITEVTEN (1U << 9) // Event interupt enable
#define I2C_CR2_ITERREN (1U << 8) // Error interupt enable
#define I2C_CR2_FREQ 0x3F // Peripheral input frequency
/* Own address register 1 */
#define I2C_OAR1_ADDMODE (1U << 15) // Addressing mode
#define I2C_OAR1_ADDMODE_7_BIT (0U << 15) // Addressing mode: 7-bit
#define I2C_OAR1_ADDMODE_10_BIT (1U << 15) // Addressing mode: 10-bit
#define I2C_OAR1_ADD 0x3FF // Interface address
/* Own address register 2 */
#define I2C_OAR2_ADD2 0xFE // Interface address
#define I2C_OAR2_ENDUAL 1U // Dual addressing mode enable
/* Status register 1 */
#define I2C_SR1_SMBALERT (1U << 15) // SMBus alert
#define I2C_SR1_TIMEOUT (1U << 14) // Timeout or Tlow error
#define I2C_SR1_PECERR (1U << 12) // PEC Error in reception
#define I2C_SR1_OVR (1U << 11) // Overrun/underrun
#define I2C_SR1_AF (1U << 10) // Acknowledge failure
#define I2C_SR1_ARLO (1U << 9) // Arbitration lost
#define I2C_SR1_BERR (1U << 8) // Bus error
#define I2C_SR1_TXE (1U << 7) // Data register empty
#define I2C_SR1_RXNE (1U << 6) // Data register not empty
#define I2C_SR1_STOPF (1U << 4) // Stop detection
#define I2C_SR1_ADD10 (1U << 3) // 10-bit header sent
#define I2C_SR1_BTF (1U << 2) // Byte transfer finished
#define I2C_SR1_ADDR (1U << 1) // Address sent/matched
#define I2C_SR1_SB (1U << 0) // Start bit
/* Status register 2 */
#define I2C_SR2_PEC 0xFF00 // Packet error checking register
#define I2C_SR2_DUALF (1U << 7) // Dual flag
#define I2C_SR2_SMBHOST (1U << 6) // SMBus host header
#define I2C_SR2_SMBDEFAULT (1U << 5) // SMBus device default address
#define I2C_SR2_GENCALL (1U << 4) // General call address
#define I2C_SR2_TRA (1U << 2) // Transmitter/receiver
#define I2C_SR2_BUSY (1U << 1) // Bus busy
#define I2C_SR2_MSL (1U << 0) // Master/slave
/* Clock control register */
#define I2C_CCR_FS (1U << 15) // Fast mode selection
#define I2C_CCR_DUTY (1U << 14) // Fast mode duty cycle
#define I2C_CCR_DUTY_2_1 (0U << 14) // Fast mode duty: 2/1
#define I2C_CCR_DUTY_16_9 (1U << 14) // Fast mode duty: 16/9
#define I2C_CCR_CCR 0xFFF // Clock control bits
/*
* Convenience routines
*/
/* Main I2C API */
/* I2C enable options */
#define I2C_FAST_MODE 0x1 // 400 khz
#define I2C_DUTY_16_9 0x2 // 16/9 duty ratio
/* Flag 0x4 is reserved; DO NOT USE. */
#define I2C_BUS_RESET 0x8 // Perform a bus reset
void i2c_master_enable(i2c_dev *dev, uint32 flags);
#define I2C_ERROR_PROTOCOL (-1)
#define I2C_ERROR_TIMEOUT (-2)
int32 i2c_master_xfer(i2c_dev *dev, i2c_msg *msgs, uint16 num, uint32 timeout);
void i2c_bus_reset(const i2c_dev *dev);
/**
* @brief Disable an I2C device
*
* This function disables the corresponding peripheral and marks dev's
* state as I2C_STATE_DISABLED.
*
* @param dev Device to disable.
*/
static inline void i2c_disable(i2c_dev *dev) {
dev->regs->CR1 &= ~I2C_CR1_PE;
dev->state = I2C_STATE_DISABLED;
}
/* Start/stop conditions */
/**
* @brief Generate a start condition on the bus.
* @param dev I2C device
*/
static inline void i2c_start_condition(i2c_dev *dev) {
uint32 cr1;
while ((cr1 = dev->regs->CR1) & (I2C_CR1_START |
I2C_CR1_STOP |
I2C_CR1_PEC)) {
;
}
dev->regs->CR1 |= I2C_CR1_START;
}
/**
* @brief Generate a stop condition on the bus
* @param dev I2C device
*/
static inline void i2c_stop_condition(i2c_dev *dev) {
uint32 cr1;
while ((cr1 = dev->regs->CR1) & (I2C_CR1_START |
I2C_CR1_STOP |
I2C_CR1_PEC)) {
;
}
dev->regs->CR1 |= I2C_CR1_STOP;
while ((cr1 = dev->regs->CR1) & (I2C_CR1_START |
I2C_CR1_STOP |
I2C_CR1_PEC)) {
;
}
}
/* IRQ enable/disable */
#ifndef _I2C_HAVE_IRQ_FIXUP
/* The series header provides this if _I2C_HAVE_IRQ_FIXUP is defined,
* but we need it either way. */
#define _i2c_irq_priority_fixup(dev) ((void)0)
#endif
#define I2C_IRQ_ERROR I2C_CR2_ITERREN
#define I2C_IRQ_EVENT I2C_CR2_ITEVTEN
#define I2C_IRQ_BUFFER I2C_CR2_ITBUFEN
/**
* @brief Enable one or more I2C interrupts
* @param dev I2C device
* @param irqs Bitwise or of:
* I2C_IRQ_ERROR (error interrupt),
* I2C_IRQ_EVENT (event interrupt), and
* I2C_IRQ_BUFFER (buffer interrupt).
*/
static inline void i2c_enable_irq(i2c_dev *dev, uint32 irqs) {
_i2c_irq_priority_fixup(dev);
dev->regs->CR2 |= irqs;
}
/**
* @brief Disable one or more I2C interrupts
* @param dev I2C device
* @param irqs Bitwise or of:
* I2C_IRQ_ERROR (error interrupt),
* I2C_IRQ_EVENT (event interrupt), and
* I2C_IRQ_BUFFER (buffer interrupt).
*/
static inline void i2c_disable_irq(i2c_dev *dev, uint32 irqs) {
dev->regs->CR2 &= ~irqs;
}
/* ACK/NACK */
/**
* @brief Enable I2C acknowledgment
* @param dev I2C device
*/
static inline void i2c_enable_ack(i2c_dev *dev) {
dev->regs->CR1 |= I2C_CR1_ACK;
}
/**
* @brief Disable I2C acknowledgment
* @param dev I2C device
*/
static inline void i2c_disable_ack(i2c_dev *dev) {
dev->regs->CR1 &= ~I2C_CR1_ACK;
}
/* GPIO control */
/**
* @brief Configure device GPIOs.
*
* Configure GPIO bits dev->sda_pin and dev->scl_pin on GPIO device
* dev->gpio_port for use with I2C device dev.
*
* @param dev I2C Device
* @see i2c_release_gpios()
*/
extern void i2c_config_gpios(const i2c_dev *dev);
/**
* @brief Release GPIOs controlling an I2C bus
*
* Releases the I2C bus controlled by dev as master, and disconnects
* GPIO bits dev->sda_pin and dev->scl_pin on GPIO device
* dev->gpio_port from I2C device dev.
*
* @param dev I2C device
* @see i2c_config_gpios()
*/
extern void i2c_master_release_bus(const i2c_dev *dev);
/* Miscellaneous low-level routines */
void i2c_init(i2c_dev *dev);
/**
* @brief Turn on an I2C peripheral
* @param dev Device to enable
*/
static inline void i2c_peripheral_enable(i2c_dev *dev) {
dev->regs->CR1 |= I2C_CR1_PE;
}
/**
* @brief Turn off an I2C peripheral
* @param dev Device to turn off
*/
static inline void i2c_peripheral_disable(i2c_dev *dev) {
dev->regs->CR1 &= ~I2C_CR1_PE;
}
/**
* @brief Fill transmit register
* @param dev I2C device
* @param byte Byte to write
*/
static inline void i2c_write(i2c_dev *dev, uint8 byte) {
dev->regs->DR = byte;
}
/**
* @brief Set input clock frequency, in MHz
* @param dev I2C device
* @param freq Frequency, in MHz. This must be at least 2, and at most
* the APB frequency of dev's bus. (For example, if
* rcc_dev_clk(dev) == RCC_APB1, freq must be at most
* PCLK1, in MHz). There is an additional limit of 46 MHz.
*/
static inline void i2c_set_input_clk(i2c_dev *dev, uint32 freq) {
#define I2C_MAX_FREQ_MHZ 46
ASSERT(2 <= freq && freq <= _i2c_bus_clk(dev) && freq <= I2C_MAX_FREQ_MHZ);
uint32 cr2 = dev->regs->CR2;
cr2 &= ~I2C_CR2_FREQ;
cr2 |= freq;
dev->regs->CR2 = freq;
#undef I2C_MAX_FREQ_MHZ
}
/**
* @brief Set I2C clock control register.
*
* See the chip reference manual for the details.
*
* @param dev I2C device
* @param val Value to use for clock control register (in
* Fast/Standard mode)
*/
static inline void i2c_set_clk_control(i2c_dev *dev, uint32 val) {
uint32 ccr = dev->regs->CCR;
ccr &= ~I2C_CCR_CCR;
ccr |= val;
dev->regs->CCR = ccr;
}
/**
* @brief Set SCL rise time
* @param dev I2C device
* @param trise Maximum rise time in fast/standard mode (see chip
* reference manual for the relevant formulas).
*/
static inline void i2c_set_trise(i2c_dev *dev, uint32 trise) {
dev->regs->TRISE = trise;
}
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -0,0 +1,93 @@
/******************************************************************************
* The MIT License
*
* Copyright (c) 2010 Perry Hung (from <libmaple/i2c.h>).
* 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/include/libmaple/i2c_common.h
* @author Marti Bolivar <mbolivar@leaflabs.com>
* @brief This file is an implementation detail
*
* CONTENTS UNSTABLE. The existence of this file is an implementation
* detail. Never include it directly. If you need something from
* here, include <libmaple/i2c.h> instead.
*/
#ifndef _LIBMAPLE_I2C_COMMON_H_
#define _LIBMAPLE_I2C_COMMON_H_
#include <libmaple/libmaple_types.h>
#include <libmaple/nvic.h>
#include <libmaple/rcc.h>
struct gpio_dev;
struct i2c_reg_map;
struct i2c_msg;
/** I2C device states */
typedef enum i2c_state {
I2C_STATE_DISABLED = 0, /**< Disabled */
I2C_STATE_IDLE = 1, /**< Idle */
I2C_STATE_XFER_DONE = 2, /**< Done with transfer */
I2C_STATE_BUSY = 3, /**< Busy */
I2C_STATE_ERROR = -1 /**< Error occurred */
} i2c_state;
/**
* @brief I2C device type.
*/
typedef struct i2c_dev {
struct i2c_reg_map *regs; /**< Register map */
struct i2c_msg *msg; /**< Messages */
uint32 error_flags; /**< Error flags, set on I2C error condition */
volatile uint32 timestamp; /**< For internal use */
/**
* @brief Deprecated. Use .scl_port or .sda_port instead.
* If non-null, this will be used as SDA, SCL pins' GPIO port. If
* null, then .sda_port will be used for SDA, and .sda_port for
* SDA. */
struct gpio_dev *gpio_port;
/**
* @brief SDA GPIO device (but see .gpio_port).
*/
struct gpio_dev *sda_port;
/**
* @brief SCL GPIO device (but see .gpio_port).
*/
struct gpio_dev *scl_port;
uint16 msgs_left; /**< Messages left */
uint8 sda_pin; /**< SDA bit on gpio_port */
uint8 scl_pin; /**< SCL bit on gpio_port */
rcc_clk_id clk_id; /**< RCC clock information */
nvic_irq_num ev_nvic_line; /**< Event IRQ number */
nvic_irq_num er_nvic_line; /**< Error IRQ number */
volatile i2c_state state; /**< Device state */
} i2c_dev;
#endif

View File

@@ -0,0 +1,115 @@
/******************************************************************************
* The MIT License
*
* Copyright (c) 2010 Michael Hope.
*
* 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/include/libmaple/iwdg.h
* @author Michael Hope, Marti Bolivar <mbolivar@leaflabs.com>
* @brief Independent watchdog support.
*
* To use the independent watchdog, first call iwdg_init() with the
* appropriate prescaler and IWDG counter reload values for your
* application. Afterwards, you must periodically call iwdg_feed()
* before the IWDG counter reaches 0 to reset the counter to its
* reload value. If you do not, the chip will reset.
*
* Once started, the independent watchdog cannot be turned off.
*/
#ifndef _LIBMAPLE_IWDG_H_
#define _LIBMAPLE_IWDG_H_
#ifdef __cplusplus
extern "C"{
#endif
#include <libmaple/libmaple_types.h>
/*
* Register map
*/
/** Independent watchdog register map type. */
typedef struct iwdg_reg_map {
__io uint32 KR; /**< Key register. */
__io uint32 PR; /**< Prescaler register. */
__io uint32 RLR; /**< Reload register. */
__io uint32 SR; /**< Status register */
} iwdg_reg_map;
/** Independent watchdog base pointer */
#define IWDG_BASE ((struct iwdg_reg_map*)0x40003000)
/*
* Register bit definitions
*/
/* Key register */
#define IWDG_KR_UNLOCK 0x5555
#define IWDG_KR_FEED 0xAAAA
#define IWDG_KR_START 0xCCCC
/* Prescaler register */
#define IWDG_PR_DIV_4 0x0
#define IWDG_PR_DIV_8 0x1
#define IWDG_PR_DIV_16 0x2
#define IWDG_PR_DIV_32 0x3
#define IWDG_PR_DIV_64 0x4
#define IWDG_PR_DIV_128 0x5
#define IWDG_PR_DIV_256 0x6
/* Status register */
#define IWDG_SR_RVU_BIT 1
#define IWDG_SR_PVU_BIT 0
#define IWDG_SR_RVU (1U << IWDG_SR_RVU_BIT)
#define IWDG_SR_PVU (1U << IWDG_SR_PVU_BIT)
/**
* @brief Independent watchdog prescalers.
*
* These divide the 40 kHz IWDG clock.
*/
typedef enum iwdg_prescaler {
IWDG_PRE_4 = IWDG_PR_DIV_4, /**< Divide by 4 */
IWDG_PRE_8 = IWDG_PR_DIV_8, /**< Divide by 8 */
IWDG_PRE_16 = IWDG_PR_DIV_16, /**< Divide by 16 */
IWDG_PRE_32 = IWDG_PR_DIV_32, /**< Divide by 32 */
IWDG_PRE_64 = IWDG_PR_DIV_64, /**< Divide by 64 */
IWDG_PRE_128 = IWDG_PR_DIV_128, /**< Divide by 128 */
IWDG_PRE_256 = IWDG_PR_DIV_256 /**< Divide by 256 */
} iwdg_prescaler;
void iwdg_init(iwdg_prescaler prescaler, uint16 reload);
void iwdg_feed(void);
#ifdef __cplusplus
} // extern "C"
#endif
#endif

View File

@@ -0,0 +1,48 @@
/******************************************************************************
* The MIT License
*
* 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/include/libmaple/libmaple.h
* @brief General include file for libmaple
*/
#ifndef _LIBMAPLE_LIBMAPLE_H_
#define _LIBMAPLE_LIBMAPLE_H_
#ifdef __cplusplus
extern "C" {
#endif
#include <libmaple/libmaple_types.h>
#include <libmaple/stm32.h>
#include <libmaple/util.h>
#include <libmaple/delay.h>
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -0,0 +1,79 @@
/******************************************************************************
* The MIT License
*
* 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/include/libmaple/libmaple_types.h
*
* @brief libmaple's types, and operations on types.
*/
#ifndef _LIBMAPLE_LIBMAPLE_TYPES_H_
#define _LIBMAPLE_LIBMAPLE_TYPES_H_
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
typedef unsigned char uint8;
typedef unsigned short uint16;
typedef uint32_t uint32;
typedef unsigned long long uint64;
typedef signed char int8;
typedef short int16;
typedef int int32;
typedef long long int64;
typedef void (*voidFuncPtr)(void);
typedef void (*voidArgumentFuncPtr)(void *);
#define __io volatile
#define __attr_flash __attribute__((section (".USER_FLASH")))
#define __packed __attribute__((__packed__))
#define __deprecated __attribute__((__deprecated__))
#define __weak __attribute__((weak))
#ifndef __always_inline
#define __always_inline __attribute__((always_inline))
#endif
#ifndef __unused
#define __unused __attribute__((unused))
#endif
#ifndef NULL
#define NULL 0
#endif
#ifndef offsetof
#define offsetof(type, member) __builtin_offsetof(type, member)
#endif
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -0,0 +1,157 @@
/******************************************************************************
* The MIT License
*
* 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/include/libmaple/nvic.h
* @brief Nested vectored interrupt controller support.
*
* Basic usage:
*
* @code
* // Initialise the interrupt controller and point to the vector
* // table at the start of flash.
* nvic_init(0x08000000, 0);
* // Bind in a timer interrupt handler
* timer_attach_interrupt(TIMER_CC1_INTERRUPT, handler);
* // Optionally set the priority
* nvic_irq_set_priority(NVIC_TIMER1_CC, 5);
* // All done, enable all interrupts
* nvic_globalirq_enable();
* @endcode
*/
#ifndef _LIBMAPLE_NVIC_H_
#define _LIBMAPLE_NVIC_H_
#ifdef __cplusplus
extern "C"{
#endif
#include <libmaple/libmaple_types.h>
#include <libmaple/util.h>
/** NVIC register map type. */
typedef struct nvic_reg_map {
__io uint32 ISER[8]; /**< Interrupt Set Enable Registers */
/** Reserved */
uint32 RESERVED0[24];
__io uint32 ICER[8]; /**< Interrupt Clear Enable Registers */
/** Reserved */
uint32 RESERVED1[24];
__io uint32 ISPR[8]; /**< Interrupt Set Pending Registers */
/** Reserved */
uint32 RESERVED2[24];
__io uint32 ICPR[8]; /**< Interrupt Clear Pending Registers */
/** Reserved */
uint32 RESERVED3[24];
__io uint32 IABR[8]; /**< Interrupt Active bit Registers */
/** Reserved */
uint32 RESERVED4[56];
__io uint8 IP[240]; /**< Interrupt Priority Registers */
/** Reserved */
uint32 RESERVED5[644];
__io uint32 STIR; /**< Software Trigger Interrupt Registers */
} nvic_reg_map;
/** NVIC register map base pointer. */
#define NVIC_BASE ((struct nvic_reg_map*)0xE000E100)
/*
* Note: The series header must define enum nvic_irq_num, which gives
* descriptive names to the interrupts and exceptions from NMI (-14)
* to the largest interrupt available in the series, where the value
* for nonnegative enumerators corresponds to its position in the
* vector table.
*
* It also must define a static inline nvic_irq_disable_all(), which
* writes 0xFFFFFFFF to all ICE registers available in the series. (We
* place the include here to give the series header access to
* NVIC_BASE, in order to let it do so).
*/
/* Roger clark. Replaced with line below #include <series/nvic.h>*/
#include "stm32f1/include/series/nvic.h"
void nvic_init(uint32 address, uint32 offset);
void nvic_set_vector_table(uint32 address, uint32 offset);
void nvic_irq_set_priority(nvic_irq_num irqn, uint8 priority);
void nvic_sys_reset();
/**
* Enables interrupts and configurable fault handlers (clear PRIMASK).
*/
static inline __always_inline void nvic_globalirq_enable() {
asm volatile("cpsie i");
}
/**
* Disable interrupts and configurable fault handlers (set PRIMASK).
*/
static inline __always_inline void nvic_globalirq_disable() {
asm volatile("cpsid i");
}
/**
* @brief Enable interrupt irq_num
* @param irq_num Interrupt to enable
*/
static inline void nvic_irq_enable(nvic_irq_num irq_num) {
if (irq_num < 0) {
return;
}
NVIC_BASE->ISER[irq_num / 32] = BIT(irq_num % 32);
}
/**
* @brief Disable interrupt irq_num
* @param irq_num Interrupt to disable
*/
static inline void nvic_irq_disable(nvic_irq_num irq_num) {
if (irq_num < 0) {
return;
}
NVIC_BASE->ICER[irq_num / 32] = BIT(irq_num % 32);
}
/**
* @brief Quickly disable all interrupts.
*
* Calling this function is significantly faster than calling
* nvic_irq_disable() in a loop.
*/
static inline void nvic_irq_disable_all(void);
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -0,0 +1,117 @@
/******************************************************************************
* The MIT License
*
* Copyright (c) 2010 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/include/libmaple/pwr.h
* @brief Power control (PWR).
*/
#ifndef _LIBMAPLE_PWR_H_
#define _LIBMAPLE_PWR_H_
#ifdef __cplusplus
extern "C" {
#endif
#include <libmaple/libmaple.h>
/* Roger clark. Replaced with line below #include <series/pwr.h>*/
#include "stm32f1/include/series/pwr.h"
/** Power interface register map. */
typedef struct pwr_reg_map {
__io uint32 CR; /**< Control register */
__io uint32 CSR; /**< Control and status register */
} pwr_reg_map;
/** Power peripheral register map base pointer. */
#define PWR_BASE ((struct pwr_reg_map*)0x40007000)
/*
* Register bit definitions
*/
/* Control register */
/** Disable backup domain write protection bit */
#define PWR_CR_DBP_BIT 8
/** Power voltage detector enable bit */
#define PWR_CR_PVDE_BIT 4
/** Clear standby flag bit */
#define PWR_CR_CSBF_BIT 3
/** Clear wakeup flag bit */
#define PWR_CR_CWUF_BIT 2
/** Power down deepsleep bit */
#define PWR_CR_PDDS_BIT 1
/** Low-power deepsleep bit */
#define PWR_CR_LPDS_BIT 0
/** Disable backup domain write protection */
#define PWR_CR_DBP (1U << PWR_CR_DBP_BIT)
/** Power voltage detector (PVD) level selection */
#define PWR_CR_PLS (0x7 << 5)
/** Power voltage detector enable */
#define PWR_CR_PVDE (1U << PWR_CR_PVDE_BIT)
/** Clear standby flag */
#define PWR_CR_CSBF (1U << PWR_CR_CSBF_BIT)
/** Clear wakeup flag */
#define PWR_CR_CWUF (1U << PWR_CR_CWUF_BIT)
/** Power down deepsleep */
#define PWR_CR_PDDS (1U << PWR_CR_PDDS_BIT)
/** Low-power deepsleep */
#define PWR_CR_LPDS (1U << PWR_CR_LPDS_BIT)
/* Control and status register */
/** Enable wakeup pin bit */
#define PWR_CSR_EWUP_BIT 8
/** PVD output bit */
#define PWR_CSR_PVDO_BIT 2
/** Standby flag bit */
#define PWR_CSR_SBF_BIT 1
/** Wakeup flag bit */
#define PWR_CSR_WUF_BIT 0
/** Enable wakeup pin */
#define PWR_CSR_EWUP (1U << PWR_CSR_EWUP_BIT)
/** PVD output */
#define PWR_CSR_PVDO (1U << PWR_CSR_PVDO_BIT)
/** Standby flag */
#define PWR_CSR_SBF (1U << PWR_CSR_SBF_BIT)
/** Wakeup flag */
#define PWR_CSR_WUF (1U << PWR_CSR_WUF_BIT)
/*
* Convenience functions
*/
void pwr_init(void);
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -0,0 +1,182 @@
/******************************************************************************
* The MIT License
*
* 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/include/libmaple/rcc.h
* @brief Reset and Clock Control (RCC) interface.
*/
#ifndef _LIBMAPLE_RCC_H_
#define _LIBMAPLE_RCC_H_
#ifdef __cplusplus
extern "C"{
#endif
#include <libmaple/libmaple_types.h>
/* Put the SYSCLK sources before the series header is included, as it
* might need them. */
/**
* @brief SYSCLK sources
* @see rcc_switch_sysclk()
*/
typedef enum rcc_sysclk_src {
RCC_CLKSRC_HSI = 0x0,
RCC_CLKSRC_HSE = 0x1,
RCC_CLKSRC_PLL = 0x2,
} rcc_sysclk_src;
/* Roger clark. Replaced with line below #include <series/rcc.h>*/
#include "stm32f1/include/series/rcc.h"
/* Note: Beyond the usual (registers, etc.), it's up to the series
* header to define the following types:
*
* - enum rcc_clk: Available system and secondary clock sources,
* e.g. RCC_CLK_HSE, RCC_CLK_PLL, RCC_CLK_LSE.
*
* Note that the inclusion of secondary clock sources (like LSI and
* LSE) makes enum rcc_clk different from the SYSCLK sources, which
* are defined in this header as enum rcc_sysclk_src.
*
* IMPORTANT NOTE TO IMPLEMENTORS: If you are adding support for a
* new STM32 series, see the comment near rcc_clk_reg() in
* libmaple/rcc.c for information on how to choose these values so
* that rcc_turn_on_clk() etc. will work on your series.
*
* - enum rcc_clk_id: For each available peripheral. These are widely used
* as unique IDs (TODO extricate from RCC?). Peripherals which are
* common across STM32 series should use the same token for their
* rcc_clk_id in each series header.
*
* - enum rcc_clk_domain: For each clock domain. This is returned by
* rcc_dev_clk(). For instance, each AHB and APB is a clock domain.
*
* - enum rcc_prescaler: And a suitable set of dividers for
* rcc_set_prescaler().
*
* - enum rcc_pllsrc: For each PLL source. Same source, same token.
*
* - A target-dependent type to be pointed to by the data field in a
* struct rcc_pll_cfg.
*/
#ifdef __DOXYGEN__
/** RCC register map base pointer */
#define RCC_BASE
#endif
/* Clock prescaler management. */
/**
* @brief Set the divider on a peripheral prescaler
* @param prescaler prescaler to set
* @param divider prescaler divider
*/
extern void rcc_set_prescaler(rcc_prescaler prescaler, uint32 divider);
/* SYSCLK. */
void rcc_switch_sysclk(rcc_sysclk_src sysclk_src);
/* PLL configuration */
/**
* @brief Specifies a configuration for the main PLL.
*/
typedef struct rcc_pll_cfg {
rcc_pllsrc pllsrc; /**< PLL source */
/** Series-specific configuration data. */
void *data;
} rcc_pll_cfg;
/**
* @brief Configure the main PLL.
*
* You may only call this function while the PLL is disabled.
*
* @param pll_cfg Desired PLL configuration. The contents of this
* struct depend entirely on the target.
*/
extern void rcc_configure_pll(rcc_pll_cfg *pll_cfg);
/* System and secondary clock sources. */
void rcc_turn_on_clk(rcc_clk clock);
void rcc_turn_off_clk(rcc_clk clock);
int rcc_is_clk_on(rcc_clk clock);
int rcc_is_clk_ready(rcc_clk clock);
/* Peripheral clock lines and clock domains. */
/**
* @brief Turn on the clock line on a peripheral
* @param id Clock ID of the peripheral to turn on.
*/
extern void rcc_clk_enable(rcc_clk_id id);
/**
* @brief Reset a peripheral.
*
* Caution: not all rcc_clk_id values refer to a peripheral which can
* be reset. (Only rcc_clk_ids for peripherals with bits in an RCC
* reset register can be used here.)
*
* @param id Clock ID of the peripheral to reset.
*/
extern void rcc_reset_dev(rcc_clk_id id);
rcc_clk_domain rcc_dev_clk(rcc_clk_id id);
/* Clock security system */
/**
* @brief Enable the clock security system (CSS).
*/
static inline void rcc_enable_css() {
RCC_BASE->CR |= RCC_CR_CSSON;
}
/**
* @brief Disable the clock security system (CSS).
*/
static inline void rcc_disable_css() {
RCC_BASE->CR &= ~RCC_CR_CSSON;
}
/**
* @brief Turn off the clock line on a peripheral
* @param id Clock ID of the peripheral to turn on.
*/
extern void rcc_clk_disable(rcc_clk_id id);
#ifdef __cplusplus
} // extern "C"
#endif
#endif

View File

@@ -0,0 +1,208 @@
/******************************************************************************
* The MIT License
*
* Copyright (c) 2011 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/include/libmaple/ring_buffer.h
* @brief Simple circular buffer
*
* This implementation is not thread-safe. In particular, none of
* these functions is guaranteed re-entrant.
*/
#ifndef _LIBMAPLE_RING_BUFFER_H_
#define _LIBMAPLE_RING_BUFFER_H_
#ifdef __cplusplus
extern "C"{
#endif
#include <libmaple/libmaple_types.h>
/**
* Ring buffer type.
*
* The buffer is empty when head == tail.
*
* The buffer is full when the head is one byte in front of the tail,
* modulo buffer length.
*
* One byte is left free to distinguish empty from full. */
typedef struct ring_buffer {
volatile uint8 *buf; /**< Buffer items are stored into */
volatile uint16 head; /**< Index of the next item to remove */
volatile uint16 tail; /**< Index where the next item will get inserted */
volatile uint16 size; /**< Buffer capacity minus one */
} ring_buffer;
/**
* Initialise a ring buffer.
*
* @param rb Instance to initialise
*
* @param size Number of items in buf. The ring buffer will always
* leave one element unoccupied, so the maximum number of
* elements it can store will be size - 1. Thus, size
* must be at least 2.
*
* @param buf Buffer to store items into
*/
static inline void rb_init(ring_buffer *rb, uint16 size, uint8 *buf) {
rb->head = 0;
rb->tail = 0;
rb->size = size - 1;
rb->buf = buf;
}
/**
* @brief Return the number of elements stored in the ring buffer.
* @param rb Buffer whose elements to count.
*/
static inline uint16 rb_full_count(ring_buffer *rb) {
__io ring_buffer *arb = rb;
int32 size = arb->tail - arb->head;
if (arb->tail < arb->head) {
size += arb->size + 1;
}
return (uint16)size;
}
/**
* @brief Returns true if and only if the ring buffer is full.
* @param rb Buffer to test.
*/
static inline int rb_is_full(ring_buffer *rb) {
return (rb->tail + 1 == rb->head) ||
(rb->tail == rb->size && rb->head == 0);
}
/**
* @brief Returns true if and only if the ring buffer is empty.
* @param rb Buffer to test.
*/
static inline int rb_is_empty(ring_buffer *rb) {
return rb->head == rb->tail;
}
/**
* Append element onto the end of a ring buffer.
* @param rb Buffer to append onto.
* @param element Value to append.
*/
static inline void rb_insert(ring_buffer *rb, uint8 element) {
rb->buf[rb->tail] = element;
rb->tail = (rb->tail == rb->size) ? 0 : rb->tail + 1;
}
/**
* @brief Remove and return the first item from a ring buffer.
* @param rb Buffer to remove from, must contain at least one element.
*/
static inline uint8 rb_remove(ring_buffer *rb) {
uint8 ch = rb->buf[rb->head];
rb->head = (rb->head == rb->size) ? 0 : rb->head + 1;
return ch;
}
/*
* Roger Clark. 20141125,
* added peek function.
* @brief Return the first item from a ring buffer, without removing it
* @param rb Buffer to remove from, must contain at least one element.
*/
static inline int rb_peek(ring_buffer *rb)
{
if (rb->head == rb->tail)
{
return -1;
}
else
{
return rb->buf[rb->head];
}
}
/**
* @brief Attempt to remove the first item from a ring buffer.
*
* If the ring buffer is nonempty, removes and returns its first item.
* If it is empty, does nothing and returns a negative value.
*
* @param rb Buffer to attempt to remove from.
*/
static inline int16 rb_safe_remove(ring_buffer *rb) {
return rb_is_empty(rb) ? -1 : rb_remove(rb);
}
/**
* @brief Attempt to insert an element into a ring buffer.
*
* @param rb Buffer to insert into.
* @param element Value to insert into rb.
* @sideeffect If rb is not full, appends element onto buffer.
* @return If element was appended, then true; otherwise, false. */
static inline int rb_safe_insert(ring_buffer *rb, uint8 element) {
if (rb_is_full(rb)) {
return 0;
}
rb_insert(rb, element);
return 1;
}
/**
* @brief Append an item onto the end of a non-full ring buffer.
*
* If the buffer is full, removes its first item, then inserts the new
* element at the end.
*
* @param rb Ring buffer to insert into.
* @param element Value to insert into ring buffer.
* @return On success, returns -1. If an element was popped, returns
* the popped value.
*/
static inline int rb_push_insert(ring_buffer *rb, uint8 element) {
int ret = -1;
if (rb_is_full(rb)) {
ret = rb_remove(rb);
}
rb_insert(rb, element);
return ret;
}
/**
* @brief Discard all items from a ring buffer.
* @param rb Ring buffer to discard all items from.
*/
static inline void rb_reset(ring_buffer *rb) {
rb->tail = rb->head;
}
#ifdef __cplusplus
} // extern "C"
#endif
#endif

View File

@@ -0,0 +1,214 @@
/******************************************************************************
* The MIT License
*
* Copyright (c) 2010 Perry Hung.
* Copyright (c) 2011-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/include/libmaple/scb.h
* @brief System control block header
*/
/*
* FIXME: STM32F2?
*/
#ifndef _LIBMAPLE_SCB_H_
#define _LIBMAPLE_SCB_H_
#ifdef __cplusplus
extern "C" {
#endif
#include <libmaple/libmaple_types.h>
/*
* Register map and base pointer
*/
/** System control block register map type */
typedef struct scb_reg_map {
__io uint32 CPUID; /**< CPU ID Base Register */
__io uint32 ICSR; /**< Interrupt Control State Register */
__io uint32 VTOR; /**< Vector Table Offset Register */
__io uint32 AIRCR; /**< Application Interrupt / Reset Control Register */
__io uint32 SCR; /**< System Control Register */
__io uint32 CCR; /**< Configuration and Control Register */
__io uint8 SHP[12]; /**< System Handler Priority Registers
(4-7, 8-11, 12-15) */
__io uint32 SHCSR; /**< System Handler Control and State Register */
__io uint32 CFSR; /**< Configurable Fault Status Register */
__io uint32 HFSR; /**< Hard Fault Status Register */
/* DFSR is not documented by ST in PM0056 (as of Revision 4), but
* there's a 4 byte hole in the SCB register map docs right where
* it belongs. Since it's specified as "always implemented" in
* the ARM v7-M ARM, I'm assuming its absence is a bug in the ST
* doc, but I haven't proven it. [mbolivar] */
__io uint32 DFSR; /**< Debug Fault Status Register */
__io uint32 MMFAR; /**< Mem Manage Address Register */
__io uint32 BFAR; /**< Bus Fault Address Register */
#if 0
/* The following registers are implementation-defined according to
* ARM v7-M, and I can't find evidence of their existence in ST's
* docs. I'm removing them. Feel free to yell at me if they do
* exist. [mbolivar]
*/
__io uint32 AFSR; /**< Auxiliary Fault Status Register */
__io uint32 PFR[2]; /**< Processor Feature Register */
__io uint32 DFR; /**< Debug Feature Register */
__io uint32 AFR; /**< Auxiliary Feature Register */
__io uint32 MMFR[4]; /**< Memory Model Feature Register */
__io uint32 ISAR[5]; /**< ISA Feature Register */
#endif
} scb_reg_map;
/** System control block register map base pointer */
#define SCB_BASE ((struct scb_reg_map*)0xE000ED00)
/*
* Register bit definitions
*/
/* No SCB_REG_FIELD_BIT macros as the relevant addresses are not in a
* bit-band region. */
/* CPUID base register (SCB_CPUID) */
#define SCB_CPUID_IMPLEMENTER (0xFF << 24)
#define SCB_CPUID_VARIANT (0xF << 20)
#define SCB_CPUID_CONSTANT (0xF << 16)
#define SCB_CPUID_PARTNO (0xFFF << 4)
#define SCB_CPUID_REVISION 0xF
/* Interrupt control state register (SCB_ICSR) */
#define SCB_ICSR_NMIPENDSET (1U << 31)
#define SCB_ICSR_PENDSVSET (1U << 28)
#define SCB_ICSR_PENDSVCLR (1U << 27)
#define SCB_ICSR_PENDSTSET (1U << 26)
#define SCB_ICSR_PENDSTCLR (1U << 25)
#define SCB_ICSR_ISRPENDING (1U << 22)
#define SCB_ICSR_VECTPENDING (0x3FF << 12)
#define SCB_ICSR_RETOBASE (1U << 11)
#define SCB_ICSR_VECTACTIVE 0xFF
/* Vector table offset register (SCB_VTOR) */
#define SCB_VTOR_TBLOFF (0x1FFFFF << 9)
/* Application interrupt and reset control register (SCB_AIRCR) */
#define SCB_AIRCR_VECTKEYSTAT (0x5FA << 16)
#define SCB_AIRCR_VECTKEY (0x5FA << 16)
#define SCB_AIRCR_ENDIANNESS (1U << 15)
#define SCB_AIRCR_PRIGROUP (0x3 << 8)
#define SCB_AIRCR_SYSRESETREQ (1U << 2)
#define SCB_AIRCR_VECTCLRACTIVE (1U << 1)
#define SCB_AIRCR_VECTRESET (1U << 0)
/* System control register (SCB_SCR) */
#define SCB_SCR_SEVONPEND (1U << 4)
#define SCB_SCR_SLEEPDEEP (1U << 2)
#define SCB_SCR_SLEEPONEXIT (1U << 1)
/* Configuration and Control Register (SCB_CCR) */
#define SCB_CCR_STKALIGN (1U << 9)
#define SCB_CCR_BFHFNMIGN (1U << 8)
#define SCB_CCR_DIV_0_TRP (1U << 4)
#define SCB_CCR_UNALIGN_TRP (1U << 3)
#define SCB_CCR_USERSETMPEND (1U << 1)
#define SCB_CCR_NONBASETHRDENA (1U << 0)
/* System handler priority registers (SCB_SHPRx) */
#define SCB_SHPR1_PRI6 (0xFF << 16)
#define SCB_SHPR1_PRI5 (0xFF << 8)
#define SCB_SHPR1_PRI4 0xFF
#define SCB_SHPR2_PRI11 (0xFF << 24)
#define SCB_SHPR3_PRI15 (0xFF << 24)
#define SCB_SHPR3_PRI14 (0xFF << 16)
/* System Handler Control and state register (SCB_SHCSR) */
#define SCB_SHCSR_USGFAULTENA (1U << 18)
#define SCB_SHCSR_BUSFAULTENA (1U << 17)
#define SCB_SHCSR_MEMFAULTENA (1U << 16)
#define SCB_SHCSR_SVCALLPENDED (1U << 15)
#define SCB_SHCSR_BUSFAULTPENDED (1U << 14)
#define SCB_SHCSR_MEMFAULTPENDED (1U << 13)
#define SCB_SHCSR_USGFAULTPENDED (1U << 12)
#define SCB_SHCSR_SYSTICKACT (1U << 11)
#define SCB_SHCSR_PENDSVACT (1U << 10)
#define SCB_SHCSR_MONITORACT (1U << 8)
#define SCB_SHCSR_SVCALLACT (1U << 7)
#define SCB_SHCSR_USGFAULTACT (1U << 3)
#define SCB_SHCSR_BUSFAULTACT (1U << 1)
#define SCB_SHCSR_MEMFAULTACT (1U << 0)
/* Configurable fault status register (SCB_CFSR) */
#define SCB_CFSR_DIVBYZERO (1U << 25)
#define SCB_CFSR_UNALIGNED (1U << 24)
#define SCB_CFSR_NOCP (1U << 19)
#define SCB_CFSR_INVPC (1U << 18)
#define SCB_CFSR_INVSTATE (1U << 17)
#define SCB_CFSR_UNDEFINSTR (1U << 16)
#define SCB_CFSR_BFARVALID (1U << 15)
#define SCB_CFSR_STKERR (1U << 12)
#define SCB_CFSR_UNSTKERR (1U << 11)
#define SCB_CFSR_IMPRECISERR (1U << 10)
#define SCB_CFSR_PRECISERR (1U << 9)
#define SCB_CFSR_IBUSERR (1U << 8)
#define SCB_CFSR_MMARVALID (1U << 7)
#define SCB_CFSR_MSTKERR (1U << 4)
#define SCB_CFSR_MUNSTKERR (1U << 3)
#define SCB_CFSR_DACCVIOL (1U << 1)
#define SCB_CFSR_IACCVIOL (1U << 0)
/* Hard Fault Status Register (SCB_HFSR) */
#define SCB_HFSR_DEBUG_VT (1U << 31)
#define SCB_CFSR_FORCED (1U << 30)
#define SCB_CFSR_VECTTBL (1U << 1)
/* Debug Fault Status Register */
/* Not specified by PM0056, but required by ARM. The bit definitions
* here are based on the names given in the ARM v7-M ARM. */
#define SCB_DFSR_EXTERNAL (1U << 4)
#define SCB_DFSR_VCATCH (1U << 3)
#define SCB_DFSR_DWTTRAP (1U << 2)
#define SCB_DFSR_BKPT (1U << 1)
#define SCB_DFSR_HALTED (1U << 0)
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -0,0 +1,270 @@
/******************************************************************************
*
* 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 sdio.h
* @brief Secure digital input/output interface.
*/
#ifndef _SDIO_H_
#define _SDIO_H_
#include <libmaple/libmaple_types.h>
#include <libmaple/stm32.h>
#include <libmaple/gpio.h>
/*
#include <libmaple/rcc.h>
#include <libmaple/nvic.h>
//#include <boards.h>
#include <stdint.h>
//#include <wirish.h>
*/
#if defined(STM32_HIGH_DENSITY) || defined(STM32_XL_DENSITY)
/*
* DMA controller and channel used in STM32F103
*/
#define SDIO_DMA_DEV DMA2
#define SDIO_DMA_CHANNEL DMA_CH4
/*
#ifdef __cplusplus
extern "C" {
#endif
*/
/*
* Register maps and devices
*/
// SDIO register map type
typedef struct sdio_reg_map {
__io uint32 POWER; // 0x00
__io uint32 CLKCR; // 0x04
__io uint32 ARG; // 0x08
__io uint32 CMD; // 0x0C
__io uint32 RESPCMD; // 0x10 (0x3F)
const uint32 RESP[4]; // 0x14 - contain the card status, which is part of the received response.
__io uint32 DTIMER; // 0x24 - contains the data timeout period, in card bus clock periods.
__io uint32 DLEN; // 0x28 (0x01FF FFFF) - contains the number of data bytes to be transferred
__io uint32 DCTRL; // 0x2C
__io uint32 DCOUNT; // 0x30 (0x01FF FFFF)
__io uint32 STA; // 0x34
__io uint32 ICR; // 0x38
__io uint32 MASK; // 0x3C
const uint32 RESERVED1[2];
__io uint32 FIFOCNT; // 0x48 (0x01FF FFFF)
const uint32 RESERVED2[13];
__io uint32 FIFO; // 0x80
} sdio_reg_map;
#define sdio_dev sdio_reg_map
/** SDIO register map base pointer */
#define SDIO_BASE ((struct sdio_reg_map*)0x40018000)
extern sdio_dev * SDIO;
/*
* Register bit definitions
*/
/* NOR/PSRAM chip-select control registers */
// SDIO_POWER register bits
// At least seven HCLK clock periods are needed between two write accesses to this register.
// After a data write, data cannot be written to this register for three SDIOCLK clock periods
// plus two PCLK2 clock periods.
#define SDIO_POWER_PWRCTRL_OFF 0x00
#define SDIO_POWER_PWRCTRL_ON 0x03
// SDIO_CLKCR register bits
// Controls the SDIO_CK output clock.
// After a data write, data cannot be written to this register for three SDIOCLK clock periods
// plus two PCLK2 clock periods. SDIO_CK can also be stopped during the read wait interval
// for SD I/O cards: in this case the SDIO_CLKCR register does not control SDIO_CK.
#define SDIO_CLKCR_HWFC_EN (1<<14) // HW Flow Control enable - DON'T USE!!! (see errata sheet 2.12.1)
// Overrun errors (Rx mode) and FIFO underrun (Tx mode)
// should be managed by the application software.
#define SDIO_CLKCR_NEGEDGE (1<<13) // SDIO_CK de-phasing selection bit - DON'T USE!!! (see errata sheet 2.12.4)
#define SDIO_CLKCR_WIDBUS (3<<11) // Data bus width
#define SDIO_CLKCR_WIDBUS_1BIT (0<<11) // 1 bit (SDIO_D0 used)
#define SDIO_CLKCR_WIDBUS_4BIT (1<<11) // 4-bit (SDIO_D[3:0] used)
#define SDIO_CLKCR_BYPASS (1<<10) // Clock divider bypass enable bit - SDIO_CK = SDIOCLK, CLKDIV not relevant.
#define SDIO_CLKCR_PWRSAV (1<<9) // 0: SDIO_CK clock is always enabled, 1: SDIO_CK is only enabled when the bus is active
#define SDIO_CLKCR_CLKEN (1<<8) // Clock enable
#define SDIO_CLKCR_CLKDIV (0xFF) // SDIO_CK = SDIOCLK / [CLKDIV + 2]
#define SDIOCLK 72000000UL // SDIO master clock frequency
// SDIO_CMD register bits
// After a data write, data cannot be written to this register for three SDIOCLK clock periods
// plus two PCLK2 clock periods.
// MultiMediaCards can send two kinds of response: short responses, 48 bits long, or long
// responses,136 bits long. SD card and SD I/O card can send only short responses, the
// argument can vary according to the type of response: the software will distinguish the type
// of response according to the sent command. CE-ATA devices send only short responses.
#define SDIO_CMD_ATACMD (1<<14)
#define SDIO_CMD_NIEN (1<<13)
#define SDIO_CMD_ENCMDCOMPL (1<<12)
#define SDIO_CMD_SDIOSUSPEND (1<<11)
#define SDIO_CMD_CPSMEN (1<<10)
#define SDIO_CMD_WAITPEND (1<<9)
#define SDIO_CMD_WAITINT (1<<8)
#define SDIO_CMD_WAITRESP (3<<6)
#define SDIO_CMD_WAIT_NO_RESP (0<<6)
#define SDIO_CMD_WAIT_SHORT_RESP (1<<6)
#define SDIO_CMD_WAIT_LONG_RESP (3<<6)
#define SDIO_CMD_CMDINDEX (0x3F)
// SDIO_DLEN register bits
// For a block data transfer, the value in the data length register must be a multiple of the block
// size (see SDIO_DCTRL). A data transfer must be written to the data timer register and the
// data length register before being written to the data control register.
// For an SDIO multibyte transfer the value in the data length register must be between 1 and 512.
#define SDIO_DLEN_DATALENGTH (0x01FFFFFF)
// SDIO_DCTRL register bits
// Controls the data path state machine (DPSM).
// After a data write, data cannot be written to this register for three SDIOCLK clock periods
// plus two PCLK2 clock periods.
#define SDIO_DCTRL_SDIOEN (1<<11) // the DPSM performs an SD I/O-card-specific operation.
#define SDIO_DCTRL_RWMODE (1<<10) // 0: Read Wait control stopping SDIO_D2, 1:Read Wait control using SDIO_CK
#define SDIO_DCTRL_RWSTOP (1<<9) // 0: Read wait in progress if RWSTART bit is set, 1: Enable for read wait stop if RWSTART bit is set
#define SDIO_DCTRL_RWSTART (1<<8) // read wait operation starts
#define SDIO_DCTRL_DBLOCKSIZE (0xF<<4) // Define the data block length when the block data transfer mode is selected: 2^N bytes
#define SDIO_BLOCKSIZE_64 (6<<4)
#define SDIO_BLOCKSIZE_512 (9<<4)
#define SDIO_DCTRL_DMAEN (1<<3) // DMA enable
#define SDIO_DCTRL_DTMODE (1<<2) // Data transfer mode selection: 0: Block data transfer, 1: Stream or SDIO multi-byte data transfer
#define SDIO_DCTRL_DTDIR (1<<1) // Data transfer direction selection: 0: From controller to card, 1: From card to controller.
#define SDIO_DIR_TX (0<<1)
#define SDIO_DIR_RX (1<<1)
#define SDIO_DCTRL_DTEN (1<<0) // Start data transfer. Depending on the direction bit, DTDIR,
// the DPSM moves to the Wait_S, Wait_R state or Readwait if RW Start is set immediately at
// the beginning of the transfer. It is not necessary to clear the enable bit after the end of a data
// transfer but the SDIO_DCTRL must be updated to enable a new data transfer
// The meaning of the DTMODE bit changes according to the value of the SDIOEN bit:
// When DTEN=0 and DTMODE=1, the MultiMediaCard stream mode is enabled.
// When DTEN=1 and DTMODE=1, the peripheral enables an SDIO multi-byte transfer.
// SDIO_STA register bits
#define SDIO_STA_CEATAEND (1<<23) // CE-ATA command completion signal received for CMD61
#define SDIO_STA_SDIOIT (1<<22) // SDIO interrupt received
#define SDIO_STA_RXDAVL (1<<21) // Data available in receive FIFO
#define SDIO_STA_TXDAVL (1<<20) // Data available in transmit FIFO
#define SDIO_STA_RXFIFOE (1<<19) // Receive FIFO empty
#define SDIO_STA_TXFIFOE (1<<18) // Transmit FIFO empty (2 words)
#define SDIO_STA_RXFIFOF (1<<17) // Receive FIFO full (2 words before the FIFO is full.)
#define SDIO_STA_TXFIFOF (1<<16) // Transmit FIFO full
#define SDIO_STA_RXFIFOHF (1<<15) // Receive FIFO half full: there are at least 8 words in the FIFO
#define SDIO_STA_TXFIFOHE (1<<14) // Transmit FIFO half empty: at least 8 words can be written into the FIFO
#define SDIO_STA_RXACT (1<<13) // Data receive in progress
#define SDIO_STA_TXACT (1<<12) // Data transmit in progress
#define SDIO_STA_CMDACT (1<<11) // Command transfer in progress
#define SDIO_STA_DBCKEND (1<<10) // Data block sent/received (CRC check passed)
#define SDIO_STA_STBITERR (1<<9) // Start bit not detected on all data signals in wide bus mode
#define SDIO_STA_DATAEND (1<<8) // Data end (data counter SDIOCOUNT is zero)
#define SDIO_STA_CMDSENT (1<<7) // Command sent (no response required)
#define SDIO_STA_CMDREND (1<<6) // Command response received (CRC check passed)
#define SDIO_STA_RXOVERR (1<<5) // Received FIFO overrun error
#define SDIO_STA_TXUNDERR (1<<4) // Transmit FIFO underrun error
#define SDIO_STA_DTIMEOUT (1<<3) // Data timeout
#define SDIO_STA_CTIMEOUT (1<<2) // Command response timeout. The Command TimeOut period has a fixed value of 64 SDIO_CK clock periods.
#define SDIO_STA_DCRCFAIL (1<<1) // Data block sent/received (CRC check failed)
#define SDIO_STA_CCRCFAIL (1<<0) // Command response received (CRC check failed)
#define SDIO_STA_CMD_ERROR_FLAGS (SDIO_STA_CTIMEOUT | SDIO_STA_CCRCFAIL)
#define SDIO_STA_TRX_ERROR_FLAGS (SDIO_STA_STBITERR | SDIO_STA_RXOVERR | SDIO_STA_TXUNDERR | SDIO_STA_DTIMEOUT | SDIO_STA_DCRCFAIL)
#define SDIO_STA_TRX_ACT_FLAGS (SDIO_STA_RXACT|SDIO_STA_TXACT)
// SDIO_ICR register bits (WO - write only)
#define SDIO_ICR_CEATAENDC (1<<23) // clear CEATAEND flag
#define SDIO_ICR_SDIOITC (1<<22) // clear SDIOIT flag
#define SDIO_ICR_DBCKENDC (1<<10) // clear DBCKENDC flag
#define SDIO_ICR_STBITERRC (1<<9) // clear STBITERRC flag
#define SDIO_ICR_DATAENDC (1<<8) // clear DATAENDC flag
#define SDIO_ICR_CMDSENTC (1<<7) // clear CMDSENTC flag
#define SDIO_ICR_CMDRENDC (1<<6) // clear CMDREND flag
#define SDIO_ICR_RXOVERRC (1<<5) // clear RXOVERR flag
#define SDIO_ICR_TXUNDERRC (1<<4) // clear TXUNDERR flag
#define SDIO_ICR_DTIMEOUTC (1<<3) // clear DTIMEOUT flag
#define SDIO_ICR_CTIMEOUTC (1<<2) // clear CTIMEOUT flag
#define SDIO_ICR_DCRCFAILC (1<<1) // clear DCRCFAIL flag
#define SDIO_ICR_CCRCFAILC (1<<0) // clear CCRCFAIL flag
#define SDIO_ICR_CMD_FLAGS (SDIO_ICR_CEATAENDC | SDIO_ICR_SDIOITC | SDIO_ICR_CMDSENTC | SDIO_ICR_CMDRENDC | SDIO_ICR_CTIMEOUTC | SDIO_ICR_CCRCFAILC)
#define SDIO_ICR_DATA_FLAGS (SDIO_ICR_DBCKENDC | SDIO_ICR_STBITERRC | SDIO_ICR_DATAENDC | SDIO_ICR_RXOVERRC | SDIO_ICR_TXUNDERRC | SDIO_ICR_DTIMEOUTC | SDIO_ICR_DCRCFAILC)
// SDIO_MASK register bits
// Determines which status flags generate an interrupt request by setting the corresponding bit to 1b.
#define SDIO_MASK_CEATAENDIE (1<<23) // enable CEATAEND interrupt
#define SDIO_MASK_SDIOITIE (1<<22) // enable SDIOIT interrupt
#define SDIO_MASK_RXDAVLIE (1<<21) // enable RXDAVL interrupt
#define SDIO_MASK_TXDAVLIE (1<<20) // enable TXDAVL interrupt
#define SDIO_MASK_RXFIFOEIE (1<<19) // enable RXFIFOE interrupt
#define SDIO_MASK_TXFIFOEIE (1<<18) // enable TXFIFOE interrupt
#define SDIO_MASK_RXFIFOFIE (1<<17) // enable RXFIFOF interrupt
#define SDIO_MASK_TXFIFOFIE (1<<16) // enable TXFIFOF interrupt
#define SDIO_MASK_RXFIFOHFIE (1<<15) // enable RXFIFOHF interrupt
#define SDIO_MASK_TXFIFOHEIE (1<<14) // enable TXFIFOHE interrupt
#define SDIO_MASK_RXACTIE (1<<13) // enable RXACT interrupt
#define SDIO_MASK_TXACTIE (1<<12) // enable TXACT interrupt
#define SDIO_MASK_CMDACTIE (1<<11) // enable CMDACT interrupt
#define SDIO_MASK_DBCKENDIE (1<<10) // enable DBCKENDC interrupt
#define SDIO_MASK_STBITERRIE (1<<9) // enable STBITERR interrupt
#define SDIO_MASK_DATAENDIE (1<<8) // enable DATAENDC interrupt
#define SDIO_MASK_CMDSENTIE (1<<7) // enable CMDSENTC interrupt
#define SDIO_MASK_CMDRENDIE (1<<6) // enable CMDREND interrupt
#define SDIO_MASK_RXOVERRIE (1<<5) // enable RXOVERR interrupt
#define SDIO_MASK_TXUNDERRIE (1<<4) // enable TXUNDERR interrupt
#define SDIO_MASK_DTIMEOUTIE (1<<3) // enable DTIMEOUT interrupt
#define SDIO_MASK_CTIMEOUTIE (1<<2) // enable CTIMEOUT interrupt
#define SDIO_MASK_DCRCFAILIE (1<<1) // enable DCRCFAIL interrupt
#define SDIO_MASK_CCRCFAILIE (1<<0) // enable CCRCFAIL interrupt
void sdio_enable(void);
void sdio_disable(void);
void sdio_begin(void);
uint8_t sdio_cmd_send(uint16_t cmd_index_resp_type, uint32_t arg);
void sdio_set_clock(uint32_t clk);
void sdio_set_dbus_width(uint16_t bus_w);
void sdio_set_dblock_size(uint8_t dbsize);
//void sdio_trx_enable(uint8_t dir);
inline void sdio_trx_enable(void)
{
SDIO->DCTRL |= SDIO_DCTRL_DTEN; // enable data transfer
}
inline uint32_t sdio_cmd_xfer_ongoing(void) { return (SDIO->STA&SDIO_STA_CMDACT); }
inline uint32_t sdio_cmd_complete(void) { return (SDIO->STA&SDIO_STA_CMDSENT); }
inline void sdio_setup_transfer(uint32_t dtimer, uint32_t dlen, uint16_t flags)
{
SDIO->ICR = SDIO_ICR_DATA_FLAGS; // clear data access relevant flags
SDIO->DTIMER = dtimer;
SDIO->DLEN = dlen;
SDIO->DCTRL = flags;// | SDIO_DCTRL_DTEN; // enable data transfer
}
/*
#ifdef __cplusplus
} // extern "C"
#endif
*/
#endif /* (STM32_HIGH_DENSITY) || (STM32_XL_DENSITY) */
#endif

View File

@@ -0,0 +1,472 @@
/******************************************************************************
* 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/include/libmaple/spi.h
* @author Marti Bolivar <mbolivar@leaflabs.com>
* @brief Serial Peripheral Interface (SPI) and Integrated
* Interchip Sound (I2S) peripheral support.
*
* I2S support is currently limited to register maps and bit definitions.
*/
#ifndef _LIBMAPLE_SPI_H_
#define _LIBMAPLE_SPI_H_
#ifdef __cplusplus
extern "C" {
#endif
#include <libmaple/libmaple_types.h>
#include <libmaple/rcc.h>
#include <libmaple/nvic.h>
/* Roger clark. Replaced with line below #include <series/spi.h>*/
#include "stm32f1/include/series/spi.h"
/*
* Register maps
*/
/** SPI register map type. */
typedef struct spi_reg_map {
__io uint32 CR1; /**< Control register 1 */
__io uint32 CR2; /**< Control register 2 */
__io uint32 SR; /**< Status register */
__io uint32 DR; /**< Data register */
__io uint32 CRCPR; /**< CRC polynomial register */
__io uint32 RXCRCR; /**< RX CRC register */
__io uint32 TXCRCR; /**< TX CRC register */
__io uint32 I2SCFGR; /**< I2S configuration register */
__io uint32 I2SPR; /**< I2S prescaler register */
} spi_reg_map;
/*
* Register bit definitions
*/
/* Control register 1 */
#define SPI_CR1_BIDIMODE_BIT 15
#define SPI_CR1_BIDIOE_BIT 14
#define SPI_CR1_CRCEN_BIT 13
#define SPI_CR1_CRCNEXT_BIT 12
#define SPI_CR1_DFF_BIT 11
#define SPI_CR1_RXONLY_BIT 10
#define SPI_CR1_SSM_BIT 9
#define SPI_CR1_SSI_BIT 8
#define SPI_CR1_LSBFIRST_BIT 7
#define SPI_CR1_SPE_BIT 6
#define SPI_CR1_MSTR_BIT 2
#define SPI_CR1_CPOL_BIT 1
#define SPI_CR1_CPHA_BIT 0
#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 (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 (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)
#define SPI_CR1_BR_PCLK_DIV_8 (0x2 << 3)
#define SPI_CR1_BR_PCLK_DIV_16 (0x3 << 3)
#define SPI_CR1_BR_PCLK_DIV_32 (0x4 << 3)
#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 (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 (1U << SPI_CR1_CPHA_BIT)
/* Control register 2 */
#define SPI_CR2_TXEIE_BIT 7
#define SPI_CR2_RXNEIE_BIT 6
#define SPI_CR2_ERRIE_BIT 5
#define SPI_CR2_SSOE_BIT 2
#define SPI_CR2_TXDMAEN_BIT 1
#define SPI_CR2_RXDMAEN_BIT 0
#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 */
#define SPI_SR_BSY_BIT 7
#define SPI_SR_OVR_BIT 6
#define SPI_SR_MODF_BIT 5
#define SPI_SR_CRCERR_BIT 4
#define SPI_SR_UDR_BIT 3
#define SPI_SR_CHSIDE_BIT 2
#define SPI_SR_TXE_BIT 1
#define SPI_SR_RXNE_BIT 0
#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 (1U << SPI_SR_TXE_BIT)
#define SPI_SR_RXNE (1U << SPI_SR_RXNE_BIT)
/* I2S configuration register */
#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 (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 (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 (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)
#define SPI_I2SCFGR_I2SSTD_PHILLIPS (0x0 << 4)
#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 (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 (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
*/
/** SPI device type */
typedef struct spi_dev {
spi_reg_map *regs; /**< Register map */
rcc_clk_id clk_id; /**< RCC clock information */
nvic_irq_num irq_num; /**< NVIC interrupt number */
} spi_dev;
/*
* 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 dev SPI device
* @param as_master If true, configure as bus master; otherwise, as slave.
* @param nss_dev NSS pin's GPIO device
* @param nss_bit NSS pin's GPIO bit on nss_dev
* @param comm_dev SCK, MISO, MOSI pins' GPIO device
* @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
*/
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.
*
* A SPI mode determines a combination of the idle state of the clock
* line (the clock polarity, or "CPOL"), and which clock edge triggers
* data capture (the clock phase, or "CPHA").
*/
typedef enum spi_mode {
/** Clock idles low, data captured on rising edge (first transition) */
SPI_MODE_LOW_RISING = 0,
/** Clock idles low, data captured on falling edge (second transition) */
SPI_MODE_LOW_FALLING = 1,
/** Clock idles high, data captured on falling edge (first transition) */
SPI_MODE_HIGH_FALLING = 2,
/** Clock idles high, data captured on rising edge (second transition) */
SPI_MODE_HIGH_RISING = 3,
SPI_MODE_0 = SPI_MODE_LOW_RISING, /**< Same as SPI_MODE_LOW_RISING */
SPI_MODE_1 = SPI_MODE_LOW_FALLING, /**< Same as SPI_MODE_LOW_FALLING */
SPI_MODE_2 = SPI_MODE_HIGH_FALLING, /**< Same as SPI_MODE_HIGH_FALLING */
SPI_MODE_3 = SPI_MODE_HIGH_RISING, /**< Same as SPI_MODE_HIGH_RISING */
} spi_mode;
/**
* @brief SPI baud rate configuration, as a divisor of f_PCLK, the
* PCLK clock frequency.
*/
typedef enum spi_baud_rate {
SPI_BAUD_PCLK_DIV_2 = SPI_CR1_BR_PCLK_DIV_2, /**< f_PCLK/2 */
SPI_BAUD_PCLK_DIV_4 = SPI_CR1_BR_PCLK_DIV_4, /**< f_PCLK/4 */
SPI_BAUD_PCLK_DIV_8 = SPI_CR1_BR_PCLK_DIV_8, /**< f_PCLK/8 */
SPI_BAUD_PCLK_DIV_16 = SPI_CR1_BR_PCLK_DIV_16, /**< f_PCLK/16 */
SPI_BAUD_PCLK_DIV_32 = SPI_CR1_BR_PCLK_DIV_32, /**< f_PCLK/32 */
SPI_BAUD_PCLK_DIV_64 = SPI_CR1_BR_PCLK_DIV_64, /**< f_PCLK/64 */
SPI_BAUD_PCLK_DIV_128 = SPI_CR1_BR_PCLK_DIV_128, /**< f_PCLK/128 */
SPI_BAUD_PCLK_DIV_256 = SPI_CR1_BR_PCLK_DIV_256, /**< f_PCLK/256 */
} spi_baud_rate;
/**
* @brief SPI initialization flags.
* @see spi_master_enable()
* @see spi_slave_enable()
*/
typedef enum spi_cfg_flag {
SPI_BIDIMODE = SPI_CR1_BIDIMODE, /**< Bidirectional mode enable */
SPI_BIDIOE = SPI_CR1_BIDIOE, /**< Output enable in bidirectional
mode */
SPI_CRCEN = SPI_CR1_CRCEN, /**< Cyclic redundancy check (CRC)
enable */
SPI_DFF_8_BIT = SPI_CR1_DFF_8_BIT, /**< 8-bit data frame format (this is
the default) */
SPI_DFF_16_BIT = SPI_CR1_DFF_16_BIT, /**< 16-bit data frame format */
SPI_RX_ONLY = SPI_CR1_RXONLY, /**< Receive only */
SPI_SW_SLAVE = SPI_CR1_SSM, /**< Software slave management */
SPI_SOFT_SS = SPI_CR1_SSI, /**< Software (internal) slave
select. This flag only has an
effect when used in combination
with SPI_SW_SLAVE. */
SPI_FRAME_LSB = SPI_CR1_LSBFIRST, /**< LSB-first (little-endian) frame
format */
SPI_FRAME_MSB = 0, /**< MSB-first (big-endian) frame
format (this is the default) */
} spi_cfg_flag;
void spi_master_enable(spi_dev *dev,
spi_baud_rate baud,
spi_mode mode,
uint32 flags);
void spi_slave_enable(spi_dev *dev,
spi_mode mode,
uint32 flags);
uint32 spi_tx(spi_dev *dev, const void *buf, uint32 len);
/**
* @brief Call a function on each SPI port
* @param fn Function to call.
*/
extern void spi_foreach(void (*fn)(spi_dev*));
void spi_peripheral_enable(spi_dev *dev);
void spi_peripheral_disable(spi_dev *dev);
void spi_tx_dma_enable(spi_dev *dev);
void spi_tx_dma_disable(spi_dev *dev);
void spi_rx_dma_enable(spi_dev *dev);
void spi_rx_dma_disable(spi_dev *dev);
/**
* @brief Determine if a SPI peripheral is enabled.
* @param dev SPI device
* @return True, if and only if dev's peripheral is enabled.
*/
static inline uint8 spi_is_enabled(spi_dev *dev) {
return dev->regs->CR1 & SPI_CR1_SPE_BIT;
}
/**
* @brief Disable all SPI peripherals
*/
static inline void spi_peripheral_disable_all(void) {
spi_foreach(spi_peripheral_disable);
}
/** Available SPI interrupts */
typedef enum spi_interrupt {
SPI_TXE_INTERRUPT = SPI_CR2_TXEIE, /**< TX buffer empty interrupt */
SPI_RXNE_INTERRUPT = SPI_CR2_RXNEIE, /**< RX buffer not empty interrupt */
SPI_ERR_INTERRUPT = SPI_CR2_ERRIE /**<
* Error interrupt (CRC, overrun,
* and mode fault errors for SPI;
* underrun, overrun errors for I2S)
*/
} spi_interrupt;
/**
* @brief Mask for all spi_interrupt values
* @see spi_interrupt
*/
#define SPI_INTERRUPTS_ALL (SPI_TXE_INTERRUPT | \
SPI_RXNE_INTERRUPT | \
SPI_ERR_INTERRUPT)
/**
* @brief Enable SPI interrupt requests
* @param dev SPI device
* @param interrupt_flags Bitwise OR of spi_interrupt values to enable
* @see spi_interrupt
*/
static inline void spi_irq_enable(spi_dev *dev, uint32 interrupt_flags) {
dev->regs->CR2 |= interrupt_flags;
nvic_irq_enable(dev->irq_num);
}
/**
* @brief Disable SPI interrupt requests
* @param dev SPI device
* @param interrupt_flags Bitwise OR of spi_interrupt values to disable
* @see spi_interrupt
*/
static inline void spi_irq_disable(spi_dev *dev, uint32 interrupt_flags) {
dev->regs->CR2 &= ~interrupt_flags;
}
/**
* @brief Get the data frame format flags with which a SPI port is
* configured.
* @param dev SPI device whose data frame format to get.
* @return SPI_DFF_8_BIT, if dev has an 8-bit data frame format.
* Otherwise, SPI_DFF_16_BIT.
*/
static inline spi_cfg_flag spi_dff(spi_dev *dev) {
return ((dev->regs->CR1 & SPI_CR1_DFF) == SPI_CR1_DFF_8_BIT ?
SPI_DFF_8_BIT :
SPI_DFF_16_BIT);
}
/**
* @brief Determine whether the device's peripheral receive (RX)
* register is empty.
* @param dev SPI device
* @return true, iff dev's RX register is empty.
*/
static inline uint8 spi_is_rx_nonempty(spi_dev *dev) {
return dev->regs->SR & SPI_SR_RXNE;
}
/**
* @brief Retrieve the contents of the device's peripheral receive
* (RX) register.
*
* You may only call this function when the RX register is nonempty.
* Calling this function clears the contents of the RX register.
*
* @param dev SPI device
* @return Contents of dev's peripheral RX register
* @see spi_is_rx_reg_nonempty()
*/
static inline uint16 spi_rx_reg(spi_dev *dev) {
return (uint16)dev->regs->DR;
}
/**
* @brief Determine whether the device's peripheral transmit (TX)
* register is empty.
* @param dev SPI device
* @return true, iff dev's TX register is empty.
*/
static inline uint8 spi_is_tx_empty(spi_dev *dev) {
return dev->regs->SR & SPI_SR_TXE;
}
/**
* @brief Load a value into the device's peripheral transmit (TX) register.
*
* You may only call this function when the TX register is empty.
* Calling this function loads val into the peripheral's TX register.
* If the device is properly configured, this will initiate a
* transmission, the completion of which will cause the TX register to
* be empty again.
*
* @param dev SPI device
* @param val Value to load into the TX register. If the SPI data
* frame format is 8 bit, the value must be right-aligned.
* @see spi_is_tx_reg_empty()
* @see spi_init()
* @see spi_master_enable()
* @see spi_slave_enable()
*/
static inline void spi_tx_reg(spi_dev *dev, uint16 val) {
dev->regs->DR = val;
}
/**
* @brief Determine whether the device's peripheral busy (SPI_SR_BSY)
* flag is set.
* @param dev SPI device
* @return true, iff dev's BSY flag is set.
*/
static inline uint8 spi_is_busy(spi_dev *dev) {
return dev->regs->SR & SPI_SR_BSY;
}
/*
* I2S convenience functions (TODO)
*/
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -0,0 +1,238 @@
/******************************************************************************
* The MIT License
*
* Copyright (c) 2010, 2011, 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/include/libmaple/stm32.h
* @brief STM32 chip header
*
* This header supplies various chip-specific values for the current
* build target. It's useful both to abstract away hardware details
* (e.g. through use of STM32_NR_INTERRUPTS) and to decide what to do
* when you want something nonportable (e.g. by checking
* STM32_MCU_SERIES).
*/
#ifndef _LIBMAPLE_STM32_H_
#define _LIBMAPLE_STM32_H_
#ifdef __cplusplus
extern "C" {
#endif
/*
* STM32 series identifiers.
*
* Don't make these into an enum; the preprocessor needs them.
*/
/** STM32F1 series. */
#define STM32_SERIES_F1 0
/** STM32F2 series. */
#define STM32_SERIES_F2 1
/** STM32L1 series. */
#define STM32_SERIES_L1 2
/** STM32F4 series. */
#define STM32_SERIES_F4 3
/* The series header is responsible for defining:
*
* - Everything in the following __DOXYGEN__ conditional block.
*
* - STM32_HAVE_FSMC: 1 if the MCU has the FSMC peripheral, and 0
* otherwise.
*
* - STM32_HAVE_USB: 1 if the MCU has a USB peripheral, and 0
* otherwise.
*/
/* roger clark. replaced with line below #include <series/stm32.h> */
#include "stm32f1/include/series/stm32.h"
/* Ensure the series header isn't broken. */
#if (!defined(STM32_PCLK1) || \
!defined(STM32_PCLK2) || \
!defined(STM32_MCU_SERIES) || \
!defined(STM32_NR_INTERRUPTS) || \
!defined(STM32_NR_GPIO_PORTS) || \
!defined(STM32_TIMER_MASK) || \
!defined(STM32_DELAY_US_MULT) || \
!defined(STM32_SRAM_END) || \
!defined(STM32_HAVE_DAC) || \
!defined(STM32_HAVE_FSMC) || \
!defined(STM32_HAVE_USB))
#error "Bad STM32F1 configuration. Check <series/stm32.h> header for your MCU."
#endif
/*
* Derived macros
*/
/* FIXME [0.0.13] add this to ReST API page */
/**
* @brief Statically determine whether a timer is present.
*
* Given a constant timer number n (starting from 1), this macro has a
* nonzero value exactly when TIMERn is available.
*/
#define STM32_HAVE_TIMER(n) (STM32_TIMER_MASK & (1 << (n)))
/*
* Doxygen for functionality provided by series header.
*/
#ifdef __DOXYGEN__
/*
* Clock configuration.
*
* These defines depend upon how the MCU is configured. Because of
* the potential for a mismatch between them and the actual clock
* configuration, keep their number to a minimum.
*/
/**
* @brief APB1 clock speed, in Hz.
*/
#define STM32_PCLK1
/**
* @brief APB2 clock speed, in Hz.
*/
#define STM32_PCLK2
/** @brief Deprecated. Use STM32_PCLK1 instead. */
#define PCLK1
/** @brief Deprecated. Use STM32_PCLK2 instead. */
#define PCLK2
/*
* Series- and MCU-specific values.
*/
/**
* @brief STM32 series value for the MCU being targeted.
*
* At time of writing, allowed values are: STM32_SERIES_F1,
* STM32_SERIES_F2. This set of values will expand as libmaple adds
* support for more STM32 series MCUs.
*/
#define STM32_MCU_SERIES
/**
* @brief Number of interrupts in the vector table.
*
* This does not include Cortex-M interrupts (NMI, HardFault, etc.).
*/
#define STM32_NR_INTERRUPTS
/**
* Number of GPIO ports.
*/
#define STM32_NR_GPIO_PORTS
/* FIXME [0.0.13] add this to ReST API page */
/**
* @brief Bitmask of timers available on the MCU.
*
* That is, if TIMERn is available, then STM32_TIMER_MASK & (1 << n)
* will be nonzero. For example, a nonzero value of "STM32_TIMER_MASK
* & 0x2" means TIMER1 is available.
*
* A bitmask is necessary as some STM32 MCUs have "holes" in the range
* of available timers.
*/
#define STM32_TIMER_MASK
/**
* @brief Multiplier to convert microseconds into loop iterations
* in delay_us().
*
* @see delay_us()
*/
#define STM32_DELAY_US_MULT
/**
* @brief Pointer to end of built-in SRAM.
*
* Points to the address which is 1 byte past the last valid
* SRAM address.
*/
#define STM32_SRAM_END
/**
* @brief 1 if the target MCU has a DAC, and 0 otherwise.
*/
#define STM32_HAVE_DAC
/**
* @brief 1 if the target MCU has the FSMC peripheral, and 0 otherwise.
*
* Note that the feature set of the FSMC peripheral is restricted on
* some MCUs.
*/
#define STM32_HAVE_FSMC
/**
* @brief 1 if the target MCU has a USB peripheral, and 0 otherwise.
*
* Note that a variety of USB peripherals are available across the
* different series, with widely varying feature sets and programming
* interfaces. This macro will be 1 if any such peripheral is present.
*/
#define STM32_HAVE_USB
#endif /* __DOXYGEN__ */
/*
* The following are for backwards compatibility only.
*/
/* PCLK1 and PCLK2 are for backwards compatibility only; don't use in
* new code. */
#ifndef PCLK1
#define PCLK1 STM32_PCLK1
#endif
#if PCLK1 != STM32_PCLK1
#error "PCLK1 (which is deprecated) differs from STM32_PCLK1."
#endif
#ifndef PCLK2
#define PCLK2 STM32_PCLK2
#endif
#if PCLK2 != STM32_PCLK2
#error "PCLK2 (which is deprecated) differs from STM32_PCLK2."
#endif
/** @brief Deprecated. Use STM32_NR_INTERRUPTS instead. */
#define NR_INTERRUPTS STM32_NR_INTERRUPTS
/** @brief Deprecated. Use STM32_NR_GPIO_PORTS instead. */
#define NR_GPIO_PORTS STM32_NR_GPIO_PORTS
/** @brief Deprecated. Use STM32_DELAY_US_MULT instead. */
#define DELAY_US_MULT STM32_DELAY_US_MULT
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -0,0 +1,151 @@
/******************************************************************************
* 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/include/libmaple/syscfg.h
* @brief System configuration controller (SYSCFG)
*
* Availability: STM32F2, STM32F4.
*/
#ifndef _LIBMAPLE_SYSCFG_H_
#define _LIBMAPLE_SYSCFG_H_
#ifdef __cplusplus
extern "C" {
#endif
#include <libmaple/libmaple_types.h>
/*
* Register map and base pointer
*/
/**
* @brief SYSCFG register map type.
*/
typedef struct syscfg_reg_map {
__io uint32 MEMRMP; /**< Memory remap register */
__io uint32 PMC; /**< Peripheral mode configuration */
__io uint32 EXTICR[4]; /**< External interrupt configuration registers */
const uint32 RESERVED1;
const uint32 RESERVED2;
__io uint32 CMPCR; /**< Compensation cell control register */
} syscfg_reg_map;
/** SYSCFG register map base pointer */
#define SYSCFG_BASE ((struct syscfg_reg_map*)0x40013800)
/*
* Register bit definitions
*/
/* Memory remap register */
#define SYSCFG_MEMRMP_MEM_MODE 0x3
#define SYSCFG_MEMRMP_MEM_MODE_FLASH 0x0
#define SYSCFG_MEMRMP_MEM_MODE_SYS_FLASH 0x1
#define SYSCFG_MEMRMP_MEM_MODE_FSMC_1 0x2
#define SYSCFG_MEMRMP_MEM_MODE_EMB_SRAM 0x3
/* Peripheral mode configuration register */
#define SYSCFG_PMC_MII_RMII_SEL_BIT 23
#define SYSCFG_PMC_MII_RMII_SEL (1U << SYSCFG_PMC_MII_RMII_SEL_BIT)
#define SYSCFG_PMC_MII_RMII_SEL_MII (0U << SYSCFG_PMC_MII_RMII_SEL_BIT)
#define SYSCFG_PMC_MII_RMII_SEL_RMII (1U << SYSCFG_PMC_MII_RMII_SEL_BIT)
/* External interrupt configuration register 1 */
#define SYSCFG_EXTICR1_EXTI0 0xF
#define SYSCFG_EXTICR1_EXTI1 0xF0
#define SYSCFG_EXTICR1_EXTI2 0xF00
#define SYSCFG_EXTICR1_EXTI3 0xF000
/* External interrupt configuration register 2 */
#define SYSCFG_EXTICR2_EXTI4 0xF
#define SYSCFG_EXTICR2_EXTI5 0xF0
#define SYSCFG_EXTICR2_EXTI6 0xF00
#define SYSCFG_EXTICR2_EXTI7 0xF000
/* External interrupt configuration register 3 */
#define SYSCFG_EXTICR3_EXTI8 0xF
#define SYSCFG_EXTICR3_EXTI9 0xF0
#define SYSCFG_EXTICR3_EXTI10 0xF00
#define SYSCFG_EXTICR3_EXTI11 0xF000
/* External interrupt configuration register 4 */
#define SYSCFG_EXTICR4_EXTI12 0xF
#define SYSCFG_EXTICR4_EXTI13 0xF0
#define SYSCFG_EXTICR4_EXTI14 0xF00
#define SYSCFG_EXTICR4_EXTI15 0xF000
/* Compensation cell control register */
#define SYSCFG_CMPCR_READY_BIT 8
#define SYSCFG_CMPCR_CMP_PD_BIT 0
#define SYSCFG_CMPCR_READY (1U << SYSCFG_CMPCR_READY_BIT)
#define SYSCFG_CMPCR_CMP_PD (1U << SYSCFG_CMPCR_CMP_PD_BIT)
#define SYSCFG_CMPCR_CMP_PD_PDWN (0U << SYSCFG_CMPCR_CMP_PD_BIT)
#define SYSCFG_CMPCR_CMP_PD_ENABLE (1U << SYSCFG_CMPCR_CMP_PD_BIT)
/*
* Routines
*/
void syscfg_init(void);
void syscfg_enable_io_compensation(void);
void syscfg_disable_io_compensation(void);
/**
* @brief System memory mode
* These values specify what memory to map to address 0x00000000.
* @see syscfg_set_mem_mode
*/
typedef enum syscfg_mem_mode {
/** Main flash memory is mapped at 0x0. */
SYCFG_MEM_MODE_FLASH = SYSCFG_MEMRMP_MEM_MODE_FLASH,
/** System flash (i.e. ST's baked-in bootloader) is mapped at 0x0. */
SYCFG_MEM_MODE_SYSTEM_FLASH = SYSCFG_MEMRMP_MEM_MODE_SYS_FLASH,
/** FSMC bank 1 (NOR/PSRAM 1 and 2) is mapped at 0x0. */
SYCFG_MEM_MODE_FSMC_BANK_1 = SYSCFG_MEMRMP_MEM_MODE_FSMC_1,
/** Embedded SRAM (i.e., not backup SRAM) is mapped at 0x0. */
SYCFG_MEM_MODE_SRAM = SYSCFG_MEMRMP_MEM_MODE_EMB_SRAM,
} syscfg_mem_mode;
void syscfg_set_mem_mode(syscfg_mem_mode);
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -0,0 +1,121 @@
/******************************************************************************
* The MIT License
*
* 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/include/libmaple/systick.h
* @brief System timer definitions
*/
#ifndef _LIBMAPLE_SYSTICK_H_
#define _LIBMAPLE_SYSTICK_H_
#ifdef __cplusplus
extern "C"{
#endif
#include <libmaple/libmaple_types.h>
#include <libmaple/util.h>
/** SysTick register map type */
typedef struct systick_reg_map {
__io uint32 CSR; /**< Control and status register */
__io uint32 RVR; /**< Reload value register */
__io uint32 CNT; /**< Current value register ("count") */
__io uint32 CVR; /**< Calibration value register */
} systick_reg_map;
/** SysTick register map base pointer */
#define SYSTICK_BASE ((struct systick_reg_map*)0xE000E010)
/*
* Register bit definitions.
*/
/* Control and status register */
#define SYSTICK_CSR_COUNTFLAG BIT(16)
#define SYSTICK_CSR_CLKSOURCE BIT(2)
#define SYSTICK_CSR_CLKSOURCE_EXTERNAL 0
#define SYSTICK_CSR_CLKSOURCE_CORE BIT(2)
#define SYSTICK_CSR_TICKINT BIT(1)
#define SYSTICK_CSR_TICKINT_PEND BIT(1)
#define SYSTICK_CSR_TICKINT_NO_PEND 0
#define SYSTICK_CSR_ENABLE BIT(0)
#define SYSTICK_CSR_ENABLE_MULTISHOT BIT(0)
#define SYSTICK_CSR_ENABLE_DISABLED 0
/* Calibration value register */
#define SYSTICK_CVR_NOREF BIT(31)
#define SYSTICK_CVR_SKEW BIT(30)
#define SYSTICK_CVR_TENMS 0xFFFFFF
/** System elapsed time, in milliseconds */
extern volatile uint32 systick_uptime_millis;
/**
* @brief Returns the system uptime, in milliseconds.
*/
static inline uint32 systick_uptime(void) {
return systick_uptime_millis;
}
void systick_init(uint32 reload_val);
void systick_disable();
void systick_enable();
/**
* @brief Returns the current value of the SysTick counter.
*/
static inline uint32 systick_get_count(void) {
return SYSTICK_BASE->CNT;
}
/**
* @brief Check for underflow.
*
* This function returns 1 if the SysTick timer has counted to 0 since
* the last time it was called. However, any reads of any part of the
* SysTick Control and Status Register SYSTICK_BASE->CSR will
* interfere with this functionality. See the ARM Cortex M3 Technical
* Reference Manual for more details (e.g. Table 8-3 in revision r1p1).
*/
static inline uint32 systick_check_underflow(void) {
return SYSTICK_BASE->CSR & SYSTICK_CSR_COUNTFLAG;
}
/**
* @brief prototype for systick_attach_callback
*
*/
extern void systick_attach_callback(void (*callback)(void));
#ifdef __cplusplus
} // extern "C"
#endif
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,523 @@
/******************************************************************************
* The MIT License
*
* 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/include/libmaple/usart.h
* @author Marti Bolivar <mbolivar@leaflabs.com>,
* Perry Hung <perry@leaflabs.com>
* @brief USART definitions and prototypes
*/
#ifndef _LIBMAPLE_USART_H_
#define _LIBMAPLE_USART_H_
#ifdef __cplusplus
extern "C"{
#endif
#include <libmaple/libmaple_types.h>
#include <libmaple/util.h>
#include <libmaple/rcc.h>
#include <libmaple/nvic.h>
#include <libmaple/ring_buffer.h>
/* Roger clark. Replaced with line below #include <series/usart.h>*/
#include "stm32f1/include/series/usart.h"
/*
* Register map (common across supported STM32 series).
*/
/** USART register map type */
typedef struct usart_reg_map {
__io uint32 SR; /**< Status register */
__io uint32 DR; /**< Data register */
__io uint32 BRR; /**< Baud rate register */
__io uint32 CR1; /**< Control register 1 */
__io uint32 CR2; /**< Control register 2 */
__io uint32 CR3; /**< Control register 3 */
__io uint32 GTPR; /**< Guard time and prescaler register */
} usart_reg_map;
/*
* Register bit definitions
*/
/* Status register */
/** Clear to send bit */
#define USART_SR_CTS_BIT 9
/** Line break detection bit */
#define USART_SR_LBD_BIT 8
/** Transmit data register empty bit */
#define USART_SR_TXE_BIT 7
/** Transmission complete bit */
#define USART_SR_TC_BIT 6
/** Read data register not empty bit */
#define USART_SR_RXNE_BIT 5
/** IDLE line detected bit */
#define USART_SR_IDLE_BIT 4
/** Overrun error bit */
#define USART_SR_ORE_BIT 3
/** Noise error bit */
#define USART_SR_NE_BIT 2
/**
* @brief Synonym for USART_SR_NE_BIT.
*
* Some series (e.g. STM32F2) use "NF" for "noise flag" instead of the
* original "NE" for "noise error". The meaning of the bit is
* unchanged, but the NF flag can be disabled when the line is
* noise-free.
*
* @see USART_SR_NE_BIT
*/
#define USART_SR_NF_BIT USART_SR_NE_BIT
/** Framing error bit */
#define USART_SR_FE_BIT 1
/** Parity error bit */
#define USART_SR_PE_BIT 0
/** Clear to send mask */
#define USART_SR_CTS BIT(USART_SR_CTS_BIT)
/** Line break detected mask */
#define USART_SR_LBD BIT(USART_SR_LBD_BIT)
/** Transmit data register empty mask */
#define USART_SR_TXE BIT(USART_SR_TXE_BIT)
/** Transmission complete mask */
#define USART_SR_TC BIT(USART_SR_TC_BIT)
/** Read data register not empty mask */
#define USART_SR_RXNE BIT(USART_SR_RXNE_BIT)
/** IDLE line detected mask */
#define USART_SR_IDLE BIT(USART_SR_IDLE_BIT)
/** Overrun error mask */
#define USART_SR_ORE BIT(USART_SR_ORE_BIT)
/** Noise error mask */
#define USART_SR_NE BIT(USART_SR_NE_BIT)
/**
* @brief Synonym for USART_SR_NE.
* @see USART_SR_NF_BIT
*/
#define USART_SR_NF USART_SR_NE
/** Framing error mask */
#define USART_SR_FE BIT(USART_SR_FE_BIT)
/** Parity error mask */
#define USART_SR_PE BIT(USART_SR_PE_BIT)
/* Data register */
/** Data register data value mask */
#define USART_DR_DR 0xFF
/* Baud rate register */
/** Mantissa of USARTDIV mask */
#define USART_BRR_DIV_MANTISSA (0xFFF << 4)
/** Fraction of USARTDIV mask */
#define USART_BRR_DIV_FRACTION 0xF
/* Control register 1 */
/** USART enable bit */
#define USART_CR1_UE_BIT 13
/** Word length bit */
#define USART_CR1_M_BIT 12
/** Wakeup method bit */
#define USART_CR1_WAKE_BIT 11
/** Parity control enable bit */
#define USART_CR1_PCE_BIT 10
/** Parity selection bit */
#define USART_CR1_PS_BIT 9
/** Parity error interrupt enable bit */
#define USART_CR1_PEIE_BIT 8
/** Transmit data regsiter not empty interrupt enable bit */
#define USART_CR1_TXEIE_BIT 7
/** Transmission complete interrupt enable bit */
#define USART_CR1_TCIE_BIT 6
/** RXNE interrupt enable bit */
#define USART_CR1_RXNEIE_BIT 5
/** IDLE interrupt enable bit */
#define USART_CR1_IDLEIE_BIT 4
/** Transmitter enable bit */
#define USART_CR1_TE_BIT 3
/** Receiver enable bit */
#define USART_CR1_RE_BIT 2
/** Receiver wakeup bit */
#define USART_CR1_RWU_BIT 1
/** Send break bit */
#define USART_CR1_SBK_BIT 0
/** USART enable mask */
#define USART_CR1_UE BIT(USART_CR1_UE_BIT)
/** Word length mask */
#define USART_CR1_M BIT(USART_CR1_M_BIT)
/** Word length: 1 start bit, 8 data bits, n stop bit */
#define USART_CR1_M_8N1 (0 << USART_CR1_M_BIT)
/** Word length: 1 start bit, 9 data bits, n stop bit */
#define USART_CR1_M_9N1 (1 << USART_CR1_M_BIT)
/** Wakeup method mask */
#define USART_CR1_WAKE BIT(USART_CR1_WAKE_BIT)
/** Wakeup on idle line */
#define USART_CR1_WAKE_IDLE (0 << USART_CR1_WAKE_BIT)
/** Wakeup on address mark */
#define USART_CR1_WAKE_ADDR (1 << USART_CR1_WAKE_BIT)
/** Parity control enable mask */
#define USART_CR1_PCE BIT(USART_CR1_PCE_BIT)
/** Parity selection mask */
#define USART_CR1_PS BIT(USART_CR1_PS_BIT)
/** Parity selection: even parity */
#define USART_CR1_PS_EVEN (0 << USART_CR1_PS_BIT)
/** Parity selection: odd parity */
#define USART_CR1_PS_ODD (1 << USART_CR1_PS_BIT)
/** Parity error interrupt enable mask */
#define USART_CR1_PEIE BIT(USART_CR1_PEIE_BIT)
/** Transmit data register empty interrupt enable mask */
#define USART_CR1_TXEIE BIT(USART_CR1_TXEIE_BIT)
/** Transmission complete interrupt enable mask */
#define USART_CR1_TCIE BIT(USART_CR1_TCIE_BIT)
/** RXNE interrupt enable mask */
#define USART_CR1_RXNEIE BIT(USART_CR1_RXNEIE_BIT)
/** IDLE line interrupt enable mask */
#define USART_CR1_IDLEIE BIT(USART_CR1_IDLEIE_BIT)
/** Transmitter enable mask */
#define USART_CR1_TE BIT(USART_CR1_TE_BIT)
/** Receiver enable mask */
#define USART_CR1_RE BIT(USART_CR1_RE_BIT)
/** Receiver wakeup mask */
#define USART_CR1_RWU BIT(USART_CR1_RWU_BIT)
/** Receiver wakeup: receiver in active mode */
#define USART_CR1_RWU_ACTIVE (0 << USART_CR1_RWU_BIT)
/** Receiver wakeup: receiver in mute mode */
#define USART_CR1_RWU_MUTE (1 << USART_CR1_RWU_BIT)
/** Send break */
#define USART_CR1_SBK BIT(USART_CR1_SBK_BIT)
/* Control register 2 */
/** LIN mode enable bit */
#define USART_CR2_LINEN_BIT 14
/** Clock enable bit */
#define USART_CR2_CLKEN_BIT 11
/** Clock polarity bit */
#define USART_CR2_CPOL_BIT 10
/** Clock phase bit */
#define USART_CR2_CPHA_BIT 9
/** Last bit clock pulse bit */
#define USART_CR2_LBCL_BIT 8
/** LIN break detection interrupt enable bit */
#define USART_CR2_LBDIE_BIT 6
/** LIN break detection length bit */
#define USART_CR2_LBDL_BIT 5
/** LIN mode enable mask */
#define USART_CR2_LINEN BIT(USART_CR2_LINEN_BIT)
/** STOP bits mask */
#define USART_CR2_STOP (0x3 << 12)
/** STOP bits: 1 stop bit */
#define USART_CR2_STOP_BITS_1 (0x0 << 12)
/**
* @brief STOP bits: 0.5 stop bits
* Not available on UART4, UART5. */
#define USART_CR2_STOP_BITS_POINT_5 (0x1 << 12)
/** STOP bits: 2 stop bits */
#define USART_CR2_STOP_BITS_2 (0x2 << 12)
/**
* @brief STOP bits: 1.5 stop bits
* Not available on UART4, UART5. */
#define USART_CR2_STOP_BITS_1_POINT_5 (0x3 << 12)
/**
* @brief Clock enable.
* Not available on UART4, UART5 */
#define USART_CR2_CLKEN BIT(USART_CR2_CLKEN_BIT)
/**
* @brief Clock polarity mask.
* Not available on UART4, UART5 */
#define USART_CR2_CPOL BIT(USART_CR2_CPOL_BIT)
/** Clock polarity: low */
#define USART_CR2_CPOL_LOW (0x0 << USART_CR2_CLKEN_BIT)
/** Clock polarity: high */
#define USART_CR2_CPOL_HIGH (0x1 << USART_CR2_CLKEN_BIT)
/**
* @brief Clock phase mask.
* Not available on UART4, UART5 */
#define USART_CR2_CPHA BIT(USART_CR2_CPHA_BIT)
/**
* @brief Clock phase: first
* First clock transition is the first data capture edge. */
#define USART_CR2_CPHA_FIRST (0x0 << USART_CR2_CPHA_BIT)
/**
* @brief Clock phase: second
* Second clock transition is the first data capture edge. */
#define USART_CR2_CPHA_SECOND (0x1 << USART_CR2_CPHA_BIT)
/**
* @brief Last bit clock pulse mask.
*
* When set, the last bit transmitted causes a clock pulse in
* synchronous mode.
*
* Not available on UART4, UART5 */
#define USART_CR2_LBCL BIT(USART_CR2_LBCL_BIT)
/** LIN break detection interrupt enable mask. */
#define USART_CR2_LBDIE BIT(USART_CR2_LBDIE_BIT)
/** LIN break detection length. */
#define USART_CR2_LBDL BIT(USART_CR2_LBDL_BIT)
/** LIN break detection length: 10 bits */
#define USART_CR2_LBDL_10_BIT (0 << USART_CR2_LBDL_BIT)
/** LIN break detection length: 11 bits */
#define USART_CR2_LBDL_11_BIT (1 << USART_CR2_LBDL_BIT)
/**
* @brief Address of the USART node
* This is useful during multiprocessor communication. */
#define USART_CR2_ADD 0xF
/* Control register 3 */
/** Clear to send interrupt enable bit */
#define USART_CR3_CTSIE_BIT 10
/** Clear to send enable bit */
#define USART_CR3_CTSE_BIT 9
/** Ready to send enable bit */
#define USART_CR3_RTSE_BIT 8
/** DMA enable transmitter bit */
#define USART_CR3_DMAT_BIT 7
/** DMA enable receiver bit */
#define USART_CR3_DMAR_BIT 6
/** Smartcard mode enable bit */
#define USART_CR3_SCEN_BIT 5
/** Smartcard NACK enable bit */
#define USART_CR3_NACK_BIT 4
/** Half-duplex selection bit */
#define USART_CR3_HDSEL_BIT 3
/** IrDA low power bit */
#define USART_CR3_IRLP_BIT 2
/** IrDA mode enable bit */
#define USART_CR3_IREN_BIT 1
/** Error interrupt enable bit */
#define USART_CR3_EIE_BIT 0
/**
* @brief Clear to send interrupt enable
* Not available on UART4, UART5. */
#define USART_CR3_CTSIE BIT(USART_CR3_CTSIE_BIT)
/**
* @brief Clear to send enable
* Not available on UART4, UART5. */
#define USART_CR3_CTSE BIT(USART_CR3_CTSE_BIT)
/**
* @brief Ready to send enable
* Not available on UART4, UART5. */
#define USART_CR3_RTSE BIT(USART_CR3_RTSE_BIT)
/**
* @brief DMA enable transmitter
* Not available on UART5. */
#define USART_CR3_DMAT BIT(USART_CR3_DMAT_BIT)
/**
* @brief DMA enable receiver
* Not available on UART5. */
#define USART_CR3_DMAR BIT(USART_CR3_DMAR_BIT)
/**
* @brief Smartcard mode enable
* Not available on UART4, UART5. */
#define USART_CR3_SCEN BIT(USART_CR3_SCEN_BIT)
/**
* @brief Smartcard NACK enable
* Not available on UART4, UART5. */
#define USART_CR3_NACK BIT(USART_CR3_NACK_BIT)
/**
* @brief Half-duplex selection
* When set, single-wire half duplex mode is selected.
*/
#define USART_CR3_HDSEL BIT(USART_CR3_HDSEL_BIT)
/** IrDA low power mode */
#define USART_CR3_IRLP BIT(USART_CR3_IRLP_BIT)
/** IrDA mode: normal */
#define USART_CR3_IRLP_NORMAL (0U << USART_CR3_IRLP_BIT)
/** IrDA mode: low power */
#define USART_CR3_IRLP_LOW_POWER (1U << USART_CR3_IRLP_BIT)
/** IrDA mode enable */
#define USART_CR3_IREN BIT(USART_CR3_IREN_BIT)
/** Error interrupt enable */
#define USART_CR3_EIE BIT(USART_CR3_EIE_BIT)
/* Guard time and prescaler register */
/**
* @brief Guard time value mask
* Used in Smartcard mode. Not available on UART4, UART5. */
#define USART_GTPR_GT (0xFF << 8)
/**
* @brief Prescaler value mask
* Restrictions on this value apply, depending on the USART mode. Not
* available on UART4, UART5. */
#define USART_GTPR_PSC 0xFF
/*
* Devices
*/
#ifndef USART_RX_BUF_SIZE
#define USART_RX_BUF_SIZE 64
#endif
#ifndef USART_TX_BUF_SIZE
#define USART_TX_BUF_SIZE 64
#endif
/** USART device type */
typedef struct usart_dev {
usart_reg_map *regs; /**< Register map */
ring_buffer *rb; /**< RX ring buffer */
ring_buffer *wb; /**< TX ring buffer */
uint32 max_baud; /**< @brief Deprecated.
* Maximum baud rate. */
uint8 rx_buf[USART_RX_BUF_SIZE]; /**< @brief Deprecated.
* Actual RX buffer used by rb.
* This field will be removed in
* a future release. */
uint8 tx_buf[USART_TX_BUF_SIZE]; /**< Actual TX buffer used by wb */
rcc_clk_id clk_id; /**< RCC clock information */
nvic_irq_num irq_num; /**< USART NVIC interrupt */
} usart_dev;
void usart_init(usart_dev *dev);
struct gpio_dev; /* forward declaration */
/* 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);
void usart_enable(usart_dev *dev);
void usart_disable(usart_dev *dev);
void usart_foreach(void (*fn)(usart_dev *dev));
uint32 usart_tx(usart_dev *dev, const uint8 *buf, uint32 len);
uint32 usart_rx(usart_dev *dev, uint8 *buf, uint32 len);
void usart_putudec(usart_dev *dev, uint32 val);
/**
* @brief Disable all serial ports.
*/
static inline void usart_disable_all(void) {
usart_foreach(usart_disable);
}
/**
* @brief Transmit one character on a serial port.
*
* This function blocks until the character has been queued
* for transmission.
*
* @param dev Serial port to send on.
* @param byte Byte to transmit.
*/
static inline void usart_putc(usart_dev* dev, uint8 byte) {
while (!usart_tx(dev, &byte, 1))
;
}
/**
* @brief Transmit a character string on a serial port.
*
* This function blocks until str is completely transmitted.
*
* @param dev Serial port to send on
* @param str String to send
*/
static inline void usart_putstr(usart_dev *dev, const char* str) {
uint32 i = 0;
while (str[i] != '\0') {
usart_putc(dev, str[i++]);
}
}
/**
* @brief Read one character from a serial port.
*
* It's not safe to call this function if the serial port has no data
* available.
*
* @param dev Serial port to read from
* @return byte read
* @see usart_data_available()
*/
static inline uint8 usart_getc(usart_dev *dev) {
return rb_remove(dev->rb);
}
/*
* Roger Clark. 20141125,
* added peek function.
* @param dev Serial port to read from
* @return byte read
*/
static inline int usart_peek(usart_dev *dev)
{
return rb_peek(dev->rb);
}
/**
* @brief Return the amount of data available in a serial port's RX buffer.
* @param dev Serial port to check
* @return Number of bytes in dev's RX buffer.
*/
static inline uint32 usart_data_available(usart_dev *dev) {
return rb_full_count(dev->rb);
}
/**
* @brief Discard the contents of a serial port's RX buffer.
* @param dev Serial port whose buffer to empty.
*/
static inline void usart_reset_rx(usart_dev *dev) {
rb_reset(dev->rb);
}
/**
* @brief Discard the contents of a serial port's RX buffer.
* @param dev Serial port whose buffer to empty.
*/
static inline void usart_reset_tx(usart_dev *dev) {
rb_reset(dev->wb);
}
#ifdef __cplusplus
} // extern "C"
#endif
#endif

View File

@@ -0,0 +1,176 @@
/******************************************************************************
* The MIT License
*
* Copyright (c) 2010, 2011, 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.
*****************************************************************************/
/*
* NOTE: This API is _unstable_ and will change drastically over time.
*/
#ifndef _LIBMAPLE_USB_H_
#define _LIBMAPLE_USB_H_
#ifdef __cplusplus
extern "C" {
#endif
#include <libmaple/libmaple_types.h>
#include <libmaple/rcc.h>
/*
* Descriptors and other paraphernalia
*/
/* Descriptor types */
#define USB_DESCRIPTOR_TYPE_DEVICE 0x01
#define USB_DESCRIPTOR_TYPE_CONFIGURATION 0x02
#define USB_DESCRIPTOR_TYPE_STRING 0x03
#define USB_DESCRIPTOR_TYPE_INTERFACE 0x04
#define USB_DESCRIPTOR_TYPE_ENDPOINT 0x05
/* Descriptor structs and declaration helpers */
#define USB_DESCRIPTOR_STRING_LEN(x) (2 + (x << 1))
#define USB_DESCRIPTOR_STRING(len) \
struct { \
uint8 bLength; \
uint8 bDescriptorType; \
uint16 bString[len]; \
} __packed
typedef struct usb_descriptor_device {
uint8 bLength;
uint8 bDescriptorType;
uint16 bcdUSB;
uint8 bDeviceClass;
uint8 bDeviceSubClass;
uint8 bDeviceProtocol;
uint8 bMaxPacketSize0;
uint16 idVendor;
uint16 idProduct;
uint16 bcdDevice;
uint8 iManufacturer;
uint8 iProduct;
uint8 iSerialNumber;
uint8 bNumConfigurations;
} __packed usb_descriptor_device;
typedef struct usb_descriptor_config_header {
uint8 bLength;
uint8 bDescriptorType;
uint16 wTotalLength;
uint8 bNumInterfaces;
uint8 bConfigurationValue;
uint8 iConfiguration;
uint8 bmAttributes;
uint8 bMaxPower;
} __packed usb_descriptor_config_header;
typedef struct usb_descriptor_interface {
uint8 bLength;
uint8 bDescriptorType;
uint8 bInterfaceNumber;
uint8 bAlternateSetting;
uint8 bNumEndpoints;
uint8 bInterfaceClass;
uint8 bInterfaceSubClass;
uint8 bInterfaceProtocol;
uint8 iInterface;
} __packed usb_descriptor_interface;
typedef struct usb_descriptor_endpoint {
uint8 bLength;
uint8 bDescriptorType;
uint8 bEndpointAddress;
uint8 bmAttributes;
uint16 wMaxPacketSize;
uint8 bInterval;
} __packed usb_descriptor_endpoint;
typedef struct usb_descriptor_string {
uint8 bLength;
uint8 bDescriptorType;
uint8 bString[];
} usb_descriptor_string;
/* Common values that go inside descriptors */
#define USB_CONFIG_ATTR_BUSPOWERED 0b10000000
#define USB_CONFIG_ATTR_SELF_POWERED 0b11000000
#define USB_EP_TYPE_INTERRUPT 0x03
#define USB_EP_TYPE_BULK 0x02
#define USB_DESCRIPTOR_ENDPOINT_IN 0x80
#define USB_DESCRIPTOR_ENDPOINT_OUT 0x00
/*
* USB module core
*/
#ifndef USB_ISR_MSK
/* Handle CTRM, WKUPM, SUSPM, ERRM, SOFM, ESOFM, RESETM */
#define USB_ISR_MSK 0xBF00
#endif
typedef enum usb_dev_state {
USB_UNCONNECTED,
USB_ATTACHED,
USB_POWERED,
USB_SUSPENDED,
USB_ADDRESSED,
USB_CONFIGURED
} usb_dev_state;
/* Encapsulates global state formerly handled by usb_lib/ */
typedef struct usblib_dev {
uint32 irq_mask;
void (**ep_int_in)(void);
void (**ep_int_out)(void);
usb_dev_state state;
usb_dev_state prevState;
rcc_clk_id clk_id;
} usblib_dev;
extern usblib_dev *USBLIB;
void usb_init_usblib(usblib_dev *dev,
void (**ep_int_in)(void),
void (**ep_int_out)(void));
static inline uint8 usb_is_connected(usblib_dev *dev) {
return dev->state != USB_UNCONNECTED;
}
static inline uint8 usb_is_configured(usblib_dev *dev) {
return dev->state == USB_CONFIGURED;
}
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -0,0 +1,180 @@
/******************************************************************************
* The MIT License
*
* Copyright (c) 2011 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/include/libmaple/usb_cdcacm.h
* @brief USB CDC ACM (virtual serial terminal) support
*
* IMPORTANT: this API is unstable, and may change without notice.
*/
#ifndef _LIBMAPLE_USB_CDCACM_H_
#define _LIBMAPLE_USB_CDCACM_H_
#include <libmaple/libmaple_types.h>
#include <libmaple/gpio.h>
#include <libmaple/usb.h>
#ifdef __cplusplus
extern "C" {
#endif
/*
* CDC ACM Requests
*/
#define USB_CDCACM_SET_LINE_CODING 0x20
#define USB_CDCACM_GET_LINE_CODING 0x21
#define USB_CDCACM_SET_COMM_FEATURE 0x02
#define USB_CDCACM_SET_CONTROL_LINE_STATE 0x22
#define USB_CDCACM_CONTROL_LINE_DTR (0x01)
#define USB_CDCACM_CONTROL_LINE_RTS (0x02)
/*
* Descriptors, etc.
*/
#define CDC_FUNCTIONAL_DESCRIPTOR_SIZE(DataSize) (3 + DataSize)
#define CDC_FUNCTIONAL_DESCRIPTOR(DataSize) \
struct { \
uint8 bLength; \
uint8 bDescriptorType; \
uint8 SubType; \
uint8 Data[DataSize]; \
} __packed
#define USB_DEVICE_CLASS_CDC 0x02
#define USB_DEVICE_SUBCLASS_CDC 0x00
#define USB_INTERFACE_CLASS_CDC 0x02
#define USB_INTERFACE_SUBCLASS_CDC_ACM 0x02
#define USB_INTERFACE_CLASS_DIC 0x0A
/*
* Endpoint configuration
*/
#define USB_CDCACM_CTRL_ENDP 0
#define USB_CDCACM_CTRL_RX_ADDR 0x40
#define USB_CDCACM_CTRL_TX_ADDR 0x80
#define USB_CDCACM_CTRL_EPSIZE 0x40
#define USB_CDCACM_TX_ENDP 1
#define USB_CDCACM_TX_ADDR 0xC0
#define USB_CDCACM_TX_EPSIZE 0x40
#define USB_CDCACM_MANAGEMENT_ENDP 2
#define USB_CDCACM_MANAGEMENT_ADDR 0x100
#define USB_CDCACM_MANAGEMENT_EPSIZE 0x40
#define USB_CDCACM_RX_ENDP 3
#define USB_CDCACM_RX_ADDR 0x110
#define USB_CDCACM_RX_EPSIZE 0x40
#ifndef __cplusplus
#define USB_CDCACM_DECLARE_DEV_DESC(vid, pid) \
{ \
.bLength = sizeof(usb_descriptor_device), \
.bDescriptorType = USB_DESCRIPTOR_TYPE_DEVICE, \
.bcdUSB = 0x0200, \
.bDeviceClass = USB_DEVICE_CLASS_CDC, \
.bDeviceSubClass = USB_DEVICE_SUBCLASS_CDC, \
.bDeviceProtocol = 0x00, \
.bMaxPacketSize0 = 0x40, \
.idVendor = vid, \
.idProduct = pid, \
.bcdDevice = 0x0200, \
.iManufacturer = 0x01, \
.iProduct = 0x02, \
.iSerialNumber = 0x00, \
.bNumConfigurations = 0x01, \
}
#endif
/*
* CDC ACM interface
*/
void usb_cdcacm_enable(gpio_dev*, uint8);
void usb_cdcacm_disable(gpio_dev*, uint8);
void usb_cdcacm_putc(char ch);
uint32 usb_cdcacm_tx(const uint8* buf, uint32 len);
uint32 usb_cdcacm_rx(uint8* buf, uint32 len);
uint32 usb_cdcacm_peek(uint8* buf, uint32 len);
uint32 usb_cdcacm_peek_ex(uint8* buf, uint32 offset, uint32 len);
uint32 usb_cdcacm_data_available(void); /* in RX buffer */
uint16 usb_cdcacm_get_pending(void);
uint8 usb_cdcacm_is_transmitting(void);
uint8 usb_cdcacm_get_dtr(void);
uint8 usb_cdcacm_get_rts(void);
typedef struct usb_cdcacm_line_coding {
uint32 dwDTERate; /* Baud rate */
#define USB_CDCACM_STOP_BITS_1 0
#define USB_CDCACM_STOP_BITS_1_5 1
#define USB_CDCACM_STOP_BITS_2 2
uint8 bCharFormat; /* Stop bits */
#define USB_CDCACM_PARITY_NONE 0
#define USB_CDCACM_PARITY_ODD 1
#define USB_CDCACM_PARITY_EVEN 2
#define USB_CDCACM_PARITY_MARK 3
#define USB_CDCACM_PARITY_SPACE 4
uint8 bParityType; /* Parity type */
uint8 bDataBits; /* Data bits: 5, 6, 7, 8, or 16 */
} __packed usb_cdcacm_line_coding;
/* Retrieve a copy of the current line coding structure. */
void usb_cdcacm_get_line_coding(usb_cdcacm_line_coding*);
/* Line coding conveniences. */
int usb_cdcacm_get_baud(void); /* dwDTERate */
int usb_cdcacm_get_stop_bits(void); /* bCharFormat */
int usb_cdcacm_get_parity(void); /* bParityType */
int usb_cdcacm_get_n_data_bits(void); /* bDataBits */
/*
* Hack: hooks for bootloader reset signalling
*/
#define USB_CDCACM_HOOK_RX 0x1
#define USB_CDCACM_HOOK_IFACE_SETUP 0x2
void usb_cdcacm_set_hooks(unsigned hook_flags, void (*hook)(unsigned, void*));
static inline __always_inline void usb_cdcacm_remove_hooks(unsigned hook_flags) {
usb_cdcacm_set_hooks(hook_flags, 0);
}
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -0,0 +1,111 @@
/******************************************************************************
* The MIT License
*
* 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/include/libmaple/util.h
* @brief Miscellaneous utility macros and procedures.
*/
#ifndef _LIBMAPLE_UTIL_H_
#define _LIBMAPLE_UTIL_H_
#ifdef __cplusplus
extern "C"{
#endif
#include <libmaple/libmaple_types.h>
/*
* Bit manipulation
*/
/** 1UL shifted left by 'shift' */
#define BIT(shift) (1UL << (shift))
/** 'Mask' shifted left by 'shift' */
#define BIT_MASK_SHIFT(mask, shift) ((mask) << (shift))
/** Bits m to n of x */
#define GET_BITS(x, m, n) ((((uint32)x) << (31 - (n))) >> ((31 - (n)) + (m)))
/** True iff v is a power of two (1, 2, 4, 8, ...) */
#define IS_POWER_OF_TWO(v) ((v) && !((v) & ((v) - 1)))
/*
* Failure routines
*/
void __error(void);
void _fail(const char*, int, const char*);
void throb(void);
/*
* Asserts and debug levels
*/
#define DEBUG_NONE 0
#define DEBUG_FAULT 1
#define DEBUG_ALL 2
/**
* \def DEBUG_LEVEL
*
* Controls the level of assertion checking.
*
* The higher the debug level, the more assertions will be compiled
* in. This increases the amount of debugging information, but slows
* down (and increases the size of) the binary.
*
* The debug levels, from lowest to highest, are DEBUG_NONE,
* DEBUG_FAULT, and DEBUG_ALL. The default level is DEBUG_ALL.
*/
#ifndef DEBUG_LEVEL
#define DEBUG_LEVEL DEBUG_ALL
#endif
#if DEBUG_LEVEL >= DEBUG_ALL
#define ASSERT(exp) \
if (exp) { \
} else { \
_fail(__FILE__, __LINE__, #exp); \
}
#else
#define ASSERT(exp) (void)((0))
#endif
#if DEBUG_LEVEL >= DEBUG_FAULT
#define ASSERT_FAULT(exp) \
if (exp) { \
} else { \
_fail(__FILE__, __LINE__, #exp); \
}
#else
#define ASSERT_FAULT(exp) (void)((0))
#endif
#ifdef __cplusplus
} // extern "C"
#endif
#endif

View File

@@ -0,0 +1,74 @@
/******************************************************************************
* The MIT License
*
* Copyright (c) 2011 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.
*****************************************************************************/
/*
* RCC private header.
*/
#ifndef _LIBMAPLE_PRIVATE_RCC_H_
#define _LIBMAPLE_PRIVATE_RCC_H_
#include <libmaple/bitband.h>
struct rcc_dev_info {
const rcc_clk_domain clk_domain;
const uint8 line_num;
};
extern const struct rcc_dev_info rcc_dev_table[];
static inline void rcc_do_clk_enable(__io uint32** enable_regs,
rcc_clk_id id) {
__io uint32 *enable_reg = enable_regs[rcc_dev_clk(id)];
uint8 line_num = rcc_dev_table[id].line_num;
bb_peri_set_bit(enable_reg, line_num, 1);
}
static inline void rcc_do_reset_dev(__io uint32** reset_regs,
rcc_clk_id id) {
__io uint32 *reset_reg = reset_regs[rcc_dev_clk(id)];
uint8 line_num = rcc_dev_table[id].line_num;
bb_peri_set_bit(reset_reg, line_num, 1);
bb_peri_set_bit(reset_reg, line_num, 0);
}
static inline void rcc_do_set_prescaler(const uint32 *masks,
rcc_prescaler prescaler,
uint32 divider) {
uint32 cfgr = RCC_BASE->CFGR;
cfgr &= ~masks[prescaler];
cfgr |= divider;
RCC_BASE->CFGR = cfgr;
}
static inline void rcc_do_clk_disable(__io uint32** enable_regs,
rcc_clk_id id) {
__io uint32 *enable_reg = enable_regs[rcc_dev_clk(id)];
uint8 line_num = rcc_dev_table[id].line_num;
bb_peri_set_bit(enable_reg, line_num, 0);
}
#endif

View File

@@ -0,0 +1,50 @@
# Standard things
sp := $(sp).x
dirstack_$(sp) := $(d)
d := $(dir)
BUILDDIRS += $(BUILD_PATH)/$(d)
LIBMAPLE_INCLUDES := -I$(LIBMAPLE_PATH)/include -I$(LIBMAPLE_MODULE_SERIES)/include
LIBMAPLE_PRIVATE_INCLUDES := -I$(LIBMAPLE_PATH)
# Local flags
CFLAGS_$(d) = $(LIBMAPLE_PRIVATE_INCLUDES) $(LIBMAPLE_INCLUDES) -Wall -Werror
# Local rules and targets
cSRCS_$(d) := adc.c
cSRCS_$(d) += dac.c
cSRCS_$(d) += dma.c
cSRCS_$(d) += exti.c
cSRCS_$(d) += flash.c
cSRCS_$(d) += gpio.c
cSRCS_$(d) += iwdg.c
cSRCS_$(d) += nvic.c
cSRCS_$(d) += pwr.c
cSRCS_$(d) += rcc.c
cSRCS_$(d) += spi.c
cSRCS_$(d) += systick.c
cSRCS_$(d) += timer.c
cSRCS_$(d) += usart.c
cSRCS_$(d) += usart_private.c
cSRCS_$(d) += util.c
sSRCS_$(d) := exc.S
# I2C support must be ported to F2:
ifeq ($(MCU_SERIES),stm32f1)
cSRCS_$(d) += i2c.c
endif
cFILES_$(d) := $(cSRCS_$(d):%=$(d)/%)
sFILES_$(d) := $(sSRCS_$(d):%=$(d)/%)
OBJS_$(d) := $(cFILES_$(d):%.c=$(BUILD_PATH)/%.o) $(sFILES_$(d):%.S=$(BUILD_PATH)/%.o)
DEPS_$(d) := $(OBJS_$(d):%.o=%.d)
$(OBJS_$(d)): TGT_CFLAGS := $(CFLAGS_$(d))
$(OBJS_$(d)): TGT_ASFLAGS :=
TGT_BIN += $(OBJS_$(d))
# Standard things
-include $(DEPS_$(d))
d := $(dirstack_$(sp))
sp := $(basename $(sp))

View File

@@ -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

View File

@@ -0,0 +1,45 @@
/******************************************************************************
* 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_STM32_PRIVATE_H_
#define _LIBMAPLE_STM32_PRIVATE_H_
typedef enum stm32_mem_block_purpose {
STM32_BLOCK_CODE,
STM32_BLOCK_SRAM,
STM32_BLOCK_PERIPH,
STM32_BLOCK_FSMC_1_2,
STM32_BLOCK_FSMC_3_4,
STM32_BLOCK_FSMC_REG,
STM32_BLOCK_UNUSED,
STM32_BLOCK_CORTEX_INTERNAL,
} stm32_mem_block_purpose;
static inline stm32_mem_block_purpose stm32_block_purpose(void *addr) {
return (stm32_mem_block_purpose)((unsigned)addr >> 29);
}
#endif

View File

@@ -0,0 +1,271 @@
/******************************************************************************
* The MIT License
*
* Copyright (c) 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/adc.h
* @author Marti Bolivar <mbolivar@leaflabs.com>,
* Perry Hung <perry@leaflabs.com>
* @brief STM32F1 ADC header.
*/
#ifndef _LIBMAPLE_STM32F1_ADC_H_
#define _LIBMAPLE_STM32F1_ADC_H_
#include <libmaple/bitband.h>
#include <libmaple/libmaple_types.h>
#include <libmaple/rcc.h> /* For the prescalers */
/*
* Devices
*/
extern adc_dev adc1;
extern struct adc_dev *ADC1;
extern adc_dev adc2;
extern struct adc_dev *ADC2;
#if defined(STM32_HIGH_DENSITY) || defined(STM32_XL_DENSITY)
extern adc_dev adc3;
extern struct adc_dev *ADC3;
#endif
/*
* Register map base pointers
*/
/** STM32F1 ADC1 register map base pointer. */
#define ADC1_BASE ((struct adc_reg_map*)0x40012400)
/** STM32F1 ADC2 register map base pointer. */
#define ADC2_BASE ((struct adc_reg_map*)0x40012800)
/** STM32F1 ADC3 register map base pointer. */
#define ADC3_BASE ((struct adc_reg_map*)0x40013C00)
/*
* Register bit definitions
*/
/* Control register 2 */
#define ADC_CR2_ADON_BIT 0
#define ADC_CR2_CONT_BIT 1
#define ADC_CR2_CAL_BIT 2
#define ADC_CR2_RSTCAL_BIT 3
#define ADC_CR2_DMA_BIT 8
#define ADC_CR2_ALIGN_BIT 11
#define ADC_CR2_JEXTTRIG_BIT 15
#define ADC_CR2_EXTTRIG_BIT 20
#define ADC_CR2_JSWSTART_BIT 21
#define ADC_CR2_SWSTART_BIT 22
#define ADC_CR2_TSVREFE_BIT 23
#define ADC_CR2_ADON (1U << ADC_CR2_ADON_BIT)
#define ADC_CR2_CONT (1U << ADC_CR2_CONT_BIT)
#define ADC_CR2_CAL (1U << ADC_CR2_CAL_BIT)
#define ADC_CR2_RSTCAL (1U << ADC_CR2_RSTCAL_BIT)
#define ADC_CR2_DMA (1U << ADC_CR2_DMA_BIT)
#define ADC_CR2_ALIGN (1U << ADC_CR2_ALIGN_BIT)
#define ADC_CR2_JEXTSEL 0x7000
#define ADC_CR2_JEXTSEL_TIM1_TRGO (0x0 << 12)
#define ADC_CR2_JEXTSEL_TIM1_CC4 (0x1 << 12)
#define ADC_CR2_JEXTSEL_TIM2_TRGO (0x2 << 12)
#define ADC_CR2_JEXTSEL_TIM2_CC1 (0x3 << 12)
#define ADC_CR2_JEXTSEL_TIM3_CC4 (0x4 << 12)
#define ADC_CR2_JEXTSEL_TIM4_TRGO (0x5 << 12)
#define ADC_CR2_JEXTSEL_EXTI15 (0x6 << 12)
#define ADC_CR2_JEXTSEL_JSWSTART (0x7 << 12)
#define ADC_CR2_JEXTTRIG (1U << ADC_CR2_JEXTTRIG_BIT)
#define ADC_CR2_EXTSEL 0xE0000
#define ADC_CR2_EXTSEL_TIM1_CC1 (0x0 << 17)
#define ADC_CR2_EXTSEL_TIM1_CC2 (0x1 << 17)
#define ADC_CR2_EXTSEL_TIM1_CC3 (0x2 << 17)
#define ADC_CR2_EXTSEL_TIM2_CC2 (0x3 << 17)
#define ADC_CR2_EXTSEL_TIM3_TRGO (0x4 << 17)
#define ADC_CR2_EXTSEL_TIM4_CC4 (0x5 << 17)
#define ADC_CR2_EXTSEL_EXTI11 (0x6 << 17)
#define ADC_CR2_EXTSEL_SWSTART (0x7 << 17)
#define ADC_CR2_EXTTRIG (1U << ADC_CR2_EXTTRIG_BIT)
#define ADC_CR2_JSWSTART (1U << ADC_CR2_JSWSTART_BIT)
#define ADC_CR2_SWSTART (1U << ADC_CR2_SWSTART_BIT)
#define ADC_CR2_TSVREFE (1U << ADC_CR2_TSVREFE_BIT)
/*
* Other types
*/
/**
* @brief STM32F1 external event selectors for regular group
* conversion.
*
* Some external events are only available on ADCs 1 and 2, others
* only on ADC3, while others are available on all three ADCs.
* Additionally, some events are only available on high- and
* XL-density STM32F1 MCUs, as they use peripherals only available on
* those MCU densities.
*
* For ease of use, each event selector is given along with the ADCs
* it's available on, along with any other availability restrictions.
*
* @see adc_set_extsel()
*/
typedef enum adc_extsel_event {
/* TODO: Smarten this up a bit, as follows.
*
* The EXTSEL bits on F1 are a little brain-damaged in that the
* TIM8 TRGO event has different bits depending on whether you're
* using ADC1/2 or ADC3. We route around this by declaring two
* enumerators, ADC_EXT_EV_ADC12_TIM8_TRGO and
* ADC_EXT_EV_ADC3_TIM8_TRGO.
*
* The right thing to do is to provide a single
* ADC_EXT_EV_TIM8_TRGO enumerator and override adc_set_extsel on
* STM32F1 to handle this situation correctly. We can do that
* later, though, and change the per-ADC enumerator values to
* ADC_EXT_EV_TIM8_TRGO to preserve compatibility. */
/* ADC1 and ADC2 only: */
ADC_EXT_EV_TIM1_CC1 = 0x00000, /**< ADC1, ADC2: Timer 1 CC1 event */
ADC_EXT_EV_TIM1_CC2 = 0x20000, /**< ADC1, ADC2: Timer 1 CC2 event */
ADC_EXT_EV_TIM2_CC2 = 0x60000, /**< ADC1, ADC2: Timer 2 CC2 event */
ADC_EXT_EV_TIM3_TRGO = 0x80000, /**< ADC1, ADC2: Timer 3 TRGO event */
ADC_EXT_EV_TIM4_CC4 = 0xA0000, /**< ADC1, ADC2: Timer 4 CC4 event */
ADC_EXT_EV_EXTI11 = 0xC0000, /**< ADC1, ADC2: EXTI11 event */
/* Common: */
ADC_EXT_EV_TIM1_CC3 = 0x40000, /**< ADC1, ADC2, ADC3: Timer 1 CC3 event */
ADC_EXT_EV_SWSTART = 0xE0000, /**< ADC1, ADC2, ADC3: Software start */
/* HD only: */
ADC_EXT_EV_TIM3_CC1 = 0x00000, /**<
* ADC3: Timer 3 CC1 event
* Availability: high- and XL-density. */
ADC_EXT_EV_TIM2_CC3 = 0x20000, /**<
* ADC3: Timer 2 CC3 event
* Availability: high- and XL-density. */
ADC_EXT_EV_TIM8_CC1 = 0x60000, /**<
* ADC3: Timer 8 CC1 event
* Availability: high- and XL-density. */
ADC_EXT_EV_ADC3_TIM8_TRGO = 0x80000, /**<
* ADC3: Timer 8 TRGO event
* Availability: high- and XL-density. */
ADC_EXT_EV_TIM5_CC1 = 0xA0000, /**<
* ADC3: Timer 5 CC1 event
* Availability: high- and XL-density. */
ADC_EXT_EV_ADC12_TIM8_TRGO = 0xC0000, /**<
* ADC1, ADC2: Timer 8 TRGO event
* Availability: high- and XL-density. */
ADC_EXT_EV_TIM5_CC3 = 0xC0000, /**<
* ADC3: Timer 5 CC3 event
* Availability: high- and XL-density. */
} adc_extsel_event;
/* We'll keep these old adc_extsel_event enumerators around for a
* while, for backwards compatibility: */
/** Deprecated. Use ADC_EXT_EV_TIM1_CC1 instead. */
#define ADC_ADC12_TIM1_CC1 ADC_EXT_EV_TIM1_CC1
/** Deprecated. Use ADC_EXT_EV_TIM1_CC2 instead. */
#define ADC_ADC12_TIM1_CC2 ADC_EXT_EV_TIM1_CC2
/** Deprecated. Use ADC_EXT_EV_TIM1_CC3 instead. */
#define ADC_ADC12_TIM1_CC3 ADC_EXT_EV_TIM1_CC3
/** Deprecated. Use ADC_EXT_EV_TIM2_CC2 instead. */
#define ADC_ADC12_TIM2_CC2 ADC_EXT_EV_TIM2_CC2
/** Deprecated. Use ADC_EXT_EV_TIM3_TRGO instead. */
#define ADC_ADC12_TIM3_TRGO ADC_EXT_EV_TIM3_TRGO
/** Deprecated. Use ADC_EXT_EV_TIM4_CC4 instead. */
#define ADC_ADC12_TIM4_CC4 ADC_EXT_EV_TIM4_CC4
/** Deprecated. Use ADC_EXT_EV_EXTI11 instead. */
#define ADC_ADC12_EXTI11 ADC_EXT_EV_EXTI11
/** Deprecated. Use ADC_EXT_EV_ADC12_TIM8_TRGO instead. */
#define ADC_ADC12_TIM8_TRGO ADC_EXT_EV_ADC12_TIM8_TRGO
/** Deprecated. Use ADC_EXT_EV_SWSTART instead. */
#define ADC_ADC12_SWSTART ADC_EXT_EV_SWSTART
/** Deprecated. Use ADC_EXT_EV_TIM1_CC1 instead. */
#define ADC_ADC3_TIM3_CC1 ADC_EXT_EV_TIM1_CC1
/** Deprecated. Use ADC_EXT_EV_TIM1_CC2 instead. */
#define ADC_ADC3_TIM2_CC3 ADC_EXT_EV_TIM1_CC2
/** Deprecated. Use ADC_EXT_EV_TIM1_CC3 instead. */
#define ADC_ADC3_TIM1_CC3 ADC_EXT_EV_TIM1_CC3
/** Deprecated. Use ADC_EXT_EV_TIM2_CC2 instead. */
#define ADC_ADC3_TIM8_CC1 ADC_EXT_EV_TIM2_CC2
/** Deprecated. Use ADC_EXT_EV_TIM3_TRGO instead. */
#define ADC_ADC3_TIM8_TRGO ADC_EXT_EV_TIM3_TRGO
/** Deprecated. Use ADC_EXT_EV_TIM4_CC4 instead. */
#define ADC_ADC3_TIM5_CC1 ADC_EXT_EV_TIM4_CC4
/** Deprecated. Use ADC_EXT_EV_EXTI11 instead. */
#define ADC_ADC3_TIM5_CC3 ADC_EXT_EV_EXTI11
/** Deprecated. Use ADC_EXT_EV_TIM8_TRGO instead. */
#define ADC_ADC3_SWSTART ADC_EXT_EV_TIM8_TRGO
/** Deprecated. Use ADC_EXT_EV_SWSTART instead. */
#define ADC_SWSTART ADC_EXT_EV_SWSTART
/**
* @brief STM32F1 sample times, in ADC clock cycles.
*
* These control the amount of time spent sampling the input voltage.
*/
typedef enum adc_smp_rate {
ADC_SMPR_1_5, /**< 1.5 ADC cycles */
ADC_SMPR_7_5, /**< 7.5 ADC cycles */
ADC_SMPR_13_5, /**< 13.5 ADC cycles */
ADC_SMPR_28_5, /**< 28.5 ADC cycles */
ADC_SMPR_41_5, /**< 41.5 ADC cycles */
ADC_SMPR_55_5, /**< 55.5 ADC cycles */
ADC_SMPR_71_5, /**< 71.5 ADC cycles */
ADC_SMPR_239_5, /**< 239.5 ADC cycles */
} adc_smp_rate;
/**
* @brief STM32F1 ADC prescalers, as divisors of PCLK2.
*/
typedef enum adc_prescaler {
/** PCLK2 divided by 2 */
ADC_PRE_PCLK2_DIV_2 = RCC_ADCPRE_PCLK_DIV_2,
/** PCLK2 divided by 4 */
ADC_PRE_PCLK2_DIV_4 = RCC_ADCPRE_PCLK_DIV_4,
/** PCLK2 divided by 6 */
ADC_PRE_PCLK2_DIV_6 = RCC_ADCPRE_PCLK_DIV_6,
/** PCLK2 divided by 8 */
ADC_PRE_PCLK2_DIV_8 = RCC_ADCPRE_PCLK_DIV_8,
} adc_prescaler;
/*
* Routines
*/
void adc_calibrate(adc_dev *dev);
/**
* @brief Set external trigger conversion mode event for regular channels
*
* Availability: STM32F1.
*
* @param dev ADC device
* @param enable If 1, conversion on external events is enabled; if 0,
* disabled.
*/
static inline void adc_set_exttrig(adc_dev *dev, uint8 enable) {
*bb_perip(&dev->regs->CR2, ADC_CR2_EXTTRIG_BIT) = !!enable;
}
#endif

View File

@@ -0,0 +1,71 @@
/******************************************************************************
* 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/stm32f1/include/series/dac.h
* @brief STM32F1 DAC support
*/
#ifndef _LIBMAPLE_STM32F1_DAC_H_
#define _LIBMAPLE_STM32F1_DAC_H_
#ifdef __cplusplus
extern "C"{
#endif
#include <libmaple/libmaple_types.h>
/** STM32F1 DAC register map type. */
typedef struct dac_reg_map {
__io uint32 CR; /**< Control register */
__io uint32 SWTRIGR; /**< Software trigger register */
__io uint32 DHR12R1; /**< Channel 1 12-bit right-aligned data
holding register */
__io uint32 DHR12L1; /**< Channel 1 12-bit left-aligned data
holding register */
__io uint32 DHR8R1; /**< Channel 1 8-bit left-aligned data
holding register */
__io uint32 DHR12R2; /**< Channel 2 12-bit right-aligned data
holding register */
__io uint32 DHR12L2; /**< Channel 2 12-bit left-aligned data
holding register */
__io uint32 DHR8R2; /**< Channel 2 8-bit left-aligned data
holding register */
__io uint32 DHR12RD; /**< Dual DAC 12-bit right-aligned data
holding register */
__io uint32 DHR12LD; /**< Dual DAC 12-bit left-aligned data
holding register */
__io uint32 DHR8RD; /**< Dual DAC 8-bit right-aligned data holding
register */
__io uint32 DOR1; /**< Channel 1 data output register */
__io uint32 DOR2; /**< Channel 2 data output register */
} dac_reg_map;
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -0,0 +1,574 @@
/******************************************************************************
* The MIT License
*
* Copyright (c) 2010 Michael Hope.
* 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/stm32f1/include/series/dma.h
* @author Marti Bolivar <mbolivar@leaflabs.com>;
* Original implementation by Michael Hope
* @brief STM32F1 DMA series header.
*/
/*
* See /notes/dma-stm32f1.txt for more information.
*/
#ifndef _LIBMAPLE_STM32F1_DMA_H_
#define _LIBMAPLE_STM32F1_DMA_H_
#ifdef __cplusplus
extern "C"{
#endif
#include <libmaple/libmaple_types.h>
#include <libmaple/dma_common.h>
/*
* Register maps and base pointers
*/
/**
* @brief STM32F1 DMA register map type.
*
* Note that DMA controller 2 (register map base pointer DMA2_BASE)
* only supports channels 1--5.
*/
typedef struct dma_reg_map {
__io uint32 ISR; /**< Interrupt status register */
__io uint32 IFCR; /**< Interrupt flag clear register */
__io uint32 CCR1; /**< Channel 1 configuration register */
__io uint32 CNDTR1; /**< Channel 1 number of data register */
__io uint32 CPAR1; /**< Channel 1 peripheral address register */
__io uint32 CMAR1; /**< Channel 1 memory address register */
const uint32 RESERVED1; /**< Reserved. */
__io uint32 CCR2; /**< Channel 2 configuration register */
__io uint32 CNDTR2; /**< Channel 2 number of data register */
__io uint32 CPAR2; /**< Channel 2 peripheral address register */
__io uint32 CMAR2; /**< Channel 2 memory address register */
const uint32 RESERVED2; /**< Reserved. */
__io uint32 CCR3; /**< Channel 3 configuration register */
__io uint32 CNDTR3; /**< Channel 3 number of data register */
__io uint32 CPAR3; /**< Channel 3 peripheral address register */
__io uint32 CMAR3; /**< Channel 3 memory address register */
const uint32 RESERVED3; /**< Reserved. */
__io uint32 CCR4; /**< Channel 4 configuration register */
__io uint32 CNDTR4; /**< Channel 4 number of data register */
__io uint32 CPAR4; /**< Channel 4 peripheral address register */
__io uint32 CMAR4; /**< Channel 4 memory address register */
const uint32 RESERVED4; /**< Reserved. */
__io uint32 CCR5; /**< Channel 5 configuration register */
__io uint32 CNDTR5; /**< Channel 5 number of data register */
__io uint32 CPAR5; /**< Channel 5 peripheral address register */
__io uint32 CMAR5; /**< Channel 5 memory address register */
const uint32 RESERVED5; /**< Reserved. */
__io uint32 CCR6; /**< Channel 6 configuration register */
__io uint32 CNDTR6; /**< Channel 6 number of data register */
__io uint32 CPAR6; /**< Channel 6 peripheral address register */
__io uint32 CMAR6; /**< Channel 6 memory address register */
const uint32 RESERVED6; /**< Reserved. */
__io uint32 CCR7; /**< Channel 7 configuration register */
__io uint32 CNDTR7; /**< Channel 7 number of data register */
__io uint32 CPAR7; /**< Channel 7 peripheral address register */
__io uint32 CMAR7; /**< Channel 7 memory address register */
const uint32 RESERVED7; /**< Reserved. */
} dma_reg_map;
/** DMA controller 1 register map base pointer */
#define DMA1_BASE ((struct dma_reg_map*)0x40020000)
/** DMA controller 2 register map base pointer */
#define DMA2_BASE ((struct dma_reg_map*)0x40020400)
/**
* @brief STM32F1 DMA channel (i.e. tube) register map type.
* Provides access to an individual channel's registers.
* @see dma_tube_regs()
*/
typedef struct dma_tube_reg_map {
__io uint32 CCR; /**< Channel configuration register */
__io uint32 CNDTR; /**< Channel number of data register */
__io uint32 CPAR; /**< Channel peripheral address register */
__io uint32 CMAR; /**< Channel memory address register */
} dma_tube_reg_map;
/** DMA1 channel 1 register map base pointer */
#define DMA1CH1_BASE ((struct dma_tube_reg_map*)0x40020008)
/** DMA1 channel 2 register map base pointer */
#define DMA1CH2_BASE ((struct dma_tube_reg_map*)0x4002001C)
/** DMA1 channel 3 register map base pointer */
#define DMA1CH3_BASE ((struct dma_tube_reg_map*)0x40020030)
/** DMA1 channel 4 register map base pointer */
#define DMA1CH4_BASE ((struct dma_tube_reg_map*)0x40020044)
/** DMA1 channel 5 register map base pointer */
#define DMA1CH5_BASE ((struct dma_tube_reg_map*)0x40020058)
/** DMA1 channel 6 register map base pointer */
#define DMA1CH6_BASE ((struct dma_tube_reg_map*)0x4002006C)
/** DMA1 channel 7 register map base pointer */
#define DMA1CH7_BASE ((struct dma_tube_reg_map*)0x40020080)
/** DMA2 channel 1 register map base pointer */
#define DMA2CH1_BASE ((struct dma_tube_reg_map*)0x40020408)
/** DMA2 channel 2 register map base pointer */
#define DMA2CH2_BASE ((struct dma_tube_reg_map*)0x4002041C)
/** DMA2 channel 3 register map base pointer */
#define DMA2CH3_BASE ((struct dma_tube_reg_map*)0x40020430)
/** DMA2 channel 4 register map base pointer */
#define DMA2CH4_BASE ((struct dma_tube_reg_map*)0x40020444)
/** DMA2 channel 5 register map base pointer */
#define DMA2CH5_BASE ((struct dma_tube_reg_map*)0x40020458)
/*
* Register bit definitions
*/
/* Interrupt status register */
#define DMA_ISR_TEIF_BIT 3
#define DMA_ISR_HTIF_BIT 2
#define DMA_ISR_TCIF_BIT 1
#define DMA_ISR_GIF_BIT 0
#define DMA_ISR_TEIF (1 << DMA_ISR_TEIF_BIT)
#define DMA_ISR_HTIF (1 << DMA_ISR_HTIF_BIT)
#define DMA_ISR_TCIF (1 << DMA_ISR_TCIF_BIT)
#define DMA_ISR_GIF (1 << DMA_ISR_GIF_BIT)
#define DMA_ISR_TEIF7_BIT 27
#define DMA_ISR_HTIF7_BIT 26
#define DMA_ISR_TCIF7_BIT 25
#define DMA_ISR_GIF7_BIT 24
#define DMA_ISR_TEIF6_BIT 23
#define DMA_ISR_HTIF6_BIT 22
#define DMA_ISR_TCIF6_BIT 21
#define DMA_ISR_GIF6_BIT 20
#define DMA_ISR_TEIF5_BIT 19
#define DMA_ISR_HTIF5_BIT 18
#define DMA_ISR_TCIF5_BIT 17
#define DMA_ISR_GIF5_BIT 16
#define DMA_ISR_TEIF4_BIT 15
#define DMA_ISR_HTIF4_BIT 14
#define DMA_ISR_TCIF4_BIT 13
#define DMA_ISR_GIF4_BIT 12
#define DMA_ISR_TEIF3_BIT 11
#define DMA_ISR_HTIF3_BIT 10
#define DMA_ISR_TCIF3_BIT 9
#define DMA_ISR_GIF3_BIT 8
#define DMA_ISR_TEIF2_BIT 7
#define DMA_ISR_HTIF2_BIT 6
#define DMA_ISR_TCIF2_BIT 5
#define DMA_ISR_GIF2_BIT 4
#define DMA_ISR_TEIF1_BIT 3
#define DMA_ISR_HTIF1_BIT 2
#define DMA_ISR_TCIF1_BIT 1
#define DMA_ISR_GIF1_BIT 0
#define DMA_ISR_TEIF7 (1U << DMA_ISR_TEIF7_BIT)
#define DMA_ISR_HTIF7 (1U << DMA_ISR_HTIF7_BIT)
#define DMA_ISR_TCIF7 (1U << DMA_ISR_TCIF7_BIT)
#define DMA_ISR_GIF7 (1U << DMA_ISR_GIF7_BIT)
#define DMA_ISR_TEIF6 (1U << DMA_ISR_TEIF6_BIT)
#define DMA_ISR_HTIF6 (1U << DMA_ISR_HTIF6_BIT)
#define DMA_ISR_TCIF6 (1U << DMA_ISR_TCIF6_BIT)
#define DMA_ISR_GIF6 (1U << DMA_ISR_GIF6_BIT)
#define DMA_ISR_TEIF5 (1U << DMA_ISR_TEIF5_BIT)
#define DMA_ISR_HTIF5 (1U << DMA_ISR_HTIF5_BIT)
#define DMA_ISR_TCIF5 (1U << DMA_ISR_TCIF5_BIT)
#define DMA_ISR_GIF5 (1U << DMA_ISR_GIF5_BIT)
#define DMA_ISR_TEIF4 (1U << DMA_ISR_TEIF4_BIT)
#define DMA_ISR_HTIF4 (1U << DMA_ISR_HTIF4_BIT)
#define DMA_ISR_TCIF4 (1U << DMA_ISR_TCIF4_BIT)
#define DMA_ISR_GIF4 (1U << DMA_ISR_GIF4_BIT)
#define DMA_ISR_TEIF3 (1U << DMA_ISR_TEIF3_BIT)
#define DMA_ISR_HTIF3 (1U << DMA_ISR_HTIF3_BIT)
#define DMA_ISR_TCIF3 (1U << DMA_ISR_TCIF3_BIT)
#define DMA_ISR_GIF3 (1U << DMA_ISR_GIF3_BIT)
#define DMA_ISR_TEIF2 (1U << DMA_ISR_TEIF2_BIT)
#define DMA_ISR_HTIF2 (1U << DMA_ISR_HTIF2_BIT)
#define DMA_ISR_TCIF2 (1U << DMA_ISR_TCIF2_BIT)
#define DMA_ISR_GIF2 (1U << DMA_ISR_GIF2_BIT)
#define DMA_ISR_TEIF1 (1U << DMA_ISR_TEIF1_BIT)
#define DMA_ISR_HTIF1 (1U << DMA_ISR_HTIF1_BIT)
#define DMA_ISR_TCIF1 (1U << DMA_ISR_TCIF1_BIT)
#define DMA_ISR_GIF1 (1U << DMA_ISR_GIF1_BIT)
/* Interrupt flag clear register */
#define DMA_IFCR_CTEIF7_BIT 27
#define DMA_IFCR_CHTIF7_BIT 26
#define DMA_IFCR_CTCIF7_BIT 25
#define DMA_IFCR_CGIF7_BIT 24
#define DMA_IFCR_CTEIF6_BIT 23
#define DMA_IFCR_CHTIF6_BIT 22
#define DMA_IFCR_CTCIF6_BIT 21
#define DMA_IFCR_CGIF6_BIT 20
#define DMA_IFCR_CTEIF5_BIT 19
#define DMA_IFCR_CHTIF5_BIT 18
#define DMA_IFCR_CTCIF5_BIT 17
#define DMA_IFCR_CGIF5_BIT 16
#define DMA_IFCR_CTEIF4_BIT 15
#define DMA_IFCR_CHTIF4_BIT 14
#define DMA_IFCR_CTCIF4_BIT 13
#define DMA_IFCR_CGIF4_BIT 12
#define DMA_IFCR_CTEIF3_BIT 11
#define DMA_IFCR_CHTIF3_BIT 10
#define DMA_IFCR_CTCIF3_BIT 9
#define DMA_IFCR_CGIF3_BIT 8
#define DMA_IFCR_CTEIF2_BIT 7
#define DMA_IFCR_CHTIF2_BIT 6
#define DMA_IFCR_CTCIF2_BIT 5
#define DMA_IFCR_CGIF2_BIT 4
#define DMA_IFCR_CTEIF1_BIT 3
#define DMA_IFCR_CHTIF1_BIT 2
#define DMA_IFCR_CTCIF1_BIT 1
#define DMA_IFCR_CGIF1_BIT 0
#define DMA_IFCR_CTEIF7 (1U << DMA_IFCR_CTEIF7_BIT)
#define DMA_IFCR_CHTIF7 (1U << DMA_IFCR_CHTIF7_BIT)
#define DMA_IFCR_CTCIF7 (1U << DMA_IFCR_CTCIF7_BIT)
#define DMA_IFCR_CGIF7 (1U << DMA_IFCR_CGIF7_BIT)
#define DMA_IFCR_CTEIF6 (1U << DMA_IFCR_CTEIF6_BIT)
#define DMA_IFCR_CHTIF6 (1U << DMA_IFCR_CHTIF6_BIT)
#define DMA_IFCR_CTCIF6 (1U << DMA_IFCR_CTCIF6_BIT)
#define DMA_IFCR_CGIF6 (1U << DMA_IFCR_CGIF6_BIT)
#define DMA_IFCR_CTEIF5 (1U << DMA_IFCR_CTEIF5_BIT)
#define DMA_IFCR_CHTIF5 (1U << DMA_IFCR_CHTIF5_BIT)
#define DMA_IFCR_CTCIF5 (1U << DMA_IFCR_CTCIF5_BIT)
#define DMA_IFCR_CGIF5 (1U << DMA_IFCR_CGIF5_BIT)
#define DMA_IFCR_CTEIF4 (1U << DMA_IFCR_CTEIF4_BIT)
#define DMA_IFCR_CHTIF4 (1U << DMA_IFCR_CHTIF4_BIT)
#define DMA_IFCR_CTCIF4 (1U << DMA_IFCR_CTCIF4_BIT)
#define DMA_IFCR_CGIF4 (1U << DMA_IFCR_CGIF4_BIT)
#define DMA_IFCR_CTEIF3 (1U << DMA_IFCR_CTEIF3_BIT)
#define DMA_IFCR_CHTIF3 (1U << DMA_IFCR_CHTIF3_BIT)
#define DMA_IFCR_CTCIF3 (1U << DMA_IFCR_CTCIF3_BIT)
#define DMA_IFCR_CGIF3 (1U << DMA_IFCR_CGIF3_BIT)
#define DMA_IFCR_CTEIF2 (1U << DMA_IFCR_CTEIF2_BIT)
#define DMA_IFCR_CHTIF2 (1U << DMA_IFCR_CHTIF2_BIT)
#define DMA_IFCR_CTCIF2 (1U << DMA_IFCR_CTCIF2_BIT)
#define DMA_IFCR_CGIF2 (1U << DMA_IFCR_CGIF2_BIT)
#define DMA_IFCR_CTEIF1 (1U << DMA_IFCR_CTEIF1_BIT)
#define DMA_IFCR_CHTIF1 (1U << DMA_IFCR_CHTIF1_BIT)
#define DMA_IFCR_CTCIF1 (1U << DMA_IFCR_CTCIF1_BIT)
#define DMA_IFCR_CGIF1 (1U << DMA_IFCR_CGIF1_BIT)
/* Channel configuration register */
#define DMA_CCR_MEM2MEM_BIT 14
#define DMA_CCR_MINC_BIT 7
#define DMA_CCR_PINC_BIT 6
#define DMA_CCR_CIRC_BIT 5
#define DMA_CCR_DIR_BIT 4
#define DMA_CCR_TEIE_BIT 3
#define DMA_CCR_HTIE_BIT 2
#define DMA_CCR_TCIE_BIT 1
#define DMA_CCR_EN_BIT 0
#define DMA_CCR_MEM2MEM (1U << DMA_CCR_MEM2MEM_BIT)
#define DMA_CCR_PL (0x3 << 12)
#define DMA_CCR_PL_LOW (0x0 << 12)
#define DMA_CCR_PL_MEDIUM (0x1 << 12)
#define DMA_CCR_PL_HIGH (0x2 << 12)
#define DMA_CCR_PL_VERY_HIGH (0x3 << 12)
#define DMA_CCR_MSIZE (0x3 << 10)
#define DMA_CCR_MSIZE_8BITS (0x0 << 10)
#define DMA_CCR_MSIZE_16BITS (0x1 << 10)
#define DMA_CCR_MSIZE_32BITS (0x2 << 10)
#define DMA_CCR_PSIZE (0x3 << 8)
#define DMA_CCR_PSIZE_8BITS (0x0 << 8)
#define DMA_CCR_PSIZE_16BITS (0x1 << 8)
#define DMA_CCR_PSIZE_32BITS (0x2 << 8)
#define DMA_CCR_MINC (1U << DMA_CCR_MINC_BIT)
#define DMA_CCR_PINC (1U << DMA_CCR_PINC_BIT)
#define DMA_CCR_CIRC (1U << DMA_CCR_CIRC_BIT)
#define DMA_CCR_DIR (1U << DMA_CCR_DIR_BIT)
#define DMA_CCR_DIR_FROM_PER (0U << DMA_CCR_DIR_BIT)
#define DMA_CCR_DIR_FROM_MEM (1U << DMA_CCR_DIR_BIT)
#define DMA_CCR_TEIE (1U << DMA_CCR_TEIE_BIT)
#define DMA_CCR_HTIE (1U << DMA_CCR_HTIE_BIT)
#define DMA_CCR_TCIE (1U << DMA_CCR_TCIE_BIT)
#define DMA_CCR_EN (1U << DMA_CCR_EN_BIT)
/*
* Devices
*/
extern dma_dev *DMA1;
#if defined(STM32_HIGH_DENSITY) || defined(STM32_XL_DENSITY)
extern dma_dev *DMA2;
#endif
/*
* Other types needed by, or useful for, <libmaple/dma.h>.
*/
/**
* @brief STM32F1 dma_tube.
* On STM32F1, DMA tubes are just channels.
*/
#define dma_tube dma_channel
/**
* @brief On STM32F1, dma_channel_reg_map is an alias for dma_tube_reg_map.
* This is for backwards compatibility. */
#define dma_channel_reg_map dma_tube_reg_map
/**
* @brief STM32F1 configuration flags for dma_tube_config
* @see struct dma_tube_config
*/
typedef enum dma_cfg_flags {
/**
* Source address increment mode
*
* If this flag is set, the source address is incremented (by the
* source size) after each DMA transfer.
*/
DMA_CFG_SRC_INC = 1U << 31,
/**
* Destination address increment mode
*
* If this flag is set, the destination address is incremented (by
* the destination size) after each DMA transfer.
*/
DMA_CFG_DST_INC = 1U << 30,
/**
* Circular mode
*
* This mode is not available for memory-to-memory transfers.
*/
DMA_CFG_CIRC = DMA_CCR_CIRC,
/** Transfer complete interrupt enable */
DMA_CFG_CMPLT_IE = DMA_CCR_TCIE,
/** Transfer half-complete interrupt enable */
DMA_CFG_HALF_CMPLT_IE = DMA_CCR_HTIE,
/** Transfer error interrupt enable */
DMA_CFG_ERR_IE = DMA_CCR_TEIE,
} dma_cfg_flags;
/**
* @brief STM32F1 DMA request sources.
*
* IMPORTANT:
*
* 1. On STM32F1, each dma_request_src can only be used by a
* particular tube on a particular DMA controller. For example,
* DMA_REQ_SRC_ADC1 belongs to DMA1, tube 1. DMA2 cannot serve
* requests from ADC1, nor can DMA1 tube 2, etc. If you try to use a
* request source with the wrong DMA controller or tube on STM32F1,
* dma_tube_cfg() will fail.
*
* 2. In general, a DMA tube can only serve a single request source at
* a time, and on STM32F1, Terrible Super-Bad Things will happen if
* two request sources are active for a single tube.
*
* To make all this easier to sort out, these dma_request_src
* enumerators are grouped by DMA controller and tube.
*
* @see struct dma_tube_config
* @see dma_tube_cfg()
*/
typedef enum dma_request_src {
/* Each request source encodes the DMA controller and channel it
* belongs to, for error checking in dma_tube_cfg(). */
/* DMA1 request sources */
/**@{*/
/** (DMA1, tube 1) */
DMA_REQ_SRC_ADC1 = (RCC_DMA1 << 3) | 1,
DMA_REQ_SRC_TIM2_CH3 = (RCC_DMA1 << 3) | 1,
DMA_REQ_SRC_TIM4_CH1 = (RCC_DMA1 << 3) | 1,
/**@}*/
/**@{*/
/** (DMA1, tube 2)*/
DMA_REQ_SRC_SPI1_RX = (RCC_DMA1 << 3) | 2,
DMA_REQ_SRC_USART3_TX = (RCC_DMA1 << 3) | 2,
DMA_REQ_SRC_TIM1_CH1 = (RCC_DMA1 << 3) | 2,
DMA_REQ_SRC_TIM2_UP = (RCC_DMA1 << 3) | 2,
DMA_REQ_SRC_TIM3_CH3 = (RCC_DMA1 << 3) | 2,
/**@}*/
/**@{*/
/** (DMA1, tube 3)*/
DMA_REQ_SRC_SPI1_TX = (RCC_DMA1 << 3) | 3,
DMA_REQ_SRC_USART3_RX = (RCC_DMA1 << 3) | 3,
DMA_REQ_SRC_TIM1_CH2 = (RCC_DMA1 << 3) | 3,
DMA_REQ_SRC_TIM3_CH4 = (RCC_DMA1 << 3) | 3,
DMA_REQ_SRC_TIM3_UP = (RCC_DMA1 << 3) | 3,
/**@}*/
/**@{*/
/** (DMA1, tube 4)*/
DMA_REQ_SRC_SPI2_RX = (RCC_DMA1 << 3) | 4,
DMA_REQ_SRC_I2S2_RX = (RCC_DMA1 << 3) | 4,
DMA_REQ_SRC_USART1_TX = (RCC_DMA1 << 3) | 4,
DMA_REQ_SRC_I2C2_TX = (RCC_DMA1 << 3) | 4,
DMA_REQ_SRC_TIM1_CH4 = (RCC_DMA1 << 3) | 4,
DMA_REQ_SRC_TIM1_TRIG = (RCC_DMA1 << 3) | 4,
DMA_REQ_SRC_TIM1_COM = (RCC_DMA1 << 3) | 4,
DMA_REQ_SRC_TIM4_CH2 = (RCC_DMA1 << 3) | 4,
/**@}*/
/**@{*/
/** (DMA1, tube 5)*/
DMA_REQ_SRC_SPI2_TX = (RCC_DMA1 << 3) | 5,
DMA_REQ_SRC_I2S2_TX = (RCC_DMA1 << 3) | 5,
DMA_REQ_SRC_USART1_RX = (RCC_DMA1 << 3) | 5,
DMA_REQ_SRC_I2C2_RX = (RCC_DMA1 << 3) | 5,
DMA_REQ_SRC_TIM1_UP = (RCC_DMA1 << 3) | 5,
DMA_REQ_SRC_TIM2_CH1 = (RCC_DMA1 << 3) | 5,
DMA_REQ_SRC_TIM4_CH3 = (RCC_DMA1 << 3) | 5,
/**@}*/
/**@{*/
/** (DMA1, tube 6)*/
DMA_REQ_SRC_USART2_RX = (RCC_DMA1 << 3) | 6,
DMA_REQ_SRC_I2C1_TX = (RCC_DMA1 << 3) | 6,
DMA_REQ_SRC_TIM1_CH3 = (RCC_DMA1 << 3) | 6,
DMA_REQ_SRC_TIM3_CH1 = (RCC_DMA1 << 3) | 6,
DMA_REQ_SRC_TIM3_TRIG = (RCC_DMA1 << 3) | 6,
/**@}*/
/**@{*/
/* Tube 7 */
DMA_REQ_SRC_USART2_TX = (RCC_DMA1 << 3) | 7,
DMA_REQ_SRC_I2C1_RX = (RCC_DMA1 << 3) | 7,
DMA_REQ_SRC_TIM2_CH2 = (RCC_DMA1 << 3) | 7,
DMA_REQ_SRC_TIM2_CH4 = (RCC_DMA1 << 3) | 7,
DMA_REQ_SRC_TIM4_UP = (RCC_DMA1 << 3) | 7,
/**@}*/
/* DMA2 request sources */
/**@{*/
/** (DMA2, tube 1)*/
DMA_REQ_SRC_SPI3_RX = (RCC_DMA2 << 3) | 1,
DMA_REQ_SRC_I2S3_RX = (RCC_DMA2 << 3) | 1,
DMA_REQ_SRC_TIM5_CH4 = (RCC_DMA2 << 3) | 1,
DMA_REQ_SRC_TIM5_TRIG = (RCC_DMA2 << 3) | 1,
/**@}*/
/**@{*/
/** (DMA2, tube 2)*/
DMA_REQ_SRC_SPI3_TX = (RCC_DMA2 << 3) | 2,
DMA_REQ_SRC_I2S3_TX = (RCC_DMA2 << 3) | 2,
DMA_REQ_SRC_TIM5_CH3 = (RCC_DMA2 << 3) | 2,
DMA_REQ_SRC_TIM5_UP = (RCC_DMA2 << 3) | 2,
/**@}*/
/**@{*/
/** (DMA2, tube 3)*/
DMA_REQ_SRC_UART4_RX = (RCC_DMA2 << 3) | 3,
DMA_REQ_SRC_TIM6_UP = (RCC_DMA2 << 3) | 3,
DMA_REQ_SRC_DAC_CH1 = (RCC_DMA2 << 3) | 3,
/**@}*/
/**@{*/
/** (DMA2, tube 4)*/
DMA_REQ_SRC_SDIO = (RCC_DMA2 << 3) | 4,
DMA_REQ_SRC_TIM5_CH2 = (RCC_DMA2 << 3) | 4,
/**@}*/
/**@{*/
/** (DMA2, tube 5)*/
DMA_REQ_SRC_ADC3 = (RCC_DMA2 << 3) | 5,
DMA_REQ_SRC_UART4_TX = (RCC_DMA2 << 3) | 5,
DMA_REQ_SRC_TIM5_CH1 = (RCC_DMA2 << 3) | 5,
/**@}*/
} dma_request_src;
/*
* Convenience routines.
*/
/**
* @brief On STM32F1, dma_is_channel_enabled() is an alias for
* dma_is_enabled().
* This is for backwards compatibility.
*/
#define dma_is_channel_enabled dma_is_enabled
#define DMA_CHANNEL_NREGS 5 /* accounts for reserved word */
static inline dma_tube_reg_map* dma_tube_regs(dma_dev *dev, dma_tube tube) {
__io uint32 *ccr1 = &dev->regs->CCR1;
return (dma_channel_reg_map*)(ccr1 + DMA_CHANNEL_NREGS * (tube - 1));
}
/**
* @brief On STM32F1, dma_channel_regs() is an alias for dma_tube_regs().
* This is for backwards compatibility. */
#define dma_channel_regs(dev, ch) dma_tube_regs(dev, ch)
static inline uint8 dma_is_enabled(dma_dev *dev, dma_tube tube) {
return (uint8)(dma_tube_regs(dev, tube)->CCR & DMA_CCR_EN);
}
static inline uint8 dma_get_isr_bits(dma_dev *dev, dma_tube tube) {
uint8 shift = (tube - 1) * 4;
return (dev->regs->ISR >> shift) & 0xF;
}
static inline void dma_clear_isr_bits(dma_dev *dev, dma_tube tube) {
dev->regs->IFCR = (1U << (4 * (tube - 1)));
}
/**
* @brief Deprecated
* STM32F1 mode flags for dma_setup_xfer(). Use dma_tube_cfg() instead.
* @see dma_tube_cfg()
*/
typedef enum dma_mode_flags {
DMA_MEM_2_MEM = 1 << 14, /**< Memory to memory mode */
DMA_MINC_MODE = 1 << 7, /**< Auto-increment memory address */
DMA_PINC_MODE = 1 << 6, /**< Auto-increment peripheral address */
DMA_CIRC_MODE = 1 << 5, /**< Circular mode */
DMA_FROM_MEM = 1 << 4, /**< Read from memory to peripheral */
DMA_TRNS_ERR = 1 << 3, /**< Interrupt on transfer error */
DMA_HALF_TRNS = 1 << 2, /**< Interrupt on half-transfer */
DMA_TRNS_CMPLT = 1 << 1 /**< Interrupt on transfer completion */
} dma_mode_flags;
/* Keep this around for backwards compatibility, but it's deprecated.
* New code should use dma_tube_cfg() instead.
*
* (It's not possible to fully configure a DMA stream on F2 with just
* this information, so this interface is too tied to the F1.) */
void dma_setup_transfer(dma_dev *dev,
dma_channel channel,
__io void *peripheral_address,
dma_xfer_size peripheral_size,
__io void *memory_address,
dma_xfer_size memory_size,
uint32 mode);
#ifdef __cplusplus
} // extern "C"
#endif
#endif

View File

@@ -0,0 +1,46 @@
/******************************************************************************
* 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/stm32f1/include/series/exti.h
* @brief STM32F1 external interrupts
*/
#ifndef _LIBMAPLE_STM32F1_EXTI_H_
#define _LIBMAPLE_STM32F1_EXTI_H_
#ifdef __cpluspus
extern "C" {
#endif
struct exti_reg_map;
#define EXTI_BASE ((struct exti_reg_map*)0x40010400)
#ifdef __cpluspus
}
#endif
#endif

View File

@@ -0,0 +1,149 @@
/******************************************************************************
* The MIT License
*
* 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/flash.h
* @brief STM32F1 Flash header.
*
* Provides register map, base pointer, and register bit definitions
* for the Flash controller on the STM32F1 line, along with
* series-specific configuration values.
*/
#ifndef _LIBMAPLE_STM32F1_FLASH_H_
#define _LIBMAPLE_STM32F1_FLASH_H_
#ifdef __cplusplus
extern "C"{
#endif
#include <libmaple/libmaple_types.h>
/*
* Register map
*/
/** @brief STM32F1 Flash register map type */
typedef struct flash_reg_map {
__io uint32 ACR; /**< Access control register */
__io uint32 KEYR; /**< Key register */
__io uint32 OPTKEYR; /**< OPTKEY register */
__io uint32 SR; /**< Status register */
__io uint32 CR; /**< Control register */
__io uint32 AR; /**< Address register */
__io uint32 OBR; /**< Option byte register */
__io uint32 WRPR; /**< Write protection register */
} flash_reg_map;
#define FLASH_BASE ((struct flash_reg_map*)0x40022000)
/*
* Register bit definitions
*/
/* Access control register */
#define FLASH_ACR_PRFTBS_BIT 5
#define FLASH_ACR_PRFTBE_BIT 4
#define FLASH_ACR_HLFCYA_BIT 3
#define FLASH_ACR_PRFTBS (1U << FLASH_ACR_PRFTBS_BIT)
#define FLASH_ACR_PRFTBE (1U << FLASH_ACR_PRFTBE_BIT)
#define FLASH_ACR_HLFCYA (1U << FLASH_ACR_HLFCYA_BIT)
#define FLASH_ACR_LATENCY 0x7
/* Status register */
#define FLASH_SR_EOP_BIT 5
#define FLASH_SR_WRPRTERR_BIT 4
#define FLASH_SR_PGERR_BIT 2
#define FLASH_SR_BSY_BIT 0
#define FLASH_SR_EOP (1U << FLASH_SR_EOP_BIT)
#define FLASH_SR_WRPRTERR (1U << FLASH_SR_WRPRTERR_BIT)
#define FLASH_SR_PGERR (1U << FLASH_SR_PGERR_BIT)
#define FLASH_SR_BSY (1U << FLASH_SR_BSY_BIT)
/* Control register */
#define FLASH_CR_EOPIE_BIT 12
#define FLASH_CR_ERRIE_BIT 10
#define FLASH_CR_OPTWRE_BIT 9
#define FLASH_CR_LOCK_BIT 7
#define FLASH_CR_STRT_BIT 6
#define FLASH_CR_OPTER_BIT 5
#define FLASH_CR_OPTPG_BIT 4
#define FLASH_CR_MER_BIT 2
#define FLASH_CR_PER_BIT 1
#define FLASH_CR_PG_BIT 0
#define FLASH_CR_EOPIE (1U << FLASH_CR_EOPIE_BIT)
#define FLASH_CR_ERRIE (1U << FLASH_CR_ERRIE_BIT)
#define FLASH_CR_OPTWRE (1U << FLASH_CR_OPTWRE_BIT)
#define FLASH_CR_LOCK (1U << FLASH_CR_LOCK_BIT)
#define FLASH_CR_STRT (1U << FLASH_CR_STRT_BIT)
#define FLASH_CR_OPTER (1U << FLASH_CR_OPTER_BIT)
#define FLASH_CR_OPTPG (1U << FLASH_CR_OPTPG_BIT)
#define FLASH_CR_MER (1U << FLASH_CR_MER_BIT)
#define FLASH_CR_PER (1U << FLASH_CR_PER_BIT)
#define FLASH_CR_PG (1U << FLASH_CR_PG_BIT)
/* Option byte register */
#define FLASH_OBR_nRST_STDBY_BIT 4
#define FLASH_OBR_nRST_STOP_BIT 3
#define FLASH_OBR_WDG_SW_BIT 2
#define FLASH_OBR_RDPRT_BIT 1
#define FLASH_OBR_OPTERR_BIT 0
#define FLASH_OBR_DATA1 (0xFF << 18)
#define FLASH_OBR_DATA0 (0xFF << 10)
#define FLASH_OBR_USER 0x3FF
#define FLASH_OBR_nRST_STDBY (1U << FLASH_OBR_nRST_STDBY_BIT)
#define FLASH_OBR_nRST_STOP (1U << FLASH_OBR_nRST_STOP_BIT)
#define FLASH_OBR_WDG_SW (1U << FLASH_OBR_WDG_SW_BIT)
#define FLASH_OBR_RDPRT (1U << FLASH_OBR_RDPRT_BIT)
#define FLASH_OBR_OPTERR (1U << FLASH_OBR_OPTERR_BIT)
/*
* Series-specific configuration values.
*/
#define FLASH_SAFE_WAIT_STATES FLASH_WAIT_STATE_2
/* Flash memory features available via ACR */
enum {
FLASH_PREFETCH = 0x10,
FLASH_HALF_CYCLE = 0x8,
FLASH_ICACHE = 0x0, /* Not available on STM32F1 */
FLASH_DCACHE = 0x0, /* Not available on STM32F1 */
};
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -0,0 +1,495 @@
/******************************************************************************
* The MIT License
*
* Copyright (c) 2010 Perry Hung.
* Copyright (c) 2011, 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/stm32f1/include/series/gpio.h
* @brief STM32F1 GPIO and AFIO support.
* General purpose I/O (GPIO) and Alternate Function I/O (AFIO).
*/
#ifndef _LIBMAPLE_STM32F1_GPIO_H_
#define _LIBMAPLE_STM32F1_GPIO_H_
#ifdef __cplusplus
extern "C"{
#endif
#include <libmaple/stm32.h>
#include <libmaple/libmaple_types.h>
#include <libmaple/exti.h>
/*
* GPIO register maps and devices
*/
/** GPIO register map type */
typedef struct gpio_reg_map {
__io uint32 CRL; /**< Port configuration register low */
__io uint32 CRH; /**< Port configuration register high */
__io uint32 IDR; /**< Port input data register */
__io uint32 ODR; /**< Port output data register */
__io uint32 BSRR; /**< Port bit set/reset register */
__io uint32 BRR; /**< Port bit reset register */
__io uint32 LCKR; /**< Port configuration lock register */
} gpio_reg_map;
struct gpio_dev;
extern struct gpio_dev gpioa;
extern struct gpio_dev* const GPIOA;
extern struct gpio_dev gpiob;
extern struct gpio_dev* const GPIOB;
extern struct gpio_dev gpioc;
extern struct gpio_dev* const GPIOC;
extern struct gpio_dev gpiod;
extern struct gpio_dev* const GPIOD;
#ifdef STM32_HIGH_DENSITY
extern struct gpio_dev gpioe;
extern struct gpio_dev* const GPIOE;
extern struct gpio_dev gpiof;
extern struct gpio_dev* const GPIOF;
extern struct gpio_dev gpiog;
extern struct gpio_dev* const GPIOG;
#endif
/** GPIO port A register map base pointer */
#define GPIOA_BASE ((struct gpio_reg_map*)0x40010800)
/** GPIO port B register map base pointer */
#define GPIOB_BASE ((struct gpio_reg_map*)0x40010C00)
/** GPIO port C register map base pointer */
#define GPIOC_BASE ((struct gpio_reg_map*)0x40011000)
/** GPIO port D register map base pointer */
#define GPIOD_BASE ((struct gpio_reg_map*)0x40011400)
/** GPIO port E register map base pointer */
#define GPIOE_BASE ((struct gpio_reg_map*)0x40011800)
/** GPIO port F register map base pointer */
#define GPIOF_BASE ((struct gpio_reg_map*)0x40011C00)
/** GPIO port G register map base pointer */
#define GPIOG_BASE ((struct gpio_reg_map*)0x40012000)
/*
* GPIO register bit definitions
*/
/* Control registers, low and high */
#define GPIO_CR_CNF (0x3 << 2)
#define GPIO_CR_CNF_INPUT_ANALOG (0x0 << 2)
#define GPIO_CR_CNF_INPUT_FLOATING (0x1 << 2)
#define GPIO_CR_CNF_INPUT_PU_PD (0x2 << 2)
#define GPIO_CR_CNF_OUTPUT_PP (0x0 << 2)
#define GPIO_CR_CNF_OUTPUT_OD (0x1 << 2)
#define GPIO_CR_CNF_AF_OUTPUT_PP (0x2 << 2)
#define GPIO_CR_CNF_AF_OUTPUT_OD (0x3 << 2)
#define GPIO_CR_MODE 0x3
#define GPIO_CR_MODE_INPUT 0x0
#define GPIO_CR_MODE_OUTPUT_10MHZ 0x1
#define GPIO_CR_MODE_OUTPUT_2MHZ 0x2
#define GPIO_CR_MODE_OUTPUT_50MHZ 0x3
/**
* @brief GPIO pin modes.
*
* These only allow for 50MHZ max output speeds; if you want slower,
* use direct register access.
*/
typedef enum gpio_pin_mode {
/** Output push-pull. */
GPIO_OUTPUT_PP = GPIO_CR_CNF_OUTPUT_PP | GPIO_CR_MODE_OUTPUT_50MHZ,
/** Output open-drain. */
GPIO_OUTPUT_OD = GPIO_CR_CNF_OUTPUT_OD | GPIO_CR_MODE_OUTPUT_50MHZ,
/** Alternate function output push-pull. */
GPIO_AF_OUTPUT_PP = GPIO_CR_CNF_AF_OUTPUT_PP | GPIO_CR_MODE_OUTPUT_50MHZ,
/** Alternate function output open drain. */
GPIO_AF_OUTPUT_OD = GPIO_CR_CNF_AF_OUTPUT_OD | GPIO_CR_MODE_OUTPUT_50MHZ,
/** Analog input. */
GPIO_INPUT_ANALOG = GPIO_CR_CNF_INPUT_ANALOG | GPIO_CR_MODE_INPUT,
/** Input floating. */
GPIO_INPUT_FLOATING = GPIO_CR_CNF_INPUT_FLOATING | GPIO_CR_MODE_INPUT,
/** Input pull-down. */
GPIO_INPUT_PD = GPIO_CR_CNF_INPUT_PU_PD | GPIO_CR_MODE_INPUT,
/** Input pull-up. */
GPIO_INPUT_PU, /* (treated a special case, for ODR twiddling) */
} gpio_pin_mode;
/* Hacks for F2: */
#define GPIO_MODE_ANALOG GPIO_INPUT_ANALOG
#define GPIO_MODE_OUTPUT GPIO_OUTPUT_PP
/*
* AFIO register map
*/
/** AFIO register map */
typedef struct afio_reg_map {
__io uint32 EVCR; /**< Event control register. */
__io uint32 MAPR; /**< AF remap and debug I/O configuration register. */
__io uint32 EXTICR1; /**< External interrupt configuration register 1. */
__io uint32 EXTICR2; /**< External interrupt configuration register 2. */
__io uint32 EXTICR3; /**< External interrupt configuration register 3. */
__io uint32 EXTICR4; /**< External interrupt configuration register 4. */
__io uint32 MAPR2; /**<
* AF remap and debug I/O configuration register 2. */
} afio_reg_map;
/** AFIO register map base pointer. */
#define AFIO_BASE ((struct afio_reg_map *)0x40010000)
/*
* AFIO register bit definitions
*/
/* Event control register */
#define AFIO_EVCR_EVOE (0x1 << 7)
#define AFIO_EVCR_PORT_PA (0x0 << 4)
#define AFIO_EVCR_PORT_PB (0x1 << 4)
#define AFIO_EVCR_PORT_PC (0x2 << 4)
#define AFIO_EVCR_PORT_PD (0x3 << 4)
#define AFIO_EVCR_PORT_PE (0x4 << 4)
#define AFIO_EVCR_PIN_0 0x0
#define AFIO_EVCR_PIN_1 0x1
#define AFIO_EVCR_PIN_2 0x2
#define AFIO_EVCR_PIN_3 0x3
#define AFIO_EVCR_PIN_4 0x4
#define AFIO_EVCR_PIN_5 0x5
#define AFIO_EVCR_PIN_6 0x6
#define AFIO_EVCR_PIN_7 0x7
#define AFIO_EVCR_PIN_8 0x8
#define AFIO_EVCR_PIN_9 0x9
#define AFIO_EVCR_PIN_10 0xA
#define AFIO_EVCR_PIN_11 0xB
#define AFIO_EVCR_PIN_12 0xC
#define AFIO_EVCR_PIN_13 0xD
#define AFIO_EVCR_PIN_14 0xE
#define AFIO_EVCR_PIN_15 0xF
/* AF remap and debug I/O configuration register */
#define AFIO_MAPR_SWJ_CFG (0x7 << 24)
#define AFIO_MAPR_SWJ_CFG_FULL_SWJ (0x0 << 24)
#define AFIO_MAPR_SWJ_CFG_FULL_SWJ_NO_NJRST (0x1 << 24)
#define AFIO_MAPR_SWJ_CFG_NO_JTAG_SW (0x2 << 24)
#define AFIO_MAPR_SWJ_CFG_NO_JTAG_NO_SW (0x4 << 24)
#define AFIO_MAPR_ADC2_ETRGREG_REMAP (1U << 20)
#define AFIO_MAPR_ADC2_ETRGINJ_REMAP (1U << 19)
#define AFIO_MAPR_ADC1_ETRGREG_REMAP (1U << 18)
#define AFIO_MAPR_ADC1_ETRGINJ_REMAP (1U << 17)
#define AFIO_MAPR_TIM5CH4_IREMAP (1U << 16)
#define AFIO_MAPR_PD01_REMAP (1U << 15)
#define AFIO_MAPR_CAN_REMAP (0x3 << 13)
#define AFIO_MAPR_CAN_REMAP_NONE (0x0 << 13)
#define AFIO_MAPR_CAN_REMAP_PB8_PB9 (0x2 << 13)
#define AFIO_MAPR_CAN_REMAP_PD0_PD1 (0x3 << 13)
#define AFIO_MAPR_TIM4_REMAP (1U << 12)
#define AFIO_MAPR_TIM3_REMAP (0x3 << 10)
#define AFIO_MAPR_TIM3_REMAP_NONE (0x0 << 10)
#define AFIO_MAPR_TIM3_REMAP_PARTIAL (0x2 << 10)
#define AFIO_MAPR_TIM3_REMAP_FULL (0x3 << 10)
#define AFIO_MAPR_TIM2_REMAP (0x3 << 8)
#define AFIO_MAPR_TIM2_REMAP_NONE (0x0 << 8)
#define AFIO_MAPR_TIM2_REMAP_PA15_PB3_PA2_PA3 (0x1 << 8)
#define AFIO_MAPR_TIM2_REMAP_PA0_PA1_PB10_PB11 (0x2 << 8)
#define AFIO_MAPR_TIM2_REMAP_FULL (0x3 << 8)
#define AFIO_MAPR_TIM1_REMAP (0x3 << 6)
#define AFIO_MAPR_TIM1_REMAP_NONE (0x0 << 6)
#define AFIO_MAPR_TIM1_REMAP_PARTIAL (0x1 << 6)
#define AFIO_MAPR_TIM1_REMAP_FULL (0x3 << 6)
#define AFIO_MAPR_USART3_REMAP (0x3 << 4)
#define AFIO_MAPR_USART3_REMAP_NONE (0x0 << 4)
#define AFIO_MAPR_USART3_REMAP_PARTIAL (0x1 << 4)
#define AFIO_MAPR_USART3_REMAP_FULL (0x3 << 4)
#define AFIO_MAPR_USART2_REMAP (1U << 3)
#define AFIO_MAPR_USART1_REMAP (1U << 2)
#define AFIO_MAPR_I2C1_REMAP (1U << 1)
#define AFIO_MAPR_SPI1_REMAP (1U << 0)
/* External interrupt configuration register 1 */
#define AFIO_EXTICR1_EXTI3 (0xF << 12)
#define AFIO_EXTICR1_EXTI3_PA (0x0 << 12)
#define AFIO_EXTICR1_EXTI3_PB (0x1 << 12)
#define AFIO_EXTICR1_EXTI3_PC (0x2 << 12)
#define AFIO_EXTICR1_EXTI3_PD (0x3 << 12)
#define AFIO_EXTICR1_EXTI3_PE (0x4 << 12)
#define AFIO_EXTICR1_EXTI3_PF (0x5 << 12)
#define AFIO_EXTICR1_EXTI3_PG (0x6 << 12)
#define AFIO_EXTICR1_EXTI2 (0xF << 8)
#define AFIO_EXTICR1_EXTI2_PA (0x0 << 8)
#define AFIO_EXTICR1_EXTI2_PB (0x1 << 8)
#define AFIO_EXTICR1_EXTI2_PC (0x2 << 8)
#define AFIO_EXTICR1_EXTI2_PD (0x3 << 8)
#define AFIO_EXTICR1_EXTI2_PE (0x4 << 8)
#define AFIO_EXTICR1_EXTI2_PF (0x5 << 8)
#define AFIO_EXTICR1_EXTI2_PG (0x6 << 8)
#define AFIO_EXTICR1_EXTI1 (0xF << 4)
#define AFIO_EXTICR1_EXTI1_PA (0x0 << 4)
#define AFIO_EXTICR1_EXTI1_PB (0x1 << 4)
#define AFIO_EXTICR1_EXTI1_PC (0x2 << 4)
#define AFIO_EXTICR1_EXTI1_PD (0x3 << 4)
#define AFIO_EXTICR1_EXTI1_PE (0x4 << 4)
#define AFIO_EXTICR1_EXTI1_PF (0x5 << 4)
#define AFIO_EXTICR1_EXTI1_PG (0x6 << 4)
#define AFIO_EXTICR1_EXTI0 0xF
#define AFIO_EXTICR1_EXTI0_PA 0x0
#define AFIO_EXTICR1_EXTI0_PB 0x1
#define AFIO_EXTICR1_EXTI0_PC 0x2
#define AFIO_EXTICR1_EXTI0_PD 0x3
#define AFIO_EXTICR1_EXTI0_PE 0x4
#define AFIO_EXTICR1_EXTI0_PF 0x5
#define AFIO_EXTICR1_EXTI0_PG 0x6
/* External interrupt configuration register 2 */
#define AFIO_EXTICR2_EXTI7 (0xF << 12)
#define AFIO_EXTICR2_EXTI7_PA (0x0 << 12)
#define AFIO_EXTICR2_EXTI7_PB (0x1 << 12)
#define AFIO_EXTICR2_EXTI7_PC (0x2 << 12)
#define AFIO_EXTICR2_EXTI7_PD (0x3 << 12)
#define AFIO_EXTICR2_EXTI7_PE (0x4 << 12)
#define AFIO_EXTICR2_EXTI7_PF (0x5 << 12)
#define AFIO_EXTICR2_EXTI7_PG (0x6 << 12)
#define AFIO_EXTICR2_EXTI6 (0xF << 8)
#define AFIO_EXTICR2_EXTI6_PA (0x0 << 8)
#define AFIO_EXTICR2_EXTI6_PB (0x1 << 8)
#define AFIO_EXTICR2_EXTI6_PC (0x2 << 8)
#define AFIO_EXTICR2_EXTI6_PD (0x3 << 8)
#define AFIO_EXTICR2_EXTI6_PE (0x4 << 8)
#define AFIO_EXTICR2_EXTI6_PF (0x5 << 8)
#define AFIO_EXTICR2_EXTI6_PG (0x6 << 8)
#define AFIO_EXTICR2_EXTI5 (0xF << 4)
#define AFIO_EXTICR2_EXTI5_PA (0x0 << 4)
#define AFIO_EXTICR2_EXTI5_PB (0x1 << 4)
#define AFIO_EXTICR2_EXTI5_PC (0x2 << 4)
#define AFIO_EXTICR2_EXTI5_PD (0x3 << 4)
#define AFIO_EXTICR2_EXTI5_PE (0x4 << 4)
#define AFIO_EXTICR2_EXTI5_PF (0x5 << 4)
#define AFIO_EXTICR2_EXTI5_PG (0x6 << 4)
#define AFIO_EXTICR2_EXTI4 0xF
#define AFIO_EXTICR2_EXTI4_PA 0x0
#define AFIO_EXTICR2_EXTI4_PB 0x1
#define AFIO_EXTICR2_EXTI4_PC 0x2
#define AFIO_EXTICR2_EXTI4_PD 0x3
#define AFIO_EXTICR2_EXTI4_PE 0x4
#define AFIO_EXTICR2_EXTI4_PF 0x5
#define AFIO_EXTICR2_EXTI4_PG 0x6
/* AF remap and debug I/O configuration register 2 */
#define AFIO_MAPR2_FSMC_NADV (1U << 10)
#define AFIO_MAPR2_TIM14_REMAP (1U << 9)
#define AFIO_MAPR2_TIM13_REMAP (1U << 8)
#define AFIO_MAPR2_TIM11_REMAP (1U << 7)
#define AFIO_MAPR2_TIM10_REMAP (1U << 6)
#define AFIO_MAPR2_TIM9_REMAP (1U << 5)
/*
* AFIO convenience routines
*/
void afio_init(void);
/* HACK: Use upper bit to denote MAPR2, Bit 31 is reserved and
* not used in either MAPR or MAPR2 */
#define AFIO_REMAP_USE_MAPR2 (1U << 31)
/**
* @brief Available peripheral remaps.
* @see afio_remap()
*/
typedef enum afio_remap_peripheral {
/** ADC 2 external trigger regular conversion remapping */
AFIO_REMAP_ADC2_ETRGREG = AFIO_MAPR_ADC2_ETRGREG_REMAP,
/** ADC 2 external trigger injected conversion remapping */
AFIO_REMAP_ADC2_ETRGINJ = AFIO_MAPR_ADC2_ETRGINJ_REMAP,
/** ADC 1 external trigger regular conversion remapping */
AFIO_REMAP_ADC1_ETRGREG = AFIO_MAPR_ADC1_ETRGREG_REMAP,
/** ADC 1 external trigger injected conversion remapping */
AFIO_REMAP_ADC1_ETRGINJ = AFIO_MAPR_ADC1_ETRGINJ_REMAP,
/** Timer 5 channel 4 internal remapping */
AFIO_REMAP_TIM5CH4_I = AFIO_MAPR_TIM5CH4_IREMAP,
/** Port D0/Port D1 mapping on OSC_IN/OSC_OUT */
AFIO_REMAP_PD01 = AFIO_MAPR_PD01_REMAP,
/** CAN alternate function remapping 1 (RX on PB8, TX on PB9) */
AFIO_REMAP_CAN_1 = AFIO_MAPR_CAN_REMAP_PB8_PB9,
/** CAN alternate function remapping 2 (RX on PD0, TX on PD1) */
AFIO_REMAP_CAN_2 = AFIO_MAPR_CAN_REMAP_PD0_PD1,
/** Timer 4 remapping */
AFIO_REMAP_TIM4 = AFIO_MAPR_TIM4_REMAP,
/** Timer 3 partial remapping */
AFIO_REMAP_TIM3_PARTIAL = AFIO_MAPR_TIM3_REMAP_PARTIAL,
/** Timer 3 full remapping */
AFIO_REMAP_TIM3_FULL = AFIO_MAPR_TIM3_REMAP_FULL,
/**
* Timer 2 partial remapping 1 (CH1 and ETR on PA15, CH2 on PB3,
* CH3 on PA2, CH4 on PA3) */
AFIO_REMAP_TIM2_PARTIAL_1 = AFIO_MAPR_TIM2_REMAP_PA15_PB3_PA2_PA3,
/**
* Timer 2 partial remapping 2 (CH1 and ETR on PA0, CH2 on PA1,
* CH3 on PB10, CH4 on PB11) */
AFIO_REMAP_TIM2_PARTIAL_2 = AFIO_MAPR_TIM2_REMAP_PA0_PA1_PB10_PB11,
/** Timer 2 full remapping */
AFIO_REMAP_TIM2_FULL = AFIO_MAPR_TIM2_REMAP_FULL,
/** USART 3 part remapping */
AFIO_REMAP_USART3_PARTIAL = AFIO_MAPR_USART3_REMAP_PARTIAL,
/** USART 2 remapping */
AFIO_REMAP_USART2 = AFIO_MAPR_USART2_REMAP,
/** USART 1 remapping */
AFIO_REMAP_USART1 = AFIO_MAPR_USART1_REMAP,
/** I2C 1 remapping */
AFIO_REMAP_I2C1 = AFIO_MAPR_I2C1_REMAP,
/** SPI 1 remapping */
AFIO_REMAP_SPI1 = AFIO_MAPR_SPI1_REMAP,
/** NADV signal not connected */
AFIO_REMAP_FSMC_NADV = AFIO_MAPR2_FSMC_NADV | AFIO_REMAP_USE_MAPR2,
/** Timer 14 remapping */
AFIO_REMAP_TIM14 = AFIO_MAPR2_TIM14_REMAP | AFIO_REMAP_USE_MAPR2,
/** Timer 13 remapping */
AFIO_REMAP_TIM13 = AFIO_MAPR2_TIM13_REMAP | AFIO_REMAP_USE_MAPR2,
/** Timer 11 remapping */
AFIO_REMAP_TIM11 = AFIO_MAPR2_TIM11_REMAP | AFIO_REMAP_USE_MAPR2,
/** Timer 10 remapping */
AFIO_REMAP_TIM10 = AFIO_MAPR2_TIM10_REMAP | AFIO_REMAP_USE_MAPR2,
/** Timer 9 remapping */
AFIO_REMAP_TIM9 = AFIO_MAPR2_TIM9_REMAP | AFIO_REMAP_USE_MAPR2,
} afio_remap_peripheral;
void afio_remap(afio_remap_peripheral p);
/**
* @brief Debug port configuration
*
* Used to configure the behavior of JTAG and Serial Wire (SW) debug
* ports and their associated GPIO pins.
*
* @see afio_cfg_debug_ports()
*/
typedef enum afio_debug_cfg {
/** Full Serial Wire and JTAG debug */
AFIO_DEBUG_FULL_SWJ = AFIO_MAPR_SWJ_CFG_FULL_SWJ,
/** Full Serial Wire and JTAG, but no NJTRST. */
AFIO_DEBUG_FULL_SWJ_NO_NJRST = AFIO_MAPR_SWJ_CFG_FULL_SWJ_NO_NJRST,
/** Serial Wire debug only (JTAG-DP disabled, SW-DP enabled) */
AFIO_DEBUG_SW_ONLY = AFIO_MAPR_SWJ_CFG_NO_JTAG_SW,
/** No debug; all JTAG and SW pins are free for use as GPIOs. */
AFIO_DEBUG_NONE = AFIO_MAPR_SWJ_CFG_NO_JTAG_NO_SW,
} afio_debug_cfg;
/**
* @brief Enable or disable the JTAG and SW debug ports.
* @param config Desired debug port configuration
* @see afio_debug_cfg
*/
static inline void afio_cfg_debug_ports(afio_debug_cfg config) {
__io uint32 *mapr = &AFIO_BASE->MAPR;
*mapr = (*mapr & ~AFIO_MAPR_SWJ_CFG) | config;
}
/*
* Deprecated bits
*/
/**
* @brief Deprecated. Use exti_cfg instead.
*
* In previous versions of libmaple, exti_attach_interrupt() took an
* afio_exti_port argument; afio_exti_port was also a member of struct
* gpio_dev. This isn't portable, so we now use exti_cfg
* instead. This typedef (and the macros AFIO_EXTI_PA, ...,
* AFIO_EXTI_PG) exist to preserve backwards compatibility.
*/
typedef exti_cfg afio_exti_port;
/** Deprecated. Use EXTI_PA instead. */
#define AFIO_EXTI_PA EXTI_PA
/** Deprecated. Use EXTI_PB instead. */
#define AFIO_EXTI_PB EXTI_PB
/** Deprecated. Use EXTI_PC instead. */
#define AFIO_EXTI_PC EXTI_PC
/** Deprecated. Use EXTI_PD instead. */
#define AFIO_EXTI_PD EXTI_PD
/** Deprecated. Use EXTI_PE instead. */
#define AFIO_EXTI_PE EXTI_PE
/** Deprecated. Use EXTI_PF instead. */
#define AFIO_EXTI_PF EXTI_PF
/** Deprecated. Use EXTI_PG instead. */
#define AFIO_EXTI_PG EXTI_PG
/**
* @brief Deprecated. Use exti_num instead.
*
* In previous versions of libmaple, exti_attach_interrupt() took an
* afio_exti_num argument. This isn't portable, so we use exti_num
* instead. This typedef (and the macros AFIO_EXTI_0, ...,
* AFIO_EXTI_15) exist to preserve backwards compatibility.
*/
typedef exti_num afio_exti_num;
/** Deprecated. Use EXTI0 instead. */
#define AFIO_EXTI_0 EXTI0
/** Deprecated. Use EXTI1 instead. */
#define AFIO_EXTI_1 EXTI1
/** Deprecated. Use EXTI2 instead. */
#define AFIO_EXTI_2 EXTI2
/** Deprecated. Use EXTI3 instead. */
#define AFIO_EXTI_3 EXTI3
/** Deprecated. Use EXTI4 instead. */
#define AFIO_EXTI_4 EXTI4
/** Deprecated. Use EXTI5 instead. */
#define AFIO_EXTI_5 EXTI5
/** Deprecated. Use EXTI6 instead. */
#define AFIO_EXTI_6 EXTI6
/** Deprecated. Use EXTI7 instead. */
#define AFIO_EXTI_7 EXTI7
/** Deprecated. Use EXTI8 instead. */
#define AFIO_EXTI_8 EXTI8
/** Deprecated. Use EXTI9 instead. */
#define AFIO_EXTI_9 EXTI9
/** Deprecated. Use EXTI10 instead. */
#define AFIO_EXTI_10 EXTI10
/** Deprecated. Use EXTI11 instead. */
#define AFIO_EXTI_11 EXTI11
/** Deprecated. Use EXTI12 instead. */
#define AFIO_EXTI_12 EXTI12
/** Deprecated. Use EXTI13 instead. */
#define AFIO_EXTI_13 EXTI13
/** Deprecated. Use EXTI14 instead. */
#define AFIO_EXTI_14 EXTI14
/** Deprecated. Use EXTI15 instead. */
#define AFIO_EXTI_15 EXTI15
/**
* @brief Deprecated. Use exti_select(exti, port) instead.
*/
static inline __always_inline void afio_exti_select(exti_num exti, exti_cfg port) {
exti_select(exti, port);
}
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -0,0 +1,85 @@
/******************************************************************************
* The MIT License
*
* Copyright (c) 2010 Perry Hung (from <libmaple/i2c.h>).
* 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/stm32f1/include/series/i2c.h
* @brief STM32F1 I2C
*/
#ifndef _LIBMAPLE_STM32F1_I2C_H_
#define _LIBMAPLE_STM32F1_I2C_H_
#include <libmaple/i2c_common.h>
#include <libmaple/gpio.h>
#include <libmaple/stm32.h>
/*
* Register maps
*/
struct i2c_reg_map;
/** STM32F1 I2C1 register map base pointer */
#define I2C1_BASE ((struct i2c_reg_map*)0x40005400)
/** STM32F1 I2C2 register map base pointer */
#define I2C2_BASE ((struct i2c_reg_map*)0x40005800)
/*
* Devices
*/
extern i2c_dev* const I2C1;
extern i2c_dev* const I2C2;
/*
* For internal use
*/
static inline uint32 _i2c_bus_clk(i2c_dev *dev) {
/* Both I2C peripherals are on APB1 */
return STM32_PCLK1 / (1000 * 1000);
}
#define _I2C_HAVE_IRQ_FIXUP 1
void _i2c_irq_priority_fixup(i2c_dev *dev);
/*
* Deprecated functionality
*/
/* Flag to use alternate pin mapping in i2c_master_enable(). */
#define _I2C_HAVE_DEPRECATED_I2C_REMAP 1
#define I2C_REMAP 0x4
static inline void _i2c_handle_remap(i2c_dev *dev, uint32 flags) {
if ((dev == I2C1) && (flags & I2C_REMAP)) {
afio_remap(AFIO_REMAP_I2C1);
I2C1->sda_pin = 9;
I2C1->scl_pin = 8;
}
}
#endif /* _LIBMAPLE_STM32F1_I2C_H_ */

View File

@@ -0,0 +1,173 @@
/******************************************************************************
* The MIT License
*
* 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/nvic.h
* @brief STM32F1 Nested Vectored Interrupt Controller (NVIC) support.
*/
#ifndef _LIBMAPLE_STM32F1_NVIC_H_
#define _LIBMAPLE_STM32F1_NVIC_H_
#ifdef __cplusplus
extern "C"{
#endif
#include <libmaple/libmaple_types.h>
#include <libmaple/stm32.h>
/**
* @brief STM32F1 interrupt vector table interrupt numbers.
* @see <libmaple/scb.h>
*/
typedef enum nvic_irq_num {
NVIC_NMI = -14, /**< Non-maskable interrupt */
NVIC_HARDFAULT = -13, /**< Hard fault (all class of fault) */
NVIC_MEM_MANAGE = -12, /**< Memory management */
NVIC_BUS_FAULT = -11, /**< Bus fault: prefetch fault, memory
access fault. */
NVIC_USAGE_FAULT = -10, /**< Usage fault: Undefined instruction or
illegal state. */
NVIC_SVC = -5, /**< System service call via SWI insruction */
NVIC_DEBUG_MON = -4, /**< Debug monitor */
NVIC_PEND_SVC = -2, /**< Pendable request for system service */
NVIC_SYSTICK = -1, /**< System tick timer */
NVIC_WWDG = 0, /**< Window watchdog interrupt */
NVIC_PVD = 1, /**< PVD through EXTI line detection */
NVIC_TAMPER = 2, /**< Tamper */
NVIC_RTC = 3, /**< Real-time clock */
NVIC_FLASH = 4, /**< Flash */
NVIC_RCC = 5, /**< Reset and clock control */
NVIC_EXTI0 = 6, /**< EXTI line 0 */
NVIC_EXTI1 = 7, /**< EXTI line 1 */
NVIC_EXTI2 = 8, /**< EXTI line 2 */
NVIC_EXTI3 = 9, /**< EXTI line 3 */
NVIC_EXTI4 = 10, /**< EXTI line 4 */
NVIC_DMA_CH1 = 11, /**< DMA1 channel 1 */
NVIC_DMA_CH2 = 12, /**< DMA1 channel 2 */
NVIC_DMA_CH3 = 13, /**< DMA1 channel 3 */
NVIC_DMA_CH4 = 14, /**< DMA1 channel 4 */
NVIC_DMA_CH5 = 15, /**< DMA1 channel 5 */
NVIC_DMA_CH6 = 16, /**< DMA1 channel 6 */
NVIC_DMA_CH7 = 17, /**< DMA1 channel 7 */
NVIC_ADC_1_2 = 18, /**< ADC1 and ADC2 */
NVIC_USB_HP_CAN_TX = 19, /**< USB high priority or CAN TX */
NVIC_USB_LP_CAN_RX0 = 20, /**< USB low priority or CAN RX0 */
NVIC_CAN_RX1 = 21, /**< CAN RX1 */
NVIC_CAN_SCE = 22, /**< CAN SCE */
NVIC_EXTI_9_5 = 23, /**< EXTI line [9:5] */
NVIC_TIMER1_BRK_TIMER9 = 24, /**< Timer 1 break, Timer 9. */
NVIC_TIMER1_UP_TIMER10 = 25, /**< Timer 1 update, Timer 10. */
NVIC_TIMER1_TRG_COM_TIMER11 = 26, /**<
* Timer 1 trigger and commutation,
* Timer 11. */
NVIC_TIMER1_CC = 27, /**< Timer 1 capture/compare */
NVIC_TIMER2 = 28, /**< Timer 2 */
NVIC_TIMER3 = 29, /**< Timer 3 */
NVIC_TIMER4 = 30, /**< Timer 4 */
NVIC_I2C1_EV = 31, /**< I2C1 event */
NVIC_I2C1_ER = 32, /**< I2C1 error */
NVIC_I2C2_EV = 33, /**< I2C2 event */
NVIC_I2C2_ER = 34, /**< I2C2 error */
NVIC_SPI1 = 35, /**< SPI1 */
NVIC_SPI2 = 36, /**< SPI2 */
NVIC_USART1 = 37, /**< USART1 */
NVIC_USART2 = 38, /**< USART2 */
NVIC_USART3 = 39, /**< USART3 */
NVIC_EXTI_15_10 = 40, /**< EXTI line [15:10] */
NVIC_RTCALARM = 41, /**< RTC alarm through EXTI line */
NVIC_USBWAKEUP = 42, /**< USB wakeup from suspend through
EXTI line */
NVIC_TIMER8_BRK_TIMER12 = 43, /**< Timer 8 break, timer 12 */
NVIC_TIMER8_UP_TIMER13 = 44, /**< Timer 8 update, timer 13 */
NVIC_TIMER8_TRG_COM_TIMER14 = 45, /**<
* Timer 8 trigger and commutation,
* Timer 14. */
NVIC_TIMER8_CC = 46, /**< Timer 8 capture/compare */
NVIC_ADC3 = 47, /**< ADC3 */
NVIC_FSMC = 48, /**< FSMC */
NVIC_SDIO = 49, /**< SDIO */
NVIC_TIMER5 = 50, /**< Timer 5 */
NVIC_SPI3 = 51, /**< SPI3 */
NVIC_UART4 = 52, /**< UART4 */
NVIC_UART5 = 53, /**< UART5 */
NVIC_TIMER6 = 54, /**< Timer 6 */
NVIC_TIMER7 = 55, /**< Timer 7 */
NVIC_DMA2_CH1 = 56, /**< DMA2 channel 1 */
NVIC_DMA2_CH2 = 57, /**< DMA2 channel 2 */
NVIC_DMA2_CH3 = 58, /**< DMA2 channel 3 */
NVIC_DMA2_CH_4_5 = 59, /**< DMA2 channels 4 and 5 */
/* Old enumerators kept around for backwards compatibility: */
NVIC_TIMER1_BRK =
NVIC_TIMER1_BRK_TIMER9, /**< @brief (Deprecated) Timer 1 break
*
* For backwards compatibility only.
* Use NVIC_TIMER1_BRK_TIMER9 instead. */
NVIC_TIMER1_UP =
NVIC_TIMER1_UP_TIMER10, /**< @brief (Deprecated) Timer 1 update.
*
* For backwards compatibility only.
* Use NVIC_TIMER1_UP_TIMER10 instead. */
NVIC_TIMER1_TRG_COM =
NVIC_TIMER1_TRG_COM_TIMER11, /**< @brief (deprecated) Timer 1 trigger
* and commutation.
*
* For backwards compatibility only.
* Use NVIC_TIMER1_TRG_COM_TIMER11
* instead. */
NVIC_TIMER8_BRK =
NVIC_TIMER8_BRK_TIMER12, /**< @brief (deprecated) Timer 8 break
*
* For backwards compatibility only.
* Use NVIC_TIMER8_BRK_TIMER12 instead. */
NVIC_TIMER8_UP =
NVIC_TIMER8_UP_TIMER13, /**< @brief (deprecated) Timer 8 update
* For backwards compatibility only.
* Use NVIC_TIMER8_UP_TIMER13 instead. */
NVIC_TIMER8_TRG_COM =
NVIC_TIMER8_TRG_COM_TIMER14, /**< @brief (deprecated) Timer 8 trigger
* and commutation.
* For backwards compatibility only.
* Use NVIC_TIMER8_TRG_COM_TIMER14
* instead. */
} nvic_irq_num;
static inline void nvic_irq_disable_all(void) {
/* Even low-density devices have over 32 interrupt lines. */
NVIC_BASE->ICER[0] = 0xFFFFFFFF;
NVIC_BASE->ICER[1] = 0xFFFFFFFF;
#if STM32_NR_INTERRUPTS > 64
/* Only some have over 64; e.g. connectivity line MCUs. */
NVIC_BASE->ICER[2] = 0xFFFFFFFF;
#endif
}
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -0,0 +1,52 @@
/******************************************************************************
* 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/stm32f1/include/series/pwr.h
* @author Marti Bolivar <mbolivar@leaflabs.com>
* @brief STM32F1 Power control (PWR) support.
*/
#ifndef _LIBMAPLE_STM32F1_PWR_H_
#define _LIBMAPLE_STM32F1_PWR_H_
/*
* Register bit definitions
*/
/* Control register */
/* PVD level selection */
#define PWR_CR_PLS_2_2V (0x0 << 5)
#define PWR_CR_PLS_2_3V (0x1 << 5)
#define PWR_CR_PLS_2_4V (0x2 << 5)
#define PWR_CR_PLS_2_5V (0x3 << 5)
#define PWR_CR_PLS_2_6V (0x4 << 5)
#define PWR_CR_PLS_2_7V (0x5 << 5)
#define PWR_CR_PLS_2_8V (0x6 << 5)
#define PWR_CR_PLS_2_9V (0x7 << 5)
#endif

View File

@@ -0,0 +1,640 @@
/******************************************************************************
* The MIT License
*
* Copyright (c) 2010 Perry Hung.
* Copyright (c) 2011 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/stm32f1/include/series/rcc.h
* @brief STM32F1 reset and clock control (RCC) support.
*/
#ifndef _LIBMAPLE_STM32F1_RCC_H_
#define _LIBMAPLE_STM32F1_RCC_H_
#ifdef __cplusplus
extern "C"{
#endif
#include <libmaple/libmaple_types.h>
#include <libmaple/bitband.h>
/*
* Register map
*/
/** STM32F1 RCC register map type */
typedef struct rcc_reg_map {
__io uint32 CR; /**< Clock control register */
__io uint32 CFGR; /**< Clock configuration register */
__io uint32 CIR; /**< Clock interrupt register */
__io uint32 APB2RSTR; /**< APB2 peripheral reset register */
__io uint32 APB1RSTR; /**< APB1 peripheral reset register */
__io uint32 AHBENR; /**< AHB peripheral clock enable register */
__io uint32 APB2ENR; /**< APB2 peripheral clock enable register */
__io uint32 APB1ENR; /**< APB1 peripheral clock enable register */
__io uint32 BDCR; /**< Backup domain control register */
__io uint32 CSR; /**< Control/status register */
} rcc_reg_map;
#define RCC_BASE ((struct rcc_reg_map*)0x40021000)
/*
* Register bit definitions
*/
/* Clock control register */
#define RCC_CR_PLLRDY_BIT 25
#define RCC_CR_PLLON_BIT 24
#define RCC_CR_CSSON_BIT 19
#define RCC_CR_HSEBYP_BIT 18
#define RCC_CR_HSERDY_BIT 17
#define RCC_CR_HSEON_BIT 16
#define RCC_CR_HSIRDY_BIT 1
#define RCC_CR_HSION_BIT 0
#define RCC_CR_PLLRDY (1U << RCC_CR_PLLRDY_BIT)
#define RCC_CR_PLLON (1U << RCC_CR_PLLON_BIT)
#define RCC_CR_CSSON (1U << RCC_CR_CSSON_BIT)
#define RCC_CR_HSEBYP (1U << RCC_CR_HSEBYP_BIT)
#define RCC_CR_HSERDY (1U << RCC_CR_HSERDY_BIT)
#define RCC_CR_HSEON (1U << RCC_CR_HSEON_BIT)
#define RCC_CR_HSICAL (0xFF << 8)
#define RCC_CR_HSITRIM (0x1F << 3)
#define RCC_CR_HSIRDY (1U << RCC_CR_HSIRDY_BIT)
#define RCC_CR_HSION (1U << RCC_CR_HSION_BIT)
/* Clock configuration register */
#define RCC_CFGR_USBPRE_BIT 22
#define RCC_CFGR_PLLXTPRE_BIT 17
#define RCC_CFGR_PLLSRC_BIT 16
#define RCC_CFGR_MCO (0x3 << 24)
#define RCC_CFGR_USBPRE (0x3 << RCC_CFGR_USBPRE_BIT)
#define RCC_CFGR_PLLMUL (0xF << 18)
#define RCC_CFGR_PLLXTPRE (1U << RCC_CFGR_PLLXTPRE_BIT)
#define RCC_CFGR_PLLSRC (1U << RCC_CFGR_PLLSRC_BIT)
#define RCC_CFGR_ADCPRE (0x3 << 14)
#define RCC_CFGR_PPRE2 (0x7 << 11)
#define RCC_CFGR_PPRE1 (0x7 << 8)
#define RCC_CFGR_HPRE (0xF << 4)
#define RCC_CFGR_SWS (0x3 << 2)
#define RCC_CFGR_SWS_PLL (0x2 << 2)
#define RCC_CFGR_SWS_HSE (0x1 << 2)
#define RCC_CFGR_SW 0x3
#define RCC_CFGR_SW_PLL 0x2
#define RCC_CFGR_SW_HSE 0x1
/* Clock interrupt register */
#define RCC_CIR_CSSC_BIT 23
#define RCC_CIR_PLLRDYC_BIT 20
#define RCC_CIR_HSERDYC_BIT 19
#define RCC_CIR_HSIRDYC_BIT 18
#define RCC_CIR_LSERDYC_BIT 17
#define RCC_CIR_LSIRDYC_BIT 16
#define RCC_CIR_PLLRDYIE_BIT 12
#define RCC_CIR_HSERDYIE_BIT 11
#define RCC_CIR_HSIRDYIE_BIT 10
#define RCC_CIR_LSERDYIE_BIT 9
#define RCC_CIR_LSIRDYIE_BIT 8
#define RCC_CIR_CSSF_BIT 7
#define RCC_CIR_PLLRDYF_BIT 4
#define RCC_CIR_HSERDYF_BIT 3
#define RCC_CIR_HSIRDYF_BIT 2
#define RCC_CIR_LSERDYF_BIT 1
#define RCC_CIR_LSIRDYF_BIT 0
#define RCC_CIR_CSSC (1U << RCC_CIR_CSSC_BIT)
#define RCC_CIR_PLLRDYC (1U << RCC_CIR_PLLRDYC_BIT)
#define RCC_CIR_HSERDYC (1U << RCC_CIR_HSERDYC_BIT)
#define RCC_CIR_HSIRDYC (1U << RCC_CIR_HSIRDYC_BIT)
#define RCC_CIR_LSERDYC (1U << RCC_CIR_LSERDYC_BIT)
#define RCC_CIR_LSIRDYC (1U << RCC_CIR_LSIRDYC_BIT)
#define RCC_CIR_PLLRDYIE (1U << RCC_CIR_PLLRDYIE_BIT)
#define RCC_CIR_HSERDYIE (1U << RCC_CIR_HSERDYIE_BIT)
#define RCC_CIR_HSIRDYIE (1U << RCC_CIR_HSIRDYIE_BIT)
#define RCC_CIR_LSERDYIE (1U << RCC_CIR_LSERDYIE_BIT)
#define RCC_CIR_LSIRDYIE (1U << RCC_CIR_LSIRDYIE_BIT)
#define RCC_CIR_CSSF (1U << RCC_CIR_CSSF_BIT)
#define RCC_CIR_PLLRDYF (1U << RCC_CIR_PLLRDYF_BIT)
#define RCC_CIR_HSERDYF (1U << RCC_CIR_HSERDYF_BIT)
#define RCC_CIR_HSIRDYF (1U << RCC_CIR_HSIRDYF_BIT)
#define RCC_CIR_LSERDYF (1U << RCC_CIR_LSERDYF_BIT)
#define RCC_CIR_LSIRDYF (1U << RCC_CIR_LSIRDYF_BIT)
/* APB2 peripheral reset register */
#define RCC_APB2RSTR_TIM11RST_BIT 21
#define RCC_APB2RSTR_TIM10RST_BIT 20
#define RCC_APB2RSTR_TIM9RST_BIT 19
#define RCC_APB2RSTR_ADC3RST_BIT 15
#define RCC_APB2RSTR_USART1RST_BIT 14
#define RCC_APB2RSTR_TIM8RST_BIT 13
#define RCC_APB2RSTR_SPI1RST_BIT 12
#define RCC_APB2RSTR_TIM1RST_BIT 11
#define RCC_APB2RSTR_ADC2RST_BIT 10
#define RCC_APB2RSTR_ADC1RST_BIT 9
#define RCC_APB2RSTR_IOPGRST_BIT 8
#define RCC_APB2RSTR_IOPFRST_BIT 7
#define RCC_APB2RSTR_IOPERST_BIT 6
#define RCC_APB2RSTR_IOPDRST_BIT 5
#define RCC_APB2RSTR_IOPCRST_BIT 4
#define RCC_APB2RSTR_IOPBRST_BIT 3
#define RCC_APB2RSTR_IOPARST_BIT 2
#define RCC_APB2RSTR_AFIORST_BIT 0
#define RCC_APB2RSTR_TIM11RST (1U << RCC_APB2RSTR_TIM11RST_BIT)
#define RCC_APB2RSTR_TIM10RST (1U << RCC_APB2RSTR_TIM10RST_BIT)
#define RCC_APB2RSTR_TIM9RST (1U << RCC_APB2RSTR_TIM9RST_BIT)
#define RCC_APB2RSTR_ADC3RST (1U << RCC_APB2RSTR_ADC3RST_BIT)
#define RCC_APB2RSTR_USART1RST (1U << RCC_APB2RSTR_USART1RST_BIT)
#define RCC_APB2RSTR_TIM8RST (1U << RCC_APB2RSTR_TIM8RST_BIT)
#define RCC_APB2RSTR_SPI1RST (1U << RCC_APB2RSTR_SPI1RST_BIT)
#define RCC_APB2RSTR_TIM1RST (1U << RCC_APB2RSTR_TIM1RST_BIT)
#define RCC_APB2RSTR_ADC2RST (1U << RCC_APB2RSTR_ADC2RST_BIT)
#define RCC_APB2RSTR_ADC1RST (1U << RCC_APB2RSTR_ADC1RST_BIT)
#define RCC_APB2RSTR_IOPGRST (1U << RCC_APB2RSTR_IOPGRST_BIT)
#define RCC_APB2RSTR_IOPFRST (1U << RCC_APB2RSTR_IOPFRST_BIT)
#define RCC_APB2RSTR_IOPERST (1U << RCC_APB2RSTR_IOPERST_BIT)
#define RCC_APB2RSTR_IOPDRST (1U << RCC_APB2RSTR_IOPDRST_BIT)
#define RCC_APB2RSTR_IOPCRST (1U << RCC_APB2RSTR_IOPCRST_BIT)
#define RCC_APB2RSTR_IOPBRST (1U << RCC_APB2RSTR_IOPBRST_BIT)
#define RCC_APB2RSTR_IOPARST (1U << RCC_APB2RSTR_IOPARST_BIT)
#define RCC_APB2RSTR_AFIORST (1U << RCC_APB2RSTR_AFIORST_BIT)
/* APB1 peripheral reset register */
#define RCC_APB1RSTR_DACRST_BIT 29
#define RCC_APB1RSTR_PWRRST_BIT 28
#define RCC_APB1RSTR_BKPRST_BIT 27
#define RCC_APB1RSTR_CANRST_BIT 25
#define RCC_APB1RSTR_USBRST_BIT 23
#define RCC_APB1RSTR_I2C2RST_BIT 22
#define RCC_APB1RSTR_I2C1RST_BIT 21
#define RCC_APB1RSTR_UART5RST_BIT 20
#define RCC_APB1RSTR_UART4RST_BIT 19
#define RCC_APB1RSTR_USART3RST_BIT 18
#define RCC_APB1RSTR_USART2RST_BIT 17
#define RCC_APB1RSTR_SPI3RST_BIT 15
#define RCC_APB1RSTR_SPI2RST_BIT 14
#define RCC_APB1RSTR_WWDRST_BIT 11
#define RCC_APB1RSTR_TIM14RST_BIT 8
#define RCC_APB1RSTR_TIM13RST_BIT 7
#define RCC_APB1RSTR_TIM12RST_BIT 6
#define RCC_APB1RSTR_TIM7RST_BIT 5
#define RCC_APB1RSTR_TIM6RST_BIT 4
#define RCC_APB1RSTR_TIM5RST_BIT 3
#define RCC_APB1RSTR_TIM4RST_BIT 2
#define RCC_APB1RSTR_TIM3RST_BIT 1
#define RCC_APB1RSTR_TIM2RST_BIT 0
#define RCC_APB1RSTR_DACRST (1U << RCC_APB1RSTR_DACRST_BIT)
#define RCC_APB1RSTR_PWRRST (1U << RCC_APB1RSTR_PWRRST_BIT)
#define RCC_APB1RSTR_BKPRST (1U << RCC_APB1RSTR_BKPRST_BIT)
#define RCC_APB1RSTR_CANRST (1U << RCC_APB1RSTR_CANRST_BIT)
#define RCC_APB1RSTR_USBRST (1U << RCC_APB1RSTR_USBRST_BIT)
#define RCC_APB1RSTR_I2C2RST (1U << RCC_APB1RSTR_I2C2RST_BIT)
#define RCC_APB1RSTR_I2C1RST (1U << RCC_APB1RSTR_I2C1RST_BIT)
#define RCC_APB1RSTR_UART5RST (1U << RCC_APB1RSTR_UART5RST_BIT)
#define RCC_APB1RSTR_UART4RST (1U << RCC_APB1RSTR_UART4RST_BIT)
#define RCC_APB1RSTR_USART3RST (1U << RCC_APB1RSTR_USART3RST_BIT)
#define RCC_APB1RSTR_USART2RST (1U << RCC_APB1RSTR_USART2RST_BIT)
#define RCC_APB1RSTR_SPI3RST (1U << RCC_APB1RSTR_SPI3RST_BIT)
#define RCC_APB1RSTR_SPI2RST (1U << RCC_APB1RSTR_SPI2RST_BIT)
#define RCC_APB1RSTR_WWDRST (1U << RCC_APB1RSTR_WWDRST_BIT)
#define RCC_APB1RSTR_TIM14RST (1U << RCC_APB1RSTR_TIM14RST_BIT)
#define RCC_APB1RSTR_TIM13RST (1U << RCC_APB1RSTR_TIM13RST_BIT)
#define RCC_APB1RSTR_TIM12RST (1U << RCC_APB1RSTR_TIM12RST_BIT)
#define RCC_APB1RSTR_TIM7RST (1U << RCC_APB1RSTR_TIM7RST_BIT)
#define RCC_APB1RSTR_TIM6RST (1U << RCC_APB1RSTR_TIM6RST_BIT)
#define RCC_APB1RSTR_TIM5RST (1U << RCC_APB1RSTR_TIM5RST_BIT)
#define RCC_APB1RSTR_TIM4RST (1U << RCC_APB1RSTR_TIM4RST_BIT)
#define RCC_APB1RSTR_TIM3RST (1U << RCC_APB1RSTR_TIM3RST_BIT)
#define RCC_APB1RSTR_TIM2RST (1U << RCC_APB1RSTR_TIM2RST_BIT)
/* AHB peripheral clock enable register */
#define RCC_AHBENR_SDIOEN_BIT 10
#define RCC_AHBENR_FSMCEN_BIT 8
#define RCC_AHBENR_CRCEN_BIT 7
#define RCC_AHBENR_FLITFEN_BIT 4
#define RCC_AHBENR_SRAMEN_BIT 2
#define RCC_AHBENR_DMA2EN_BIT 1
#define RCC_AHBENR_DMA1EN_BIT 0
#define RCC_AHBENR_SDIOEN (1U << RCC_AHBENR_SDIOEN_BIT)
#define RCC_AHBENR_FSMCEN (1U << RCC_AHBENR_FSMCEN_BIT)
#define RCC_AHBENR_CRCEN (1U << RCC_AHBENR_CRCEN_BIT)
#define RCC_AHBENR_FLITFEN (1U << RCC_AHBENR_FLITFEN_BIT)
#define RCC_AHBENR_SRAMEN (1U << RCC_AHBENR_SRAMEN_BIT)
#define RCC_AHBENR_DMA2EN (1U << RCC_AHBENR_DMA2EN_BIT)
#define RCC_AHBENR_DMA1EN (1U << RCC_AHBENR_DMA1EN_BIT)
/* APB2 peripheral clock enable register */
#define RCC_APB2ENR_TIM11EN_BIT 21
#define RCC_APB2ENR_TIM10EN_BIT 20
#define RCC_APB2ENR_TIM9EN_BIT 19
#define RCC_APB2ENR_ADC3EN_BIT 15
#define RCC_APB2ENR_USART1EN_BIT 14
#define RCC_APB2ENR_TIM8EN_BIT 13
#define RCC_APB2ENR_SPI1EN_BIT 12
#define RCC_APB2ENR_TIM1EN_BIT 11
#define RCC_APB2ENR_ADC2EN_BIT 10
#define RCC_APB2ENR_ADC1EN_BIT 9
#define RCC_APB2ENR_IOPGEN_BIT 8
#define RCC_APB2ENR_IOPFEN_BIT 7
#define RCC_APB2ENR_IOPEEN_BIT 6
#define RCC_APB2ENR_IOPDEN_BIT 5
#define RCC_APB2ENR_IOPCEN_BIT 4
#define RCC_APB2ENR_IOPBEN_BIT 3
#define RCC_APB2ENR_IOPAEN_BIT 2
#define RCC_APB2ENR_AFIOEN_BIT 0
#define RCC_APB2ENR_TIM11EN (1U << RCC_APB2ENR_TIM11EN_BIT)
#define RCC_APB2ENR_TIM10EN (1U << RCC_APB2ENR_TIM10EN_BIT)
#define RCC_APB2ENR_TIM9EN (1U << RCC_APB2ENR_TIM9EN_BIT)
#define RCC_APB2ENR_ADC3EN (1U << RCC_APB2ENR_ADC3EN_BIT)
#define RCC_APB2ENR_USART1EN (1U << RCC_APB2ENR_USART1EN_BIT)
#define RCC_APB2ENR_TIM8EN (1U << RCC_APB2ENR_TIM8EN_BIT)
#define RCC_APB2ENR_SPI1EN (1U << RCC_APB2ENR_SPI1EN_BIT)
#define RCC_APB2ENR_TIM1EN (1U << RCC_APB2ENR_TIM1EN_BIT)
#define RCC_APB2ENR_ADC2EN (1U << RCC_APB2ENR_ADC2EN_BIT)
#define RCC_APB2ENR_ADC1EN (1U << RCC_APB2ENR_ADC1EN_BIT)
#define RCC_APB2ENR_IOPGEN (1U << RCC_APB2ENR_IOPGEN_BIT)
#define RCC_APB2ENR_IOPFEN (1U << RCC_APB2ENR_IOPFEN_BIT)
#define RCC_APB2ENR_IOPEEN (1U << RCC_APB2ENR_IOPEEN_BIT)
#define RCC_APB2ENR_IOPDEN (1U << RCC_APB2ENR_IOPDEN_BIT)
#define RCC_APB2ENR_IOPCEN (1U << RCC_APB2ENR_IOPCEN_BIT)
#define RCC_APB2ENR_IOPBEN (1U << RCC_APB2ENR_IOPBEN_BIT)
#define RCC_APB2ENR_IOPAEN (1U << RCC_APB2ENR_IOPAEN_BIT)
#define RCC_APB2ENR_AFIOEN (1U << RCC_APB2ENR_AFIOEN_BIT)
/* APB1 peripheral clock enable register */
#define RCC_APB1ENR_DACEN_BIT 29
#define RCC_APB1ENR_PWREN_BIT 28
#define RCC_APB1ENR_BKPEN_BIT 27
#define RCC_APB1ENR_CANEN_BIT 25
#define RCC_APB1ENR_USBEN_BIT 23
#define RCC_APB1ENR_I2C2EN_BIT 22
#define RCC_APB1ENR_I2C1EN_BIT 21
#define RCC_APB1ENR_UART5EN_BIT 20
#define RCC_APB1ENR_UART4EN_BIT 19
#define RCC_APB1ENR_USART3EN_BIT 18
#define RCC_APB1ENR_USART2EN_BIT 17
#define RCC_APB1ENR_SPI3EN_BIT 15
#define RCC_APB1ENR_SPI2EN_BIT 14
#define RCC_APB1ENR_WWDEN_BIT 11
#define RCC_APB1ENR_TIM14EN_BIT 8
#define RCC_APB1ENR_TIM13EN_BIT 7
#define RCC_APB1ENR_TIM12EN_BIT 6
#define RCC_APB1ENR_TIM7EN_BIT 5
#define RCC_APB1ENR_TIM6EN_BIT 4
#define RCC_APB1ENR_TIM5EN_BIT 3
#define RCC_APB1ENR_TIM4EN_BIT 2
#define RCC_APB1ENR_TIM3EN_BIT 1
#define RCC_APB1ENR_TIM2EN_BIT 0
#define RCC_APB1ENR_DACEN (1U << RCC_APB1ENR_DACEN_BIT)
#define RCC_APB1ENR_PWREN (1U << RCC_APB1ENR_PWREN_BIT)
#define RCC_APB1ENR_BKPEN (1U << RCC_APB1ENR_BKPEN_BIT)
#define RCC_APB1ENR_CANEN (1U << RCC_APB1ENR_CANEN_BIT)
#define RCC_APB1ENR_USBEN (1U << RCC_APB1ENR_USBEN_BIT)
#define RCC_APB1ENR_I2C2EN (1U << RCC_APB1ENR_I2C2EN_BIT)
#define RCC_APB1ENR_I2C1EN (1U << RCC_APB1ENR_I2C1EN_BIT)
#define RCC_APB1ENR_UART5EN (1U << RCC_APB1ENR_UART5EN_BIT)
#define RCC_APB1ENR_UART4EN (1U << RCC_APB1ENR_UART4EN_BIT)
#define RCC_APB1ENR_USART3EN (1U << RCC_APB1ENR_USART3EN_BIT)
#define RCC_APB1ENR_USART2EN (1U << RCC_APB1ENR_USART2EN_BIT)
#define RCC_APB1ENR_SPI3EN (1U << RCC_APB1ENR_SPI3EN_BIT)
#define RCC_APB1ENR_SPI2EN (1U << RCC_APB1ENR_SPI2EN_BIT)
#define RCC_APB1ENR_WWDEN (1U << RCC_APB1ENR_WWDEN_BIT)
#define RCC_APB1ENR_TIM14EN (1U << RCC_APB1ENR_TIM14EN_BIT)
#define RCC_APB1ENR_TIM13EN (1U << RCC_APB1ENR_TIM13EN_BIT)
#define RCC_APB1ENR_TIM12EN (1U << RCC_APB1ENR_TIM12EN_BIT)
#define RCC_APB1ENR_TIM7EN (1U << RCC_APB1ENR_TIM7EN_BIT)
#define RCC_APB1ENR_TIM6EN (1U << RCC_APB1ENR_TIM6EN_BIT)
#define RCC_APB1ENR_TIM5EN (1U << RCC_APB1ENR_TIM5EN_BIT)
#define RCC_APB1ENR_TIM4EN (1U << RCC_APB1ENR_TIM4EN_BIT)
#define RCC_APB1ENR_TIM3EN (1U << RCC_APB1ENR_TIM3EN_BIT)
#define RCC_APB1ENR_TIM2EN (1U << RCC_APB1ENR_TIM2EN_BIT)
/* Backup domain control register */
#define RCC_BDCR_BDRST_BIT 16
#define RCC_BDCR_RTCEN_BIT 15
#define RCC_BDCR_LSEBYP_BIT 2
#define RCC_BDCR_LSERDY_BIT 1
#define RCC_BDCR_LSEON_BIT 0
#define RCC_BDCR_BDRST (1U << RCC_BDCR_BDRST_BIT)
#define RCC_BDCR_RTCEN (1U << RCC_BDCR_RTC_BIT)
#define RCC_BDCR_RTCSEL (0x3 << 8)
#define RCC_BDCR_RTCSEL_NONE (0x0 << 8)
#define RCC_BDCR_RTCSEL_LSE (0x1 << 8)
#define RCC_BDCR_RTCSEL_LSI (0x2 << 8) // added to support RTClock
#define RCC_BDCR_RTCSEL_HSE (0x3 << 8)
#define RCC_BDCR_LSEBYP (1U << RCC_BDCR_LSEBYP_BIT)
#define RCC_BDCR_LSERDY (1U << RCC_BDCR_LSERDY_BIT)
#define RCC_BDCR_LSEON (1U << RCC_BDCR_LSEON_BIT)
/* Control/status register */
#define RCC_CSR_LPWRRSTF_BIT 31
#define RCC_CSR_WWDGRSTF_BIT 30
#define RCC_CSR_IWDGRSTF_BIT 29
#define RCC_CSR_SFTRSTF_BIT 28
#define RCC_CSR_PORRSTF_BIT 27
#define RCC_CSR_PINRSTF_BIT 26
#define RCC_CSR_RMVF_BIT 24
#define RCC_CSR_LSIRDY_BIT 1
#define RCC_CSR_LSION_BIT 0
#define RCC_CSR_LPWRRSTF (1U << RCC_CSR_LPWRRSTF_BIT)
#define RCC_CSR_WWDGRSTF (1U << RCC_CSR_WWDGRSTF_BIT)
#define RCC_CSR_IWDGRSTF (1U << RCC_CSR_IWDGRSTF_BIT)
#define RCC_CSR_SFTRSTF (1U << RCC_CSR_SFTRSTF_BIT)
#define RCC_CSR_PORRSTF (1U << RCC_CSR_PORRSTF_BIT)
#define RCC_CSR_PINRSTF (1U << RCC_CSR_PINRSTF_BIT)
#define RCC_CSR_RMVF (1U << RCC_CSR_RMVF_BIT)
#define RCC_CSR_LSIRDY (1U << RCC_CSR_LSIRDY_BIT)
#define RCC_CSR_LSION (1U << RCC_CSR_LSION_BIT)
/*
* libmaple-mandated enumeration types.
*/
/**
* @brief STM32F1 rcc_clk_id.
*/
typedef enum rcc_clk_id {
RCC_ADC1,
RCC_ADC2,
RCC_ADC3,
RCC_AFIO,
RCC_BKP,
RCC_CRC,
RCC_DAC,
RCC_DMA1,
RCC_DMA2,
RCC_FLITF,
RCC_FSMC,
RCC_GPIOA,
RCC_GPIOB,
RCC_GPIOC,
RCC_GPIOD,
RCC_GPIOE,
RCC_GPIOF,
RCC_GPIOG,
RCC_I2C1,
RCC_I2C2,
RCC_PWR,
RCC_SDIO,
RCC_SPI1,
RCC_SPI2,
RCC_SPI3,
RCC_SRAM,
RCC_TIMER1,
RCC_TIMER2,
RCC_TIMER3,
RCC_TIMER4,
RCC_TIMER5,
RCC_TIMER6,
RCC_TIMER7,
RCC_TIMER8,
RCC_TIMER9,
RCC_TIMER10,
RCC_TIMER11,
RCC_TIMER12,
RCC_TIMER13,
RCC_TIMER14,
RCC_USART1,
RCC_USART2,
RCC_USART3,
RCC_UART4,
RCC_UART5,
RCC_USB,
} rcc_clk_id;
/**
* @brief STM32F1 PLL clock sources.
* @see rcc_configure_pll()
*/
typedef enum rcc_pllsrc {
RCC_PLLSRC_HSE = (0x1 << 16),
RCC_PLLSRC_HSI_DIV_2 = (0x0 << 16)
} rcc_pllsrc;
/**
* @brief STM32F1 clock domains.
* @see rcc_dev_clk()
*/
typedef enum rcc_clk_domain {
RCC_APB1,
RCC_APB2,
RCC_AHB
} rcc_clk_domain;
/**
* @brief STM32F1 Prescaler identifiers
* @see rcc_set_prescaler()
*/
typedef enum rcc_prescaler {
RCC_PRESCALER_AHB,
RCC_PRESCALER_APB1,
RCC_PRESCALER_APB2,
RCC_PRESCALER_USB,
RCC_PRESCALER_ADC
} rcc_prescaler;
/**
* @brief STM32F1 ADC prescaler dividers
* @see rcc_set_prescaler()
*/
typedef enum rcc_adc_divider {
RCC_ADCPRE_PCLK_DIV_2 = 0x0 << 14,
RCC_ADCPRE_PCLK_DIV_4 = 0x1 << 14,
RCC_ADCPRE_PCLK_DIV_6 = 0x2 << 14,
RCC_ADCPRE_PCLK_DIV_8 = 0x3 << 14,
} rcc_adc_divider;
/**
* @brief STM32F1 APB1 prescaler dividers
* @see rcc_set_prescaler()
*/
typedef enum rcc_apb1_divider {
RCC_APB1_HCLK_DIV_1 = 0x0 << 8,
RCC_APB1_HCLK_DIV_2 = 0x4 << 8,
RCC_APB1_HCLK_DIV_4 = 0x5 << 8,
RCC_APB1_HCLK_DIV_8 = 0x6 << 8,
RCC_APB1_HCLK_DIV_16 = 0x7 << 8,
} rcc_apb1_divider;
/**
* @brief STM32F1 APB2 prescaler dividers
* @see rcc_set_prescaler()
*/
typedef enum rcc_apb2_divider {
RCC_APB2_HCLK_DIV_1 = 0x0 << 11,
RCC_APB2_HCLK_DIV_2 = 0x4 << 11,
RCC_APB2_HCLK_DIV_4 = 0x5 << 11,
RCC_APB2_HCLK_DIV_8 = 0x6 << 11,
RCC_APB2_HCLK_DIV_16 = 0x7 << 11,
} rcc_apb2_divider;
/**
* @brief STM32F1 AHB prescaler dividers
* @see rcc_set_prescaler()
*/
typedef enum rcc_ahb_divider {
RCC_AHB_SYSCLK_DIV_1 = 0x0 << 4,
RCC_AHB_SYSCLK_DIV_2 = 0x8 << 4,
RCC_AHB_SYSCLK_DIV_4 = 0x9 << 4,
RCC_AHB_SYSCLK_DIV_8 = 0xA << 4,
RCC_AHB_SYSCLK_DIV_16 = 0xB << 4,
RCC_AHB_SYSCLK_DIV_32 = 0xC << 4,
RCC_AHB_SYSCLK_DIV_64 = 0xD << 4,
RCC_AHB_SYSCLK_DIV_128 = 0xD << 4,
RCC_AHB_SYSCLK_DIV_256 = 0xE << 4,
RCC_AHB_SYSCLK_DIV_512 = 0xF << 4,
} rcc_ahb_divider;
/**
* @brief STM32F1 USB prescaler dividers
* @see rcc_set_prescaler()
*/
/*
Set and reset by software to control the USB clock prescaler value. The USB clock
must be 48MHz. These bits cant be reset if the USB clock is enabled.
00: (CK_PLL / 1.5) selected
01: CK_PLL selected
*/
typedef enum rcc_usb_divider {
RCC_USB_SYSCLK_DIV_1 = 0x1 << 22,
RCC_USB_SYSCLK_DIV_1_5 = 0x0 << 22,
RCC_USB_SYSCLK_DIV_2 = 0x3 << 22,
RCC_USB_SYSCLK_DIV_2_5 = 0x2 << 22,
} rcc_usb_divider;
/**
* @brief Start the low speed internal oscillator
*/
static inline void rcc_start_lsi(void) {
*bb_perip(&RCC_BASE->CSR, RCC_CSR_LSION_BIT) = 1;
while (*bb_perip(&RCC_BASE->CSR, RCC_CSR_LSIRDY_BIT) == 0);
}
/**
* @brief STM32F1 clock sources.
*/
typedef enum rcc_clk {
RCC_CLK_PLL = (uint16)((offsetof(struct rcc_reg_map, CR) << 8) |
RCC_CR_PLLON_BIT), /**< Main PLL, clocked by
HSI or HSE. */
RCC_CLK_HSE = (uint16)((offsetof(struct rcc_reg_map, CR) << 8) |
RCC_CR_HSEON_BIT), /**< High speed external. */
RCC_CLK_HSI = (uint16)((offsetof(struct rcc_reg_map, CR) << 8) |
RCC_CR_HSION_BIT), /**< High speed internal. */
RCC_CLK_LSE = (uint16)((offsetof(struct rcc_reg_map, BDCR) << 8) |
RCC_BDCR_LSEON_BIT), /**< Low-speed external
* (32.768 KHz). */
RCC_CLK_LSI = (uint16)((offsetof(struct rcc_reg_map, CSR) << 8) |
RCC_CSR_LSION_BIT), /**< Low-speed internal
* (approximately 32 KHz). */
} rcc_clk;
/**
* @brief STM32F1 PLL multipliers.
*/
typedef enum rcc_pll_multiplier {
RCC_PLLMUL_2 = (0x0 << 18),
RCC_PLLMUL_3 = (0x1 << 18),
RCC_PLLMUL_4 = (0x2 << 18),
RCC_PLLMUL_5 = (0x3 << 18),
RCC_PLLMUL_6 = (0x4 << 18),
RCC_PLLMUL_7 = (0x5 << 18),
RCC_PLLMUL_8 = (0x6 << 18),
RCC_PLLMUL_9 = (0x7 << 18),
RCC_PLLMUL_10 = (0x8 << 18),
RCC_PLLMUL_11 = (0x9 << 18),
RCC_PLLMUL_12 = (0xA << 18),
RCC_PLLMUL_13 = (0xB << 18),
RCC_PLLMUL_14 = (0xC << 18),
RCC_PLLMUL_15 = (0xD << 18),
RCC_PLLMUL_16 = (0xE << 18),
} rcc_pll_multiplier;
/* FIXME [0.0.13] Just have data point to an rcc_pll_multiplier! */
/**
* @brief Start the low speed external oscillatior
*/
static inline void rcc_start_lse(void) {
bb_peri_set_bit(&RCC_BASE->BDCR, RCC_BDCR_LSEBYP_BIT, 0);
bb_peri_set_bit(&RCC_BASE->BDCR, RCC_BDCR_LSEON_BIT, 1);
while (bb_peri_get_bit(&RCC_BASE->BDCR, RCC_BDCR_LSERDY_BIT ) == 0);
}
/**
* @brief STM32F1 PLL configuration values.
* Point to one of these with the "data" field in a struct rcc_pll_cfg.
* @see struct rcc_pll_cfg.
*/
typedef struct stm32f1_rcc_pll_data {
rcc_pll_multiplier pll_mul; /**< PLL multiplication factor. */
} stm32f1_rcc_pll_data;
/*
* Deprecated bits.
*/
static inline void rcc_start_hse(void) { // Added to support RTClock
// *bb_perip(&RCC_BASE->CR, RCC_CR_HSEON_BIT) = 1;
while (bb_peri_get_bit(&RCC_BASE->CR, RCC_CR_HSERDY_BIT) == 0);
}
/**
* @brief Deprecated; STM32F1 only.
*
* Initialize the clock control system. Initializes the system
* clock source to use the PLL driven by an external oscillator.
*
* @param sysclk_src system clock source, must be PLL
* @param pll_src pll clock source, must be HSE
* @param pll_mul pll multiplier
*/
__deprecated
void rcc_clk_init(rcc_sysclk_src sysclk_src,
rcc_pllsrc pll_src,
rcc_pll_multiplier pll_mul);
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -0,0 +1,99 @@
/******************************************************************************
* 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_
#include <libmaple/libmaple_types.h>
#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)
/*
* 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
/*
* 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 inline __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
#endif

View File

@@ -0,0 +1,279 @@
/******************************************************************************
* The MIT License
*
* Copyright (c) 2010, 2011 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/stm32f1/include/series/stm32.h
* @brief STM32F1 chip- and series-specific definitions.
*/
/*
* Modified by Roger Clark. 20141111. Wrapped #define STM32_MEDIUM_DENSITY in #ifndef
* to prevent redefinition warnings as SSTM32_MEDIUM_DENSITY is defined in boards.txt as a compilor define.
*/
#ifndef _LIBMAPLE_STM32F1_H_
#define _LIBMAPLE_STM32F1_H_
#ifdef __cplusplus
extern "C" {
#endif
#define STM32_MCU_SERIES STM32_SERIES_F1
/* The STM32F1 series is subdivided into "lines". libmaple currently
* officially supports STM32F103 performance line MCUs (see the
* MCU-specific value section below).
*
* You can use these F1 line defines if porting libmaple to support
* MCUs on other lines. */
/** STM32F1 value line (STM32F100 MCUs). */
#define STM32_F1_LINE_VALUE 0
/** STM32F1 access line (STM32F101 MCUs). */
#define STM32_F1_LINE_ACCESS 1
/** STM32F1 USB access line (STM32F102 MCUs). */
#define STM32_F1_LINE_USB_ACCESS 2
/** STM32F1 performance line (STM32F103 MCUs). */
#define STM32_F1_LINE_PERFORMANCE 3
/** STM32F1 connectivity line (STM32F105/F107 MCUs). */
#define STM32_F1_LINE_CONNECTIVITY 5
/*
* MCU-specific values.
*
* You can use this section to override any of the below settings on a
* per-MCU basis. For example, if your MCU has different STM32_PCLK1
* or STM32_PCLK2 values, you can set them here and the values for
* STM32F103 microcontrollers set below won't take effect.
*/
#if defined(MCU_STM32F103T8)
# define STM32_NR_GPIO_PORTS 2
# define STM32_SRAM_END ((void*)0x20005000)
# define NR_GPIO_PORTS STM32_NR_GPIO_PORTS
# define STM32_F1_LINE STM32_F1_LINE_PERFORMANCE
# define STM32_MEDIUM_DENSITY
#elif defined(MCU_STM32F103TB)
# define STM32_NR_GPIO_PORTS 2
# define STM32_SRAM_END ((void*)0x20005000)
# define NR_GPIO_PORTS STM32_NR_GPIO_PORTS
# define STM32_F1_LINE STM32_F1_LINE_PERFORMANCE
# define STM32_MEDIUM_DENSITY
#elif defined(MCU_STM32F103C8)
# define STM32_NR_GPIO_PORTS 3
# define STM32_SRAM_END ((void*)0x20005000)
# define NR_GPIO_PORTS STM32_NR_GPIO_PORTS
# define STM32_F1_LINE STM32_F1_LINE_PERFORMANCE
# define STM32_MEDIUM_DENSITY
#elif defined(MCU_STM32F103CB)
# define STM32_F1_LINE STM32_F1_LINE_PERFORMANCE
/* This STM32_NR_GPIO_PORTS is not true, but only pins 0 and
* exist, and they're used for OSC (e.g. on LeafLabs' Maple Mini),
* so we'll live with this for now. */
# define STM32_NR_GPIO_PORTS 3
# define STM32_SRAM_END ((void*)0x20005000)
# define STM32_MEDIUM_DENSITY
#elif defined(MCU_STM32F103R8)
# define STM32_F1_LINE STM32_F1_LINE_PERFORMANCE
# define STM32_NR_GPIO_PORTS 4
# define STM32_SRAM_END ((void*)0x20005000)
# define STM32_MEDIUM_DENSITY
#elif defined(MCU_STM32F103RB)
# define STM32_F1_LINE STM32_F1_LINE_PERFORMANCE
# define STM32_NR_GPIO_PORTS 4
# define STM32_SRAM_END ((void*)0x20005000)
# define STM32_MEDIUM_DENSITY
#elif defined(MCU_STM32F103RC)
# define STM32_F1_LINE STM32_F1_LINE_PERFORMANCE
# define STM32_NR_GPIO_PORTS 4
# define STM32_SRAM_END ((void*)0x2000C000)
# define STM32_HIGH_DENSITY
#elif defined(MCU_STM32F103RD) || defined(MCU_STM32F103RE)
# define STM32_F1_LINE STM32_F1_LINE_PERFORMANCE
# define STM32_NR_GPIO_PORTS 4
# define STM32_SRAM_END ((void*)0x20010000)
# define STM32_HIGH_DENSITY
#elif defined(MCU_STM32F103V8)
# define STM32_F1_LINE STM32_F1_LINE_PERFORMANCE
# define STM32_NR_GPIO_PORTS 5
# define STM32_SRAM_END ((void*)0x20005000)
# define STM32_MEDIUM_DENSITY
#elif defined(MCU_STM32F103VB)
# define STM32_F1_LINE STM32_F1_LINE_PERFORMANCE
# define STM32_NR_GPIO_PORTS 5
# define STM32_SRAM_END ((void*)0x20005000)
# define STM32_MEDIUM_DENSITY
#elif defined(MCU_STM32F103VC)
# define STM32_F1_LINE STM32_F1_LINE_PERFORMANCE
# define STM32_NR_GPIO_PORTS 5
# define STM32_SRAM_END ((void*)0x2000C000)
# define STM32_HIGH_DENSITY
#elif defined(MCU_STM32F103VD) || defined(MCU_STM32F103VE)
# define STM32_F1_LINE STM32_F1_LINE_PERFORMANCE
# define STM32_NR_GPIO_PORTS 5
# define STM32_SRAM_END ((void*)0x20010000)
# define STM32_HIGH_DENSITY
#elif defined(MCU_STM32F103ZC)
# define STM32_F1_LINE STM32_F1_LINE_PERFORMANCE
# define STM32_NR_GPIO_PORTS 7
# define STM32_SRAM_END ((void*)0x2000C000)
# define STM32_HIGH_DENSITY
#elif defined(MCU_STM32F103ZD) || defined(MCU_STM32F103ZE)
# define STM32_F1_LINE STM32_F1_LINE_PERFORMANCE
# define STM32_NR_GPIO_PORTS 7
# define STM32_SRAM_END ((void*)0x20010000)
# define STM32_HIGH_DENSITY
#elif defined(MCU_STM32F100RB)
# define STM32_F1_LINE STM32_F1_LINE_VALUE
# define STM32_NR_GPIO_PORTS 4
# define STM32_TIMER_MASK 0x380DE /* Timers: 1-4, 6, 7, 15-17. */
# define STM32_SRAM_END ((void*)0x20002000)
# define STM32_MEDIUM_DENSITY
#else
#warning "Unsupported or unspecified STM32F1 MCU."
#endif
/*
* Derived values.
*/
#if STM32_F1_LINE == STM32_F1_LINE_PERFORMANCE
/* All supported performance line MCUs have a USB peripheral */
# define STM32_HAVE_USB 1
# ifdef STM32_MEDIUM_DENSITY
# define STM32_NR_INTERRUPTS 43
# define STM32_TIMER_MASK 0x1E /* TIMER1--TIMER4 */
# define STM32_HAVE_FSMC 0
# define STM32_HAVE_DAC 0
# elif defined(STM32_HIGH_DENSITY)
# define STM32_NR_INTERRUPTS 60
# define STM32_TIMER_MASK 0x1FE /* TIMER1--TIMER8 */
# define STM32_HAVE_FSMC 1
# define STM32_HAVE_DAC 1
# elif defined(STM32_XL_DENSITY)
# define STM32_NR_INTERRUPTS 60
# define STM32_TIMER_MASK 0x7FFE /* TIMER1--TIMER14 */
# define STM32_HAVE_FSMC 1
# define STM32_HAVE_DAC 1
# endif
#elif STM32_F1_LINE == STM32_F1_LINE_VALUE
/* Value line MCUs don't have USB peripherals. */
# define STM32_HAVE_USB 0
# ifdef STM32_MEDIUM_DENSITY
# define STM32_NR_INTERRUPTS 56
# define STM32_HAVE_FSMC 0
# define STM32_HAVE_DAC 1
# elif defined(STM32_HIGH_DENSITY)
/* 61 interrupts here counts the possibility for a remapped
* DMA2 channel 5 IRQ occurring at NVIC index 60. */
# define STM32_NR_INTERRUPTS 61
# define STM32_HAVE_FSMC 1
# define STM32_HAVE_DAC 1
# endif
#endif
/*
* Clock configuration.
*
* You can patch these for your line, MCU, clock configuration,
* etc. here or by setting cflags when compiling libmaple.
*/
#if STM32_F1_LINE == STM32_F1_LINE_PERFORMANCE
# ifndef STM32_PCLK1
# define STM32_PCLK1 F_CPU/2
# endif
# ifndef STM32_PCLK2
# define STM32_PCLK2 F_CPU
# endif
# ifndef STM32_DELAY_US_MULT
# define STM32_DELAY_US_MULT (F_CPU / 6000000L)
# endif
#elif STM32_F1_LINE == STM32_F1_LINE_VALUE /* TODO */
# ifndef STM32_PCLK1
# define STM32_PCLK1 12000000U
# endif
# ifndef STM32_PCLK2
# define STM32_PCLK2 24000000U
# endif
# ifndef STM32_DELAY_US_MULT
# define STM32_DELAY_US_MULT 8 /* FIXME: value is incorrect. */
# endif
#elif STM32_F1_LINE == STM32_F1_LINE_ACCESS /* TODO */
#elif STM32_F1_LINE == STM32_F1_LINE_USB_ACCESS /* TODO */
#elif STM32_F1_LINE == STM32_F1_LINE_CONNECTIVITY /* TODO */
#endif
/*
* Sanity checks.
*
* Make sure we have the F1-specific defines we need.
* <libmaple/stm32.h> will check that we've defined everything it needs.
*/
#if !defined(STM32_F1_LINE)
#error "Bad STM32F1 configuration. Check STM32F1 <series/stm32.h> header."
#endif
/*
* Doxygen
*/
#ifdef __DOXYGEN__
/**
* @brief STM32 line value for the STM32F1 MCU being targeted.
*
* At time of writing, allowed values are: STM32_F1_LINE_PERFORMANCE,
* STM32_F1_LINE_VALUE. This set of values may expand as libmaple adds
* support for more STM32F1 lines.
*/
#define STM32_F1_LINE
#endif /* __DOXYGEN__ */
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -0,0 +1,128 @@
/******************************************************************************
* 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/stm32f1/include/series/timer.h
* @author Marti Bolivar <mbolivar@leaflabs.com>
* @brief STM32F1 timer support.
*/
#ifndef _LIBMAPLE_STM32F1_TIMER_H_
#define _LIBMAPLE_STM32F1_TIMER_H_
#include <libmaple/libmaple_types.h>
/*
* Register maps and base pointers
*/
/** STM32F1 general purpose timer register map type */
typedef struct timer_gen_reg_map {
__io uint32 CR1; /**< Control register 1 */
__io uint32 CR2; /**< Control register 2 */
__io uint32 SMCR; /**< Slave mode control register */
__io uint32 DIER; /**< DMA/Interrupt enable register */
__io uint32 SR; /**< Status register */
__io uint32 EGR; /**< Event generation register */
__io uint32 CCMR1; /**< Capture/compare mode register 1 */
__io uint32 CCMR2; /**< Capture/compare mode register 2 */
__io uint32 CCER; /**< Capture/compare enable register */
__io uint32 CNT; /**< Counter */
__io uint32 PSC; /**< Prescaler */
__io uint32 ARR; /**< Auto-reload register */
const uint32 RESERVED1; /**< Reserved */
__io uint32 CCR1; /**< Capture/compare register 1 */
__io uint32 CCR2; /**< Capture/compare register 2 */
__io uint32 CCR3; /**< Capture/compare register 3 */
__io uint32 CCR4; /**< Capture/compare register 4 */
const uint32 RESERVED2; /**< Reserved */
__io uint32 DCR; /**< DMA control register */
__io uint32 DMAR; /**< DMA address for full transfer */
} timer_gen_reg_map;
struct timer_adv_reg_map;
struct timer_bas_reg_map;
/** Timer 1 register map base pointer */
#define TIMER1_BASE ((struct timer_adv_reg_map*)0x40012C00)
/** Timer 2 register map base pointer */
#define TIMER2_BASE ((struct timer_gen_reg_map*)0x40000000)
/** Timer 3 register map base pointer */
#define TIMER3_BASE ((struct timer_gen_reg_map*)0x40000400)
/** Timer 4 register map base pointer */
#define TIMER4_BASE ((struct timer_gen_reg_map*)0x40000800)
/** Timer 5 register map base pointer */
#define TIMER5_BASE ((struct timer_gen_reg_map*)0x40000C00)
/** Timer 6 register map base pointer */
#define TIMER6_BASE ((struct timer_bas_reg_map*)0x40001000)
/** Timer 7 register map base pointer */
#define TIMER7_BASE ((struct timer_bas_reg_map*)0x40001400)
/** Timer 8 register map base pointer */
#define TIMER8_BASE ((struct timer_adv_reg_map*)0x40013400)
/** Timer 9 register map base pointer */
#define TIMER9_BASE ((struct timer_gen_reg_map*)0x40014C00)
/** Timer 10 register map base pointer */
#define TIMER10_BASE ((struct timer_gen_reg_map*)0x40015000)
/** Timer 11 register map base pointer */
#define TIMER11_BASE ((struct timer_gen_reg_map*)0x40015400)
/** Timer 12 register map base pointer */
#define TIMER12_BASE ((struct timer_gen_reg_map*)0x40001800)
/** Timer 13 register map base pointer */
#define TIMER13_BASE ((struct timer_gen_reg_map*)0x40001C00)
/** Timer 14 register map base pointer */
#define TIMER14_BASE ((struct timer_gen_reg_map*)0x40002000)
/*
* Device pointers
*
* We only declare device pointers to timers which actually exist on
* the target MCU. This helps when porting programs to STM32F1 (or
* within F1 to a lower density MCU), as attempts to use nonexistent
* timers cause build errors instead of undefined behavior.
*/
struct timer_dev;
extern struct timer_dev *const TIMER1;
extern struct timer_dev *const TIMER2;
extern struct timer_dev *const TIMER3;
extern struct timer_dev *const TIMER4;
#if defined(STM32_HIGH_DENSITY) || defined(STM32_XL_DENSITY)
extern struct timer_dev *const TIMER5;
extern struct timer_dev *const TIMER6;
extern struct timer_dev *const TIMER7;
extern struct timer_dev *const TIMER8;
#endif
#ifdef STM32_XL_DENSITY
extern struct timer_dev *const TIMER9;
extern struct timer_dev *const TIMER10;
extern struct timer_dev *const TIMER11;
extern struct timer_dev *const TIMER12;
extern struct timer_dev *const TIMER13;
extern struct timer_dev *const TIMER14;
#endif
#endif

View File

@@ -0,0 +1,76 @@
/******************************************************************************
* 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/stm32f1/include/series/usart.h
* @author Marti Bolivar <mbolivar@leaflabs.com>
* @brief STM32F1 USART support.
*/
#ifndef _LIBMAPLE_STM32F1_USART_H_
#define _LIBMAPLE_STM32F1_USART_H_
#ifdef __cplusplus
extern "C"{
#endif
/*
* Register map base pointers
*/
struct usart_reg_map;
/** USART1 register map base pointer */
#define USART1_BASE ((struct usart_reg_map*)0x40013800)
/** USART2 register map base pointer */
#define USART2_BASE ((struct usart_reg_map*)0x40004400)
/** USART3 register map base pointer */
#define USART3_BASE ((struct usart_reg_map*)0x40004800)
#ifdef STM32_HIGH_DENSITY
/** UART4 register map base pointer */
#define UART4_BASE ((struct usart_reg_map*)0x40004C00)
/** UART5 register map base pointer */
#define UART5_BASE ((struct usart_reg_map*)0x40005000)
#endif
/*
* Devices
*/
struct usart_dev;
extern struct usart_dev *USART1;
extern struct usart_dev *USART2;
extern struct usart_dev *USART3;
#ifdef STM32_HIGH_DENSITY
extern struct usart_dev *UART4;
extern struct usart_dev *UART5;
#endif
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -0,0 +1,45 @@
# Standard things
sp := $(sp).x
dirstack_$(sp) := $(d)
d := $(dir)
BUILDDIRS += $(BUILD_PATH)/$(d)
# Local flags
CFLAGS_$(d) = -I$(d) $(LIBMAPLE_PRIVATE_INCLUDES) $(LIBMAPLE_INCLUDES) -Wall -Werror
ASFLAGS_$(d) = -I$(d) $(LIBMAPLE_PRIVATE_INCLUDES) $(LIBMAPLE_INCLUDES) -Wall -Werror
# Extra BUILDDIRS
BUILDDIRS += $(BUILD_PATH)/$(d)/$(MCU_F1_LINE)
# Local rules and targets
sSRCS_$(d) := $(MCU_F1_LINE)/isrs.S
sSRCS_$(d) += $(MCU_F1_LINE)/vector_table.S
cSRCS_$(d) := adc.c
cSRCS_$(d) += bkp.c
cSRCS_$(d) += dma.c
cSRCS_$(d) += exti.c
cSRCS_$(d) += fsmc.c
cSRCS_$(d) += gpio.c
cSRCS_$(d) += i2c.c
cSRCS_$(d) += rcc.c
cSRCS_$(d) += spi.c
cSRCS_$(d) += timer.c
cSRCS_$(d) += usart.c
sFILES_$(d) := $(sSRCS_$(d):%=$(d)/%)
cFILES_$(d) := $(cSRCS_$(d):%=$(d)/%)
OBJS_$(d) := $(sFILES_$(d):%.S=$(BUILD_PATH)/%.o) \
$(cFILES_$(d):%.c=$(BUILD_PATH)/%.o)
DEPS_$(d) := $(OBJS_$(d):%.o=%.d)
$(OBJS_$(d)): TGT_ASFLAGS := $(ASFLAGS_$(d))
$(OBJS_$(d)): TGT_CFLAGS := $(CFLAGS_$(d))
TGT_BIN += $(OBJS_$(d))
# Standard things
-include $(DEPS_$(d))
d := $(dirstack_$(sp))
sp := $(basename $(sp))

View File

@@ -0,0 +1,335 @@
/******************************************************************************
* 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/adc.h
* @author Marti Bolivar <mbolivar@leaflabs.com>,
* @brief STM32F2 ADC support.
*/
#ifndef _LIBMAPLE_STM32F2_ADC_H_
#define _LIBMAPLE_STM32F2_ADC_H_
#include <libmaple/libmaple_types.h>
/*
* Devices
*/
extern const struct adc_dev *ADC1;
extern const struct adc_dev *ADC2;
extern const struct adc_dev *ADC3;
/*
* Common register map
*/
/** ADC common register map type */
typedef struct adc_common_reg_map {
__io uint32 CSR; /**< Common status register */
__io uint32 CCR; /**< Common control register */
__io uint32 CDR; /**<
* @brief Common regular data register
* for dual and triple modes */
} adc_common_reg_map;
/*
* Register map base pointers
*/
/** ADC1 register map base pointer. */
#define ADC1_BASE ((struct adc_reg_map*)0x40012000)
/** ADC2 register map base pointer. */
#define ADC2_BASE ((struct adc_reg_map*)0x40012100)
/** ADC3 register map base pointer. */
#define ADC3_BASE ((struct adc_reg_map*)0x40012200)
/** ADC common register map base pointer. */
#define ADC_COMMON_BASE ((struct adc_common_reg_map*)0x40012300)
/*
* Register bit definitions
*/
/* Status register */
/** Overrun bit. */
#define ADC_SR_OVR_BIT 5
/** Overrun. */
#define ADC_SR_OVR (1U << ADC_SR_OVR_BIT)
/* Control register 1 */
/** Overrun interrupt enable bit. */
#define ADC_CR1_OVRIE_BIT 26
/** Overrun interrupt error enable. */
#define ADC_CR1_OVRIE (1U << ADC_CR1_OVRIE_BIT)
/** Conversion resolution. */
#define ADC_CR1_RES (0x3U << 24)
/** Conversion resolution: 12 bit (at least 15 ADCCLK cycles). */
#define ADC_CR1_RES_12BIT (0x0U << 24)
/** Conversion resolution: 10 bit (at least 13 ADCCLK cycles). */
#define ADC_CR1_RES_10BIT (0x1U << 24)
/** Conversion resolution: 8 bit (at least 11 ADCCLK cycles). */
#define ADC_CR1_RES_8BIT (0x2U << 24)
/** Conversion resolution: 6 bit (at least 9 ADCCLK cycles). */
#define ADC_CR1_RES_6BIT (0x3U << 24)
/* Control register 2 */
#define ADC_CR2_SWSTART_BIT 30
#define ADC_CR2_JSWSTART_BIT 22
#define ADC_CR2_ALIGN_BIT 11
#define ADC_CR2_EOCS_BIT 10
#define ADC_CR2_DDS_BIT 9
#define ADC_CR2_DMA_BIT 8
#define ADC_CR2_CONT_BIT 1
#define ADC_CR2_ADON_BIT 0
#define ADC_CR2_SWSTART (1U << ADC_CR2_SWSTART_BIT)
#define ADC_CR2_EXTEN (0x3 << 28)
#define ADC_CR2_EXTEN_DISABLED (0x0 << 28)
#define ADC_CR2_EXTEN_RISE (0x1 << 28)
#define ADC_CR2_EXTEN_FALL (0x2 << 28)
#define ADC_CR2_EXTEN_RISE_FALL (0x3 << 28)
#define ADC_CR2_EXTSEL (0xF << 24)
#define ADC_CR2_EXTSEL_TIM1_CC1 (0x0 << 24)
#define ADC_CR2_EXTSEL_TIM1_CC2 (0x1 << 24)
#define ADC_CR2_EXTSEL_TIM1_CC3 (0x2 << 24)
#define ADC_CR2_EXTSEL_TIM2_CC2 (0x3 << 24)
#define ADC_CR2_EXTSEL_TIM2_CC3 (0x4 << 24)
#define ADC_CR2_EXTSEL_TIM2_CC4 (0x5 << 24)
#define ADC_CR2_EXTSEL_TIM1_TRGO (0x6 << 24)
#define ADC_CR2_EXTSEL_TIM3_CC1 (0x7 << 24)
#define ADC_CR2_EXTSEL_TIM3_TRGO (0x8 << 24)
#define ADC_CR2_EXTSEL_TIM4_CC4 (0x9 << 24)
#define ADC_CR2_EXTSEL_TIM5_CC1 (0xA << 24)
#define ADC_CR2_EXTSEL_TIM5_CC2 (0xB << 24)
#define ADC_CR2_EXTSEL_TIM5_CC3 (0xC << 24)
#define ADC_CR2_EXTSEL_TIM8_CC1 (0xD << 24)
#define ADC_CR2_EXTSEL_TIM8_TRGO (0xE << 24)
#define ADC_CR2_EXTSEL_TIM1_EXTI11 (0xF << 24)
#define ADC_CR2_JSWSTART (1U << ADC_CR2_JSWSTART_BIT)
#define ADC_CR2_JEXTEN (0x3 << 20)
#define ADC_CR2_JEXTEN_DISABLED (0x0 << 20)
#define ADC_CR2_JEXTEN_RISE (0x1 << 20)
#define ADC_CR2_JEXTEN_FALL (0x2 << 20)
#define ADC_CR2_JEXTEN_RISE_FALL (0x3 << 20)
#define ADC_CR2_JEXTSEL (0xF << 16)
#define ADC_CR2_JEXTSEL_TIM1_CC4 (0x0 << 16)
#define ADC_CR2_JEXTSEL_TIM1_TRGO (0x1 << 16)
#define ADC_CR2_JEXTSEL_TIM2_CC1 (0x2 << 16)
#define ADC_CR2_JEXTSEL_TIM2_TRGO (0x3 << 16)
#define ADC_CR2_JEXTSEL_TIM3_CC2 (0x4 << 16)
#define ADC_CR2_JEXTSEL_TIM3_CC4 (0x5 << 16)
#define ADC_CR2_JEXTSEL_TIM4_CC1 (0x6 << 16)
#define ADC_CR2_JEXTSEL_TIM4_CC2 (0x7 << 16)
#define ADC_CR2_JEXTSEL_TIM4_CC3 (0x8 << 16)
#define ADC_CR2_JEXTSEL_TIM4_TRGO (0x9 << 16)
#define ADC_CR2_JEXTSEL_TIM5_CC4 (0xA << 16)
#define ADC_CR2_JEXTSEL_TIM5_TRGO (0xB << 16)
#define ADC_CR2_JEXTSEL_TIM8_CC2 (0xC << 16)
#define ADC_CR2_JEXTSEL_TIM8_CC3 (0xD << 16)
#define ADC_CR2_JEXTSEL_TIM8_CC4 (0xE << 16)
#define ADC_CR2_JEXTSEL_TIM1_EXTI15 (0xF << 16)
#define ADC_CR2_ALIGN (1U << ADC_CR2_ALIGN_BIT)
#define ADC_CR2_ALIGN_RIGHT (0U << ADC_CR2_ALIGN_BIT)
#define ADC_CR2_ALIGN_LEFT (1U << ADC_CR2_ALIGN_BIT)
#define ADC_CR2_EOCS (1U << ADC_CR2_EOCS_BIT)
#define ADC_CR2_EOCS_SEQUENCE (0U << ADC_CR2_EOCS_BIT)
#define ADC_CR2_EOCS_CONVERSION (1U << ADC_CR2_EOCS_BIT)
#define ADC_CR2_DDS (1U << ADC_CR2_DDS_BIT)
#define ADC_CR2_DMA (1U << ADC_CR2_DMA_BIT)
#define ADC_CR2_CONT (1U << ADC_CR2_CONT_BIT)
#define ADC_CR2_ADON (1U << ADC_CR2_ADON_BIT)
/* Common status register */
#define ADC_CSR_OVR3_BIT 21
#define ADC_CSR_STRT3_BIT 20
#define ADC_CSR_JSTRT3_BIT 19
#define ADC_CSR_JEOC3_BIT 18
#define ADC_CSR_EOC3_BIT 17
#define ADC_CSR_AWD3_BIT 16
#define ADC_CSR_OVR2_BIT 13
#define ADC_CSR_STRT2_BIT 12
#define ADC_CSR_JSTRT2_BIT 11
#define ADC_CSR_JEOC2_BIT 10
#define ADC_CSR_EOC2_BIT 9
#define ADC_CSR_AWD2_BIT 8
#define ADC_CSR_OVR1_BIT 5
#define ADC_CSR_STRT1_BIT 4
#define ADC_CSR_JSTRT1_BIT 3
#define ADC_CSR_JEOC1_BIT 2
#define ADC_CSR_EOC1_BIT 1
#define ADC_CSR_AWD1_BIT 0
#define ADC_CSR_OVR3 (1U << ADC_CSR_OVR3_BIT)
#define ADC_CSR_STRT3 (1U << ADC_CSR_STRT3_BIT)
#define ADC_CSR_JSTRT3 (1U << ADC_CSR_JSTRT3_BIT)
#define ADC_CSR_JEOC3 (1U << ADC_CSR_JEOC3_BIT)
#define ADC_CSR_EOC3 (1U << ADC_CSR_EOC3_BIT)
#define ADC_CSR_AWD3 (1U << ADC_CSR_AWD3_BIT)
#define ADC_CSR_OVR2 (1U << ADC_CSR_OVR2_BIT)
#define ADC_CSR_STRT2 (1U << ADC_CSR_STRT2_BIT)
#define ADC_CSR_JSTRT2 (1U << ADC_CSR_JSTRT2_BIT)
#define ADC_CSR_JEOC2 (1U << ADC_CSR_JEOC2_BIT)
#define ADC_CSR_EOC2 (1U << ADC_CSR_EOC2_BIT)
#define ADC_CSR_AWD2 (1U << ADC_CSR_AWD2_BIT)
#define ADC_CSR_OVR1 (1U << ADC_CSR_OVR1_BIT)
#define ADC_CSR_STRT1 (1U << ADC_CSR_STRT1_BIT)
#define ADC_CSR_JSTRT1 (1U << ADC_CSR_JSTRT1_BIT)
#define ADC_CSR_JEOC1 (1U << ADC_CSR_JEOC1_BIT)
#define ADC_CSR_EOC1 (1U << ADC_CSR_EOC1_BIT)
#define ADC_CSR_AWD1 (1U << ADC_CSR_AWD1_BIT)
/* Common control register */
#define ADC_CCR_TSVREFE_BIT 23
#define ADC_CCR_VBATE_BIT 22
#define ADC_CCR_DDS_BIT 13
#define ADC_CCR_TSVREFE (1U << ADC_CCR_TSVREFE_BIT)
#define ADC_CCR_VBATE (1U << ADC_CCR_VBATE_BIT)
#define ADC_CCR_ADCPRE (0x3 << 16)
#define ADC_CCR_ADCPRE_PCLK2_DIV_2 (0x0 << 16)
#define ADC_CCR_ADCPRE_PCLK2_DIV_4 (0x1 << 16)
#define ADC_CCR_ADCPRE_PCLK2_DIV_6 (0x2 << 16)
#define ADC_CCR_ADCPRE_PCLK2_DIV_8 (0x3 << 16)
#define ADC_CCR_DMA (0x3 << 14)
#define ADC_CCR_DMA_DIS (0x0 << 14)
#define ADC_CCR_DMA_MODE_1 (0x1 << 14)
#define ADC_CCR_DMA_MODE_2 (0x2 << 14)
#define ADC_CCR_DMA_MODE_3 (0x3 << 14)
#define ADC_CCR_DDS (1U << ADC_CCR_DDS_BIT)
#define ADC_CCR_DELAY (0xF << 8)
#define ADC_CCR_DELAY_5 (0x0 << 8)
#define ADC_CCR_DELAY_6 (0x1 << 8)
#define ADC_CCR_DELAY_7 (0x2 << 8)
#define ADC_CCR_DELAY_8 (0x3 << 8)
#define ADC_CCR_DELAY_9 (0x4 << 8)
#define ADC_CCR_DELAY_10 (0x5 << 8)
#define ADC_CCR_DELAY_11 (0x6 << 8)
#define ADC_CCR_DELAY_12 (0x7 << 8)
#define ADC_CCR_DELAY_13 (0x8 << 8)
#define ADC_CCR_DELAY_14 (0x9 << 8)
#define ADC_CCR_DELAY_15 (0xA << 8)
#define ADC_CCR_DELAY_16 (0xB << 8)
#define ADC_CCR_DELAY_17 (0xC << 8)
#define ADC_CCR_DELAY_18 (0xD << 8)
#define ADC_CCR_DELAY_19 (0xE << 8)
#define ADC_CCR_DELAY_20 (0xF << 8)
/** Multi ADC mode selection. */
#define ADC_CCR_MULTI 0x1F
/** All ADCs independent. */
#define ADC_CCR_MULTI_INDEPENDENT 0x0
/** Dual mode: combined regular simultaneous/injected simultaneous. */
#define ADC_CCR_MULTI_DUAL_REG_SIM_INJ_SIM 0x1
/** Dual mode: combined regular simultaneous/alternate trigger. */
#define ADC_CCR_MULTI_DUAL_REG_SIM_ALT_TRIG 0x2
/** Dual mode: injected simultaneous mode only. */
#define ADC_CCR_MULTI_DUAL_INJ_SIM 0x5
/** Dual mode: regular simultaneous mode only. */
#define ADC_CCR_MULTI_DUAL_REG_SIM 0x6
/** Dual mode: interleaved mode only. */
#define ADC_CCR_MULTI_DUAL_INTER 0x7
/** Dual mode: alternate trigger mode only. */
#define ADC_CCR_MULTI_DUAL_ALT_TRIG 0x9
/** Triple mode: combined regular simultaneous/injected simultaneous. */
#define ADC_CCR_MULTI_TRIPLE_REG_SIM_INJ_SIM 0x10
/** Triple mode: combined regular simultaneous/alternate trigger. */
#define ADC_CCR_MULTI_TRIPLE_REG_SIM_ALT_TRIG 0x11
/** Triple mode: injected simultaneous mode only. */
#define ADC_CCR_MULTI_TRIPLE_INJ_SIM 0x12
/** Triple mode: regular simultaneous mode only. */
#define ADC_CCR_MULTI_TRIPLE_REG_SIM 0x15
/** Triple mode: interleaved mode only. */
#define ADC_CCR_MULTI_TRIPLE_INTER 0x17
/** Triple mode: alternate trigger mode only. */
#define ADC_CCR_MULTI_TRIPLE_ALT_TRIG 0x19
/* Common regular data register for dual and triple modes */
#define ADC_CDR_DATA2 0xFFFF0000
#define ADC_CDR_DATA1 0xFFFF
/*
* Other types
*/
/**
* @brief STM32F2 external event selectors for regular group
* conversion.
* @see adc_set_extsel()
*/
typedef enum adc_extsel_event {
ADC_EXT_EV_TIM1_CC1 = ADC_CR2_EXTSEL_TIM1_CC1,
ADC_EXT_EV_TIM1_CC2 = ADC_CR2_EXTSEL_TIM1_CC2,
ADC_EXT_EV_TIM1_CC3 = ADC_CR2_EXTSEL_TIM1_CC3,
ADC_EXT_EV_TIM2_CC2 = ADC_CR2_EXTSEL_TIM2_CC2,
ADC_EXT_EV_TIM2_CC3 = ADC_CR2_EXTSEL_TIM2_CC3,
ADC_EXT_EV_TIM2_CC4 = ADC_CR2_EXTSEL_TIM2_CC4,
ADC_EXT_EV_TIM1_TRGO = ADC_CR2_EXTSEL_TIM1_TRGO,
ADC_EXT_EV_TIM3_CC1 = ADC_CR2_EXTSEL_TIM3_CC1,
ADC_EXT_EV_TIM3_TRGO = ADC_CR2_EXTSEL_TIM3_TRGO,
ADC_EXT_EV_TIM4_CC4 = ADC_CR2_EXTSEL_TIM4_CC4,
ADC_EXT_EV_TIM5_CC1 = ADC_CR2_EXTSEL_TIM5_CC1,
ADC_EXT_EV_TIM5_CC2 = ADC_CR2_EXTSEL_TIM5_CC2,
ADC_EXT_EV_TIM5_CC3 = ADC_CR2_EXTSEL_TIM5_CC3,
ADC_EXT_EV_TIM8_CC1 = ADC_CR2_EXTSEL_TIM8_CC1,
ADC_EXT_EV_TIM8_TRGO = ADC_CR2_EXTSEL_TIM8_TRGO,
ADC_EXT_EV_TIM1_EXTI11 = ADC_CR2_EXTSEL_TIM1_EXTI11,
} adc_extsel_event;
/**
* @brief STM32F2 sample times, in ADC clock cycles.
*/
typedef enum adc_smp_rate {
ADC_SMPR_3, /**< 3 ADC cycles */
ADC_SMPR_15, /**< 15 ADC cycles */
ADC_SMPR_28, /**< 28 ADC cycles */
ADC_SMPR_56, /**< 56 ADC cycles */
ADC_SMPR_84, /**< 84 ADC cycles */
ADC_SMPR_112, /**< 112 ADC cycles */
ADC_SMPR_144, /**< 144 ADC cycles */
ADC_SMPR_480, /**< 480 ADC cycles */
} adc_smp_rate;
/**
* @brief STM32F2 ADC prescalers, as divisors of PCLK2.
*/
typedef enum adc_prescaler {
/** PCLK2 divided by 2 */
ADC_PRE_PCLK2_DIV_2 = ADC_CCR_ADCPRE_PCLK2_DIV_2,
/** PCLK2 divided by 4 */
ADC_PRE_PCLK2_DIV_4 = ADC_CCR_ADCPRE_PCLK2_DIV_4,
/** PCLK2 divided by 6 */
ADC_PRE_PCLK2_DIV_6 = ADC_CCR_ADCPRE_PCLK2_DIV_6,
/** PCLK2 divided by 8 */
ADC_PRE_PCLK2_DIV_8 = ADC_CCR_ADCPRE_PCLK2_DIV_8,
} adc_prescaler;
#endif

View File

@@ -0,0 +1,94 @@
/******************************************************************************
* 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/dac.h
* @brief STM32F2 DAC support
*/
#ifndef _LIBMAPLE_STM32F2_DAC_H_
#define _LIBMAPLE_STM32F2_DAC_H_
#ifdef __cplusplus
extern "C"{
#endif
#include <libmaple/libmaple_types.h>
/*
* Register map type
*/
/** STM32F2 DAC register map type. */
typedef struct dac_reg_map {
__io uint32 CR; /**< Control register */
__io uint32 SWTRIGR; /**< Software trigger register */
__io uint32 DHR12R1; /**< Channel 1 12-bit right-aligned data
holding register */
__io uint32 DHR12L1; /**< Channel 1 12-bit left-aligned data
holding register */
__io uint32 DHR8R1; /**< Channel 1 8-bit left-aligned data
holding register */
__io uint32 DHR12R2; /**< Channel 2 12-bit right-aligned data
holding register */
__io uint32 DHR12L2; /**< Channel 2 12-bit left-aligned data
holding register */
__io uint32 DHR8R2; /**< Channel 2 8-bit left-aligned data
holding register */
__io uint32 DHR12RD; /**< Dual DAC 12-bit right-aligned data
holding register */
__io uint32 DHR12LD; /**< Dual DAC 12-bit left-aligned data
holding register */
__io uint32 DHR8RD; /**< Dual DAC 8-bit right-aligned data holding
register */
__io uint32 DOR1; /**< Channel 1 data output register */
__io uint32 DOR2; /**< Channel 2 data output register */
__io uint32 SR; /**< Status register */
} dac_reg_map;
/*
* Register bit definitions
*/
/* Control register */
#define DAC_CR_DMAUDRIE1 (1U << 13) /* Channel 1 DMA underrun
* interrupt enable */
#define DAC_CR_DMAUDRIE2 (1U << 29) /* Channel 2 DMA underrun
* interrupt enable */
/* Status register */
#define DAC_SR_DMAUDR1 (1U << 13) /* Channel 1 DMA underrun
* occurred */
#define DAC_SR_DMAUDR2 (1U << 29) /* Channel 2 DMA underrun
* ocurred */
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -0,0 +1,810 @@
/******************************************************************************
* 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/dma.h
* @author Marti Bolivar <mbolivar@leaflabs.com>
* @brief STM32F2 DMA series header
*/
#ifndef _LIBMAPLE_STM32F2_DMA_H_
#define _LIBMAPLE_STM32F2_DMA_H_
#ifdef __cplusplus
extern "C"{
#endif
#include <libmaple/dma_common.h>
#include <libmaple/libmaple_types.h>
/*
* Register map and base pointers
*/
/**
* @brief STM32F2 DMA register map type.
*/
typedef struct dma_reg_map {
/* Isn't it nice how on F1, it's CCR1, but on F2, it's S1CR? */
/* Global DMA registers */
__io uint32 LISR; /**< Low interrupt status register */
__io uint32 HISR; /**< High interrupt status register */
__io uint32 LIFCR; /**< Low interrupt flag clear register */
__io uint32 HIFCR; /**< High interrupt flag clear register */
/* Stream 0 registers */
__io uint32 S0CR; /**< Stream 0 control register */
__io uint32 S0NDTR; /**< Stream 0 number of data register */
__io uint32 S0PAR; /**< Stream 0 peripheral address register */
__io uint32 S0M0AR; /**< Stream 0 memory 0 address register */
__io uint32 S0M1AR; /**< Stream 0 memory 1 address register */
__io uint32 S0FCR; /**< Stream 0 FIFO control register */
/* Stream 1 registers */
__io uint32 S1CR; /**< Stream 1 control register */
__io uint32 S1NDTR; /**< Stream 1 number of data register */
__io uint32 S1PAR; /**< Stream 1 peripheral address register */
__io uint32 S1M0AR; /**< Stream 1 memory 0 address register */
__io uint32 S1M1AR; /**< Stream 1 memory 1 address register */
__io uint32 S1FCR; /**< Stream 1 FIFO control register */
/* Stream 2 registers */
__io uint32 S2CR; /**< Stream 2 control register */
__io uint32 S2NDTR; /**< Stream 2 number of data register */
__io uint32 S2PAR; /**< Stream 2 peripheral address register */
__io uint32 S2M0AR; /**< Stream 2 memory 0 address register */
__io uint32 S2M1AR; /**< Stream 2 memory 1 address register */
__io uint32 S2FCR; /**< Stream 2 FIFO control register */
/* Stream 3 registers */
__io uint32 S3CR; /**< Stream 3 control register */
__io uint32 S3NDTR; /**< Stream 3 number of data register */
__io uint32 S3PAR; /**< Stream 3 peripheral address register */
__io uint32 S3M0AR; /**< Stream 3 memory 0 address register */
__io uint32 S3M1AR; /**< Stream 3 memory 1 address register */
__io uint32 S3FCR; /**< Stream 3 FIFO control register */
/* Stream 4 registers */
__io uint32 S4CR; /**< Stream 4 control register */
__io uint32 S4NDTR; /**< Stream 4 number of data register */
__io uint32 S4PAR; /**< Stream 4 peripheral address register */
__io uint32 S4M0AR; /**< Stream 4 memory 0 address register */
__io uint32 S4M1AR; /**< Stream 4 memory 1 address register */
__io uint32 S4FCR; /**< Stream 4 FIFO control register */
/* Stream 5 registers */
__io uint32 S5CR; /**< Stream 5 control register */
__io uint32 S5NDTR; /**< Stream 5 number of data register */
__io uint32 S5PAR; /**< Stream 5 peripheral address register */
__io uint32 S5M0AR; /**< Stream 5 memory 0 address register */
__io uint32 S5M1AR; /**< Stream 5 memory 1 address register */
__io uint32 S5FCR; /**< Stream 5 FIFO control register */
/* Stream 6 registers */
__io uint32 S6CR; /**< Stream 6 control register */
__io uint32 S6NDTR; /**< Stream 6 number of data register */
__io uint32 S6PAR; /**< Stream 6 peripheral address register */
__io uint32 S6M0AR; /**< Stream 6 memory 0 address register */
__io uint32 S6M1AR; /**< Stream 6 memory 1 address register */
__io uint32 S6FCR; /**< Stream 6 FIFO control register */
/* Stream 7 registers */
__io uint32 S7CR; /**< Stream 7 control register */
__io uint32 S7NDTR; /**< Stream 7 number of data register */
__io uint32 S7PAR; /**< Stream 7 peripheral address register */
__io uint32 S7M0AR; /**< Stream 7 memory 0 address register */
__io uint32 S7M1AR; /**< Stream 7 memory 1 address register */
__io uint32 S7FCR; /**< Stream 7 FIFO control register */
} dma_reg_map;
/** DMA controller 1 register map base pointer */
#define DMA1_BASE ((struct dma_reg_map*)0x40026000)
/** DMA controller 2 register map base pointer */
#define DMA2_BASE ((struct dma_reg_map*)0x40026400)
/**
* @brief STM32F2 DMA stream (i.e. tube) register map type.
* Provides access to an individual stream's registers.
* @see dma_tube_regs()
*/
typedef struct dma_tube_reg_map {
__io uint32 SCR; /**< Stream configuration register */
__io uint32 SNDTR; /**< Stream number of data register */
__io uint32 SPAR; /**< Stream peripheral address register */
__io uint32 SM0AR; /**< Stream memory 0 address register */
__io uint32 SM1AR; /**< Stream memory 1 address register */
__io uint32 SFCR; /**< Stream FIFO control register */
} dma_tube_reg_map;
/** DMA1 stream 0 register map base pointer */
#define DMA1S0_BASE ((struct dma_tube_reg_map*)0x40026010)
/** DMA1 stream 1 register map base pointer */
#define DMA1S1_BASE ((struct dma_tube_reg_map*)0x40026028)
/** DMA1 stream 2 register map base pointer */
#define DMA1S2_BASE ((struct dma_tube_reg_map*)0x40026040)
/** DMA1 stream 3 register map base pointer */
#define DMA1S3_BASE ((struct dma_tube_reg_map*)0x40026058)
/** DMA1 stream 4 register map base pointer */
#define DMA1S4_BASE ((struct dma_tube_reg_map*)0x40026070)
/** DMA1 stream 5 register map base pointer */
#define DMA1S5_BASE ((struct dma_tube_reg_map*)0x40026088)
/** DMA1 stream 6 register map base pointer */
#define DMA1S6_BASE ((struct dma_tube_reg_map*)0x400260A0)
/** DMA1 stream 7 register map base pointer */
#define DMA1S7_BASE ((struct dma_tube_reg_map*)0x400260B8)
/** DMA2 stream 0 register map base pointer */
#define DMA2S0_BASE ((struct dma_tube_reg_map*)0x40026410)
/** DMA2 stream 1 register map base pointer */
#define DMA2S1_BASE ((struct dma_tube_reg_map*)0x40026028)
/** DMA2 stream 2 register map base pointer */
#define DMA2S2_BASE ((struct dma_tube_reg_map*)0x40026040)
/** DMA2 stream 3 register map base pointer */
#define DMA2S3_BASE ((struct dma_tube_reg_map*)0x40026058)
/** DMA2 stream 4 register map base pointer */
#define DMA2S4_BASE ((struct dma_tube_reg_map*)0x40026070)
/** DMA2 stream 5 register map base pointer */
#define DMA2S5_BASE ((struct dma_tube_reg_map*)0x40026088)
/** DMA2 stream 6 register map base pointer */
#define DMA2S6_BASE ((struct dma_tube_reg_map*)0x400260A0)
/** DMA2 stream 7 register map base pointer */
#define DMA2S7_BASE ((struct dma_tube_reg_map*)0x400260B8)
/*
* Register bit definitions
*/
/* Low interrupt status register */
#define DMA_LISR_TCIF3_BIT 27
#define DMA_LISR_HTIF3_BIT 26
#define DMA_LISR_TEIF3_BIT 25
#define DMA_LISR_DMEIF3_BIT 24
#define DMA_LISR_FEIF3_BIT 22
#define DMA_LISR_TCIF2_BIT 21
#define DMA_LISR_HTIF2_BIT 20
#define DMA_LISR_TEIF2_BIT 19
#define DMA_LISR_DMEIF2_BIT 18
#define DMA_LISR_FEIF2_BIT 16
#define DMA_LISR_TCIF1_BIT 11
#define DMA_LISR_HTIF1_BIT 10
#define DMA_LISR_TEIF1_BIT 9
#define DMA_LISR_DMEIF1_BIT 8
#define DMA_LISR_FEIF1_BIT 6
#define DMA_LISR_TCIF0_BIT 5
#define DMA_LISR_HTIF0_BIT 4
#define DMA_LISR_TEIF0_BIT 3
#define DMA_LISR_DMEIF0_BIT 2
#define DMA_LISR_FEIF0_BIT 0
#define DMA_LISR_TCIF3 (1U << DMA_LISR_TCIF3_BIT)
#define DMA_LISR_HTIF3 (1U << DMA_LISR_HTIF3_BIT)
#define DMA_LISR_TEIF3 (1U << DMA_LISR_TEIF3_BIT)
#define DMA_LISR_DMEIF3 (1U << DMA_LISR_DMEIF3_BIT)
#define DMA_LISR_FEIF3 (1U << DMA_LISR_FEIF3_BIT)
#define DMA_LISR_TCIF2 (1U << DMA_LISR_TCIF2_BIT)
#define DMA_LISR_HTIF2 (1U << DMA_LISR_HTIF2_BIT)
#define DMA_LISR_TEIF2 (1U << DMA_LISR_TEIF2_BIT)
#define DMA_LISR_DMEIF2 (1U << DMA_LISR_DMEIF2_BIT)
#define DMA_LISR_FEIF2 (1U << DMA_LISR_FEIF2_BIT)
#define DMA_LISR_TCIF1 (1U << DMA_LISR_TCIF1_BIT)
#define DMA_LISR_HTIF1 (1U << DMA_LISR_HTIF1_BIT)
#define DMA_LISR_TEIF1 (1U << DMA_LISR_TEIF1_BIT)
#define DMA_LISR_DMEIF1 (1U << DMA_LISR_DMEIF1_BIT)
#define DMA_LISR_FEIF1 (1U << DMA_LISR_FEIF1_BIT)
#define DMA_LISR_TCIF0 (1U << DMA_LISR_TCIF0_BIT)
#define DMA_LISR_HTIF0 (1U << DMA_LISR_HTIF0_BIT)
#define DMA_LISR_TEIF0 (1U << DMA_LISR_TEIF0_BIT)
#define DMA_LISR_DMEIF0 (1U << DMA_LISR_DMEIF0_BIT)
#define DMA_LISR_FEIF0 (1U << DMA_LISR_FEIF0_BIT)
/* High interrupt status register */
#define DMA_HISR_TCIF7_BIT 27
#define DMA_HISR_HTIF7_BIT 26
#define DMA_HISR_TEIF7_BIT 25
#define DMA_HISR_DMEIF7_BIT 24
#define DMA_HISR_FEIF7_BIT 22
#define DMA_HISR_TCIF6_BIT 21
#define DMA_HISR_HTIF6_BIT 20
#define DMA_HISR_TEIF6_BIT 19
#define DMA_HISR_DMEIF6_BIT 18
#define DMA_HISR_FEIF6_BIT 16
#define DMA_HISR_TCIF5_BIT 11
#define DMA_HISR_HTIF5_BIT 10
#define DMA_HISR_TEIF5_BIT 9
#define DMA_HISR_DMEIF5_BIT 8
#define DMA_HISR_FEIF5_BIT 6
#define DMA_HISR_TCIF4_BIT 5
#define DMA_HISR_HTIF4_BIT 4
#define DMA_HISR_TEIF4_BIT 3
#define DMA_HISR_DMEIF4_BIT 2
#define DMA_HISR_FEIF4_BIT 0
#define DMA_HISR_TCIF7 (1U << DMA_HISR_TCIF7_BIT)
#define DMA_HISR_HTIF7 (1U << DMA_HISR_HTIF7_BIT)
#define DMA_HISR_TEIF7 (1U << DMA_HISR_TEIF7_BIT)
#define DMA_HISR_DMEIF7 (1U << DMA_HISR_DMEIF7_BIT)
#define DMA_HISR_FEIF7 (1U << DMA_HISR_FEIF7_BIT)
#define DMA_HISR_TCIF6 (1U << DMA_HISR_TCIF6_BIT)
#define DMA_HISR_HTIF6 (1U << DMA_HISR_HTIF6_BIT)
#define DMA_HISR_TEIF6 (1U << DMA_HISR_TEIF6_BIT)
#define DMA_HISR_DMEIF6 (1U << DMA_HISR_DMEIF6_BIT)
#define DMA_HISR_FEIF6 (1U << DMA_HISR_FEIF6_BIT)
#define DMA_HISR_TCIF5 (1U << DMA_HISR_TCIF5_BIT)
#define DMA_HISR_HTIF5 (1U << DMA_HISR_HTIF5_BIT)
#define DMA_HISR_TEIF5 (1U << DMA_HISR_TEIF5_BIT)
#define DMA_HISR_DMEIF5 (1U << DMA_HISR_DMEIF5_BIT)
#define DMA_HISR_FEIF5 (1U << DMA_HISR_FEIF5_BIT)
#define DMA_HISR_TCIF4 (1U << DMA_HISR_TCIF4_BIT)
#define DMA_HISR_HTIF4 (1U << DMA_HISR_HTIF4_BIT)
#define DMA_HISR_TEIF4 (1U << DMA_HISR_TEIF4_BIT)
#define DMA_HISR_DMEIF4 (1U << DMA_HISR_DMEIF4_BIT)
#define DMA_HISR_FEIF4 (1U << DMA_HISR_FEIF4_BIT)
/* Low interrupt flag clear register */
#define DMA_LIFCR_CTCIF3_BIT 27
#define DMA_LIFCR_CHTIF3_BIT 26
#define DMA_LIFCR_CTEIF3_BIT 25
#define DMA_LIFCR_CDMEIF3_BIT 24
#define DMA_LIFCR_CFEIF3_BIT 22
#define DMA_LIFCR_CTCIF2_BIT 21
#define DMA_LIFCR_CHTIF2_BIT 20
#define DMA_LIFCR_CTEIF2_BIT 19
#define DMA_LIFCR_CDMEIF2_BIT 18
#define DMA_LIFCR_CFEIF2_BIT 16
#define DMA_LIFCR_CTCIF1_BIT 11
#define DMA_LIFCR_CHTIF1_BIT 10
#define DMA_LIFCR_CTEIF1_BIT 9
#define DMA_LIFCR_CDMEIF1_BIT 8
#define DMA_LIFCR_CFEIF1_BIT 6
#define DMA_LIFCR_CTCIF0_BIT 5
#define DMA_LIFCR_CHTIF0_BIT 4
#define DMA_LIFCR_CTEIF0_BIT 3
#define DMA_LIFCR_CDMEIF0_BIT 2
#define DMA_LIFCR_CFEIF0_BIT 0
#define DMA_LIFCR_CTCIF3 (1U << DMA_LIFCR_CTCIF3_BIT)
#define DMA_LIFCR_CHTIF3 (1U << DMA_LIFCR_CHTIF3_BIT)
#define DMA_LIFCR_CTEIF3 (1U << DMA_LIFCR_CTEIF3_BIT)
#define DMA_LIFCR_CDMEIF3 (1U << DMA_LIFCR_CDMEIF3_BIT)
#define DMA_LIFCR_CFEIF3 (1U << DMA_LIFCR_CFEIF3_BIT)
#define DMA_LIFCR_CTCIF2 (1U << DMA_LIFCR_CTCIF2_BIT)
#define DMA_LIFCR_CHTIF2 (1U << DMA_LIFCR_CHTIF2_BIT)
#define DMA_LIFCR_CTEIF2 (1U << DMA_LIFCR_CTEIF2_BIT)
#define DMA_LIFCR_CDMEIF2 (1U << DMA_LIFCR_CDMEIF2_BIT)
#define DMA_LIFCR_CFEIF2 (1U << DMA_LIFCR_CFEIF2_BIT)
#define DMA_LIFCR_CTCIF1 (1U << DMA_LIFCR_CTCIF1_BIT)
#define DMA_LIFCR_CHTIF1 (1U << DMA_LIFCR_CHTIF1_BIT)
#define DMA_LIFCR_CTEIF1 (1U << DMA_LIFCR_CTEIF1_BIT)
#define DMA_LIFCR_CDMEIF1 (1U << DMA_LIFCR_CDMEIF1_BIT)
#define DMA_LIFCR_CFEIF1 (1U << DMA_LIFCR_CFEIF1_BIT)
#define DMA_LIFCR_CTCIF0 (1U << DMA_LIFCR_CTCIF0_BIT)
#define DMA_LIFCR_CHTIF0 (1U << DMA_LIFCR_CHTIF0_BIT)
#define DMA_LIFCR_CTEIF0 (1U << DMA_LIFCR_CTEIF0_BIT)
#define DMA_LIFCR_CDMEIF0 (1U << DMA_LIFCR_CDMEIF0_BIT)
#define DMA_LIFCR_CFEIF0 (1U << DMA_LIFCR_CFEIF0_BIT)
/* High interrupt flag clear regsister */
#define DMA_HIFCR_CTCIF7_BIT 27
#define DMA_HIFCR_CHTIF7_BIT 26
#define DMA_HIFCR_CTEIF7_BIT 25
#define DMA_HIFCR_CDMEIF7_BIT 24
#define DMA_HIFCR_CFEIF7_BIT 22
#define DMA_HIFCR_CTCIF6_BIT 21
#define DMA_HIFCR_CHTIF6_BIT 20
#define DMA_HIFCR_CTEIF6_BIT 19
#define DMA_HIFCR_CDMEIF6_BIT 18
#define DMA_HIFCR_CFEIF6_BIT 16
#define DMA_HIFCR_CTCIF5_BIT 11
#define DMA_HIFCR_CHTIF5_BIT 10
#define DMA_HIFCR_CTEIF5_BIT 9
#define DMA_HIFCR_CDMEIF5_BIT 8
#define DMA_HIFCR_CFEIF5_BIT 6
#define DMA_HIFCR_CTCIF4_BIT 5
#define DMA_HIFCR_CHTIF4_BIT 4
#define DMA_HIFCR_CTEIF4_BIT 3
#define DMA_HIFCR_CDMEIF4_BIT 2
#define DMA_HIFCR_CFEIF4_BIT 0
#define DMA_HIFCR_CTCIF7 (1U << DMA_HIFCR_CTCIF7_BIT)
#define DMA_HIFCR_CHTIF7 (1U << DMA_HIFCR_CHTIF7_BIT)
#define DMA_HIFCR_CTEIF7 (1U << DMA_HIFCR_CTEIF7_BIT)
#define DMA_HIFCR_CDMEIF7 (1U << DMA_HIFCR_CDMEIF7_BIT)
#define DMA_HIFCR_CFEIF7 (1U << DMA_HIFCR_CFEIF7_BIT)
#define DMA_HIFCR_CTCIF6 (1U << DMA_HIFCR_CTCIF6_BIT)
#define DMA_HIFCR_CHTIF6 (1U << DMA_HIFCR_CHTIF6_BIT)
#define DMA_HIFCR_CTEIF6 (1U << DMA_HIFCR_CTEIF6_BIT)
#define DMA_HIFCR_CDMEIF6 (1U << DMA_HIFCR_CDMEIF6_BIT)
#define DMA_HIFCR_CFEIF6 (1U << DMA_HIFCR_CFEIF6_BIT)
#define DMA_HIFCR_CTCIF5 (1U << DMA_HIFCR_CTCIF5_BIT)
#define DMA_HIFCR_CHTIF5 (1U << DMA_HIFCR_CHTIF5_BIT)
#define DMA_HIFCR_CTEIF5 (1U << DMA_HIFCR_CTEIF5_BIT)
#define DMA_HIFCR_CDMEIF5 (1U << DMA_HIFCR_CDMEIF5_BIT)
#define DMA_HIFCR_CFEIF5 (1U << DMA_HIFCR_CFEIF5_BIT)
#define DMA_HIFCR_CTCIF4 (1U << DMA_HIFCR_CTCIF4_BIT)
#define DMA_HIFCR_CHTIF4 (1U << DMA_HIFCR_CHTIF4_BIT)
#define DMA_HIFCR_CTEIF4 (1U << DMA_HIFCR_CTEIF4_BIT)
#define DMA_HIFCR_CDMEIF4 (1U << DMA_HIFCR_CDMEIF4_BIT)
#define DMA_HIFCR_CFEIF4 (1U << DMA_HIFCR_CFEIF4_BIT)
/* Stream configuration register */
#define DMA_SCR_CT_BIT 19
#define DMA_SCR_DBM_BIT 18
#define DMA_SCR_PINCOS_BIT 15
#define DMA_SCR_MINC_BIT 10
#define DMA_SCR_PINC_BIT 9
#define DMA_SCR_CIRC_BIT 8
#define DMA_SCR_PFCTRL_BIT 5
#define DMA_SCR_TCIE_BIT 4
#define DMA_SCR_HTIE_BIT 3
#define DMA_SCR_TEIE_BIT 2
#define DMA_SCR_DMEIE_BIT 1
#define DMA_SCR_EN_BIT 0
#define DMA_SCR_CHSEL (0x7 << 25)
#define DMA_SCR_CHSEL_CH_0 (0x0 << 25)
#define DMA_SCR_CHSEL_CH_1 (0x1 << 25)
#define DMA_SCR_CHSEL_CH_2 (0x2 << 25)
#define DMA_SCR_CHSEL_CH_3 (0x3 << 25)
#define DMA_SCR_CHSEL_CH_4 (0x4 << 25)
#define DMA_SCR_CHSEL_CH_5 (0x5 << 25)
#define DMA_SCR_CHSEL_CH_6 (0x6 << 25)
#define DMA_SCR_CHSEL_CH_7 (0x7 << 25)
#define DMA_SCR_MBURST (0x3 << 23)
#define DMA_SCR_MBURST_SINGLE (0x0 << 23)
#define DMA_SCR_MBURST_INCR4 (0x1 << 23)
#define DMA_SCR_MBURST_INCR8 (0x2 << 23)
#define DMA_SCR_MBURST_INCR16 (0x3 << 23)
#define DMA_SCR_PBURST (0x3 << 21)
#define DMA_SCR_PBURST_SINGLE (0x0 << 21)
#define DMA_SCR_PBURST_INCR4 (0x1 << 21)
#define DMA_SCR_PBURST_INCR8 (0x2 << 21)
#define DMA_SCR_PBURST_INCR16 (0x3 << 21)
#define DMA_SCR_CT (1U << DMA_SCR_CT_BIT)
#define DMA_SCR_DBM (1U << DMA_SCR_DBM_BIT)
#define DMA_SCR_PL (0x3 << 16)
#define DMA_SCR_PL_LOW (0x0 << 16)
#define DMA_SCR_PL_MEDIUM (0x1 << 16)
#define DMA_SCR_PL_HIGH (0x2 << 16)
#define DMA_SCR_VERY_HIGH (0x3 << 16)
#define DMA_SCR_PINCOS (1U << DMA_SCR_PINCOS_BIT)
#define DMA_SCR_MSIZE (0x3 << 13)
#define DMA_SCR_MSIZE_8BITS (0x0 << 13)
#define DMA_SCR_MSIZE_16BITS (0x1 << 13)
#define DMA_SCR_MSIZE_32BITS (0x2 << 13)
#define DMA_SCR_PSIZE (0x3 << 11)
#define DMA_SCR_PSIZE_8BITS (0x0 << 11)
#define DMA_SCR_PSIZE_16BITS (0x1 << 11)
#define DMA_SCR_PSIZE_32BITS (0x2 << 11)
#define DMA_SCR_MINC (1U << DMA_SCR_MINC_BIT)
#define DMA_SCR_PINC (1U << DMA_SCR_PINC_BIT)
#define DMA_SCR_CIRC (1U << DMA_SCR_CIRC_BIT)
#define DMA_SCR_DIR (0x3 << 6)
#define DMA_SCR_DIR_PER_TO_MEM (0x0 << 6)
#define DMA_SCR_DIR_MEM_TO_PER (0x1 << 6)
#define DMA_SCR_DIR_MEM_TO_MEM (0x2 << 6)
#define DMA_SCR_PFCTRL (1U << DMA_SCR_PFCTRL_BIT)
#define DMA_SCR_TCIE (1U << DMA_SCR_TCIE_BIT)
#define DMA_SCR_HTIE (1U << DMA_SCR_HTIE_BIT)
#define DMA_SCR_TEIE (1U << DMA_SCR_TEIE_BIT)
#define DMA_SCR_DMEIE (1U << DMA_SCR_DMEIE_BIT)
#define DMA_SCR_EN (1U << DMA_SCR_EN_BIT)
/* Stream FIFO control register */
#define DMA_SFCR_FEIE_BIT 7
#define DMA_SFCR_DMDIS_BIT 2
#define DMA_SFCR_FEIE (1U << DMA_SFCR_FEIE_BIT)
#define DMA_SFCR_FS (0x7 << 3)
#define DMA_SFCR_FS_ZERO_TO_QUARTER (0x0 << 3)
#define DMA_SFCR_FS_QUARTER_TO_HALF (0x1 << 3)
#define DMA_SFCR_FS_HALF_TO_THREE_QUARTERS (0x2 << 3)
#define DMA_SFCR_FS_THREE_QUARTERS_TO_FULL (0x3 << 3)
#define DMA_SFCR_FS_EMPTY (0x4 << 3)
#define DMA_SFCR_FS_FULL (0x5 << 3)
#define DMA_SFCR_DMDIS (1U << DMA_SFCR_DMDIS_BIT)
#define DMA_SFCR_FTH (0x3 << 0)
#define DMA_SFCR_FTH_QUARTER_FULL (0x0 << 3)
#define DMA_SFCR_FTH_HALF_FULL (0x1 << 3)
#define DMA_SFCR_FTH_THREE_QUARTERS_FULL (0x2 << 3)
#define DMA_SFCR_FTH_FULL (0x3 << 3)
/*
* Devices
*/
extern dma_dev *DMA1;
extern dma_dev *DMA2;
/*
* Other types needed by, or useful for, <libmaple/dma.h>
*/
/**
* @brief DMA streams
* This is also the dma_tube type for STM32F2.
* @see dma_tube
*/
typedef enum dma_stream {
DMA_S0 = 0,
DMA_S1 = 1,
DMA_S2 = 2,
DMA_S3 = 3,
DMA_S4 = 4,
DMA_S5 = 5,
DMA_S6 = 6,
DMA_S7 = 7,
} dma_stream;
/** STM32F2 dma_tube (=dma_stream) */
#define dma_tube dma_stream
/**
* @brief STM32F2 configuration flags for dma_tube_config.
* @see struct dma_tube_config
*/
typedef enum dma_cfg_flags {
/* NB: flags that aren't SCR bits are treated specially. */
/**
* Source address increment mode
*
* If this flag is set, the source address is incremented (by the
* source size) after each DMA transfer.
*/
DMA_CFG_SRC_INC = 1U << 31,
/**
* Destination address increment mode
*
* If this flag is set, the destination address is incremented (by
* the destination size) after each DMA transfer.
*/
DMA_CFG_DST_INC = 1U << 30,
/**
* Circular mode
*
* This mode is not available for memory-to-memory transfers.
*/
DMA_CFG_CIRC = DMA_SCR_CIRC,
/** Transfer complete interrupt enable */
DMA_CFG_CMPLT_IE = DMA_SCR_TCIE,
/** Transfer half-complete interrupt enable */
DMA_CFG_HALF_CMPLT_IE = DMA_SCR_HTIE,
/** Transfer error interrupt enable */
DMA_CFG_ERR_IE = DMA_SCR_TEIE,
/** Direct mode error interrupt enable */
DMA_CFG_DM_ERR_IE = DMA_SCR_DMEIE,
/** FIFO error interrupt enable */
DMA_CFG_FIFO_ERR_IE = (1U << 29),
} dma_cfg_flags;
/**
* @brief STM32F2 DMA request sources.
*
* IMPORTANT:
*
* 1. On STM32F2, a particular dma_request_src is always tied to a
* single DMA controller, but often can be supported by multiple
* streams. For example, DMA requests from ADC1 (DMA_REQ_SRC_ADC1) can
* only be handled by DMA2, but they can go to either stream 0 or
* stream 4 (though not any other stream). If you try to use a request
* source with the wrong DMA controller or the wrong stream on
* STM32F2, dma_tube_cfg() will fail.
*
* 2. A single stream can only handle a single request source at a
* time. If you change a stream's request source later, it will stop
* serving requests from the old source. However, for some streams,
* some sources conflict with one another (when they correspond to the
* same channel on that stream), and on STM32F2, Terrible Super-Bad
* Things will happen if two conflicting request sources are active at
* the same time.
*
* @see struct dma_tube_config
* @see dma_tube_cfg()
*/
typedef enum dma_request_src {
/* These are constructed like so (though this may change, so user
* code shouldn't depend on it):
*
* Bits 0--2: Channel associated with request source
*
* Bits 3--9: rcc_clk_id of DMA controller associated with request source
*
* Bits 10--17: Bit mask of streams which can handle that request
* source. (E.g., bit 10 set means stream 0 can
* handle the source, bit 11 set means stream 1 can,
* etc.)
*
* Among other things, this is used for error checking in
* dma_tube_cfg(). If you change this bit encoding, you need to
* update the helper functions in stm32f2/dma.c.
*/
#define _DMA_STM32F2_REQ_SRC(stream_mask, clk_id, channel) \
(((stream_mask) << 10) | ((clk_id) << 3) | (channel))
#define _DMA_S(n) (1U << (n))
/* DMA1 request sources */
#define _DMA_1_REQ_SRC(stream_mask, channel) \
_DMA_STM32F2_REQ_SRC(stream_mask, RCC_DMA1, channel)
/* Channel 0 */
DMA_REQ_SRC_SPI3_RX = _DMA_1_REQ_SRC(_DMA_S(0) | _DMA_S(2), 0),
DMA_REQ_SRC_SPI2_RX = _DMA_1_REQ_SRC(_DMA_S(3), 0),
DMA_REQ_SRC_SPI2_TX = _DMA_1_REQ_SRC(_DMA_S(4), 0),
DMA_REQ_SRC_SPI3_TX = _DMA_1_REQ_SRC(_DMA_S(5) | _DMA_S(7), 0),
/* Channel 1 */
DMA_REQ_SRC_I2C1_RX = _DMA_1_REQ_SRC(_DMA_S(0) | _DMA_S(5), 1),
DMA_REQ_SRC_TIM7_UP = _DMA_1_REQ_SRC(_DMA_S(2) | _DMA_S(4), 1),
DMA_REQ_SRC_I2C1_TX = _DMA_1_REQ_SRC(_DMA_S(6) | _DMA_S(7), 1),
/* Channel 2 */
DMA_REQ_SRC_TIM4_CH1 = _DMA_1_REQ_SRC(_DMA_S(0), 2),
DMA_REQ_SRC_TIM4_CH2 = _DMA_1_REQ_SRC(_DMA_S(3), 2),
DMA_REQ_SRC_TIM4_UP = _DMA_1_REQ_SRC(_DMA_S(6), 2),
DMA_REQ_SRC_TIM4_CH3 = _DMA_1_REQ_SRC(_DMA_S(7), 2),
/* Channel 3 */
DMA_REQ_SRC_TIM2_UP = _DMA_1_REQ_SRC(_DMA_S(1) | _DMA_S(7), 3),
DMA_REQ_SRC_TIM2_CH3 = _DMA_1_REQ_SRC(_DMA_S(1), 3),
DMA_REQ_SRC_I2C3_RX = _DMA_1_REQ_SRC(_DMA_S(2), 3),
DMA_REQ_SRC_I2C3_TX = _DMA_1_REQ_SRC(_DMA_S(4), 3),
DMA_REQ_SRC_TIM2_CH1 = _DMA_1_REQ_SRC(_DMA_S(5), 3),
DMA_REQ_SRC_TIM2_CH2 = _DMA_1_REQ_SRC(_DMA_S(6), 3),
DMA_REQ_SRC_TIM2_CH4 = _DMA_1_REQ_SRC(_DMA_S(6) | _DMA_S(7), 3),
/* Channel 4 */
DMA_REQ_SRC_UART5_RX = _DMA_1_REQ_SRC(_DMA_S(0), 4),
DMA_REQ_SRC_USART3_RX = _DMA_1_REQ_SRC(_DMA_S(1), 4),
DMA_REQ_SRC_UART4_RX = _DMA_1_REQ_SRC(_DMA_S(2), 4),
DMA_REQ_SRC_USART3_TX = _DMA_1_REQ_SRC(_DMA_S(3), 4),
DMA_REQ_SRC_UART4_TX = _DMA_1_REQ_SRC(_DMA_S(4), 4),
DMA_REQ_SRC_USART2_RX = _DMA_1_REQ_SRC(_DMA_S(5), 4),
DMA_REQ_SRC_USART2_TX = _DMA_1_REQ_SRC(_DMA_S(6), 4),
DMA_REQ_SRC_UART5_TX = _DMA_1_REQ_SRC(_DMA_S(7), 4),
/* Channel 5 */
DMA_REQ_SRC_TIM3_CH4 = _DMA_1_REQ_SRC(_DMA_S(2), 5),
DMA_REQ_SRC_TIM3_UP = _DMA_1_REQ_SRC(_DMA_S(2), 5),
DMA_REQ_SRC_TIM3_CH1 = _DMA_1_REQ_SRC(_DMA_S(4), 5),
DMA_REQ_SRC_TIM3_TRIG = _DMA_1_REQ_SRC(_DMA_S(4), 5),
DMA_REQ_SRC_TIM3_CH2 = _DMA_1_REQ_SRC(_DMA_S(5), 5),
DMA_REQ_SRC_TIM3_CH3 = _DMA_1_REQ_SRC(_DMA_S(7), 5),
/* Channel 6 */
DMA_REQ_SRC_TIM5_CH3 = _DMA_1_REQ_SRC(_DMA_S(0), 6),
DMA_REQ_SRC_TIM5_UP = _DMA_1_REQ_SRC(_DMA_S(0) | _DMA_S(6), 6),
DMA_REQ_SRC_TIM5_CH4 = _DMA_1_REQ_SRC(_DMA_S(1) | _DMA_S(3), 6),
DMA_REQ_SRC_TIM5_TRIG = _DMA_1_REQ_SRC(_DMA_S(1) | _DMA_S(3), 6),
DMA_REQ_SRC_TIM5_CH1 = _DMA_1_REQ_SRC(_DMA_S(2), 6),
DMA_REQ_SRC_TIM5_CH2 = _DMA_1_REQ_SRC(_DMA_S(4), 6),
/* Channel 7 */
DMA_REQ_SRC_TIM6_UP = _DMA_1_REQ_SRC(_DMA_S(1), 7),
DMA_REQ_SRC_I2C2_RX = _DMA_1_REQ_SRC(_DMA_S(2) | _DMA_S(3), 7),
DMA_REQ_SRC_USART3_TX_ALTERNATE = _DMA_1_REQ_SRC(_DMA_S(4), 7),
DMA_REQ_SRC_DAC1 = _DMA_1_REQ_SRC(_DMA_S(5), 7),
DMA_REQ_SRC_DAC2 = _DMA_1_REQ_SRC(_DMA_S(6), 7),
DMA_REQ_SRC_I2C2_TX = _DMA_1_REQ_SRC(_DMA_S(7), 7),
#undef _DMA_1_REQ_SRC
/* DMA2 request sources */
#define _DMA_2_REQ_SRC(stream_mask, channel) \
_DMA_STM32F2_REQ_SRC(stream_mask, RCC_DMA2, channel)
/* Channel 0 */
DMA_REQ_SRC_ADC1 = _DMA_2_REQ_SRC(_DMA_S(0) | _DMA_S(4), 0),
/* You can use these "DMA_REQ_SRC_TIMx_CHx_ALTERNATE" if you know
* what you're doing, but the other ones (for channels 6 and 7),
* are better, in that they don't conflict with one another. */
DMA_REQ_SRC_TIM8_CH1_ALTERNATE = _DMA_2_REQ_SRC(_DMA_S(2), 0),
DMA_REQ_SRC_TIM8_CH2_ALTERNATE = _DMA_2_REQ_SRC(_DMA_S(2), 0),
DMA_REQ_SRC_TIM8_CH3_ALTERNATE = _DMA_2_REQ_SRC(_DMA_S(2), 0),
DMA_REQ_SRC_TIM1_CH1_ALTERNATE = _DMA_2_REQ_SRC(_DMA_S(6), 0),
DMA_REQ_SRC_TIM1_CH2_ALTERNATE = _DMA_2_REQ_SRC(_DMA_S(6), 0),
DMA_REQ_SRC_TIM1_CH3_ALTENRATE = _DMA_2_REQ_SRC(_DMA_S(6), 0),
/* Channel 1 */
DMA_REQ_SRC_DCMI = _DMA_2_REQ_SRC(_DMA_S(1) | _DMA_S(7), 1),
DMA_REQ_SRC_ADC2 = _DMA_2_REQ_SRC(_DMA_S(2) | _DMA_S(3), 1),
/* Channel 2 */
DMA_REQ_SRC_ADC3 = _DMA_2_REQ_SRC(_DMA_S(0) | _DMA_S(1), 2),
DMA_REQ_SRC_CRYP_OUT = _DMA_2_REQ_SRC(_DMA_S(5), 2),
DMA_REQ_SRC_CRYP_IN = _DMA_2_REQ_SRC(_DMA_S(6), 2),
DMA_REQ_SRC_HASH_IN = _DMA_2_REQ_SRC(_DMA_S(7), 2),
/* Channel 3 */
DMA_REQ_SRC_SPI1_RX = _DMA_2_REQ_SRC(_DMA_S(0) | _DMA_S(2), 3),
DMA_REQ_SRC_SPI1_TX = _DMA_2_REQ_SRC(_DMA_S(3) | _DMA_S(5), 3),
/* Channel 4 */
DMA_REQ_SRC_USART1_RX = _DMA_2_REQ_SRC(_DMA_S(2) | _DMA_S(5), 4),
DMA_REQ_SRC_SDIO = _DMA_2_REQ_SRC(_DMA_S(3) | _DMA_S(6), 4),
DMA_REQ_SRC_USART1_TX = _DMA_2_REQ_SRC(_DMA_S(7), 4),
/* Channel 5 */
DMA_REQ_SRC_USART6_RX = _DMA_2_REQ_SRC(_DMA_S(1) | _DMA_S(2), 5),
DMA_REQ_SRC_USART6_TX = _DMA_2_REQ_SRC(_DMA_S(6) | _DMA_S(7), 5),
/* Channel 6 */
DMA_REQ_SRC_TIM1_TRIG = _DMA_2_REQ_SRC(_DMA_S(0) | _DMA_S(4), 6),
DMA_REQ_SRC_TIM1_CH1 = _DMA_2_REQ_SRC(_DMA_S(1) | _DMA_S(3), 6),
DMA_REQ_SRC_TIM1_CH2 = _DMA_2_REQ_SRC(_DMA_S(3), 6),
DMA_REQ_SRC_TIM1_CH4 = _DMA_2_REQ_SRC(_DMA_S(4), 6),
DMA_REQ_SRC_TIM1_COM = _DMA_2_REQ_SRC(_DMA_S(4), 6),
DMA_REQ_SRC_TIM1_UP = _DMA_2_REQ_SRC(_DMA_S(5), 6),
DMA_REQ_SRC_TIM1_CH3 = _DMA_2_REQ_SRC(_DMA_S(6), 6),
/* Channel 7 */
DMA_REQ_SRC_TIM8_UP = _DMA_2_REQ_SRC(_DMA_S(1), 7),
DMA_REQ_SRC_TIM8_CH1 = _DMA_2_REQ_SRC(_DMA_S(2), 7),
DMA_REQ_SRC_TIM8_CH2 = _DMA_2_REQ_SRC(_DMA_S(3), 7),
DMA_REQ_SRC_TIM8_CH3 = _DMA_2_REQ_SRC(_DMA_S(4), 7),
DMA_REQ_SRC_TIM8_CH4 = _DMA_2_REQ_SRC(_DMA_S(7), 7),
DMA_REQ_SRC_TIM8_TRIG = _DMA_2_REQ_SRC(_DMA_S(7), 7),
DMA_REQ_SRC_TIM8_COM = _DMA_2_REQ_SRC(_DMA_S(7), 7),
#undef _DMA_2_REQ_SRC
#undef _DMA_S
} dma_request_src;
/*
* Tube conveniences
*/
static inline dma_tube_reg_map* dma_tube_regs(dma_dev *dev,
dma_tube tube) {
ASSERT(DMA_S0 <= tube && tube <= DMA_S7);
switch (dev->clk_id) {
case RCC_DMA1:
return DMA1S0_BASE + (int)tube;
case RCC_DMA2:
return DMA2S0_BASE + (int)tube;
default:
/* Can't happen */
ASSERT(0);
return 0;
}
}
static inline uint8 dma_is_enabled(dma_dev *dev, dma_tube tube) {
return dma_tube_regs(dev, tube)->SCR & DMA_SCR_EN;
}
/* F2-only; available because of double-buffering. */
void dma_set_mem_n_addr(dma_dev *dev, dma_tube tube, int n,
__io void *address);
/**
* @brief Set memory 0 address.
* Availability: STM32F2.
*
* @param dev DMA device
* @param tube Tube whose memory 0 address to set
* @param addr Address to use as memory 0
*/
static inline __always_inline void
dma_set_mem0_addr(dma_dev *dev, dma_tube tube, __io void *addr) {
dma_set_mem_n_addr(dev, tube, 0, addr);
}
/**
* @brief Set memory 1 address.
* Availability: STM32F2.
*
* @param dev DMA device
* @param tube Tube whose memory 1 address to set
* @param addr Address to use as memory 1
*/
static inline __always_inline void
dma_set_mem1_addr(dma_dev *dev, dma_tube tube, __io void *addr) {
dma_set_mem_n_addr(dev, tube, 1, addr);
}
/* Assume the user means SM0AR in a non-double-buffered configuration. */
static inline __always_inline void
dma_set_mem_addr(dma_dev *dev, dma_tube tube, __io void *addr) {
dma_set_mem0_addr(dev, tube, addr);
}
/* SM0AR and SM1AR are treated as though they have the same size */
static inline dma_xfer_size dma_get_mem_size(dma_dev *dev, dma_tube tube) {
return (dma_xfer_size)(dma_tube_regs(dev, tube)->SCR >> 13);
}
static inline dma_xfer_size dma_get_per_size(dma_dev *dev, dma_tube tube) {
return (dma_xfer_size)(dma_tube_regs(dev, tube)->SCR >> 11);
}
void dma_enable_fifo(dma_dev *dev, dma_tube tube);
void dma_disable_fifo(dma_dev *dev, dma_tube tube);
static inline __always_inline int dma_is_fifo_enabled(dma_dev *dev, dma_tube tube) {
return dma_tube_regs(dev, tube)->SFCR & DMA_SFCR_DMDIS;
}
/*
* TODO:
* - Double-buffer configuration function
* - FIFO configuration function
* - MBURST/PBURST configuration function
*/
/*
* ISR/IFCR conveniences.
*/
/* (undocumented) helper for reading LISR/HISR and writing
* LIFCR/HIFCR. For these registers,
*
* S0, S4: bits start at bit 0
* S1, S5: 6
* S2, S6: 16
* S3, S7: 22
*
* I can't imagine why ST didn't just use a byte for each group. The
* bits fit, and it would have made functions like these simpler and
* faster. Oh well. */
static inline __always_inline uint32 _dma_sr_fcr_shift(dma_tube tube) {
switch (tube) {
case DMA_S0: /* fall through */
case DMA_S4:
return 0;
case DMA_S1: /* fall through */
case DMA_S5:
return 6;
case DMA_S2: /* fall through */
case DMA_S6:
return 16;
case DMA_S3: /* fall through */
case DMA_S7:
return 22;
}
/* Can't happen */
ASSERT(0);
return 0;
}
static inline uint8 dma_get_isr_bits(dma_dev *dev, dma_tube tube) {
dma_reg_map *regs = dev->regs;
__io uint32 *isr = tube > DMA_S3 ? &regs->HISR : &regs->LISR;
return (*isr >> _dma_sr_fcr_shift(tube)) & 0x3D;
}
static inline void dma_clear_isr_bits(dma_dev *dev, dma_tube tube) {
dma_reg_map *regs = dev->regs;
__io uint32 *ifcr = tube > DMA_S3 ? &regs->HIFCR : &regs->LIFCR;
*ifcr = (0x3D << _dma_sr_fcr_shift(tube));
}
#undef _DMA_IRQ_BIT_SHIFT
#ifdef __cplusplus
} // extern "C"
#endif
#endif

View File

@@ -0,0 +1,46 @@
/******************************************************************************
* 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/stm32f1/include/series/exti.h
* @brief STM32F2 external interrupts
*/
#ifndef _LIBMAPLE_STM32F2_EXTI_H_
#define _LIBMAPLE_STM32F2_EXTI_H_
#ifdef __cpluspus
extern "C" {
#endif
struct exti_reg_map;
#define EXTI_BASE ((struct exti_reg_map*)0x40013C00)
#ifdef __cpluspus
}
#endif
#endif

View File

@@ -0,0 +1,202 @@
/******************************************************************************
* The MIT License
*
* Copyright (c) 2011 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/flash.h
* @brief STM32F2 Flash header.
*
* Provides register map, base pointer, and register bit definitions
* for the Flash controller on the STM32F2 series, along with
* series-specific configuration values.
*/
#ifndef _LIBMAPLE_STM32F2_FLASH_H_
#define _LIBMAPLE_STM32F2_FLASH_H_
#ifdef __cplusplus
extern "C"{
#endif
#include <libmaple/libmaple_types.h>
/*
* Register map
*/
/** @brief STM32F2 Flash register map type */
typedef struct flash_reg_map {
__io uint32 ACR; /**< Access control register */
__io uint32 KEYR; /**< Key register */
__io uint32 OPTKEYR; /**< Option key register */
__io uint32 SR; /**< Status register */
__io uint32 CR; /**< Control register */
__io uint32 OPTCR; /**< Option control register */
} flash_reg_map;
#define FLASH_BASE ((struct flash_reg_map*)0x40023C00)
/*
* Register bit definitions
*/
/* Access control register */
#define FLASH_ACR_DCRST_BIT 12
#define FLASH_ACR_ICRST_BIT 11
#define FLASH_ACR_DCEN_BIT 10
#define FLASH_ACR_ICEN_BIT 9
#define FLASH_ACR_PRFTEN_BIT 8
#define FLASH_ACR_DCRST (1U << FLASH_ACR_DCRST_BIT)
#define FLASH_ACR_ICRST (1U << FLASH_ACR_ICRST_BIT)
#define FLASH_ACR_DCEN (1U << FLASH_ACR_DCEN_BIT)
#define FLASH_ACR_ICEN (1U << FLASH_ACR_ICEN_BIT)
#define FLASH_ACR_PRFTEN (1U << FLASH_ACR_PRFTEN_BIT)
#define FLASH_ACR_LATENCY 0x7
#define FLASH_ACR_LATENCY_0WS 0x0
#define FLASH_ACR_LATENCY_1WS 0x1
#define FLASH_ACR_LATENCY_2WS 0x2
#define FLASH_ACR_LATENCY_3WS 0x3
#define FLASH_ACR_LATENCY_4WS 0x4
#define FLASH_ACR_LATENCY_5WS 0x5
#define FLASH_ACR_LATENCY_6WS 0x6
#define FLASH_ACR_LATENCY_7WS 0x7
/* Key register */
#define FLASH_KEYR_KEY1 0x45670123
#define FLASH_KEYR_KEY2 0xCDEF89AB
/* Option key register */
#define FLASH_OPTKEYR_OPTKEY1 0x08192A3B
#define FLASH_OPTKEYR_OPTKEY2 0x4C5D6E7F
/* Status register */
#define FLASH_SR_BSY_BIT 16
#define FLASH_SR_PGSERR_BIT 7
#define FLASH_SR_PGPERR_BIT 6
#define FLASH_SR_PGAERR_BIT 5
#define FLASH_SR_WRPERR_BIT 4
#define FLASH_SR_OPERR_BIT 1
#define FLASH_SR_EOP_BIT 0
#define FLASH_SR_BSY (1U << FLASH_SR_BSY_BIT)
#define FLASH_SR_PGSERR (1U << FLASH_SR_PGSERR_BIT)
#define FLASH_SR_PGPERR (1U << FLASH_SR_PGPERR_BIT)
#define FLASH_SR_PGAERR (1U << FLASH_SR_PGAERR_BIT)
#define FLASH_SR_WRPERR (1U << FLASH_SR_WRPERR_BIT)
#define FLASH_SR_OPERR (1U << FLASH_SR_OPERR_BIT)
#define FLASH_SR_EOP (1U << FLASH_SR_EOP_BIT)
/* Control register */
#define FLASH_CR_LOCK_BIT 31
#define FLASH_CR_ERRIE_BIT 25
#define FLASH_CR_EOPIE_BIT 24
#define FLASH_CR_STRT_BIT 16
#define FLASH_CR_MER_BIT 2
#define FLASH_CR_SER_BIT 1
#define FLASH_CR_PG_BIT 0
#define FLASH_CR_LOCK (1U << FLASH_CR_LOCK_BIT)
#define FLASH_CR_ERRIE (1U << FLASH_CR_ERRIE_BIT)
#define FLASH_CR_EOPIE (1U << FLASH_CR_EOPIE_BIT)
#define FLASH_CR_STRT (1U << FLASH_CR_STRT_BIT)
#define FLASH_CR_PSIZE (0x3 << 8)
#define FLASH_CR_PSIZE_MUL8 (0x0 << 8)
#define FLASH_CR_PSIZE_MUL16 (0x1 << 8)
#define FLASH_CR_PSIZE_MUL32 (0x2 << 8)
#define FLASH_CR_PSIZE_MUL64 (0x3 << 8)
#define FLASH_CR_SNB (0xF << 3)
#define FLASH_CR_SNB_0 (0x0 << 3)
#define FLASH_CR_SNB_1 (0x1 << 3)
#define FLASH_CR_SNB_2 (0x2 << 3)
#define FLASH_CR_SNB_3 (0x3 << 3)
#define FLASH_CR_SNB_4 (0x4 << 3)
#define FLASH_CR_SNB_5 (0x5 << 3)
#define FLASH_CR_SNB_6 (0x6 << 3)
#define FLASH_CR_SNB_7 (0x7 << 3)
#define FLASH_CR_SNB_8 (0x8 << 3)
#define FLASH_CR_SNB_9 (0x9 << 3)
#define FLASH_CR_SNB_10 (0xA << 3)
#define FLASH_CR_SNB_11 (0xB << 3)
#define FLASH_CR_MER (1U << FLASH_CR_MER_BIT)
#define FLASH_CR_SER (1U << FLASH_CR_SER_BIT)
#define FLASH_CR_PG (1U << FLASH_CR_PG_BIT)
/* Option control register */
#define FLASH_OPTCR_NRST_STDBY_BIT 7
#define FLASH_OPTCR_NRST_STOP_BIT 6
#define FLASH_OPTCR_WDG_SW_BIT 5
#define FLASH_OPTCR_OPTSTRT_BIT 1
#define FLASH_OPTCR_OPTLOCK_BIT 0
#define FLASH_OPTCR_NWRP (0x3FF << 16)
/* Excluded: The many level 1 values */
#define FLASH_OPTCR_RDP (0xFF << 8)
#define FLASH_OPTCR_RDP_LEVEL0 (0xAA << 8)
#define FLASH_OPTCR_RDP_LEVEL2 (0xCC << 8)
#define FLASH_OPTCR_USER (0x7 << 5)
#define FLASH_OPTCR_nRST_STDBY (1U << FLASH_OPTCR_nRST_STDBY_BIT)
#define FLASH_OPTCR_nRST_STOP (1U << FLASH_OPTCR_nRST_STOP_BIT)
#define FLASH_OPTCR_WDG_SW (1U << FLASH_OPTCR_WDG_SW_BIT)
#define FLASH_OPTCR_BOR_LEV (0x3 << 2)
#define FLASH_OPTCR_BOR_LEVEL3 (0x0 << 2)
#define FLASH_OPTCR_BOR_LEVEL2 (0x1 << 2)
#define FLASH_OPTCR_BOR_LEVEL1 (0x2 << 2)
#define FLASH_OPTCR_BOR_OFF (0x3 << 2)
#define FLASH_OPTCR_OPTSTRT (1U << FLASH_OPTCR_OPTSTRT_BIT)
#define FLASH_OPTCR_OPTLOCK (1U << FLASH_OPTCR_OPTLOCK_BIT)
/*
* Series-specific configuration values
*/
/* Note that this value depends on a 2.7V--3.6V supply voltage */
#define FLASH_SAFE_WAIT_STATES FLASH_WAIT_STATE_3
/* Flash memory features available via ACR. */
enum {
FLASH_PREFETCH = 0x100,
FLASH_ICACHE = 0x200,
FLASH_DCACHE = 0x400,
};
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -0,0 +1,264 @@
/******************************************************************************
* The MIT License
*
* Copyright (c) 2011, 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/gpio.h
* @brief STM32F2 GPIO support.
*/
#ifndef _LIBMAPLE_STM32F2_GPIO_H_
#define _LIBMAPLE_STM32F2_GPIO_H_
#ifdef __cplusplus
extern "C"{
#endif
#include <libmaple/libmaple_types.h>
/*
* GPIO register maps and devices
*/
/** GPIO register map type */
typedef struct gpio_reg_map {
__io uint32 MODER; /**< Mode register */
__io uint32 OTYPER; /**< Output type register */
__io uint32 OSPEEDR; /**< Output speed register */
__io uint32 PUPDR; /**< Pull-up/pull-down register */
__io uint32 IDR; /**< Input data register */
__io uint32 ODR; /**< Output data register */
__io uint32 BSRR; /**< Bit set/reset register */
__io uint32 LCKR; /**< Configuration lock register */
__io uint32 AFRL; /**< Alternate function low register */
__io uint32 AFRH; /**< Alternate function high register */
} gpio_reg_map;
/** GPIO port A register map base pointer */
#define GPIOA_BASE ((struct gpio_reg_map*)0x40020000)
/** GPIO port B register map base pointer */
#define GPIOB_BASE ((struct gpio_reg_map*)0x40020400)
/** GPIO port C register map base pointer */
#define GPIOC_BASE ((struct gpio_reg_map*)0x40020800)
/** GPIO port D register map base pointer */
#define GPIOD_BASE ((struct gpio_reg_map*)0x40020C00)
/** GPIO port E register map base pointer */
#define GPIOE_BASE ((struct gpio_reg_map*)0x40021000)
/** GPIO port F register map base pointer */
#define GPIOF_BASE ((struct gpio_reg_map*)0x40021400)
/** GPIO port G register map base pointer */
#define GPIOG_BASE ((struct gpio_reg_map*)0x40021800)
/** GPIO port H register map base pointer */
#define GPIOH_BASE ((struct gpio_reg_map*)0x40021C00)
/** GPIO port I register map base pointer */
#define GPIOI_BASE ((struct gpio_reg_map*)0x40022000)
struct gpio_dev;
extern struct gpio_dev* const GPIOA;
extern struct gpio_dev gpioa;
extern struct gpio_dev* const GPIOB;
extern struct gpio_dev gpiob;
extern struct gpio_dev* const GPIOC;
extern struct gpio_dev gpioc;
extern struct gpio_dev* const GPIOD;
extern struct gpio_dev gpiod;
extern struct gpio_dev* const GPIOE;
extern struct gpio_dev gpioe;
extern struct gpio_dev* const GPIOF;
extern struct gpio_dev gpiof;
extern struct gpio_dev* const GPIOG;
extern struct gpio_dev gpiog;
extern struct gpio_dev* const GPIOH;
extern struct gpio_dev gpioh;
extern struct gpio_dev* const GPIOI;
extern struct gpio_dev gpioi;
/*
* Register bit definitions
*
* Currently, we only provide masks to be used for shifting for some
* registers, rather than repeating the same values 16 times.
*/
/* Mode register */
#define GPIO_MODER_INPUT 0x0
#define GPIO_MODER_OUTPUT 0x1
#define GPIO_MODER_AF 0x2
#define GPIO_MODER_ANALOG 0x3
/* Output type register */
#define GPIO_OTYPER_PP 0x0
#define GPIO_OTYPER_OD 0x1
/* Output speed register */
#define GPIO_OSPEEDR_LOW 0x0
#define GPIO_OSPEEDR_MED 0x1
#define GPIO_OSPEEDR_FAST 0x2
#define GPIO_OSPEEDR_HIGH 0x3
/* Pull-up/pull-down register */
#define GPIO_PUPDR_NOPUPD 0x0
#define GPIO_PUPDR_PU 0x1
#define GPIO_PUPDR_PD 0x2
/* Alternate function register low */
#define GPIO_AFRL_AF0 (0xFU << 0)
#define GPIO_AFRL_AF1 (0xFU << 4)
#define GPIO_AFRL_AF2 (0xFU << 8)
#define GPIO_AFRL_AF3 (0xFU << 12)
#define GPIO_AFRL_AF4 (0xFU << 16)
#define GPIO_AFRL_AF5 (0xFU << 20)
#define GPIO_AFRL_AF6 (0xFU << 24)
#define GPIO_AFRL_AF7 (0xFU << 28)
/* Alternate function register high */
#define GPIO_AFRH_AF8 (0xFU << 0)
#define GPIO_AFRH_AF9 (0xFU << 4)
#define GPIO_AFRH_AF10 (0xFU << 8)
#define GPIO_AFRH_AF11 (0xFU << 12)
#define GPIO_AFRH_AF12 (0xFU << 16)
#define GPIO_AFRH_AF13 (0xFU << 20)
#define GPIO_AFRH_AF14 (0xFU << 24)
#define GPIO_AFRH_AF15 (0xFU << 28)
/*
* GPIO routines
*/
/**
* @brief GPIO pin modes
*/
typedef enum gpio_pin_mode {
GPIO_MODE_INPUT = GPIO_MODER_INPUT, /**< Input mode */
GPIO_MODE_OUTPUT = GPIO_MODER_OUTPUT, /**< Output mode */
GPIO_MODE_AF = GPIO_MODER_AF, /**< Alternate function mode */
GPIO_MODE_ANALOG = GPIO_MODER_ANALOG, /**< Analog mode */
} gpio_pin_mode;
/**
* @brief Additional flags to be used when setting a pin's mode.
*
* Beyond the basic modes (input, general purpose output, alternate
* function, and analog), there are three parameters that can affect a
* pin's mode:
*
* 1. Output type: push/pull or open-drain. This only has an effect
* for output modes. Choices are: GPIO_MODEF_TYPE_PP (the default)
* and GPIO_MODEF_TYPE_OD.
*
* 2. Output speed: specifies the frequency at which a pin changes
* state. This only has an effect for output modes. Choices are:
* GPIO_MODEF_SPEED_LOW (default), GPIO_MODEF_SPEED_MED,
* GPIO_MODEF_SPEED_FAST, and GPIO_MODEF_SPEED_HIGH.
*
* 3. Push/pull setting: All GPIO pins have weak pull-up and pull-down
* resistors that can be enabled when the pin's mode is
* set. Choices are: GPIO_MODEF_PUPD_NONE (default),
* GPIO_MODEF_PUPD_PU, and GPIO_MODEF_PUPD_PD.
*/
typedef enum gpio_mode_flags {
/* Output type in bit 0 */
GPIO_MODEF_TYPE_PP = GPIO_OTYPER_PP, /**< Output push/pull (default).
Applies only when the mode
specifies output. */
GPIO_MODEF_TYPE_OD = GPIO_OTYPER_OD, /**< Output open drain.
Applies only when the mode
specifies output. */
/* Speed in bits 2:1 */
GPIO_MODEF_SPEED_LOW = GPIO_OSPEEDR_LOW << 1, /**< Low speed (default):
2 MHz. */
GPIO_MODEF_SPEED_MED = GPIO_OSPEEDR_MED << 1, /**< Medium speed: 25 MHz. */
GPIO_MODEF_SPEED_FAST = GPIO_OSPEEDR_FAST << 1, /**< Fast speed: 50 MHz. */
GPIO_MODEF_SPEED_HIGH = GPIO_OSPEEDR_HIGH << 1, /**< High speed:
100 MHz on 30 pF,
80 MHz on 15 pF. */
/* Pull-up/pull-down in bits 4:3 */
GPIO_MODEF_PUPD_NONE = GPIO_PUPDR_NOPUPD << 3, /**< No pull-up/pull-down
(default). */
GPIO_MODEF_PUPD_PU = GPIO_PUPDR_PU << 3, /**< Pull-up */
GPIO_MODEF_PUPD_PD = GPIO_PUPDR_PD << 3, /**< Pull-down */
} gpio_mode_flags;
void gpio_set_modef(struct gpio_dev *dev,
uint8 bit,
gpio_pin_mode mode,
unsigned flags);
/**
* @brief Set the mode of a GPIO pin.
*
* Calling this function is equivalent to calling gpio_set_modef(dev,
* pin, mode, GPIO_MODE_SPEED_HIGH). Note that this overrides the
* default speed.
*
* @param dev GPIO device.
* @param bit Bit on the device whose mode to set, 0--15.
* @param mode Mode to set the pin to.
*/
static inline void gpio_set_mode(struct gpio_dev *dev,
uint8 bit,
gpio_pin_mode mode) {
gpio_set_modef(dev, bit, mode, GPIO_MODEF_SPEED_HIGH);
}
/**
* @brief GPIO alternate functions.
* Use these to select an alternate function for a pin.
* @see gpio_set_af()
*/
typedef enum gpio_af {
GPIO_AF_SYS = 0, /**< System. */
GPIO_AF_TIM_1_2 = 1, /**< Timers 1 and 2. */
GPIO_AF_TIM_3_4_5 = 2, /**< Timers 3, 4, and 5. */
GPIO_AF_TIM_8_9_10_11 = 3, /**< Timers 8 through 11. */
GPIO_AF_I2C = 4, /**< I2C 1, 2, and 3. */
GPIO_AF_SPI_1_2 = 5, /**< SPI1, SPI2/I2S2. */
GPIO_AF_SPI3 = 6, /**< SPI3/I2S3. */
GPIO_AF_USART_1_2_3 = 7, /**< USART 1, 2, and 3. */
GPIO_AF_USART_4_5_6 = 8, /**< UART 4 and 5, USART 6. */
GPIO_AF_CAN_1_2_TIM_12_13_14 = 9, /**<
* CAN 1 and 2, timers 12, 13, and 14. */
GPIO_AF_USB_OTG_FS_HS = 10, /**< USB OTG HS and FS. */
GPIO_AF_ETH = 11, /**< Ethernet MII and RMII. */
GPIO_AF_FSMC_SDIO_OTG_FS = 12, /**< FSMC, SDIO, and USB OTG FS. */
GPIO_AF_DCMI = 13, /**< DCMI. */
GPIO_AF_EVENTOUT = 15, /**< EVENTOUT. */
} gpio_af;
void gpio_set_af(struct gpio_dev *dev, uint8 bit, gpio_af af);
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -0,0 +1,160 @@
/******************************************************************************
* The MIT License
*
* Copyright (c) 2011 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/nvic.h
* @brief STM32F2 nested vectored interrupt controller (NVIC) header.
*/
#ifndef _LIBMAPLE_STM32F2_NVIC_H_
#define _LIBMAPLE_STM32F2_NVIC_H_
#ifdef __cplusplus
extern "C"{
#endif
/**
* @brief STM32F2 interrupt vector table interrupt numbers.
*/
typedef enum nvic_irq_num {
NVIC_NMI = -14, /**< Non-maskable interrupt */
NVIC_HARDFAULT = -13, /**< Hard fault (all class of fault) */
NVIC_MEM_MANAGE = -12, /**< Memory management */
NVIC_BUS_FAULT = -11, /**< Bus fault: prefetch fault, memory
access fault. */
NVIC_USAGE_FAULT = -10, /**< Usage fault: Undefined instruction
or illegal state. */
NVIC_SVC = -5, /**< System service call via SWI
instruction */
NVIC_DEBUG_MON = -4, /**< Debug monitor */
NVIC_PEND_SVC = -2, /**< Pendable request for system
service */
NVIC_SYSTICK = -1, /**< System tick timer */
NVIC_WWDG = 0, /**< Window watchdog interrupt */
NVIC_PVD = 1, /**< PVD through EXTI line detection */
NVIC_TAMP_STAMP = 2, /**< Tamper and TimeStamp */
NVIC_RTC_WKUP = 3, /**< Real-time clock wakeup */
NVIC_FLASH = 4, /**< Flash */
NVIC_RCC = 5, /**< Reset and clock control */
NVIC_EXTI0 = 6, /**< EXTI line 0 */
NVIC_EXTI1 = 7, /**< EXTI line 1 */
NVIC_EXTI2 = 8, /**< EXTI line 2 */
NVIC_EXTI3 = 9, /**< EXTI line 3 */
NVIC_EXTI4 = 10, /**< EXTI line 4 */
NVIC_DMA1_STREAM0 = 11, /**< DMA1 stream 0 */
NVIC_DMA1_STREAM1 = 12, /**< DMA1 stream 1 */
NVIC_DMA1_STREAM2 = 13, /**< DMA1 stream 2 */
NVIC_DMA1_STREAM3 = 14, /**< DMA1 stream 3 */
NVIC_DMA1_STREAM4 = 15, /**< DMA1 stream 4 */
NVIC_DMA1_STREAM5 = 16, /**< DMA1 stream 5 */
NVIC_DMA1_STREAM6 = 17, /**< DMA1 stream 6 */
NVIC_ADC = 18, /**< ADC */
NVIC_CAN1_TX = 19, /**< CAN1 TX */
NVIC_CAN1_RX0 = 20, /**< CAN1 RX0 */
NVIC_CAN1_RX1 = 21, /**< CAN1 RX1 */
NVIC_CAN1_SCE = 22, /**< CAN1 SCE */
NVIC_EXTI_9_5 = 23, /**< EXTI lines [9:5] */
NVIC_TIMER1_BRK_TIMER9 = 24, /**< Timer 1 break and timer 9 */
NVIC_TIMER1_UP_TIMER10 = 25, /**< Timer 1 update and timer 10 */
NVIC_TIMER1_TRG_COM_TIMER11 = 26, /**< Timer 1 trigger and commutation and
timer 11.*/
NVIC_TIMER1_CC = 27, /**< Timer 1 capture and compare */
NVIC_TIMER2 = 28, /**< Timer 2 */
NVIC_TIMER3 = 29, /**< Timer 3 */
NVIC_TIMER4 = 30, /**< Timer 4 */
NVIC_I2C1_EV = 31, /**< I2C1 event */
NVIC_I2C1_ER = 32, /**< I2C2 error */
NVIC_I2C2_EV = 33, /**< I2C2 event */
NVIC_I2C2_ER = 34, /**< I2C2 error */
NVIC_SPI1 = 35, /**< SPI1 */
NVIC_SPI2 = 36, /**< SPI2 */
NVIC_USART1 = 37, /**< USART1 */
NVIC_USART2 = 38, /**< USART2 */
NVIC_USART3 = 39, /**< USART3 */
NVIC_EXTI_15_10 = 40, /**< EXTI lines [15:10] */
NVIC_RTCALARM = 41, /**< RTC alarms A and B through EXTI */
NVIC_OTG_FS_WKUP = 42, /**< USB on-the-go full-speed wakeup
through EXTI*/
NVIC_TIMER8_BRK_TIMER12 = 43, /**< Timer 8 break and timer 12 */
NVIC_TIMER8_UP_TIMER13 = 44, /**< Timer 8 update and timer 13 */
NVIC_TIMER8_TRG_COM_TIMER14 = 45, /**< Timer 8 trigger and commutation and
timer 14 */
NVIC_TIMER8_CC = 46, /**< Timer 8 capture and compare */
NVIC_DMA1_STREAM7 = 47, /**< DMA1 stream 7 */
NVIC_FSMC = 48, /**< FSMC */
NVIC_SDIO = 49, /**< SDIO */
NVIC_TIMER5 = 50, /**< Timer 5 */
NVIC_SPI3 = 51, /**< SPI3 */
NVIC_UART4 = 52, /**< UART4 */
NVIC_UART5 = 53, /**< UART5 */
NVIC_TIMER6_DAC = 54, /**< Timer 6 and DAC underrun */
NVIC_TIMER7 = 55, /**< Timer 7 */
NVIC_DMA2_STREAM0 = 56, /**< DMA2 stream 0 */
NVIC_DMA2_STREAM1 = 57, /**< DMA2 stream 1 */
NVIC_DMA2_STREAM2 = 58, /**< DMA2 stream 2 */
NVIC_DMA2_STREAM3 = 59, /**< DMA2 stream 3 */
NVIC_DMA2_STREAM4 = 60, /**< DMA2 stream 4 */
NVIC_ETH = 61, /**< Ethernet */
NVIC_ETH_WKUP = 62, /**< Ethernet wakeup through EXTI */
NVIC_CAN2_TX = 63, /**< CAN2 TX */
NVIC_CAN2_RX0 = 64, /**< CAN2 RX0 */
NVIC_CAN2_RX1 = 65, /**< CAN2 RX1 */
NVIC_CAN2_SCE = 66, /**< CAN2 SCE */
NVIC_OTG_FS = 67, /**< USB on-the-go full-speed */
NVIC_DMA2_STREAM5 = 68, /**< DMA2 stream 5 */
NVIC_DMA2_STREAM6 = 69, /**< DMA2 stream 6 */
NVIC_DMA2_STREAM7 = 70, /**< DMA2 stream 7 */
NVIC_USART6 = 71, /**< USART6 */
NVIC_I2C3_EV = 72, /**< I2C3 event */
NVIC_I2C3_ER = 73, /**< I2C3 error */
NVIC_OTG_HS_EP1_OUT = 74, /**< USB on-the-go high-speed
endpoint 1 OUT */
NVIC_OTG_HS_EP1_IN = 75, /**< USB on-the-go high-speed
endpoint 1 IN */
NVIC_OTG_HS_WKUP = 76, /**< USB on-the-go high-speed wakeup
through EXTI*/
NVIC_OTG_HS = 77, /**< USB on-the-go high-speed */
NVIC_DCMI = 78, /**< DCMI */
NVIC_CRYP = 79, /**< Cryptographic processor */
NVIC_HASH_RNG = 80, /**< Hash and random number
generation */
/* Fake enumerator values, for compatiblity with F1.
* TODO decide if this is actually a good idea. */
NVIC_TIMER6 = NVIC_TIMER6_DAC, /**< For compatibility with STM32F1. */
} nvic_irq_num;
static inline void nvic_irq_disable_all(void) {
NVIC_BASE->ICER[0] = 0xFFFFFFFF;
NVIC_BASE->ICER[1] = 0xFFFFFFFF;
NVIC_BASE->ICER[2] = 0xFFFFFFFF;
}
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -0,0 +1,73 @@
/******************************************************************************
* 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/pwr.h
* @author Marti Bolivar <mbolivar@leaflabs.com>
* @brief STM32F2 Power control (PWR) support.
*/
#ifndef _LIBMAPLE_STM32F2_PWR_H_
#define _LIBMAPLE_STM32F2_PWR_H_
/*
* Additional register bits
*/
/* Control register */
/**
* @brief Flash power down in stop mode bit.
* Availability: STM32F2 */
#define PWR_CR_FPDS_BIT 9
/**
* @brief Flash power down in stop mode.
* Availability: STM32F2 */
#define PWR_CR_FPDS (1U << PWR_CR_FPDS_BIT)
/* PVD level selection */
#define PWR_CR_PLS_2_0V (0x0 << 5)
#define PWR_CR_PLS_2_1V (0x1 << 5)
#define PWR_CR_PLS_2_3V (0x2 << 5)
#define PWR_CR_PLS_2_5V (0x3 << 5)
#define PWR_CR_PLS_2_6V (0x4 << 5)
#define PWR_CR_PLS_2_7V (0x5 << 5)
#define PWR_CR_PLS_2_8V (0x6 << 5)
#define PWR_CR_PLS_2_9V (0x7 << 5)
/* Control/Status register */
/** Backup regulator enable bit. */
#define PWR_CSR_BRE_BIT 9
/** Backup regulator ready bit. */
#define PWR_CSR_BRR_BIT 3
/** Backup regulator enable. */
#define PWR_CSR_BRE (1U << PWR_CSR_BRE_BIT)
/** Backup regulator ready. */
#define PWR_CSR_BRR (1U << PWR_CSR_BRR_BIT)
#endif

View File

@@ -0,0 +1,951 @@
/******************************************************************************
* The MIT License
*
* Copyright (c) 2011 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/rcc.h
* @brief STM32F2 reset and clock control (RCC) support.
*/
#ifndef _LIBMAPLE_STM32F2_RCC_H_
#define _LIBMAPLE_STM32F2_RCC_H_
#ifdef __cplusplus
extern "C"{
#endif
#include <libmaple/libmaple_types.h>
/*
* Register map
*/
/** STM32F2 RCC register map type */
typedef struct rcc_reg_map {
__io uint32 CR; /**< Clock control register */
__io uint32 PLLCFGR; /**< PLL configuration register */
__io uint32 CFGR; /**< Clock configuration register */
__io uint32 CIR; /**< Clock interrupt register */
__io uint32 AHB1RSTR; /**< AHB1 peripheral reset register */
__io uint32 AHB2RSTR; /**< AHB2 peripheral reset register */
__io uint32 AHB3RSTR; /**< AHB3 peripheral reset register */
const uint32 RESERVED1; /**< Reserved */
__io uint32 APB1RSTR; /**< APB1 peripheral reset register */
__io uint32 APB2RSTR; /**< APB2 peripheral reset register */
const uint32 RESERVED2; /**< Reserved */
const uint32 RESERVED3; /**< Reserved */
__io uint32 AHB1ENR; /**< AHB1 peripheral clock enable register */
__io uint32 AHB2ENR; /**< AHB2 peripheral clock enable register */
__io uint32 AHB3ENR; /**< AHB3 peripheral clock enable register */
const uint32 RESERVED4; /**< Reserved */
__io uint32 APB1ENR; /**< APB1 peripheral clock enable register */
__io uint32 APB2ENR; /**< APB2 peripheral clock enable register */
const uint32 RESERVED5; /**< Reserved */
const uint32 RESERVED6; /**< Reserved */
__io uint32 AHB1LPENR; /**< AHB1 peripheral clock enable in
low power mode register */
__io uint32 AHB2LPENR; /**< AHB2 peripheral clock enable in
low power mode register */
__io uint32 AHB3LPENR; /**< AHB3 peripheral clock enable in
low power mode register */
const uint32 RESERVED7; /**< Reserved */
__io uint32 APB1LPENR; /**< APB1 peripheral clock enable in
low power mode register */
__io uint32 APB2LPENR; /**< APB2 peripheral clock enable in
low power mode register */
const uint32 RESERVED8; /**< Reserved */
const uint32 RESERVED9; /**< Reserved */
__io uint32 BDCR; /**< Backup domain control register */
__io uint32 CSR; /**< Clock control and status register */
const uint32 RESERVED10; /**< Reserved */
const uint32 RESERVED11; /**< Reserved */
__io uint32 SSCGR; /**< Spread spectrum clock generation
register */
__io uint32 PLLI2SCFGR; /**< PLLI2S configuration register */
} rcc_reg_map;
#define RCC_BASE ((struct rcc_reg_map*)0x40023800)
/*
* Register bit definitions
*/
/* Clock control register */
#define RCC_CR_PLLI2SRDY_BIT 27
#define RCC_CR_PLLI2SON_BIT 26
#define RCC_CR_PLLRDY_BIT 25
#define RCC_CR_PLLON_BIT 24
#define RCC_CR_CSSON_BIT 19
#define RCC_CR_HSEBYP_BIT 18
#define RCC_CR_HSERDY_BIT 17
#define RCC_CR_HSEON_BIT 16
#define RCC_CR_HSIRDY_BIT 1
#define RCC_CR_HSION_BIT 0
#define RCC_CR_PLLI2SRDY (1U << RCC_CR_PLLI2SRDY_BIT)
#define RCC_CR_PLLI2SON (1U << RCC_CR_PLLI2SON_BIT)
#define RCC_CR_PLLRDY (1U << RCC_CR_PLLRDY_BIT)
#define RCC_CR_PLLON (1U << RCC_CR_PLLON_BIT)
#define RCC_CR_CSSON (1U << RCC_CR_CSSON_BIT)
#define RCC_CR_HSEBYP (1U << RCC_CR_HSEBYP_BIT)
#define RCC_CR_HSERDY (1U << RCC_CR_HSERDY_BIT)
#define RCC_CR_HSEON (1U << RCC_CR_HSEON_BIT)
#define RCC_CR_HSICAL (0xFF << 8)
#define RCC_CR_HSITRIM (0x1F << 3)
#define RCC_CR_HSIRDY (1U << RCC_CR_HSIRDY_BIT)
#define RCC_CR_HSION (1U << RCC_CR_HSION_BIT)
/* PLL configuration register */
#define RCC_PLLCFGR_PLLSRC_BIT 22
#define RCC_PLLCFGR_PLLQ (0xF << 24)
#define RCC_PLLCFGR_PLLSRC (1U << RCC_PLLCFGR_PLLSRC_BIT)
#define RCC_PLLCFGR_PLLSRC_HSI (0x0 << RCC_PLLCFGR_PLLSRC_BIT)
#define RCC_PLLCFGR_PLLSRC_HSE (0x1 << RCC_PLLCFGR_PLLSRC_BIT)
#define RCC_PLLCFGR_PLLP (0x3 << 16)
#define RCC_PLLCFGR_PLLN (0x1FF << 6)
#define RCC_PLLCFGR_PLLM 0x1F
/* Clock configuration register */
#define RCC_CFGR_I2SSRC_BIT 23
#define RCC_CFGR_MCO2 (0x3 << 30)
#define RCC_CFGR_MCO2_SYSCLK (0x0 << 30)
#define RCC_CFGR_MCO2_PLLI2S (0x1 << 30)
#define RCC_CFGR_MCO2_HSE (0x2 << 30)
#define RCC_CFGR_MCO2_PLL (0x3 << 30)
#define RCC_CFGR_MCO2PRE (0x7 << 27)
#define RCC_CFGR_MCO2PRE_DIV_1 (0x0 << 27)
#define RCC_CFGR_MCO2PRE_DIV_2 (0x4 << 27)
#define RCC_CFGR_MCO2PRE_DIV_3 (0x5 << 27)
#define RCC_CFGR_MCO2PRE_DIV_4 (0x6 << 27)
#define RCC_CFGR_MCO2PRE_DIV_5 (0x7 << 27)
#define RCC_CFGR_MCO1PRE (0x7 << 24)
#define RCC_CFGR_MCO1PRE_DIV_1 (0x0 << 24)
#define RCC_CFGR_MCO1PRE_DIV_2 (0x4 << 24)
#define RCC_CFGR_MCO1PRE_DIV_3 (0x5 << 24)
#define RCC_CFGR_MCO1PRE_DIV_4 (0x6 << 24)
#define RCC_CFGR_MCO1PRE_DIV_5 (0x7 << 24)
#define RCC_CFGR_I2SSRC (1U << RCC_CFGR_I2SSRC_BIT)
#define RCC_CFGR_I2SSRC_PLLI2S (0 << RCC_CFGR_I2SSRC_BIT)
#define RCC_CFGR_I2SSRC_I2S_CKIN (1 << RCC_CFGR_I2SSRC_BIT)
#define RCC_CFGR_MCO1 (0x3 << 21)
#define RCC_CFGR_MCO1_HSI (0x0 << 21)
#define RCC_CFGR_MCO1_LSE (0x1 << 21)
#define RCC_CFGR_MCO1_HSE (0x2 << 21)
#define RCC_CFGR_MCO1_PLL (0x3 << 21)
#define RCC_CFGR_RTCPRE (0x1F << 16)
/* Skipped: all the 0b0xx values meaning "not divided" */
#define RCC_CFGR_PPRE2 (0x7 << 13)
#define RCC_CFGR_PPRE2_AHB_DIV_2 (0x4 << 13)
#define RCC_CFGR_PPRE2_AHB_DIV_4 (0x5 << 13)
#define RCC_CFGR_PPRE2_AHB_DIV_8 (0x6 << 13)
#define RCC_CFGR_PPRE2_AHB_DIV_16 (0x7 << 13)
/* Skipped: all the 0b0xx values meaning "not divided" */
#define RCC_CFGR_PPRE1 (0x7 << 10)
#define RCC_CFGR_PPRE1_AHB_DIV_2 (0x4 << 10)
#define RCC_CFGR_PPRE1_AHB_DIV_4 (0x5 << 10)
#define RCC_CFGR_PPRE1_AHB_DIV_8 (0x6 << 10)
#define RCC_CFGR_PPRE1_AHB_DIV_16 (0x7 << 10)
/* Skipped: all the 0b0xxx values meaning "not divided" */
#define RCC_CFGR_HPRE (0xF << 4)
#define RCC_CFGR_HPRE_SYSCLK_DIV_2 (0x8 << 4)
#define RCC_CFGR_HPRE_SYSCLK_DIV_4 (0x9 << 4)
#define RCC_CFGR_HPRE_SYSCLK_DIV_8 (0xA << 4)
#define RCC_CFGR_HPRE_SYSCLK_DIV_16 (0xB << 4)
#define RCC_CFGR_HPRE_SYSCLK_DIV_64 (0xC << 4)
#define RCC_CFGR_HPRE_SYSCLK_DIV_128 (0xD << 4)
#define RCC_CFGR_HPRE_SYSCLK_DIV_256 (0xE << 4)
#define RCC_CFGR_HPRE_SYSCLK_DIV_512 (0xF << 4)
#define RCC_CFGR_SWS (0x3 << 2)
#define RCC_CFGR_SWS_HSI (0x0 << 2)
#define RCC_CFGR_SWS_HSE (0x1 << 2)
#define RCC_CFGR_SWS_PLL (0x2 << 2)
#define RCC_CFGR_SW 0x3
#define RCC_CFGR_SW_HSI 0x0
#define RCC_CFGR_SW_HSE 0x1
#define RCC_CFGR_SW_PLL 0x2
/* Clock interrupt register */
#define RCC_CIR_CSSC_BIT 23
#define RCC_CIR_PLLI2SRDYC_BIT 21
#define RCC_CIR_PLLRDYC_BIT 20
#define RCC_CIR_HSERDYC_BIT 19
#define RCC_CIR_HSIRDYC_BIT 18
#define RCC_CIR_LSERDYC_BIT 17
#define RCC_CIR_LSIRDYC_BIT 16
#define RCC_CIR_PLLI2SRDYIE_BIT 13
#define RCC_CIR_PLLRDYIE_BIT 12
#define RCC_CIR_HSERDYIE_BIT 11
#define RCC_CIR_HSIRDYIE_BIT 10
#define RCC_CIR_LSERDYIE_BIT 9
#define RCC_CIR_LSIRDYIE_BIT 8
#define RCC_CIR_CSSF_BIT 7
#define RCC_CIR_PLLI2SRDYF_BIT 5
#define RCC_CIR_PLLRDYF_BIT 4
#define RCC_CIR_HSERDYF_BIT 3
#define RCC_CIR_HSIRDYF_BIT 2
#define RCC_CIR_LSERDYF_BIT 1
#define RCC_CIR_LSIRDYF_BIT 0
#define RCC_CIR_CSSC (1U << RCC_CIR_CSSC_BIT)
#define RCC_CIR_PLLI2SRDYC (1U << RCC_CIR_PLLI2SRDYC_BIT)
#define RCC_CIR_PLLRDYC (1U << RCC_CIR_PLLRDYC_BIT)
#define RCC_CIR_HSERDYC (1U << RCC_CIR_HSERDYC_BIT)
#define RCC_CIR_HSIRDYC (1U << RCC_CIR_HSIRDYC_BIT)
#define RCC_CIR_LSERDYC (1U << RCC_CIR_LSERDYC_BIT)
#define RCC_CIR_LSIRDYC (1U << RCC_CIR_LSIRDYC_BIT)
#define RCC_CIR_PLLI2SRDYIE (1U << RCC_CIR_PLLI2SRDYIE_BIT)
#define RCC_CIR_PLLRDYIE (1U << RCC_CIR_PLLRDYIE_BIT)
#define RCC_CIR_HSERDYIE (1U << RCC_CIR_HSERDYIE_BIT)
#define RCC_CIR_HSIRDYIE (1U << RCC_CIR_HSIRDYIE_BIT)
#define RCC_CIR_LSERDYIE (1U << RCC_CIR_LSERDYIE_BIT)
#define RCC_CIR_LSIRDYIE (1U << RCC_CIR_LSIRDYIE_BIT)
#define RCC_CIR_CSSF (1U << RCC_CIR_CSSF_BIT)
#define RCC_CIR_PLLI2SRDYF (1U << RCC_CIR_PLLI2SRDYF_BIT)
#define RCC_CIR_PLLRDYF (1U << RCC_CIR_PLLRDYF_BIT)
#define RCC_CIR_HSERDYF (1U << RCC_CIR_HSERDYF_BIT)
#define RCC_CIR_HSIRDYF (1U << RCC_CIR_HSIRDYF_BIT)
#define RCC_CIR_LSERDYF (1U << RCC_CIR_LSERDYF_BIT)
#define RCC_CIR_LSIRDYF (1U << RCC_CIR_LSIRDYF_BIT)
/* AHB1 peripheral reset register */
#define RCC_AHB1RSTR_OTGHSRST_BIT 29
#define RCC_AHB1RSTR_ETHMACRST_BIT 25
#define RCC_AHB1RSTR_DMA2RST_BIT 22
#define RCC_AHB1RSTR_DMA1RST_BIT 21
#define RCC_AHB1RSTR_CRCRST_BIT 12
#define RCC_AHB1RSTR_GPIOIRST_BIT 8
#define RCC_AHB1RSTR_GPIOHRST_BIT 7
#define RCC_AHB1RSTR_GPIOGRST_BIT 6
#define RCC_AHB1RSTR_GPIOFRST_BIT 5
#define RCC_AHB1RSTR_GPIOERST_BIT 4
#define RCC_AHB1RSTR_GPIODRST_BIT 3
#define RCC_AHB1RSTR_GPIOCRST_BIT 2
#define RCC_AHB1RSTR_GPIOBRST_BIT 1
#define RCC_AHB1RSTR_GPIOARST_BIT 0
#define RCC_AHB1RSTR_OTGHSRST (1U << RCC_AHB1RSTR_OTGHSRST_BIT)
#define RCC_AHB1RSTR_ETHMACRST (1U << RCC_AHB1RSTR_ETHMACRST_BIT)
#define RCC_AHB1RSTR_DMA2RST (1U << RCC_AHB1RSTR_DMA2RST_BIT)
#define RCC_AHB1RSTR_DMA1RST (1U << RCC_AHB1RSTR_DMA1RST_BIT)
#define RCC_AHB1RSTR_CRCRST (1U << RCC_AHB1RSTR_CRCRST_BIT)
#define RCC_AHB1RSTR_GPIOIRST (1U << RCC_AHB1RSTR_GPIOIRST_BIT)
#define RCC_AHB1RSTR_GPIOHRST (1U << RCC_AHB1RSTR_GPIOHRST_BIT)
#define RCC_AHB1RSTR_GPIOGRST (1U << RCC_AHB1RSTR_GPIOGRST_BIT)
#define RCC_AHB1RSTR_GPIOFRST (1U << RCC_AHB1RSTR_GPIOFRST_BIT)
#define RCC_AHB1RSTR_GPIOERST (1U << RCC_AHB1RSTR_GPIOERST_BIT)
#define RCC_AHB1RSTR_GPIODRST (1U << RCC_AHB1RSTR_GPIODRST_BIT)
#define RCC_AHB1RSTR_GPIOCRST (1U << RCC_AHB1RSTR_GPIOCRST_BIT)
#define RCC_AHB1RSTR_GPIOBRST (1U << RCC_AHB1RSTR_GPIOBRST_BIT)
#define RCC_AHB1RSTR_GPIOARST (1U << RCC_AHB1RSTR_GPIOARST_BIT)
/* AHB2 peripheral reset register */
#define RCC_AHB2RSTR_OTGFSRST_BIT 7
#define RCC_AHB2RSTR_RNGRST_BIT 6
#define RCC_AHB2RSTR_HASHRST_BIT 5
#define RCC_AHB2RSTR_CRYPRST_BIT 4
#define RCC_AHB2RSTR_DCMIRST_BIT 0
#define RCC_AHB2RSTR_OTGFSRST (1U << RCC_AHB2RSTR_OTGFSRST_BIT)
#define RCC_AHB2RSTR_RNGRST (1U << RCC_AHB2RSTR_RNGRST_BIT)
#define RCC_AHB2RSTR_HASHRST (1U << RCC_AHB2RSTR_HASHRST_BIT)
#define RCC_AHB2RSTR_CRYPRST (1U << RCC_AHB2RSTR_CRYPRST_BIT)
#define RCC_AHB2RSTR_DCMIRST (1U << RCC_AHB2RSTR_DCMIRST_BIT)
/* AHB3 peripheral reset register */
#define RCC_AHB3RSTR_FSMCRST_BIT 0
#define RCC_AHB3RSTR_FSMCRST (1U << RCC_AHB3RSTR_FSMCRST_BIT)
/* APB1 peripheral reset register */
#define RCC_APB1RSTR_DACRST_BIT 29
#define RCC_APB1RSTR_PWRRST_BIT 28
#define RCC_APB1RSTR_CAN2RST_BIT 26
#define RCC_APB1RSTR_CAN1RST_BIT 25
#define RCC_APB1RSTR_I2C3RST_BIT 23
#define RCC_APB1RSTR_I2C2RST_BIT 22
#define RCC_APB1RSTR_I2C1RST_BIT 21
#define RCC_APB1RSTR_UART5RST_BIT 20
#define RCC_APB1RSTR_UART4RST_BIT 19
#define RCC_APB1RSTR_UART3RST_BIT 18
#define RCC_APB1RSTR_UART2RST_BIT 17
#define RCC_APB1RSTR_SPI3RST_BIT 15
#define RCC_APB1RSTR_SPI2RST_BIT 14
#define RCC_APB1RSTR_WWDGRST_BIT 11
#define RCC_APB1RSTR_TIM14RST_BIT 8
#define RCC_APB1RSTR_TIM13RST_BIT 7
#define RCC_APB1RSTR_TIM12RST_BIT 6
#define RCC_APB1RSTR_TIM7RST_BIT 5
#define RCC_APB1RSTR_TIM6RST_BIT 4
#define RCC_APB1RSTR_TIM5RST_BIT 3
#define RCC_APB1RSTR_TIM4RST_BIT 2
#define RCC_APB1RSTR_TIM3RST_BIT 1
#define RCC_APB1RSTR_TIM2RST_BIT 0
#define RCC_APB1RSTR_DACRST (1U << RCC_APB1RSTR_DACRST_BIT)
#define RCC_APB1RSTR_PWRRST (1U << RCC_APB1RSTR_PWRRST_BIT)
#define RCC_APB1RSTR_CAN2RST (1U << RCC_APB1RSTR_CAN2RST_BIT)
#define RCC_APB1RSTR_CAN1RST (1U << RCC_APB1RSTR_CAN1RST_BIT)
#define RCC_APB1RSTR_I2C3RST (1U << RCC_APB1RSTR_I2C3RST_BIT)
#define RCC_APB1RSTR_I2C2RST (1U << RCC_APB1RSTR_I2C2RST_BIT)
#define RCC_APB1RSTR_I2C1RST (1U << RCC_APB1RSTR_I2C1RST_BIT)
#define RCC_APB1RSTR_UART5RST (1U << RCC_APB1RSTR_UART5RST_BIT)
#define RCC_APB1RSTR_UART4RST (1U << RCC_APB1RSTR_UART4RST_BIT)
#define RCC_APB1RSTR_UART3RST (1U << RCC_APB1RSTR_UART3RST_BIT)
#define RCC_APB1RSTR_UART2RST (1U << RCC_APB1RSTR_UART2RST_BIT)
#define RCC_APB1RSTR_SPI3RST (1U << RCC_APB1RSTR_SPI3RST_BIT)
#define RCC_APB1RSTR_SPI2RST (1U << RCC_APB1RSTR_SPI2RST_BIT)
#define RCC_APB1RSTR_WWDGRST (1U << RCC_APB1RSTR_WWDGRST_BIT)
#define RCC_APB1RSTR_TIM14RST (1U << RCC_APB1RSTR_TIM14RST_BIT)
#define RCC_APB1RSTR_TIM13RST (1U << RCC_APB1RSTR_TIM13RST_BIT)
#define RCC_APB1RSTR_TIM12RST (1U << RCC_APB1RSTR_TIM12RST_BIT)
#define RCC_APB1RSTR_TIM7RST (1U << RCC_APB1RSTR_TIM7RST_BIT)
#define RCC_APB1RSTR_TIM6RST (1U << RCC_APB1RSTR_TIM6RST_BIT)
#define RCC_APB1RSTR_TIM5RST (1U << RCC_APB1RSTR_TIM5RST_BIT)
#define RCC_APB1RSTR_TIM4RST (1U << RCC_APB1RSTR_TIM4RST_BIT)
#define RCC_APB1RSTR_TIM3RST (1U << RCC_APB1RSTR_TIM3RST_BIT)
#define RCC_APB1RSTR_TIM2RST (1U << RCC_APB1RSTR_TIM2RST_BIT)
/* APB2 peripheral reset register */
#define RCC_APB2RSTR_TIM11RST_BIT 18
#define RCC_APB2RSTR_TIM10RST_BIT 17
#define RCC_APB2RSTR_TIM9RST_BIT 16
#define RCC_APB2RSTR_SYSCFGRST_BIT 14
#define RCC_APB2RSTR_SPI1RST_BIT 12
#define RCC_APB2RSTR_SDIORST_BIT 11
#define RCC_APB2RSTR_ADCRST_BIT 8
#define RCC_APB2RSTR_USART6RST_BIT 5
#define RCC_APB2RSTR_USART1RST_BIT 4
#define RCC_APB2RSTR_TIM8RST_BIT 1
#define RCC_APB2RSTR_TIM1RST_BIT 0
#define RCC_APB2RSTR_TIM11RST (1U << RCC_APB2RSTR_TIM11RST_BIT)
#define RCC_APB2RSTR_TIM10RST (1U << RCC_APB2RSTR_TIM10RST_BIT)
#define RCC_APB2RSTR_TIM9RST (1U << RCC_APB2RSTR_TIM9RST_BIT)
#define RCC_APB2RSTR_SYSCFGRST (1U << RCC_APB2RSTR_SYSCFGRST_BIT)
#define RCC_APB2RSTR_SPI1RST (1U << RCC_APB2RSTR_SPI1RST_BIT)
#define RCC_APB2RSTR_SDIORST (1U << RCC_APB2RSTR_SDIORST_BIT)
#define RCC_APB2RSTR_ADCRST (1U << RCC_APB2RSTR_ADCRST_BIT)
#define RCC_APB2RSTR_USART6RST (1U << RCC_APB2RSTR_USART6RST_BIT)
#define RCC_APB2RSTR_USART1RST (1U << RCC_APB2RSTR_USART1RST_BIT)
#define RCC_APB2RSTR_TIM8RST (1U << RCC_APB2RSTR_TIM8RST_BIT)
#define RCC_APB2RSTR_TIM1RST (1U << RCC_APB2RSTR_TIM1RST_BIT)
/* AHB1 peripheral clock enable register */
#define RCC_AHB1ENR_OTGHSULPIEN_BIT 30
#define RCC_AHB1ENR_OTGHSEN_BIT 29
#define RCC_AHB1ENR_ETHMACPTPEN_BIT 28
#define RCC_AHB1ENR_ETHMACRXEN_BIT 27
#define RCC_AHB1ENR_ETHMACTXEN_BIT 26
#define RCC_AHB1ENR_ETHMACEN_BIT 25
#define RCC_AHB1ENR_DMA2EN_BIT 22
#define RCC_AHB1ENR_DMA1EN_BIT 21
#define RCC_AHB1ENR_BKPSRAMEN_BIT 18
#define RCC_AHB1ENR_CRCEN_BIT 12
#define RCC_AHB1ENR_GPIOIEN_BIT 8
#define RCC_AHB1ENR_GPIOHEN_BIT 7
#define RCC_AHB1ENR_GPIOGEN_BIT 6
#define RCC_AHB1ENR_GPIOFEN_BIT 5
#define RCC_AHB1ENR_GPIOEEN_BIT 4
#define RCC_AHB1ENR_GPIODEN_BIT 3
#define RCC_AHB1ENR_GPIOCEN_BIT 2
#define RCC_AHB1ENR_GPIOBEN_BIT 1
#define RCC_AHB1ENR_GPIOAEN_BIT 0
#define RCC_AHB1ENR_OTGHSULPIEN (1U << RCC_AHB1ENR_OTGHSULPIEN_BIT)
#define RCC_AHB1ENR_OTGHSEN (1U << RCC_AHB1ENR_OTGHSEN_BIT)
#define RCC_AHB1ENR_ETHMACPTPEN (1U << RCC_AHB1ENR_ETHMACPTPEN_BIT)
#define RCC_AHB1ENR_ETHMACRXEN (1U << RCC_AHB1ENR_ETHMACRXEN_BIT)
#define RCC_AHB1ENR_ETHMACTXEN (1U << RCC_AHB1ENR_ETHMACTXEN_BIT)
#define RCC_AHB1ENR_ETHMACEN (1U << RCC_AHB1ENR_ETHMACEN_BIT)
#define RCC_AHB1ENR_DMA2EN (1U << RCC_AHB1ENR_DMA2EN_BIT)
#define RCC_AHB1ENR_DMA1EN (1U << RCC_AHB1ENR_DMA1EN_BIT)
#define RCC_AHB1ENR_BKPSRAMEN (1U << RCC_AHB1ENR_BKPSRAMEN_BIT)
#define RCC_AHB1ENR_CRCEN (1U << RCC_AHB1ENR_CRCEN_BIT)
#define RCC_AHB1ENR_GPIOIEN (1U << RCC_AHB1ENR_GPIOIEN_BIT)
#define RCC_AHB1ENR_GPIOHEN (1U << RCC_AHB1ENR_GPIOHEN_BIT)
#define RCC_AHB1ENR_GPIOGEN (1U << RCC_AHB1ENR_GPIOGEN_BIT)
#define RCC_AHB1ENR_GPIOFEN (1U << RCC_AHB1ENR_GPIOFEN_BIT)
#define RCC_AHB1ENR_GPIOEEN (1U << RCC_AHB1ENR_GPIOEEN_BIT)
#define RCC_AHB1ENR_GPIODEN (1U << RCC_AHB1ENR_GPIODEN_BIT)
#define RCC_AHB1ENR_GPIOCEN (1U << RCC_AHB1ENR_GPIOCEN_BIT)
#define RCC_AHB1ENR_GPIOBEN (1U << RCC_AHB1ENR_GPIOBEN_BIT)
#define RCC_AHB1ENR_GPIOAEN (1U << RCC_AHB1ENR_GPIOAEN_BIT)
/* AHB2 peripheral clock enable register */
#define RCC_AHB2ENR_OTGFSEN_BIT 7
#define RCC_AHB2ENR_RNGEN_BIT 6
#define RCC_AHB2ENR_HASHEN_BIT 5
#define RCC_AHB2ENR_CRYPEN_BIT 4
#define RCC_AHB2ENR_DCMIEN_BIT 0
#define RCC_AHB2ENR_OTGFSEN (1U << RCC_AHB2ENR_OTGFSEN_BIT)
#define RCC_AHB2ENR_RNGEN (1U << RCC_AHB2ENR_RNGEN_BIT)
#define RCC_AHB2ENR_HASHEN (1U << RCC_AHB2ENR_HASHEN_BIT)
#define RCC_AHB2ENR_CRYPEN (1U << RCC_AHB2ENR_CRYPEN_BIT)
#define RCC_AHB2ENR_DCMIEN (1U << RCC_AHB2ENR_DCMIEN_BIT)
/* AHB3 peripheral clock enable register */
#define RCC_AHB3ENR_FSMCEN_BIT 0
#define RCC_AHB3ENR_FSMCEN (1U << RCC_AHB3ENR_FSMCEN_BIT)
/* APB1 peripheral clock enable register */
#define RCC_APB1ENR_DACEN_BIT 29
#define RCC_APB1ENR_PWREN_BIT 28
#define RCC_APB1ENR_CAN2EN_BIT 26
#define RCC_APB1ENR_CAN1EN_BIT 25
#define RCC_APB1ENR_I2C3EN_BIT 23
#define RCC_APB1ENR_I2C2EN_BIT 22
#define RCC_APB1ENR_I2C1EN_BIT 21
#define RCC_APB1ENR_UART5EN_BIT 20
#define RCC_APB1ENR_UART4EN_BIT 19
#define RCC_APB1ENR_USART3EN_BIT 18
#define RCC_APB1ENR_USART2EN_BIT 17
#define RCC_APB1ENR_SPI3EN_BIT 15
#define RCC_APB1ENR_SPI2EN_BIT 14
#define RCC_APB1ENR_WWDGEN_BIT 11
#define RCC_APB1ENR_TIM14EN_BIT 8
#define RCC_APB1ENR_TIM13EN_BIT 7
#define RCC_APB1ENR_TIM12EN_BIT 6
#define RCC_APB1ENR_TIM7EN_BIT 5
#define RCC_APB1ENR_TIM6EN_BIT 4
#define RCC_APB1ENR_TIM5EN_BIT 3
#define RCC_APB1ENR_TIM4EN_BIT 2
#define RCC_APB1ENR_TIM3EN_BIT 1
#define RCC_APB1ENR_TIM2EN_BIT 0
#define RCC_APB1ENR_DACEN (1U << RCC_APB1ENR_DACEN_BIT)
#define RCC_APB1ENR_PWREN (1U << RCC_APB1ENR_PWREN_BIT)
#define RCC_APB1ENR_CAN2EN (1U << RCC_APB1ENR_CAN2EN_BIT)
#define RCC_APB1ENR_CAN1EN (1U << RCC_APB1ENR_CAN1EN_BIT)
#define RCC_APB1ENR_I2C3EN (1U << RCC_APB1ENR_I2C3EN_BIT)
#define RCC_APB1ENR_I2C2EN (1U << RCC_APB1ENR_I2C2EN_BIT)
#define RCC_APB1ENR_I2C1EN (1U << RCC_APB1ENR_I2C1EN_BIT)
#define RCC_APB1ENR_UART5EN (1U << RCC_APB1ENR_UART5EN_BIT)
#define RCC_APB1ENR_UART4EN (1U << RCC_APB1ENR_UART4EN_BIT)
#define RCC_APB1ENR_USART3EN (1U << RCC_APB1ENR_USART3EN_BIT)
#define RCC_APB1ENR_USART2EN (1U << RCC_APB1ENR_USART2EN_BIT)
#define RCC_APB1ENR_SPI3EN (1U << RCC_APB1ENR_SPI3EN_BIT)
#define RCC_APB1ENR_SPI2EN (1U << RCC_APB1ENR_SPI2EN_BIT)
#define RCC_APB1ENR_WWDGEN (1U << RCC_APB1ENR_WWDGEN_BIT)
#define RCC_APB1ENR_TIM14EN (1U << RCC_APB1ENR_TIM14EN_BIT)
#define RCC_APB1ENR_TIM13EN (1U << RCC_APB1ENR_TIM13EN_BIT)
#define RCC_APB1ENR_TIM12EN (1U << RCC_APB1ENR_TIM12EN_BIT)
#define RCC_APB1ENR_TIM7EN (1U << RCC_APB1ENR_TIM7EN_BIT)
#define RCC_APB1ENR_TIM6EN (1U << RCC_APB1ENR_TIM6EN_BIT)
#define RCC_APB1ENR_TIM5EN (1U << RCC_APB1ENR_TIM5EN_BIT)
#define RCC_APB1ENR_TIM4EN (1U << RCC_APB1ENR_TIM4EN_BIT)
#define RCC_APB1ENR_TIM3EN (1U << RCC_APB1ENR_TIM3EN_BIT)
#define RCC_APB1ENR_TIM2EN (1U << RCC_APB1ENR_TIM2EN_BIT)
/* APB2 peripheral clock enable register */
#define RCC_APB2ENR_TIM11EN_BIT 18
#define RCC_APB2ENR_TIM10EN_BIT 17
#define RCC_APB2ENR_TIM9EN_BIT 16
#define RCC_APB2ENR_SYSCFGEN_BIT 14
#define RCC_APB2ENR_SPI1EN_BIT 12
#define RCC_APB2ENR_SDIOEN_BIT 11
#define RCC_APB2ENR_ADC3EN_BIT 10
#define RCC_APB2ENR_ADC2EN_BIT 9
#define RCC_APB2ENR_ADC1EN_BIT 8
#define RCC_APB2ENR_USART6EN_BIT 5
#define RCC_APB2ENR_USART1EN_BIT 4
#define RCC_APB2ENR_TIM8EN_BIT 1
#define RCC_APB2ENR_TIM1EN_BIT 0
#define RCC_APB2ENR_TIM11EN (1U << RCC_APB2ENR_TIM11EN_BIT)
#define RCC_APB2ENR_TIM10EN (1U << RCC_APB2ENR_TIM10EN_BIT)
#define RCC_APB2ENR_TIM9EN (1U << RCC_APB2ENR_TIM9EN_BIT)
#define RCC_APB2ENR_SYSCFGEN (1U << RCC_APB2ENR_SYSCFGEN_BIT)
#define RCC_APB2ENR_SPI1EN (1U << RCC_APB2ENR_SPI1EN_BIT)
#define RCC_APB2ENR_SDIOEN (1U << RCC_APB2ENR_SDIOEN_BIT)
#define RCC_APB2ENR_ADC3EN (1U << RCC_APB2ENR_ADC3EN_BIT)
#define RCC_APB2ENR_ADC2EN (1U << RCC_APB2ENR_ADC2EN_BIT)
#define RCC_APB2ENR_ADC1EN (1U << RCC_APB2ENR_ADC1EN_BIT)
#define RCC_APB2ENR_USART6EN (1U << RCC_APB2ENR_USART6EN_BIT)
#define RCC_APB2ENR_USART1EN (1U << RCC_APB2ENR_USART1EN_BIT)
#define RCC_APB2ENR_TIM8EN (1U << RCC_APB2ENR_TIM8EN_BIT)
#define RCC_APB2ENR_TIM1EN (1U << RCC_APB2ENR_TIM1EN_BIT)
/* AHB1 peripheral clock enable in low power mode register */
#define RCC_AHB1LPENR_OTGHSULPILPEN_BIT 30
#define RCC_AHB1LPENR_OTGHSLPEN_BIT 29
#define RCC_AHB1LPENR_ETHMACPTPLPEN_BIT 28
#define RCC_AHB1LPENR_ETHMACRXLPEN_BIT 27
#define RCC_AHB1LPENR_ETHMACTXLPEN_BIT 26
#define RCC_AHB1LPENR_ETHMACLPEN_BIT 25
#define RCC_AHB1LPENR_DMA2LPEN_BIT 22
#define RCC_AHB1LPENR_DMA1LPEN_BIT 21
#define RCC_AHB1LPENR_BKPSRAMLPEN_BIT 18
#define RCC_AHB1LPENR_SRAM2LPEN_BIT 17
#define RCC_AHB1LPENR_SRAM1LPEN_BIT 16
#define RCC_AHB1LPENR_FLITFLPEN_BIT 15
#define RCC_AHB1LPENR_CRCLPEN_BIT 12
#define RCC_AHB1LPENR_GPIOILPEN_BIT 8
#define RCC_AHB1LPENR_GPIOGLPEN_BIT 6
#define RCC_AHB1LPENR_GPIOFLPEN_BIT 5
#define RCC_AHB1LPENR_GPIOELPEN_BIT 4
#define RCC_AHB1LPENR_GPIODLPEN_BIT 3
#define RCC_AHB1LPENR_GPIOCLPEN_BIT 2
#define RCC_AHB1LPENR_GPIOBLPEN_BIT 1
#define RCC_AHB1LPENR_GPIOALPEN_BIT 0
#define RCC_AHB1LPENR_OTGHSULPILPEN (1U << RCC_AHB1LPENR_OTGHSULPILPEN_BIT)
#define RCC_AHB1LPENR_OTGHSLPEN (1U << RCC_AHB1LPENR_OTGHSLPEN_BIT)
#define RCC_AHB1LPENR_ETHMACPTPLPEN (1U << RCC_AHB1LPENR_ETHMACPTPLPEN_BIT)
#define RCC_AHB1LPENR_ETHMACRXLPEN (1U << RCC_AHB1LPENR_ETHMACRXLPEN_BIT)
#define RCC_AHB1LPENR_ETHMACTXLPEN (1U << RCC_AHB1LPENR_ETHMACTXLPEN_BIT)
#define RCC_AHB1LPENR_ETHMACLPEN (1U << RCC_AHB1LPENR_ETHMACLPEN_BIT)
#define RCC_AHB1LPENR_DMA2LPEN (1U << RCC_AHB1LPENR_DMA2LPEN_BIT)
#define RCC_AHB1LPENR_DMA1LPEN (1U << RCC_AHB1LPENR_DMA1LPEN_BIT)
#define RCC_AHB1LPENR_BKPSRAMLPEN (1U << RCC_AHB1LPENR_BKPSRAMLPEN_BIT)
#define RCC_AHB1LPENR_SRAM2LPEN (1U << RCC_AHB1LPENR_SRAM2LPEN_BIT)
#define RCC_AHB1LPENR_SRAM1LPEN (1U << RCC_AHB1LPENR_SRAM1LPEN_BIT)
#define RCC_AHB1LPENR_FLITFLPEN (1U << RCC_AHB1LPENR_FLITFLPEN_BIT)
#define RCC_AHB1LPENR_CRCLPEN (1U << RCC_AHB1LPENR_CRCLPEN_BIT)
#define RCC_AHB1LPENR_GPIOILPEN (1U << RCC_AHB1LPENR_GPIOILPEN_BIT)
#define RCC_AHB1LPENR_GPIOGLPEN (1U << RCC_AHB1LPENR_GPIOGLPEN_BIT)
#define RCC_AHB1LPENR_GPIOFLPEN (1U << RCC_AHB1LPENR_GPIOFLPEN_BIT)
#define RCC_AHB1LPENR_GPIOELPEN (1U << RCC_AHB1LPENR_GPIOELPEN_BIT)
#define RCC_AHB1LPENR_GPIODLPEN (1U << RCC_AHB1LPENR_GPIODLPEN_BIT)
#define RCC_AHB1LPENR_GPIOCLPEN (1U << RCC_AHB1LPENR_GPIOCLPEN_BIT)
#define RCC_AHB1LPENR_GPIOBLPEN (1U << RCC_AHB1LPENR_GPIOBLPEN_BIT)
#define RCC_AHB1LPENR_GPIOALPEN (1U << RCC_AHB1LPENR_GPIOALPEN_BIT)
/* AHB2 peripheral clock enable in low power mode register */
#define RCC_AHB2LPENR_OTGFSLPEN_BIT 7
#define RCC_AHB2LPENR_RNGLPEN_BIT 6
#define RCC_AHB2LPENR_HASHLPEN_BIT 5
#define RCC_AHB2LPENR_CRYPLPEN_BIT 4
#define RCC_AHB2LPENR_DCMILPEN_BIT 0
#define RCC_AHB2LPENR_OTGFSLPEN (1U << RCC_AHB2LPENR_OTGFSLPEN_BIT)
#define RCC_AHB2LPENR_RNGLPEN (1U << RCC_AHB2LPENR_RNGLPEN_BIT)
#define RCC_AHB2LPENR_HASHLPEN (1U << RCC_AHB2LPENR_HASHLPEN_BIT)
#define RCC_AHB2LPENR_CRYPLPEN (1U << RCC_AHB2LPENR_CRYPLPEN_BIT)
#define RCC_AHB2LPENR_DCMILPEN (1U << RCC_AHB2LPENR_DCMILPEN_BIT)
/* AHB3 peripheral clock enable in low power mode register */
#define RCC_AHB3LPENR_FSMCLPEN_BIT 0
#define RCC_AHB3LPENR_FSMCLPEN (1U << RCC_AHB3LPENR_FSMCLPEN_BIT)
/* APB1 peripheral clock enable in low power mode register */
#define RCC_APB1LPENR_DACLPEN_BIT 29
#define RCC_APB1LPENR_PWRLPEN_BIT 28
#define RCC_APB1LPENR_CAN2LPEN_BIT 26
#define RCC_APB1LPENR_CAN1LPEN_BIT 25
#define RCC_APB1LPENR_I2C3LPEN_BIT 23
#define RCC_APB1LPENR_I2C2LPEN_BIT 22
#define RCC_APB1LPENR_I2C1LPEN_BIT 21
#define RCC_APB1LPENR_UART5LPEN_BIT 20
#define RCC_APB1LPENR_UART4LPEN_BIT 19
#define RCC_APB1LPENR_USART3LPEN_BIT 18
#define RCC_APB1LPENR_USART2LPEN_BIT 17
#define RCC_APB1LPENR_SPI3LPEN_BIT 15
#define RCC_APB1LPENR_SPI2LPEN_BIT 14
#define RCC_APB1LPENR_WWDGLPEN_BIT 11
#define RCC_APB1LPENR_TIM14LPEN_BIT 8
#define RCC_APB1LPENR_TIM13LPEN_BIT 7
#define RCC_APB1LPENR_TIM12LPEN_BIT 6
#define RCC_APB1LPENR_TIM7LPEN_BIT 5
#define RCC_APB1LPENR_TIM6LPEN_BIT 4
#define RCC_APB1LPENR_TIM5LPEN_BIT 3
#define RCC_APB1LPENR_TIM4LPEN_BIT 2
#define RCC_APB1LPENR_TIM3LPEN_BIT 1
#define RCC_APB1LPENR_TIM2LPEN_BIT 0
#define RCC_APB1LPENR_DACLPEN (1U << RCC_APB1LPENR_DACLPEN_BIT)
#define RCC_APB1LPENR_PWRLPEN (1U << RCC_APB1LPENR_PWRLPEN_BIT)
#define RCC_APB1LPENR_CAN2LPEN (1U << RCC_APB1LPENR_CAN2LPEN_BIT)
#define RCC_APB1LPENR_CAN1LPEN (1U << RCC_APB1LPENR_CAN1LPEN_BIT)
#define RCC_APB1LPENR_I2C3LPEN (1U << RCC_APB1LPENR_I2C3LPEN_BIT)
#define RCC_APB1LPENR_I2C2LPEN (1U << RCC_APB1LPENR_I2C2LPEN_BIT)
#define RCC_APB1LPENR_I2C1LPEN (1U << RCC_APB1LPENR_I2C1LPEN_BIT)
#define RCC_APB1LPENR_UART5LPEN (1U << RCC_APB1LPENR_UART5LPEN_BIT)
#define RCC_APB1LPENR_UART4LPEN (1U << RCC_APB1LPENR_UART4LPEN_BIT)
#define RCC_APB1LPENR_USART3LPEN (1U << RCC_APB1LPENR_USART3LPEN_BIT)
#define RCC_APB1LPENR_USART2LPEN (1U << RCC_APB1LPENR_USART2LPEN_BIT)
#define RCC_APB1LPENR_SPI3LPEN (1U << RCC_APB1LPENR_SPI3LPEN_BIT)
#define RCC_APB1LPENR_SPI2LPEN (1U << RCC_APB1LPENR_SPI2LPEN_BIT)
#define RCC_APB1LPENR_WWDGLPEN (1U << RCC_APB1LPENR_WWDGLPEN_BIT)
#define RCC_APB1LPENR_TIM14LPEN (1U << RCC_APB1LPENR_TIM14LPEN_BIT)
#define RCC_APB1LPENR_TIM13LPEN (1U << RCC_APB1LPENR_TIM13LPEN_BIT)
#define RCC_APB1LPENR_TIM12LPEN (1U << RCC_APB1LPENR_TIM12LPEN_BIT)
#define RCC_APB1LPENR_TIM7LPEN (1U << RCC_APB1LPENR_TIM7LPEN_BIT)
#define RCC_APB1LPENR_TIM6LPEN (1U << RCC_APB1LPENR_TIM6LPEN_BIT)
#define RCC_APB1LPENR_TIM5LPEN (1U << RCC_APB1LPENR_TIM5LPEN_BIT)
#define RCC_APB1LPENR_TIM4LPEN (1U << RCC_APB1LPENR_TIM4LPEN_BIT)
#define RCC_APB1LPENR_TIM3LPEN (1U << RCC_APB1LPENR_TIM3LPEN_BIT)
#define RCC_APB1LPENR_TIM2LPEN (1U << RCC_APB1LPENR_TIM2LPEN_BIT)
/* APB2 peripheral clock enable in low power mode register */
#define RCC_APB2LPENR_TIM11LPEN_BIT 18
#define RCC_APB2LPENR_TIM10LPEN_BIT 17
#define RCC_APB2LPENR_TIM9LPEN_BIT 16
#define RCC_APB2LPENR_SYSCFGLPEN_BIT 14
#define RCC_APB2LPENR_SPI1LPEN_BIT 12
#define RCC_APB2LPENR_SDIOLPEN_BIT 11
#define RCC_APB2LPENR_ADC3LPEN_BIT 10
#define RCC_APB2LPENR_ADC2LPEN_BIT 9
#define RCC_APB2LPENR_ADC1LPEN_BIT 8
#define RCC_APB2LPENR_USART6LPEN_BIT 5
#define RCC_APB2LPENR_USART1LPEN_BIT 4
#define RCC_APB2LPENR_TIM8LPEN_BIT 1
#define RCC_APB2LPENR_TIM1LPEN_BIT 0
#define RCC_APB2LPENR_TIM11LPEN (1U << RCC_APB2LPENR_TIM11LPEN_BIT)
#define RCC_APB2LPENR_TIM10LPEN (1U << RCC_APB2LPENR_TIM10LPEN_BIT)
#define RCC_APB2LPENR_TIM9LPEN (1U << RCC_APB2LPENR_TIM9LPEN_BIT)
#define RCC_APB2LPENR_SYSCFGLPEN (1U << RCC_APB2LPENR_SYSCFGLPEN_BIT)
#define RCC_APB2LPENR_SPI1LPEN (1U << RCC_APB2LPENR_SPI1LPEN_BIT)
#define RCC_APB2LPENR_SDIOLPEN (1U << RCC_APB2LPENR_SDIOLPEN_BIT)
#define RCC_APB2LPENR_ADC3LPEN (1U << RCC_APB2LPENR_ADC3LPEN_BIT)
#define RCC_APB2LPENR_ADC2LPEN (1U << RCC_APB2LPENR_ADC2LPEN_BIT)
#define RCC_APB2LPENR_ADC1LPEN (1U << RCC_APB2LPENR_ADC1LPEN_BIT)
#define RCC_APB2LPENR_USART6LPEN (1U << RCC_APB2LPENR_USART6LPEN_BIT)
#define RCC_APB2LPENR_USART1LPEN (1U << RCC_APB2LPENR_USART1LPEN_BIT)
#define RCC_APB2LPENR_TIM8LPEN (1U << RCC_APB2LPENR_TIM8LPEN_BIT)
#define RCC_APB2LPENR_TIM1LPEN (1U << RCC_APB2LPENR_TIM1LPEN_BIT)
/* Backup domain control register */
#define RCC_BDCR_BDRST_BIT 16
#define RCC_BDCR_RTCEN_BIT 15
#define RCC_BDCR_LSEBYP_BIT 2
#define RCC_BDCR_LSERDY_BIT 1
#define RCC_BDCR_LSEON_BIT 0
#define RCC_BDCR_BDRST (1U << RCC_BDCR_BDRST_BIT)
#define RCC_BDCR_RTCEN (1U << RCC_BDCR_RTCEN_BIT)
#define RCC_BDCR_RTCSEL (0x3 << 8)
#define RCC_BDCR_RTCSEL_NOCLOCK (0x0 << 8)
#define RCC_BDCR_RTCSEL_LSE (0x1 << 8)
#define RCC_BDCR_RTCSEL_LSI (0x2 << 8)
#define RCC_BDCR_RTCSEL_HSE_DIV (0x3 << 8)
#define RCC_BDCR_LSEBYP (1U << RCC_BDCR_LSEBYP_BIT)
#define RCC_BDCR_LSERDY (1U << RCC_BDCR_LSERDY_BIT)
#define RCC_BDCR_LSEON (1U << RCC_BDCR_LSEON_BIT)
/* Clock control and status register */
#define RCC_CSR_LPWRRSTF_BIT 31
#define RCC_CSR_WWDGRSTF_BIT 30
#define RCC_CSR_IWDGRSTF_BIT 29
#define RCC_CSR_SFTRSTF_BIT 28
#define RCC_CSR_PORRSTF_BIT 27
#define RCC_CSR_PINRSTF_BIT 26
#define RCC_CSR_BORRSTF_BIT 25
#define RCC_CSR_RMVF_BIT 24
#define RCC_CSR_LSIRDY_BIT 1
#define RCC_CSR_LSION_BIT 0
#define RCC_CSR_LPWRRSTF (1U << RCC_CSR_LPWRRSTF_BIT)
#define RCC_CSR_WWDGRSTF (1U << RCC_CSR_WWDGRSTF_BIT)
#define RCC_CSR_IWDGRSTF (1U << RCC_CSR_IWDGRSTF_BIT)
#define RCC_CSR_SFTRSTF (1U << RCC_CSR_SFTRSTF_BIT)
#define RCC_CSR_PORRSTF (1U << RCC_CSR_PORRSTF_BIT)
#define RCC_CSR_PINRSTF (1U << RCC_CSR_PINRSTF_BIT)
#define RCC_CSR_BORRSTF (1U << RCC_CSR_BORRSTF_BIT)
#define RCC_CSR_RMVF (1U << RCC_CSR_RMVF_BIT)
#define RCC_CSR_LSIRDY (1U << RCC_CSR_LSIRDY_BIT)
#define RCC_CSR_LSION (1U << RCC_CSR_LSION_BIT)
/* Spread spectrum clock generation register */
#define RCC_SSCGR_SSCGEN_BIT 31
#define RCC_SSCGR_SPREADSEL_BIT 30
#define RCC_SSCGR_SSCGEN (1U << RCC_SSCGR_SSCGEN_BIT)
#define RCC_SSCGR_SPREADSEL (1U << RCC_SSCGR_SPREADSEL_BIT)
#define RCC_SSCGR_SPREADSEL_CENTER (0x0 << RCC_SSCGR_SPREADSEL_BIT)
#define RCC_SSCGR_SPREADSEL_DOWN (0x1 << RCC_SSCGR_SPREADSEL_BIT)
#define RCC_SSCGR_INCSTEP (0xFFF << 16)
#define RCC_SSCGR_MODPER 0xFFFF
/* PLLI2S configuration register */
#define RCC_PLLI2SCFGR_PLLI2SR (0x7 << 28)
#define RCC_PLLI2SCFGR_PLLI2SN (0x1FF << 6)
/*
* Clock sources, domains, and peripheral clock IDs.
*/
/**
* @brief STM32F2 clock sources.
*/
typedef enum rcc_clk {
RCC_CLK_PLLI2S = (uint16)((offsetof(struct rcc_reg_map, CR) << 8) |
RCC_CR_PLLI2SON_BIT), /**< Dedicated PLL
for I2S. */
RCC_CLK_PLL = (uint16)((offsetof(struct rcc_reg_map, CR) << 8) |
RCC_CR_PLLON_BIT), /**< Main PLL, clocked by
HSI or HSE. */
RCC_CLK_HSE = (uint16)((offsetof(struct rcc_reg_map, CR) << 8) |
RCC_CR_HSEON_BIT), /**< High speed external. */
RCC_CLK_HSI = (uint16)((offsetof(struct rcc_reg_map, CR) << 8) |
RCC_CR_HSION_BIT), /**< High speed internal. */
RCC_CLK_LSE = (uint16)((offsetof(struct rcc_reg_map, BDCR) << 8) |
RCC_BDCR_LSEON_BIT), /**< Low-speed external
* (32.768 KHz). */
RCC_CLK_LSI = (uint16)((offsetof(struct rcc_reg_map, CSR) << 8) |
RCC_CSR_LSION_BIT), /**< Low-speed internal
* (approximately 32 KHz). */
} rcc_clk;
/**
* @brief STM32F2 rcc_clk_id.
*/
typedef enum rcc_clk_id {
RCC_ADC1,
RCC_ADC2,
RCC_ADC3,
RCC_BKPSRAM,
RCC_CAN1,
RCC_CAN2,
RCC_CRC,
RCC_CRYP,
RCC_DAC,
RCC_DCMI,
RCC_DMA1,
RCC_DMA2,
RCC_ETHMAC,
RCC_ETHMACPTP,
RCC_ETHMACRX,
RCC_ETHMACTX,
RCC_FSMC,
RCC_GPIOA,
RCC_GPIOB,
RCC_GPIOC,
RCC_GPIOD,
RCC_GPIOE,
RCC_GPIOF,
RCC_GPIOG,
RCC_GPIOH,
RCC_GPIOI,
RCC_HASH,
RCC_I2C1,
RCC_I2C2,
RCC_I2C3,
RCC_OTGFS,
RCC_OTGHS,
RCC_OTGHSULPI,
RCC_PWR,
RCC_RNG,
RCC_SDIO,
RCC_SPI1,
RCC_SPI2,
RCC_SPI3,
RCC_SYSCFG,
RCC_TIMER1,
RCC_TIMER10,
RCC_TIMER11,
RCC_TIMER12,
RCC_TIMER13,
RCC_TIMER14,
RCC_TIMER2,
RCC_TIMER3,
RCC_TIMER4,
RCC_TIMER5,
RCC_TIMER6,
RCC_TIMER7,
RCC_TIMER8,
RCC_TIMER9,
RCC_USART1,
RCC_USART2,
RCC_USART3,
RCC_UART4,
RCC_UART5,
RCC_USART6,
RCC_WWDG,
} rcc_clk_id;
/**
* @brief STM32F2 PLL entry clock source
* @see rcc_configure_pll()
*/
typedef enum rcc_pllsrc {
RCC_PLLSRC_HSI = 0,
RCC_PLLSRC_HSE = RCC_PLLCFGR_PLLSRC,
} rcc_pllsrc;
/**
* @brief STM32F2 Peripheral clock domains.
*/
typedef enum rcc_clk_domain {
RCC_APB1,
RCC_APB2,
RCC_AHB1,
RCC_AHB2,
RCC_AHB3,
} rcc_clk_domain;
/*
* Prescalers and dividers.
*/
/**
* @brief STM32F2 Prescaler identifiers.
*/
typedef enum rcc_prescaler {
RCC_PRESCALER_MCO2,
RCC_PRESCALER_MCO1,
RCC_PRESCALER_RTC,
RCC_PRESCALER_APB2,
RCC_PRESCALER_APB1,
RCC_PRESCALER_AHB
} rcc_prescaler;
/**
* @brief STM32F2 MCO2 prescaler dividers.
*/
typedef enum rcc_mco2_divider {
RCC_MCO2_DIV_1 = RCC_CFGR_MCO2PRE_DIV_1,
RCC_MCO2_DIV_2 = RCC_CFGR_MCO2PRE_DIV_2,
RCC_MCO2_DIV_3 = RCC_CFGR_MCO2PRE_DIV_3,
RCC_MCO2_DIV_4 = RCC_CFGR_MCO2PRE_DIV_4,
RCC_MCO2_DIV_5 = RCC_CFGR_MCO2PRE_DIV_5,
} rcc_mco2_divider;
/**
* @brief STM32F2 MCO1 prescaler dividers.
*/
typedef enum rcc_mco1_divider {
RCC_MCO1_DIV_1 = RCC_CFGR_MCO1PRE_DIV_1,
RCC_MCO1_DIV_2 = RCC_CFGR_MCO1PRE_DIV_2,
RCC_MCO1_DIV_3 = RCC_CFGR_MCO1PRE_DIV_3,
RCC_MCO1_DIV_4 = RCC_CFGR_MCO1PRE_DIV_4,
RCC_MCO1_DIV_5 = RCC_CFGR_MCO1PRE_DIV_5,
} rcc_mco1_divider;
/**
* @brief STM32F2 RTC prescaler dividers.
*/
typedef enum rcc_rtc_divider { /* FIXME [0.0.13] TODO */
RCC_RTC_DIV_TODO = 0xFFFFFFFF,
} rcc_rtc_divider;
/**
* @brief STM32F2 AP2 prescaler dividers.
*/
typedef enum rcc_apb2_divider {
RCC_APB2_HCLK_DIV_1 = 0,
RCC_APB2_HCLK_DIV_2 = RCC_CFGR_PPRE2_AHB_DIV_2,
RCC_APB2_HCLK_DIV_4 = RCC_CFGR_PPRE2_AHB_DIV_4,
RCC_APB2_HCLK_DIV_8 = RCC_CFGR_PPRE2_AHB_DIV_8,
RCC_APB2_HCLK_DIV_16 = RCC_CFGR_PPRE2_AHB_DIV_16,
} rcc_apb2_divider;
/**
* @brief STM32F2 APB1 prescaler dividers.
*/
typedef enum rcc_apb1_divider {
RCC_APB1_HCLK_DIV_1 = 0,
RCC_APB1_HCLK_DIV_2 = RCC_CFGR_PPRE1_AHB_DIV_2,
RCC_APB1_HCLK_DIV_4 = RCC_CFGR_PPRE1_AHB_DIV_4,
RCC_APB1_HCLK_DIV_8 = RCC_CFGR_PPRE1_AHB_DIV_8,
RCC_APB1_HCLK_DIV_16 = RCC_CFGR_PPRE1_AHB_DIV_16,
} rcc_apb1_divider;
/**
* @brief STM32F2 AHB prescaler dividers.
*/
typedef enum rcc_ahb_divider {
RCC_AHB_SYSCLK_DIV_1 = 0,
RCC_AHB_SYSCLK_DIV_2 = RCC_CFGR_HPRE_SYSCLK_DIV_2,
RCC_AHB_SYSCLK_DIV_4 = RCC_CFGR_HPRE_SYSCLK_DIV_4,
RCC_AHB_SYSCLK_DIV_8 = RCC_CFGR_HPRE_SYSCLK_DIV_8,
RCC_AHB_SYSCLK_DIV_16 = RCC_CFGR_HPRE_SYSCLK_DIV_16,
RCC_AHB_SYSCLK_DIV_64 = RCC_CFGR_HPRE_SYSCLK_DIV_64,
RCC_AHB_SYSCLK_DIV_128 = RCC_CFGR_HPRE_SYSCLK_DIV_128,
RCC_AHB_SYSCLK_DIV_256 = RCC_CFGR_HPRE_SYSCLK_DIV_256,
RCC_AHB_SYSCLK_DIV_512 = RCC_CFGR_HPRE_SYSCLK_DIV_512,
} rcc_ahb_divider;
/**
* @brief STM32F2 PLL configuration values.
* Point to one of these with the "data" field in a struct rcc_pll_cfg.
* @see struct rcc_pll_cfg.
*/
typedef struct stm32f2_rcc_pll_data {
uint8 pllq; /**<
* @brief PLLQ value.
* Allowed values: 4, 5, ..., 15. */
uint8 pllp; /**<
* @brief PLLP value.
* Allowed values: 2, 4, 6, 8. */
uint16 plln; /**<
* @brief PLLN value.
* Allowed values: 192, 193, ..., 432. */
uint8 pllm; /**<
* @brief PLLM value.
* Allowed values: 2, 3, ..., 63. */
} stm32f2_rcc_pll_data;
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -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 <mbolivar@leaflabs.com>
* @brief STM32F2 SPI/I2S series header.
*/
#ifndef _LIBMAPLE_STM32F2_SPI_H_
#define _LIBMAPLE_STM32F2_SPI_H_
#include <libmaple/gpio.h> /* 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

View File

@@ -0,0 +1,77 @@
/******************************************************************************
* The MIT License
*
* Copyright (c) 2011 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/stm32.h
* @brief STM32F2 chip- and series-specific definitions.
*/
#ifndef _LIBMAPLE_STM32F2_STM32_H_
#define _LIBMAPLE_STM32F2_STM32_H_
#ifdef __cplusplus
extern "C" {
#endif
/*
* Chip configuration
*/
#ifndef STM32_PCLK1
#define STM32_PCLK1 30000000U
#endif
#ifndef STM32_PCLK2
#define STM32_PCLK2 60000000U
#endif
#ifndef STM32_DELAY_US_MULT
#define STM32_DELAY_US_MULT 20 /* FIXME: dummy value. */
#endif
/*
* Series- and MCU-specific values
*/
#define STM32_MCU_SERIES STM32_SERIES_F2
#define STM32_NR_INTERRUPTS 81
#define STM32_HAVE_FSMC 1
#define STM32_HAVE_USB 1
#define STM32_HAVE_DAC 1
#if defined(MCU_STM32F207IC) || defined(MCU_STM32F207IG)
# define STM32_NR_GPIO_PORTS 9
# define STM32_TIMER_MASK 0x7FFE /* TIMER1-TIMER14. */
# define STM32_SRAM_END ((void*)0x20020000)
#else
#warning "Unsupported or unspecified STM32F2 MCU."
#endif
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -0,0 +1,176 @@
/******************************************************************************
* The MIT License
*
* Copyright (c) 2011,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/timer.h
* @author Marti Bolivar <mbolivar@leaflabs.com>
* @brief STM32F2 timer support.
*/
#ifndef _LIBMAPLE_STM32F2_TIMER_H_
#define _LIBMAPLE_STM32F2_TIMER_H_
#include <libmaple/libmaple_types.h>
#include <libmaple/gpio.h> /* for gpio_af */
/*
* Register maps and base pointers
*/
/**
* @brief STM32F2 general purpose timer register map type
*
* Note that not all general purpose timers have all of these
* registers. Consult your chip's reference manual for the details.
*/
typedef struct timer_gen_reg_map {
__io uint32 CR1; /**< Control register 1 */
__io uint32 CR2; /**< Control register 2 */
__io uint32 SMCR; /**< Slave mode control register */
__io uint32 DIER; /**< DMA/Interrupt enable register */
__io uint32 SR; /**< Status register */
__io uint32 EGR; /**< Event generation register */
__io uint32 CCMR1; /**< Capture/compare mode register 1 */
__io uint32 CCMR2; /**< Capture/compare mode register 2 */
__io uint32 CCER; /**< Capture/compare enable register */
__io uint32 CNT; /**< Counter */
__io uint32 PSC; /**< Prescaler */
__io uint32 ARR; /**< Auto-reload register */
const uint32 RESERVED1; /**< Reserved */
__io uint32 CCR1; /**< Capture/compare register 1 */
__io uint32 CCR2; /**< Capture/compare register 2 */
__io uint32 CCR3; /**< Capture/compare register 3 */
__io uint32 CCR4; /**< Capture/compare register 4 */
const uint32 RESERVED2; /**< Reserved */
__io uint32 DCR; /**< DMA control register */
__io uint32 DMAR; /**< DMA address for full transfer */
__io uint32 OR; /**< Option register. */
} timer_gen_reg_map;
struct timer_adv_reg_map;
struct timer_bas_reg_map;
/** Timer 1 register map base pointer */
#define TIMER1_BASE ((struct timer_adv_reg_map*)0x40010000)
/** Timer 2 register map base pointer */
#define TIMER2_BASE ((struct timer_gen_reg_map*)0x40000000)
/** Timer 3 register map base pointer */
#define TIMER3_BASE ((struct timer_gen_reg_map*)0x40000400)
/** Timer 4 register map base pointer */
#define TIMER4_BASE ((struct timer_gen_reg_map*)0x40000800)
/** Timer 5 register map base pointer */
#define TIMER5_BASE ((struct timer_gen_reg_map*)0x40000C00)
/** Timer 6 register map base pointer */
#define TIMER6_BASE ((struct timer_bas_reg_map*)0x40001000)
/** Timer 7 register map base pointer */
#define TIMER7_BASE ((struct timer_bas_reg_map*)0x40001400)
/** Timer 8 register map base pointer */
#define TIMER8_BASE ((struct timer_adv_reg_map*)0x40010400)
/** Timer 9 register map base pointer */
#define TIMER9_BASE ((struct timer_gen_reg_map*)0x40014000)
/** Timer 10 register map base pointer */
#define TIMER10_BASE ((struct timer_gen_reg_map*)0x40014400)
/** Timer 11 register map base pointer */
#define TIMER11_BASE ((struct timer_gen_reg_map*)0x40014800)
/** Timer 12 register map base pointer */
#define TIMER12_BASE ((struct timer_gen_reg_map*)0x40001800)
/** Timer 13 register map base pointer */
#define TIMER13_BASE ((struct timer_gen_reg_map*)0x40001C00)
/** Timer 14 register map base pointer */
#define TIMER14_BASE ((struct timer_gen_reg_map*)0x40002000)
/*
* Register bit definitions
*/
/* TIM2 option register */
/** Timer 2 option register internal trigger 1 remap */
#define TIMER2_OR_ITR1_RMP (0x3 << 10)
/** Timer 2 OR internal trigger 1: TIM8_TRGOUT */
#define TIMER2_OR_ITR1_RMP_TIM8_TRGOUT (0x0 << 10)
/** Timer 2 OR internal trigger 1: Ethernet PTP trigger output */
#define TIMER2_OR_ITR1_RMP_PTP_TRGOUT (0x1 << 10)
/** Timer 2 OR internal trigger 1: USB OTG full speed start of frame */
#define TIMER2_OR_ITR1_RMP_OTG_FS_SOF (0x2 << 10)
/** Timer 2 OR internal trigger 1: USB OTG high speed start of frame */
#define TIMER2_OR_ITR1_RMP_OTG_HS_SOF (0x3 << 10)
/* TIM5 option register */
/**
* Timer 5 option register input 4 remap.
*
* These bits control whether TIM5_CH4 is connected to a GPIO or a
* clock. Connecting to a GPIO is the normal mode, useful for e.g. PWM
* generation or input pulse duration measurement. Connecting to a
* clock is useful for calibrating that clock.
*/
#define TIMER5_OR_TI4_RMP (0x3 << 6)
/**
* Timer 5 OR input 4: Timer 5 channel 4 connected to GPIO. */
#define TIMER5_OR_TI4_RMP_GPIO (0x0 << 6)
/**
* Timer 5 OR input 4: low speed internal clock (LSI) is connected to
* TIM5_CH4. */
#define TIMER5_OR_TI4_RMP_LSI (0x1 << 6)
/**
* Timer 5 OR input 4: low speed external clock (LSE) is connected to
* TIM5_CH4. */
#define TIMER5_OR_TI4_RMP_LSE (0x2 << 6)
/**
* Timer 5 OR input 4: real time clock (RTC) output is connected to
* TIM5_CH4. */
#define TIMER5_OR_TI4_RMP_RTC (0x3 << 6)
/*
* Device pointers
*/
struct timer_dev;
extern struct timer_dev *TIMER1;
extern struct timer_dev *TIMER2;
extern struct timer_dev *TIMER3;
extern struct timer_dev *TIMER4;
extern struct timer_dev *TIMER5;
extern struct timer_dev *TIMER6;
extern struct timer_dev *TIMER7;
extern struct timer_dev *TIMER8;
extern struct timer_dev *TIMER9;
extern struct timer_dev *TIMER10;
extern struct timer_dev *TIMER11;
extern struct timer_dev *TIMER12;
extern struct timer_dev *TIMER13;
extern struct timer_dev *TIMER14;
/*
* Routines
*/
gpio_af timer_get_af(struct timer_dev *dev);
#endif

View File

@@ -0,0 +1,111 @@
/******************************************************************************
* 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/usart.h
* @author Marti Bolivar <mbolivar@leaflabs.com>
* @brief STM32F2 USART support.
*/
#ifndef _LIBMAPLE_STM32F2_USART_H_
#define _LIBMAPLE_STM32F2_USART_H_
#ifdef __cplusplus
extern "C"{
#endif
#include <libmaple/gpio.h> /* for gpio_af */
/*
* Register map base pointers.
*/
struct usart_reg_map;
/** USART1 register map base pointer */
#define USART1_BASE ((struct usart_reg_map*)0x40011000)
/** USART2 register map base pointer */
#define USART2_BASE ((struct usart_reg_map*)0x40004400)
/** USART3 register map base pointer */
#define USART3_BASE ((struct usart_reg_map*)0x40004800)
/** UART4 register map base pointer */
#define UART4_BASE ((struct usart_reg_map*)0x40004C00)
/** UART5 register map base pointer */
#define UART5_BASE ((struct usart_reg_map*)0x40005000)
/** USART6 register map base pointer */
#define USART6_BASE ((struct usart_reg_map*)0x40011400)
/*
* F2-only register bit definitions.
*/
/* Control register 1 */
/**
* @brief Oversampling mode bit.
* Availability: STM32F2. */
#define USART_CR1_OVER8_BIT 15
/**
* @brief Oversampling mode.
* Availability: STM32F2. */
#define USART_CR1_OVER8 (1U << USART_CR1_OVER8_BIT)
/* Control register 3 */
/** One sample bit method enable bit. */
#define USART_CR3_ONEBIT_BIT 11
/** One bit sample method enable. */
#define USART_CR3_ONEBIT (1 << USART_CR3_ONEBIT_BIT)
/** Sample method: Three sample bit method. */
#define USART_CR3_ONEBIT_3SAMPLE (0 << USART_CR3_ONEBIT_BIT)
/** Sample method: One sample bit method. */
#define USART_CR3_ONEBIT_1SAMPLE (1 << USART_CR3_ONEBIT_BIT)
/*
* Devices
*/
struct usart_dev;
extern struct usart_dev *USART1;
extern struct usart_dev *USART2;
extern struct usart_dev *USART3;
extern struct usart_dev *UART4;
extern struct usart_dev *UART5;
extern struct usart_dev *USART6;
/*
* Routines
*/
gpio_af usart_get_af(struct usart_dev *dev);
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -0,0 +1,40 @@
# Standard things
sp := $(sp).x
dirstack_$(sp) := $(d)
d := $(dir)
BUILDDIRS += $(BUILD_PATH)/$(d)
# Local flags
CFLAGS_$(d) = -I$(d) $(LIBMAPLE_INCLUDES) $(LIBMAPLE_PRIVATE_INCLUDES) -Wall -Werror
# Local rules and targets
sSRCS_$(d) := isrs.S
sSRCS_$(d) += vector_table.S
cSRCS_$(d) := adc.c
cSRCS_$(d) += dma.c
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
sFILES_$(d) := $(sSRCS_$(d):%=$(d)/%)
cFILES_$(d) := $(cSRCS_$(d):%=$(d)/%)
OBJS_$(d) := $(sFILES_$(d):%.S=$(BUILD_PATH)/%.o) \
$(cFILES_$(d):%.c=$(BUILD_PATH)/%.o)
DEPS_$(d) := $(OBJS_$(d):%.o=%.d)
$(OBJS_$(d)): TGT_ASFLAGS :=
$(OBJS_$(d)): TGT_CFLAGS := $(CFLAGS_$(d))
TGT_BIN += $(OBJS_$(d))
# Standard things
-include $(DEPS_$(d))
d := $(dirstack_$(sp))
sp := $(basename $(sp))

View File

@@ -0,0 +1,235 @@
/******************************************************************************
* The MIT License
*
* Copyright (c) 2011, 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/timer_private.h
* @author Marti Bolivar <mbolivar@leaflabs.com>
* @brief Private, internal timer APIs.
*/
#ifndef _LIBMAPLE_TIMER_PRIVATE_H_
#define _LIBMAPLE_TIMER_PRIVATE_H_
/*
* Helper macros for declaring timer_devs of various timer_types
*/
/* The indexes of user handlers in a timer_dev.handlers are just like
* the corresponding DIER bits, as follows: */
/* Advanced timers:
* [0] = Update handler;
* [1,2,3,4] = capture/compare 1,2,3,4 handlers, respectively;
* [5] = COM;
* [6] = TRG;
* [7] = BRK. */
#define NR_ADV_HANDLERS 8
/* General purpose timers:
* [0] = update;
* [1,2,3,4] = capture/compare 1,2,3,4;
* [5] = <junk>;
* [6] = trigger. */
#define NR_GEN_HANDLERS 7
/* Basic timers:
* [0] = update. */
#define NR_BAS_HANDLERS 1
/* For declaring advanced timers. */
#define ADVANCED_TIMER(num) \
{ \
.regs = { .adv = TIMER##num##_BASE }, \
.clk_id = RCC_TIMER##num, \
.type = TIMER_ADVANCED, \
.handlers = { [NR_ADV_HANDLERS - 1] = 0 }, \
}
/* For declaring full-featured general purpose timers. */
#define GENERAL_TIMER(num) \
{ \
.regs = { .gen = TIMER##num##_BASE }, \
.clk_id = RCC_TIMER##num, \
.type = TIMER_GENERAL, \
.handlers = { [NR_GEN_HANDLERS - 1] = 0 }, \
}
/* For declaring general purpose timers with limited interrupt
* capability (e.g. timers 9 through 14 on STM32F2 and XL-density
* STM32F1). */
#define RESTRICTED_GENERAL_TIMER(num, max_dier_bit) \
{ \
.regs = { .gen = TIMER##num##_BASE }, \
.clk_id = RCC_TIMER##num, \
.type = TIMER_GENERAL, \
.handlers = { [max_dier_bit] = 0 }, \
}
/* For declaring basic timers (e.g. TIM6 and TIM7). */
#define BASIC_TIMER(num) \
{ \
.regs = { .bas = TIMER##num##_BASE }, \
.clk_id = RCC_TIMER##num, \
.type = TIMER_BASIC, \
.handlers = { [NR_BAS_HANDLERS - 1] = 0 }, \
}
/*
* IRQ handlers
*
* These decode TIMx_DIER and TIMx_SR, then dispatch to the user-level
* IRQ handlers. They also clean up TIMx_SR afterwards, so the user
* doesn't have to deal with register details.
*
* Notes:
*
* - These dispatch routines make use of the fact that DIER interrupt
* enable bits and SR interrupt flags have common bit positions.
* Thus, ANDing DIER and SR lets us check if an interrupt is enabled
* and if it has occurred simultaneously.
*
* - We force these routines to inline to avoid call overhead, but
* there aren't any measurements to prove that this is actually a
* good idea. Profile-directed optimizations are definitely wanted. */
/* A special-case dispatch routine for timers which only serve a
* single interrupt on a given IRQ line.
*
* This function still checks DIER & SR, as in some cases, a timer may
* only serve a single interrupt on a particular NVIC line, but that
* line may be shared with another timer. For example, the timer 1
* update interrupt shares an IRQ line with the timer 10 interrupt on
* STM32F1 (XL-density), STM32F2, and STM32F4. */
static inline __always_inline void dispatch_single_irq(timer_dev *dev,
timer_interrupt_id iid,
uint32 irq_mask) {
timer_bas_reg_map *regs = (dev->regs).bas;
if (regs->DIER & regs->SR & irq_mask) {
void (*handler)(void) = dev->handlers[iid];
if (handler) {
handler();
regs->SR &= ~irq_mask;
}
}
}
/* Helper macro for dispatch routines which service multiple interrupts. */
#define handle_irq(dier_sr, irq_mask, handlers, iid, handled_irq) do { \
if ((dier_sr) & (irq_mask)) { \
void (*__handler)(void) = (handlers)[iid]; \
if (__handler) { \
__handler(); \
handled_irq |= (irq_mask); \
} \
} \
} while (0)
static inline __always_inline void dispatch_adv_brk(timer_dev *dev) {
dispatch_single_irq(dev, TIMER_BREAK_INTERRUPT, TIMER_SR_BIF);
}
static inline __always_inline void dispatch_adv_up(timer_dev *dev) {
dispatch_single_irq(dev, TIMER_UPDATE_INTERRUPT, TIMER_SR_UIF);
}
static inline __always_inline void dispatch_adv_trg_com(timer_dev *dev) {
timer_adv_reg_map *regs = (dev->regs).adv;
uint32 dsr = regs->DIER & regs->SR;
void (**hs)(void) = dev->handlers;
uint32 handled = 0; /* Logical OR of SR interrupt flags we end up
* handling. We clear these. User handlers
* must clear overcapture flags, to avoid
* wasting time in output mode. */
handle_irq(dsr, TIMER_SR_TIF, hs, TIMER_TRG_INTERRUPT, handled);
handle_irq(dsr, TIMER_SR_COMIF, hs, TIMER_COM_INTERRUPT, handled);
regs->SR &= ~handled;
}
static inline __always_inline void dispatch_adv_cc(timer_dev *dev) {
timer_adv_reg_map *regs = (dev->regs).adv;
uint32 dsr = regs->DIER & regs->SR;
void (**hs)(void) = dev->handlers;
uint32 handled = 0;
handle_irq(dsr, TIMER_SR_CC4IF, hs, TIMER_CC4_INTERRUPT, handled);
handle_irq(dsr, TIMER_SR_CC3IF, hs, TIMER_CC3_INTERRUPT, handled);
handle_irq(dsr, TIMER_SR_CC2IF, hs, TIMER_CC2_INTERRUPT, handled);
handle_irq(dsr, TIMER_SR_CC1IF, hs, TIMER_CC1_INTERRUPT, handled);
regs->SR &= ~handled;
}
static inline __always_inline void dispatch_general(timer_dev *dev) {
timer_gen_reg_map *regs = (dev->regs).gen;
uint32 dsr = regs->DIER & regs->SR;
void (**hs)(void) = dev->handlers;
uint32 handled = 0;
handle_irq(dsr, TIMER_SR_TIF, hs, TIMER_TRG_INTERRUPT, handled);
handle_irq(dsr, TIMER_SR_CC4IF, hs, TIMER_CC4_INTERRUPT, handled);
handle_irq(dsr, TIMER_SR_CC3IF, hs, TIMER_CC3_INTERRUPT, handled);
handle_irq(dsr, TIMER_SR_CC2IF, hs, TIMER_CC2_INTERRUPT, handled);
handle_irq(dsr, TIMER_SR_CC1IF, hs, TIMER_CC1_INTERRUPT, handled);
handle_irq(dsr, TIMER_SR_UIF, hs, TIMER_UPDATE_INTERRUPT, handled);
regs->SR &= ~handled;
}
/* On F1 (XL-density), F2, and F4, TIM9 and TIM12 are restricted
* general-purpose timers with update, CC1, CC2, and TRG interrupts. */
static inline __always_inline void dispatch_tim_9_12(timer_dev *dev) {
timer_gen_reg_map *regs = (dev->regs).gen;
uint32 dsr = regs->DIER & regs->SR;
void (**hs)(void) = dev->handlers;
uint32 handled = 0;
handle_irq(dsr, TIMER_SR_TIF, hs, TIMER_TRG_INTERRUPT, handled);
handle_irq(dsr, TIMER_SR_CC2IF, hs, TIMER_CC2_INTERRUPT, handled);
handle_irq(dsr, TIMER_SR_CC1IF, hs, TIMER_CC1_INTERRUPT, handled);
handle_irq(dsr, TIMER_SR_UIF, hs, TIMER_UPDATE_INTERRUPT, handled);
regs->SR &= ~handled;
}
/* On F1 (XL-density), F2, and F4, timers 10, 11, 13, and 14 are
* restricted general-purpose timers with update and CC1 interrupts. */
static inline __always_inline void dispatch_tim_10_11_13_14(timer_dev *dev) {
timer_gen_reg_map *regs = (dev->regs).gen;
uint32 dsr = regs->DIER & regs->SR;
void (**hs)(void) = dev->handlers;
uint32 handled = 0;
handle_irq(dsr, TIMER_SR_CC1IF, hs, TIMER_CC1_INTERRUPT, handled);
handle_irq(dsr, TIMER_SR_UIF, hs, TIMER_UPDATE_INTERRUPT, handled);
regs->SR &= ~handled;
}
static inline __always_inline void dispatch_basic(timer_dev *dev) {
dispatch_single_irq(dev, TIMER_UPDATE_INTERRUPT, TIMER_SR_UIF);
}
#endif

View File

@@ -0,0 +1,67 @@
/******************************************************************************
* The MIT License
*
* Copyright (c) 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/usart_private.h
* @author Marti Bolivar <mbolivar@leaflabs.com>
* @brief Private USART header.
*/
#ifndef _LIBMAPLE_USART_PRIVATE_H_
#define _LIBMAPLE_USART_PRIVATE_H_
#include <libmaple/ring_buffer.h>
#include <libmaple/usart.h>
static inline __always_inline void usart_irq(ring_buffer *rb, ring_buffer *wb, usart_reg_map *regs) {
/* Handling RXNEIE and TXEIE interrupts.
* RXNE signifies availability of a byte in DR.
*
* See table 198 (sec 27.4, p809) in STM document RM0008 rev 15.
* We enable RXNEIE. */
if ((regs->CR1 & USART_CR1_RXNEIE) && (regs->SR & USART_SR_RXNE)) {
#ifdef USART_SAFE_INSERT
/* If the buffer is full and the user defines USART_SAFE_INSERT,
* ignore new bytes. */
rb_safe_insert(rb, (uint8)regs->DR);
#else
/* By default, push bytes around in the ring buffer. */
rb_push_insert(rb, (uint8)regs->DR);
#endif
}
/* TXE signifies readiness to send a byte to DR. */
if ((regs->CR1 & USART_CR1_TXEIE) && (regs->SR & USART_SR_TXE)) {
if (!rb_is_empty(wb))
regs->DR=rb_remove(wb);
else
regs->CR1 &= ~((uint32)USART_CR1_TXEIE); // disable TXEIE
}
}
uint32 _usart_clock_freq(usart_dev *dev);
#endif

View File

@@ -0,0 +1,63 @@
The USB submodule of libmaple is a separate piece of the codebase for
reasons that are largely historical.
Current Status:
There's only support for the USB device peripheral found on
STM32F103s.
We rely on the low level core library provided by ST to implement
the USB transfer protocol for control endpoint transfers.
The virtual com port (which is exposed via
<libmaple/usb_cdcacm.h>) serves two important purposes.
1) It allows serial data transfers between user sketches an a
host computer.
2) It allows the host PC to issue a system reset into the DFU
bootloader with the DTR + RTS + "1EAF" sequence (see
leaflabs.com/docs/bootloader.html for more information on
this).
After reset, Maple will run the DFU bootloader for a few seconds,
during which the user can begin a DFU upload operation (uploads
application binary into RAM/FLASH). Thus, without this virtual com
port, it would be necessary to find an alternative means to reset
the chip in order to enable the bootloader.
If you would like to develop your own USB application for whatever
reason (e.g. to use faster isochronous enpoints for streaming
audio, or implement the USB HID or Mass Storage specs), then
ensure that you leave some hook for resetting Maple remotely in
order to spin up the DFU bootloader. Please make sure to get
yourself a unique vendor/product ID pair for your application, as
some operating systems will assign a host-side driver based on
these tags.
It would be possible to build a compound USB device, that
implements endpoints for both the virtual COM port as well as some
other components (mass storage etc.). However, this turns out to
be a burden from the host driver side, as Windows and *nix handle
compound USB devices quite differently.
Be mindful that enabling the USB peripheral isn't "free." The
device must respond to periodic bus activity (every few
milliseconds) by servicing an ISR. Therefore, the USB application
should be disabled inside of timing critical applications.
In order to disconnect the device from the host, a USB_DISC pin is
asserted (e.g. on Maple, this is PC12). Alternatively, the NVIC
can be directly configured to disable the USB LP/HP IRQ's.
The files inside of usb_lib were provided by ST and are subject to
their own license, all other files were written by the LeafLabs
team and fall under the MIT license.
TODO:
- Generic USB driver core with series-provided backends, like
libopencm3 has.
- Strip out ST code.
- Integration with a high level USB library (like LUFA/MyUSB) to
allow users to write custom USB applications.

View File

@@ -0,0 +1,45 @@
# Standard things
sp := $(sp).x
dirstack_$(sp) := $(d)
d := $(dir)
BUILDDIRS += $(BUILD_PATH)/$(d)
# Local flags
CFLAGS_$(d) = -I$(d) -I$(d)/$(MCU_SERIES) -I$(d)/usb_lib $(LIBMAPLE_INCLUDES) $(LIBMAPLE_PRIVATE_INCLUDES) -Wall
# Add usblib and series subdirectory to BUILDDIRS.
BUILDDIRS += $(BUILD_PATH)/$(d)/$(MCU_SERIES)
BUILDDIRS += $(BUILD_PATH)/$(d)/usb_lib
# Local rules and targets
sSRCS_$(d) :=
cSRCS_$(d) :=
# We currently only have F1 performance line support. Sigh.
ifeq ($(MCU_SERIES), stm32f1)
ifeq ($(MCU_F1_LINE), performance)
cSRCS_$(d) += $(MCU_SERIES)/usb.c
cSRCS_$(d) += $(MCU_SERIES)/usb_reg_map.c
cSRCS_$(d) += $(MCU_SERIES)/usb_cdcacm.c
cSRCS_$(d) += usb_lib/usb_core.c
cSRCS_$(d) += usb_lib/usb_init.c
cSRCS_$(d) += usb_lib/usb_mem.c
cSRCS_$(d) += usb_lib/usb_regs.c
endif
endif
sFILES_$(d) := $(sSRCS_$(d):%=$(d)/%)
cFILES_$(d) := $(cSRCS_$(d):%=$(d)/%)
OBJS_$(d) := $(sFILES_$(d):%.S=$(BUILD_PATH)/%.o) \
$(cFILES_$(d):%.c=$(BUILD_PATH)/%.o)
DEPS_$(d) := $(OBJS_$(d):%.o=%.d)
$(OBJS_$(d)): TGT_CFLAGS := $(CFLAGS_$(d))
$(OBJS_$(d)): TGT_ASFLAGS :=
TGT_BIN += $(OBJS_$(d))
# Standard things
-include $(DEPS_$(d))
d := $(dirstack_$(sp))
sp := $(basename $(sp))

View File

@@ -0,0 +1,55 @@
/******************************************************************************
* The MIT License
*
* Copyright (c) 2011 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 _USB_LIB_GLOBALS_H_
#define _USB_LIB_GLOBALS_H_
/* usb_lib headers */
#include "usb_type.h"
#include "usb_core.h"
#ifdef __cplusplus
extern "C" {
#endif
extern USER_STANDARD_REQUESTS User_Standard_Requests;
extern USER_STANDARD_REQUESTS *pUser_Standard_Requests;
extern DEVICE_PROP Device_Property;
extern DEVICE_PROP *pProperty;
extern DEVICE_INFO Device_Info;
extern DEVICE_INFO *pInformation;
extern DEVICE Device_Table;
extern u16 SaveRState;
extern u16 SaveTState;
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -0,0 +1,617 @@
/******************************************************************************
* The MIT License
*
* Copyright (c) 2011 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.
*****************************************************************************/
#include <libmaple/libmaple_types.h>
#include <libmaple/util.h>
#ifndef _USB_REG_MAP_H_
#define _USB_REG_MAP_H_
/* TODO:
* - Pick one of "endp", "ep" "endpt"
*/
/*
* Register map and base pointer
*/
#define USB_NR_EP_REGS 8
/** USB register map type */
typedef struct usb_reg_map {
__io uint32 EP[USB_NR_EP_REGS]; /**< Endpoint registers */
const uint32 RESERVED[8]; /**< Reserved */
__io uint32 CNTR; /**< Control register */
__io uint32 ISTR; /**< Interrupt status register */
__io uint32 FNR; /**< Frame number register */
__io uint32 DADDR; /**< Device address */
__io uint32 BTABLE; /**< @brief Buffer table address
*
* Address offset within the USB
* packet memory area which points
* to the base of the buffer
* descriptor table. Must be
* aligned to an 8 byte boundary.
*/
} usb_reg_map;
/** USB register map base pointer */
#define USB_BASE ((struct usb_reg_map*)0x40005C00)
/*
* Register bit definitions
*/
/* Endpoint registers (USB_EPnR) */
#define USB_EP_CTR_RX_BIT 15
#define USB_EP_DTOG_RX_BIT 14
#define USB_EP_SETUP_BIT 11
#define USB_EP_EP_KIND_BIT 8
#define USB_EP_CTR_TX_BIT 7
#define USB_EP_DTOG_TX_BIT 6
#define USB_EP_CTR_RX BIT(USB_EP_CTR_RX_BIT)
#define USB_EP_DTOG_RX BIT(USB_EP_DTOG_RX_BIT)
#define USB_EP_STAT_RX (0x3 << 12)
#define USB_EP_STAT_RX_DISABLED (0x0 << 12)
#define USB_EP_STAT_RX_STALL (0x1 << 12)
#define USB_EP_STAT_RX_NAK (0x2 << 12)
#define USB_EP_STAT_RX_VALID (0x3 << 12)
#define USB_EP_SETUP BIT(USB_EP_SETUP_BIT)
#define USB_EP_EP_TYPE (0x3 << 9)
#define USB_EP_EP_TYPE_BULK (0x0 << 9)
#define USB_EP_EP_TYPE_CONTROL (0x1 << 9)
#define USB_EP_EP_TYPE_ISO (0x2 << 9)
#define USB_EP_EP_TYPE_INTERRUPT (0x3 << 9)
#define USB_EP_EP_KIND BIT(USB_EP_EP_KIND_BIT)
#define USB_EP_EP_KIND_DBL_BUF (0x1 << USB_EP_EP_KIND_BIT)
#define USB_EP_CTR_TX BIT(USB_EP_CTR_TX_BIT)
#define USB_EP_DTOG_TX BIT(USB_EP_DTOG_TX_BIT)
#define USB_EP_STAT_TX (0x3 << 4)
#define USB_EP_STAT_TX_DISABLED (0x0 << 4)
#define USB_EP_STAT_TX_STALL (0x1 << 4)
#define USB_EP_STAT_TX_NAK (0x2 << 4)
#define USB_EP_STAT_TX_VALID (0x3 << 4)
#define USB_EP_EA 0xF
/* Control register (USB_CNTR) */
#define USB_CNTR_CTRM_BIT 15
#define USB_CNTR_PMAOVERM_BIT 14
#define USB_CNTR_ERRM_BIT 13
#define USB_CNTR_WKUPM_BIT 12
#define USB_CNTR_SUSPM_BIT 11
#define USB_CNTR_RESETM_BIT 10
#define USB_CNTR_SOFM_BIT 9
#define USB_CNTR_ESOFM_BIT 8
#define USB_CNTR_RESUME_BIT 4
#define USB_CNTR_FSUSP_BIT 3
#define USB_CNTR_LP_MODE_BIT 2
#define USB_CNTR_PDWN_BIT 1
#define USB_CNTR_FRES_BIT 0
#define USB_CNTR_CTRM BIT(USB_CNTR_CTRM_BIT)
#define USB_CNTR_PMAOVERM BIT(USB_CNTR_PMAOVERM_BIT)
#define USB_CNTR_ERRM BIT(USB_CNTR_ERRM_BIT)
#define USB_CNTR_WKUPM BIT(USB_CNTR_WKUPM_BIT)
#define USB_CNTR_SUSPM BIT(USB_CNTR_SUSPM_BIT)
#define USB_CNTR_RESETM BIT(USB_CNTR_RESETM_BIT)
#define USB_CNTR_SOFM BIT(USB_CNTR_SOFM_BIT)
#define USB_CNTR_ESOFM BIT(USB_CNTR_ESOFM_BIT)
#define USB_CNTR_RESUME BIT(USB_CNTR_RESUME_BIT)
#define USB_CNTR_FSUSP BIT(USB_CNTR_FSUSP_BIT)
#define USB_CNTR_LP_MODE BIT(USB_CNTR_LP_MODE_BIT)
#define USB_CNTR_PDWN BIT(USB_CNTR_PDWN_BIT)
#define USB_CNTR_FRES BIT(USB_CNTR_FRES_BIT)
/* Interrupt status register (USB_ISTR) */
#define USB_ISTR_CTR_BIT 15
#define USB_ISTR_PMAOVR_BIT 14
#define USB_ISTR_ERR_BIT 13
#define USB_ISTR_WKUP_BIT 12
#define USB_ISTR_SUSP_BIT 11
#define USB_ISTR_RESET_BIT 10
#define USB_ISTR_SOF_BIT 9
#define USB_ISTR_ESOF_BIT 8
#define USB_ISTR_DIR_BIT 4
#define USB_ISTR_CTR BIT(USB_ISTR_CTR_BIT)
#define USB_ISTR_PMAOVR BIT(USB_ISTR_PMAOVR_BIT)
#define USB_ISTR_ERR BIT(USB_ISTR_ERR_BIT)
#define USB_ISTR_WKUP BIT(USB_ISTR_WKUP_BIT)
#define USB_ISTR_SUSP BIT(USB_ISTR_SUSP_BIT)
#define USB_ISTR_RESET BIT(USB_ISTR_RESET_BIT)
#define USB_ISTR_SOF BIT(USB_ISTR_SOF_BIT)
#define USB_ISTR_ESOF BIT(USB_ISTR_ESOF_BIT)
#define USB_ISTR_DIR BIT(USB_ISTR_DIR_BIT)
#define USB_ISTR_EP_ID 0xF
/* Frame number register (USB_FNR) */
#define USB_FNR_RXDP_BIT 15
#define USB_FNR_RXDM_BIT 14
#define USB_FNR_LCK_BIT 13
#define USB_FNR_RXDP BIT(USB_FNR_RXDP_BIT)
#define USB_FNR_RXDM BIT(USB_FNR_RXDM_BIT)
#define USB_FNR_LCK BIT(USB_FNR_LCK_BIT)
#define USB_FNR_LSOF (0x3 << 11)
#define USB_FNR_FN 0x7FF
/* Device address (USB_DADDR) */
#define USB_DADDR_EF_BIT 7
#define USB_DADDR_ADD6_BIT 6
#define USB_DADDR_ADD5_BIT 5
#define USB_DADDR_ADD4_BIT 4
#define USB_DADDR_ADD3_BIT 3
#define USB_DADDR_ADD2_BIT 2
#define USB_DADDR_ADD1_BIT 1
#define USB_DADDR_ADD0_BIT 0
#define USB_DADDR_EF BIT(USB_DADDR_EF_BIT)
#define USB_DADDR_ADD6 BIT(USB_DADDR_ADD6_BIT)
#define USB_DADDR_ADD5 BIT(USB_DADDR_ADD5_BIT)
#define USB_DADDR_ADD4 BIT(USB_DADDR_ADD4_BIT)
#define USB_DADDR_ADD3 BIT(USB_DADDR_ADD3_BIT)
#define USB_DADDR_ADD2 BIT(USB_DADDR_ADD2_BIT)
#define USB_DADDR_ADD1 BIT(USB_DADDR_ADD1_BIT)
#define USB_DADDR_ADD0 BIT(USB_DADDR_ADD0_BIT)
/* Buffer table address (USB_BTABLE) */
#define USB_BTABLE_BTABLE (0x1FFF << 3)
/*
* Register convenience routines
*/
#define __EP_CTR_NOP (USB_EP_CTR_RX | USB_EP_CTR_TX)
#define __EP_NONTOGGLE (USB_EP_CTR_RX | USB_EP_SETUP | \
USB_EP_EP_TYPE | USB_EP_EP_KIND | \
USB_EP_CTR_TX | USB_EP_EA)
static inline void usb_clear_ctr_rx(uint8 ep) {
uint32 epr = USB_BASE->EP[ep];
USB_BASE->EP[ep] = epr & ~USB_EP_CTR_RX & __EP_NONTOGGLE;
}
static inline void usb_clear_ctr_tx(uint8 ep) {
uint32 epr = USB_BASE->EP[ep];
USB_BASE->EP[ep] = epr & ~USB_EP_CTR_TX & __EP_NONTOGGLE;
}
static inline uint32 usb_get_ep_dtog_tx(uint8 ep) {
uint32 epr = USB_BASE->EP[ep];
return epr & USB_EP_DTOG_TX;
}
static inline uint32 usb_get_ep_dtog_rx(uint8 ep) {
uint32 epr = USB_BASE->EP[ep];
return epr & USB_EP_DTOG_RX;
}
static inline uint32 usb_get_ep_tx_sw_buf(uint8 ep) {
return usb_get_ep_dtog_rx(ep);
}
static inline uint32 usb_get_ep_rx_sw_buf(uint8 ep) {
return usb_get_ep_dtog_tx(ep);
}
static inline void usb_toggle_ep_dtog_tx(uint8 ep) {
uint32 epr = USB_BASE->EP[ep];
epr &= __EP_NONTOGGLE;
epr |= USB_EP_DTOG_TX;
USB_BASE->EP[ep] = epr;
}
static inline void usb_toggle_ep_dtog_rx(uint8 ep) {
uint32 epr = USB_BASE->EP[ep];
epr &= __EP_NONTOGGLE;
epr |= USB_EP_DTOG_RX;
USB_BASE->EP[ep] = epr;
}
static inline void usb_clear_ep_dtog_tx(uint8 ep) {
if (usb_get_ep_dtog_tx(ep) != 0) {
usb_toggle_ep_dtog_tx(ep);
}
}
static inline void usb_clear_ep_dtog_rx(uint8 ep) {
if (usb_get_ep_dtog_rx(ep) != 0) {
usb_toggle_ep_dtog_rx(ep);
}
}
static inline void usb_set_ep_dtog_tx(uint8 ep) {
if (usb_get_ep_dtog_tx(ep) == 0) {
usb_toggle_ep_dtog_tx(ep);
}
}
static inline void usb_set_ep_dtog_rx(uint8 ep) {
if (usb_get_ep_dtog_rx(ep) == 0) {
usb_toggle_ep_dtog_rx(ep);
}
}
static inline void usb_toggle_ep_rx_sw_buf(uint8 ep) {
usb_toggle_ep_dtog_tx(ep);
}
static inline void usb_toggle_ep_tx_sw_buf(uint8 ep) {
usb_toggle_ep_dtog_rx(ep);
}
static inline void usb_clear_ep_rx_sw_buf(uint8 ep) {
usb_clear_ep_dtog_tx(ep);
}
static inline void usb_clear_ep_tx_sw_buf(uint8 ep) {
usb_clear_ep_dtog_rx(ep);
}
static inline void usb_set_ep_rx_sw_buf(uint8 ep) {
usb_set_ep_dtog_tx(ep);
}
static inline void usb_set_ep_tx_sw_buf(uint8 ep) {
usb_set_ep_dtog_rx(ep);
}
static inline void usb_set_ep_rx_stat(uint8 ep, uint32 status) {
uint32 epr = USB_BASE->EP[ep];
epr &= ~(USB_EP_STAT_TX | USB_EP_DTOG_RX | USB_EP_DTOG_TX);
epr |= __EP_CTR_NOP;
epr ^= status;
USB_BASE->EP[ep] = epr;
}
static inline void usb_set_ep_tx_stat(uint8 ep, uint32 status) {
uint32 epr = USB_BASE->EP[ep];
epr &= ~(USB_EP_STAT_RX | USB_EP_DTOG_RX | USB_EP_DTOG_TX);
epr |= __EP_CTR_NOP;
epr ^= status;
USB_BASE->EP[ep] = epr;
}
static inline void usb_set_ep_type(uint8 ep, uint32 type) {
uint32 epr = USB_BASE->EP[ep];
epr &= ~USB_EP_EP_TYPE & __EP_NONTOGGLE;
epr |= type;
USB_BASE->EP[ep] = epr;
}
static inline void usb_set_ep_kind(uint8 ep, uint32 kind) {
uint32 epr = USB_BASE->EP[ep];
epr &= ~USB_EP_EP_KIND & __EP_NONTOGGLE;
epr |= kind;
USB_BASE->EP[ep] = epr;
}
static inline uint32 usb_get_ep_type(uint8 ep) {
uint32 epr = USB_BASE->EP[ep];
return epr & USB_EP_EP_TYPE;
}
static inline uint32 usb_get_ep_kind(uint8 ep) {
uint32 epr = USB_BASE->EP[ep];
return epr & USB_EP_EP_TYPE;
}
static inline void usb_clear_status_out(uint8 ep) {
usb_set_ep_kind(ep, 0);
}
/*
* Packet memory area (PMA) base pointer
*/
/**
* @brief USB packet memory area (PMA) base pointer.
*
* The USB PMA is SRAM shared between USB and CAN. The USB peripheral
* accesses this memory directly via the packet buffer interface. */
#define USB_PMA_BASE ((__io void*)0x40006000)
/*
* PMA conveniences
*/
/*
void usb_copy_to_pma(const uint8 *buf, uint16 len, uint16 pma_offset);
void usb_copy_from_pma(uint8 *buf, uint16 len, uint16 pma_offset);
*/
static inline uint32 * usb_pma_ptr(uint32 offset) {
return (uint32*)(USB_PMA_BASE + 2 * offset);
}
/*
* BTABLE
*/
/* (Forward-declared) BTABLE entry.
*
* The BTABLE can be viewed as an array of usb_btable_ent values;
* these vary in structure according to the configuration of the
* endpoint.
*/
union usb_btable_ent;
/* Bidirectional endpoint BTABLE entry */
typedef struct usb_btable_bidi {
__io uint16 addr_tx; const uint16 PAD1;
__io uint16 count_tx; const uint16 PAD2;
__io uint16 addr_rx; const uint16 PAD3;
__io uint16 count_rx; const uint16 PAD4;
} usb_btable_bidi;
/* Unidirectional receive-only endpoint BTABLE entry */
typedef struct usb_btable_uni_rx {
__io uint16 empty1; const uint16 PAD1;
__io uint16 empty2; const uint16 PAD2;
__io uint16 addr_rx; const uint16 PAD3;
__io uint16 count_rx; const uint16 PAD4;
} usb_btable_uni_rx;
/* Unidirectional transmit-only endpoint BTABLE entry */
typedef struct usb_btable_uni_tx {
__io uint16 addr_tx; const uint16 PAD1;
__io uint16 count_tx; const uint16 PAD2;
__io uint16 empty1; const uint16 PAD3;
__io uint16 empty2; const uint16 PAD4;
} usb_btable_uni_tx;
/* Double-buffered transmission endpoint BTABLE entry */
typedef struct usb_btable_dbl_tx {
__io uint16 addr_tx0; const uint16 PAD1;
__io uint16 count_tx0; const uint16 PAD2;
__io uint16 addr_tx1; const uint16 PAD3;
__io uint16 count_tx1; const uint16 PAD4;
} usb_btable_dbl_tx;
/* Double-buffered reception endpoint BTABLE entry */
typedef struct usb_btable_dbl_rx {
__io uint16 addr_rx0; const uint16 PAD1;
__io uint16 count_rx0; const uint16 PAD2;
__io uint16 addr_rx1; const uint16 PAD3;
__io uint16 count_rx1; const uint16 PAD4;
} usb_btable_dbl_rx;
/* TODO isochronous endpoint entries */
/* Definition for above forward-declared BTABLE entry. */
typedef union usb_btable_ent {
usb_btable_bidi bidi;
usb_btable_uni_rx u_rx;
usb_btable_uni_tx u_tx;
usb_btable_dbl_tx d_tx;
usb_btable_dbl_rx d_rx;
} usb_btable_ent;
/*
* BTABLE conveniences
*/
/* TODO (?) Convert usages of the many (and lengthily-named)
* accessors/mutators below to just manipulating usb_btable_entry
* values. */
static inline uint32* usb_btable_ptr(uint32 offset) {
return (uint32*)usb_pma_ptr(USB_BASE->BTABLE + offset);
}
/* TX address */
static inline uint32* usb_ep_tx_addr_ptr(uint8 ep) {
return usb_btable_ptr(ep * 8);
}
static inline uint16 usb_get_ep_tx_addr(uint8 ep) {
return (uint16)*usb_ep_tx_addr_ptr(ep);
}
static inline void usb_set_ep_tx_addr(uint8 ep, uint16 addr) {
volatile uint32 *tx_addr = usb_ep_tx_addr_ptr(ep);
*tx_addr = addr & ~0x1;
}
/* RX address */
static inline uint32* usb_ep_rx_addr_ptr(uint8 ep) {
return usb_btable_ptr(ep * 8 + 4);
}
static inline uint16 usb_get_ep_rx_addr(uint8 ep) {
return (uint16)*usb_ep_rx_addr_ptr(ep);
}
static inline void usb_set_ep_rx_addr(uint8 ep, uint16 addr) {
volatile uint32 *rx_addr = usb_ep_rx_addr_ptr(ep);
*rx_addr = addr & ~0x1;
}
/* TX count (doesn't cover double-buffered and isochronous in) */
static inline uint32* usb_ep_tx_count_ptr(uint8 ep) {
return usb_btable_ptr(ep * 8 + 2);
}
static inline uint16 usb_get_ep_tx_count(uint8 ep) {
/* FIXME: this is broken somehow; calling it seems to
* confuse/crash the chip. */
return (uint16)(*usb_ep_tx_count_ptr(ep) & 0x3FF);
}
static inline void usb_set_ep_tx_count(uint8 ep, uint16 count) {
volatile uint32 *txc = usb_ep_tx_count_ptr(ep);
*txc = count;
}
/* RX count */
static inline uint32* usb_ep_rx_count_ptr(uint8 ep) {
return usb_btable_ptr(ep * 8 + 6);
}
static inline uint16 usb_get_ep_rx_count(uint8 ep) {
return (uint16)*usb_ep_rx_count_ptr(ep) & 0x3FF;
}
void usb_set_ep_rx_count(uint8 ep, uint16 count);
/* double buffer definitions */
static inline uint32* usb_get_ep_tx_buf0_addr_ptr(uint8 ep) {
return usb_ep_tx_addr_ptr(ep);
}
static inline uint16 usb_get_ep_tx_buf0_addr(uint8 ep) {
return usb_get_ep_tx_addr(ep);
}
static inline void usb_set_ep_tx_buf0_addr(uint8 ep, uint16 addr) {
usb_set_ep_tx_addr(ep, addr);
}
static inline uint32* usb_get_ep_tx_buf1_addr_ptr(uint8 ep) {
return usb_ep_rx_addr_ptr(ep);
}
static inline uint16 usb_get_ep_tx_buf1_addr(uint8 ep) {
return usb_get_ep_rx_addr(ep);
}
static inline void usb_set_ep_tx_buf1_addr(uint8 ep, uint16 addr) {
usb_set_ep_rx_addr(ep, addr);
}
static inline uint32* usb_ep_tx_buf0_count_ptr(uint8 ep) {
return usb_ep_tx_count_ptr(ep);
}
static inline uint16 usb_get_ep_tx_buf0_count(uint8 ep) {
return usb_get_ep_tx_count(ep);
}
static inline void usb_set_ep_tx_buf0_count(uint8 ep, uint16 count) {
usb_set_ep_tx_count(ep, count);
}
static inline uint32* usb_ep_tx_buf1_count_ptr(uint8 ep) {
return usb_ep_rx_count_ptr(ep);
}
static inline uint16 usb_get_ep_tx_buf1_count(uint8 ep) {
return usb_get_ep_rx_count(ep);
}
static inline void usb_set_ep_tx_buf1_count(uint8 ep, uint16 count) {
usb_set_ep_rx_count(ep, count);
}
static inline uint32* usb_get_ep_rx_buf0_addr_ptr(uint8 ep) {
return usb_ep_tx_addr_ptr(ep);
}
static inline uint16 usb_get_ep_rx_buf0_addr(uint8 ep) {
return usb_get_ep_tx_addr(ep);
}
static inline void usb_set_ep_rx_buf0_addr(uint8 ep, uint16 addr) {
usb_set_ep_tx_addr(ep, addr);
}
static inline uint32* usb_get_ep_rx_buf1_addr_ptr(uint8 ep) {
return usb_ep_rx_addr_ptr(ep);
}
static inline uint16 usb_get_ep_rx_buf1_addr(uint8 ep) {
return usb_get_ep_rx_addr(ep);
}
static inline void usb_set_ep_rx_buf1_addr(uint8 ep, uint16 addr) {
usb_set_ep_rx_addr(ep, addr);
}
static inline uint32* usb_ep_rx_buf0_count_ptr(uint8 ep) {
return usb_ep_tx_count_ptr(ep);
}
static inline uint16 usb_get_ep_rx_buf0_count(uint8 ep) {
return usb_get_ep_tx_count(ep);
}
//void usb_set_ep_rx_buf0_count(uint8 ep, uint16 count);
static inline uint32* usb_ep_rx_buf1_count_ptr(uint8 ep) {
return usb_ep_rx_count_ptr(ep);
}
static inline uint16 usb_get_ep_rx_buf1_count(uint8 ep) {
return usb_get_ep_rx_count(ep);
}
static inline void usb_set_ep_rx_buf1_count(uint8 ep, uint16 count) {
usb_set_ep_rx_count(ep, count);
}
/*
* Misc. types
*/
typedef enum usb_ep {
USB_EP0,
USB_EP1,
USB_EP2,
USB_EP3,
USB_EP4,
USB_EP5,
USB_EP6,
USB_EP7,
} usb_ep;
typedef enum usb_ep_type {
USB_EP_T_CTL = USB_EP_EP_TYPE_CONTROL,
USB_EP_T_BULK = USB_EP_EP_TYPE_BULK,
USB_EP_T_INT = USB_EP_EP_TYPE_INTERRUPT,
USB_EP_T_ISO = USB_EP_EP_TYPE_ISO
} usb_ep_type;
typedef enum usb_ep_stat {
USB_EP_ST_RX_DIS = USB_EP_STAT_RX_DISABLED,
USB_EP_ST_RX_STL = USB_EP_STAT_RX_STALL,
USB_EP_ST_RX_NAK = USB_EP_STAT_RX_NAK,
USB_EP_ST_RX_VAL = USB_EP_STAT_RX_VALID,
USB_EP_ST_TX_DIS = USB_EP_STAT_TX_DISABLED,
USB_EP_ST_TX_STL = USB_EP_STAT_TX_STALL,
USB_EP_ST_TX_NAK = USB_EP_STAT_TX_NAK,
USB_EP_ST_TX_VAL = USB_EP_STAT_TX_VALID
} usb_ep_stat;
#endif

View File

@@ -0,0 +1,254 @@
/******************** (C) COPYRIGHT 2008 STMicroelectronics ********************
* File Name : usb_core.h
* Author : MCD Application Team
* Version : V2.2.1
* Date : 09/22/2008
* Description : Standard protocol processing functions prototypes
********************************************************************************
* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME.
* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT,
* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE
* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING
* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
*******************************************************************************/
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __USB_CORE_H
#define __USB_CORE_H
#if defined(__cplusplus)
extern "C" {
#endif
/* Includes ------------------------------------------------------------------*/
/* Exported types ------------------------------------------------------------*/
typedef enum _CONTROL_STATE
{
WAIT_SETUP, /* 0 */
SETTING_UP, /* 1 */
IN_DATA, /* 2 */
OUT_DATA, /* 3 */
LAST_IN_DATA, /* 4 */
LAST_OUT_DATA, /* 5 */
WAIT_STATUS_IN, /* 7 */
WAIT_STATUS_OUT, /* 8 */
STALLED, /* 9 */
PAUSE /* 10 */
} CONTROL_STATE; /* The state machine states of a control pipe */
typedef struct OneDescriptor
{
u8 *Descriptor;
u16 Descriptor_Size;
}
ONE_DESCRIPTOR, *PONE_DESCRIPTOR;
/* All the request process routines return a value of this type
If the return value is not SUCCESS or NOT_READY,
the software will STALL the correspond endpoint */
typedef enum _RESULT
{
USB_SUCCESS = 0, /* Process sucessfully */
USB_ERROR,
USB_UNSUPPORT,
USB_NOT_READY /* The process has not been finished, endpoint will be
NAK to further rquest */
} RESULT;
/*-*-*-*-*-*-*-*-*-*-* Definitions for endpoint level -*-*-*-*-*-*-*-*-*-*-*-*/
typedef struct _ENDPOINT_INFO
{
/* When send data out of the device,
CopyData() is used to get data buffer 'Length' bytes data
if Length is 0,
CopyData() returns the total length of the data
if the request is not supported, returns 0
(NEW Feature )
if CopyData() returns -1, the calling routine should not proceed
further and will resume the SETUP process by the class device
if Length is not 0,
CopyData() returns a pointer to indicate the data location
Usb_wLength is the data remain to be sent,
Usb_wOffset is the Offset of original data
When receive data from the host,
CopyData() is used to get user data buffer which is capable
of Length bytes data to copy data from the endpoint buffer.
if Length is 0,
CopyData() returns the available data length,
if Length is not 0,
CopyData() returns user buffer address
Usb_rLength is the data remain to be received,
Usb_rPointer is the Offset of data buffer
*/
u16 Usb_wLength;
u16 Usb_wOffset;
u16 PacketSize;
u8 *(*CopyData)(u16 Length);
}ENDPOINT_INFO;
/*-*-*-*-*-*-*-*-*-*-*-* Definitions for device level -*-*-*-*-*-*-*-*-*-*-*-*/
typedef struct _DEVICE
{
u8 Total_Endpoint; /* Number of endpoints that are used */
u8 Total_Configuration;/* Number of configuration available */
}
DEVICE;
typedef union
{
u16 w;
struct BW
{
/* Little Endian */
u8 bb0;
u8 bb1;
}
bw;
} u16_u8;
typedef struct _DEVICE_INFO
{
u8 USBbmRequestType; /* bmRequestType */
u8 USBbRequest; /* bRequest */
u16_u8 USBwValues; /* wValue */
u16_u8 USBwIndexs; /* wIndex */
u16_u8 USBwLengths; /* wLength */
u8 ControlState; /* of type CONTROL_STATE */
u8 Current_Feature;
u8 Current_Configuration; /* Selected configuration */
u8 Current_Interface; /* Selected interface of current configuration */
u8 Current_AlternateSetting;/* Selected Alternate Setting of current
interface*/
ENDPOINT_INFO Ctrl_Info;
}DEVICE_INFO;
typedef struct _DEVICE_PROP
{
void (*Init)(void); /* Initialize the device */
void (*Reset)(void); /* Reset routine of this device */
/* Device dependent process after the status stage */
void (*Process_Status_IN)(void);
void (*Process_Status_OUT)(void);
/* Procedure of process on setup stage of a class specified request with data stage */
/* All class specified requests with data stage are processed in Class_Data_Setup
Class_Data_Setup()
responses to check all special requests and fills ENDPOINT_INFO
according to the request
If IN tokens are expected, then wLength & wOffset will be filled
with the total transferring bytes and the starting position
If OUT tokens are expected, then rLength & rOffset will be filled
with the total expected bytes and the starting position in the buffer
If the request is valid, Class_Data_Setup returns SUCCESS, else UNSUPPORT
CAUTION:
Since GET_CONFIGURATION & GET_INTERFACE are highly related to
the individual classes, they will be checked and processed here.
*/
RESULT (*Class_Data_Setup)(u8 RequestNo);
/* Procedure of process on setup stage of a class specified request without data stage */
/* All class specified requests without data stage are processed in Class_NoData_Setup
Class_NoData_Setup
responses to check all special requests and perform the request
CAUTION:
Since SET_CONFIGURATION & SET_INTERFACE are highly related to
the individual classes, they will be checked and processed here.
*/
RESULT (*Class_NoData_Setup)(u8 RequestNo);
/*Class_Get_Interface_Setting
This function is used by the file usb_core.c to test if the selected Interface
and Alternate Setting (u8 Interface, u8 AlternateSetting) are supported by
the application.
This function is writing by user. It should return "SUCCESS" if the Interface
and Alternate Setting are supported by the application or "UNSUPPORT" if they
are not supported. */
RESULT (*Class_Get_Interface_Setting)(u8 Interface, u8 AlternateSetting);
u8* (*GetDeviceDescriptor)(u16 Length);
u8* (*GetConfigDescriptor)(u16 Length);
u8* (*GetStringDescriptor)(u16 Length);
u8* RxEP_buffer;
u8 MaxPacketSize;
}DEVICE_PROP;
typedef struct _USER_STANDARD_REQUESTS
{
void (*User_GetConfiguration)(void); /* Get Configuration */
void (*User_SetConfiguration)(void); /* Set Configuration */
void (*User_GetInterface)(void); /* Get Interface */
void (*User_SetInterface)(void); /* Set Interface */
void (*User_GetStatus)(void); /* Get Status */
void (*User_ClearFeature)(void); /* Clear Feature */
void (*User_SetEndPointFeature)(void); /* Set Endpoint Feature */
void (*User_SetDeviceFeature)(void); /* Set Device Feature */
void (*User_SetDeviceAddress)(void); /* Set Device Address */
}
USER_STANDARD_REQUESTS;
/* Exported constants --------------------------------------------------------*/
#define Type_Recipient (pInformation->USBbmRequestType & (REQUEST_TYPE | RECIPIENT))
#define Usb_rLength Usb_wLength
#define Usb_rOffset Usb_wOffset
#define USBwValue USBwValues.w
#define USBwValue0 USBwValues.bw.bb0
#define USBwValue1 USBwValues.bw.bb1
#define USBwIndex USBwIndexs.w
#define USBwIndex0 USBwIndexs.bw.bb0
#define USBwIndex1 USBwIndexs.bw.bb1
#define USBwLength USBwLengths.w
#define USBwLength0 USBwLengths.bw.bb0
#define USBwLength1 USBwLengths.bw.bb1
#define StatusInfo0 StatusInfo.bw.bb0
#define StatusInfo1 StatusInfo.bw.bb1
/* Exported macro ------------------------------------------------------------*/
/* Exported functions ------------------------------------------------------- */
u8 Setup0_Process(void);
u8 Post0_Process(void);
u8 Out0_Process(void);
u8 In0_Process(void);
RESULT Standard_SetEndPointFeature(void);
RESULT Standard_SetDeviceFeature(void);
u8 *Standard_GetConfiguration(u16 Length);
RESULT Standard_SetConfiguration(void);
u8 *Standard_GetInterface(u16 Length);
RESULT Standard_SetInterface(void);
u8 *Standard_GetDescriptorData(u16 Length, PONE_DESCRIPTOR pDesc);
u8 *Standard_GetStatus(u16 Length);
RESULT Standard_ClearFeature(void);
void SetDeviceAddress(u8);
void NOP_Process(void);
extern DEVICE_PROP Device_Property;
extern USER_STANDARD_REQUESTS User_Standard_Requests;
extern DEVICE Device_Table;
extern DEVICE_INFO Device_Info;
/* cells saving status during interrupt servicing */
extern u16 SaveRState;
extern u16 SaveTState;
#if defined(__cplusplus)
}
#endif
#endif /* __USB_CORE_H */
/******************* (C) COPYRIGHT 2008 STMicroelectronics *****END OF FILE****/

View File

@@ -0,0 +1,88 @@
/******************** (C) COPYRIGHT 2008 STMicroelectronics ********************
* File Name : usb_def.h
* Author : MCD Application Team
* Version : V2.2.1
* Date : 09/22/2008
* Description : Definitions related to USB Core
********************************************************************************
* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME.
* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT,
* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE
* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING
* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
*******************************************************************************/
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __USB_DEF_H
#define __USB_DEF_H
#if defined(__cplusplus)
extern "C" {
#endif
/* Includes ------------------------------------------------------------------*/
/* Exported types ------------------------------------------------------------*/
typedef enum _RECIPIENT_TYPE
{
DEVICE_RECIPIENT, /* Recipient device */
INTERFACE_RECIPIENT, /* Recipient interface */
ENDPOINT_RECIPIENT, /* Recipient endpoint */
OTHER_RECIPIENT
} RECIPIENT_TYPE;
typedef enum _STANDARD_REQUESTS
{
GET_STATUS = 0,
CLEAR_FEATURE,
RESERVED1,
SET_FEATURE,
RESERVED2,
SET_ADDRESS,
GET_DESCRIPTOR,
SET_DESCRIPTOR,
GET_CONFIGURATION,
SET_CONFIGURATION,
GET_INTERFACE,
SET_INTERFACE,
TOTAL_sREQUEST, /* Total number of Standard request */
SYNCH_FRAME = 12
} STANDARD_REQUESTS;
/* Definition of "USBwValue" */
typedef enum _DESCRIPTOR_TYPE
{
DEVICE_DESCRIPTOR = 1,
CONFIG_DESCRIPTOR,
STRING_DESCRIPTOR,
INTERFACE_DESCRIPTOR,
ENDPOINT_DESCRIPTOR
} DESCRIPTOR_TYPE;
/* Feature selector of a SET_FEATURE or CLEAR_FEATURE */
typedef enum _FEATURE_SELECTOR
{
ENDPOINT_STALL,
DEVICE_REMOTE_WAKEUP
} FEATURE_SELECTOR;
/* Exported constants --------------------------------------------------------*/
/* Definition of "USBbmRequestType" */
#define REQUEST_TYPE 0x60 /* Mask to get request type */
#define STANDARD_REQUEST 0x00 /* Standard request */
#define CLASS_REQUEST 0x20 /* Class request */
#define VENDOR_REQUEST 0x40 /* Vendor request */
#define RECIPIENT 0x1F /* Mask to get recipient */
/* Exported macro ------------------------------------------------------------*/
/* Exported functions ------------------------------------------------------- */
#if defined(__cplusplus)
}
#endif
#endif /* __USB_DEF_H */
/******************* (C) COPYRIGHT 2008 STMicroelectronics *****END OF FILE****/

View File

@@ -0,0 +1,57 @@
/******************** (C) COPYRIGHT 2008 STMicroelectronics ********************
* File Name : usb_init.h
* Author : MCD Application Team
* Version : V2.2.1
* Date : 09/22/2008
* Description : Initialization routines & global variables
********************************************************************************
* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME.
* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT,
* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE
* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING
* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
*******************************************************************************/
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __USB_INIT_H
#define __USB_INIT_H
#if defined(__cplusplus)
extern "C" {
#endif
/* Includes ------------------------------------------------------------------*/
/* Exported types ------------------------------------------------------------*/
/* Exported constants --------------------------------------------------------*/
/* Exported macro ------------------------------------------------------------*/
/* Exported functions ------------------------------------------------------- */
void USB_Init(void);
/* External variables --------------------------------------------------------*/
/* The number of current endpoint, it will be used to specify an endpoint */
extern u8 EPindex;
/* The number of current device, it is an index to the Device_Table */
/*extern u8 Device_no; */
/* Points to the DEVICE_INFO structure of current device */
/* The purpose of this register is to speed up the execution */
extern DEVICE_INFO* pInformation;
/* Points to the DEVICE_PROP structure of current device */
/* The purpose of this register is to speed up the execution */
extern DEVICE_PROP* pProperty;
/* Temporary save the state of Rx & Tx status. */
/* Whenever the Rx or Tx state is changed, its value is saved */
/* in this variable first and will be set to the EPRB or EPRA */
/* at the end of interrupt process */
extern USER_STANDARD_REQUESTS *pUser_Standard_Requests;
extern u16 SaveState ;
extern u16 wInterrupt_Mask;
#if defined(__cplusplus)
}
#endif
#endif /* __USB_INIT_H */
/******************* (C) COPYRIGHT 2008 STMicroelectronics *****END OF FILE****/

View File

@@ -0,0 +1,36 @@
/******************** (C) COPYRIGHT 2008 STMicroelectronics ********************
* File Name : usb_lib.h
* Author : MCD Application Team
* Version : V2.2.1
* Date : 09/22/2008
* Description : USB library include files
********************************************************************************
* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME.
* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT,
* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE
* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING
* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
*******************************************************************************/
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __USB_LIB_H
#define __USB_LIB_H
/* Includes ------------------------------------------------------------------*/
#include "usb_type.h"
#include "usb_regs.h"
#include "usb_def.h"
#include "usb_core.h"
#include "usb_init.h"
#include "usb_mem.h"
/* Exported types ------------------------------------------------------------*/
/* Exported constants --------------------------------------------------------*/
/* Exported macro ------------------------------------------------------------*/
/* Exported functions ------------------------------------------------------- */
/* External variables --------------------------------------------------------*/
#endif /* __USB_LIB_H */
/******************* (C) COPYRIGHT 2008 STMicroelectronics *****END OF FILE****/

View File

@@ -0,0 +1,40 @@
/******************** (C) COPYRIGHT 2008 STMicroelectronics ********************
* File Name : usb_mem.h
* Author : MCD Application Team
* Version : V2.2.1
* Date : 09/22/2008
* Description : Utility prototypes functions for memory/PMA transfers
********************************************************************************
* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME.
* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT,
* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE
* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING
* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
*******************************************************************************/
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __USB_MEM_H
#define __USB_MEM_H
/* Includes ------------------------------------------------------------------*/
/* Exported types ------------------------------------------------------------*/
/* Exported constants --------------------------------------------------------*/
/* Exported macro ------------------------------------------------------------*/
/* Exported functions ------------------------------------------------------- */
#if defined(__cplusplus)
extern "C" {
#endif
void UserToPMABufferCopy(const u8 *pbUsrBuf, u16 wPMABufAddr, u16 wNBytes);
void PMAToUserBufferCopy(u8 *pbUsrBuf, u16 wPMABufAddr, u16 wNBytes);
#if defined(__cplusplus)
}
#endif
/* External variables --------------------------------------------------------*/
#endif /*__USB_MEM_H*/
/******************* (C) COPYRIGHT 2008 STMicroelectronics *****END OF FILE****/

View File

@@ -0,0 +1,627 @@
/******************** (C) COPYRIGHT 2008 STMicroelectronics ********************
* File Name : usb_regs.h
* Author : MCD Application Team
* Version : V2.2.1
* Date : 09/22/2008
* Description : Interface prototype functions to USB cell registers
********************************************************************************
* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME.
* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT,
* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE
* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING
* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
*******************************************************************************/
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __USB_REGS_H
#define __USB_REGS_H
/* Includes ------------------------------------------------------------------*/
/* Exported types ------------------------------------------------------------*/
#if defined(__cplusplus)
extern "C" {
#endif
typedef enum _EP_DBUF_DIR
{
/* double buffered endpoint direction */
EP_DBUF_ERR,
EP_DBUF_OUT,
EP_DBUF_IN
}EP_DBUF_DIR;
/* endpoint buffer number */
enum EP_BUF_NUM
{
EP_NOBUF,
EP_BUF0,
EP_BUF1
};
/* Exported constants --------------------------------------------------------*/
#define RegBase (0x40005C00L) /* USB_IP Peripheral Registers base address */
#define PMAAddr (0x40006000L) /* USB_IP Packet Memory Area base address */
/******************************************************************************/
/* General registers */
/******************************************************************************/
/* Control register */
#define CNTR ((volatile unsigned *)(RegBase + 0x40))
/* Interrupt status register */
#define ISTR ((volatile unsigned *)(RegBase + 0x44))
/* Frame number register */
#define FNR ((volatile unsigned *)(RegBase + 0x48))
/* Device address register */
#define DADDR ((volatile unsigned *)(RegBase + 0x4C))
/* Buffer Table address register */
#define BTABLE ((volatile unsigned *)(RegBase + 0x50))
/******************************************************************************/
/* Endpoint registers */
/******************************************************************************/
#define EP0REG ((volatile unsigned *)(RegBase)) /* endpoint 0 register address */
/* endpoints enumeration */
#define ENDP0 ((u8)0)
#define ENDP1 ((u8)1)
#define ENDP2 ((u8)2)
#define ENDP3 ((u8)3)
#define ENDP4 ((u8)4)
#define ENDP5 ((u8)5)
#define ENDP6 ((u8)6)
#define ENDP7 ((u8)7)
/******************************************************************************/
/* ISTR interrupt events */
/******************************************************************************/
#define ISTR_CTR (0x8000) /* Correct TRansfer (clear-only bit) */
#define ISTR_DOVR (0x4000) /* DMA OVeR/underrun (clear-only bit) */
#define ISTR_ERR (0x2000) /* ERRor (clear-only bit) */
#define ISTR_WKUP (0x1000) /* WaKe UP (clear-only bit) */
#define ISTR_SUSP (0x0800) /* SUSPend (clear-only bit) */
#define ISTR_RESET (0x0400) /* RESET (clear-only bit) */
#define ISTR_SOF (0x0200) /* Start Of Frame (clear-only bit) */
#define ISTR_ESOF (0x0100) /* Expected Start Of Frame (clear-only bit) */
#define ISTR_DIR (0x0010) /* DIRection of transaction (read-only bit) */
#define ISTR_EP_ID (0x000F) /* EndPoint IDentifier (read-only bit) */
#define CLR_CTR (~ISTR_CTR) /* clear Correct TRansfer bit */
#define CLR_DOVR (~ISTR_DOVR) /* clear DMA OVeR/underrun bit*/
#define CLR_ERR (~ISTR_ERR) /* clear ERRor bit */
#define CLR_WKUP (~ISTR_WKUP) /* clear WaKe UP bit */
#define CLR_SUSP (~ISTR_SUSP) /* clear SUSPend bit */
#define CLR_RESET (~ISTR_RESET) /* clear RESET bit */
#define CLR_SOF (~ISTR_SOF) /* clear Start Of Frame bit */
#define CLR_ESOF (~ISTR_ESOF) /* clear Expected Start Of Frame bit */
/******************************************************************************/
/* CNTR control register bits definitions */
/******************************************************************************/
#define CNTR_CTRM (0x8000) /* Correct TRansfer Mask */
#define CNTR_DOVRM (0x4000) /* DMA OVeR/underrun Mask */
#define CNTR_ERRM (0x2000) /* ERRor Mask */
#define CNTR_WKUPM (0x1000) /* WaKe UP Mask */
#define CNTR_SUSPM (0x0800) /* SUSPend Mask */
#define CNTR_RESETM (0x0400) /* RESET Mask */
#define CNTR_SOFM (0x0200) /* Start Of Frame Mask */
#define CNTR_ESOFM (0x0100) /* Expected Start Of Frame Mask */
#define CNTR_RESUME (0x0010) /* RESUME request */
#define CNTR_FSUSP (0x0008) /* Force SUSPend */
#define CNTR_LPMODE (0x0004) /* Low-power MODE */
#define CNTR_PDWN (0x0002) /* Power DoWN */
#define CNTR_FRES (0x0001) /* Force USB RESet */
/******************************************************************************/
/* FNR Frame Number Register bit definitions */
/******************************************************************************/
#define FNR_RXDP (0x8000) /* status of D+ data line */
#define FNR_RXDM (0x4000) /* status of D- data line */
#define FNR_LCK (0x2000) /* LoCKed */
#define FNR_LSOF (0x1800) /* Lost SOF */
#define FNR_FN (0x07FF) /* Frame Number */
/******************************************************************************/
/* DADDR Device ADDRess bit definitions */
/******************************************************************************/
#define DADDR_EF (0x80)
#define DADDR_ADD (0x7F)
/******************************************************************************/
/* Endpoint register */
/******************************************************************************/
/* bit positions */
#define EP_CTR_RX (0x8000) /* EndPoint Correct TRansfer RX */
#define EP_DTOG_RX (0x4000) /* EndPoint Data TOGGLE RX */
#define EPRX_STAT (0x3000) /* EndPoint RX STATus bit field */
#define EP_SETUP (0x0800) /* EndPoint SETUP */
#define EP_T_FIELD (0x0600) /* EndPoint TYPE */
#define EP_KIND (0x0100) /* EndPoint KIND */
#define EP_CTR_TX (0x0080) /* EndPoint Correct TRansfer TX */
#define EP_DTOG_TX (0x0040) /* EndPoint Data TOGGLE TX */
#define EPTX_STAT (0x0030) /* EndPoint TX STATus bit field */
#define EPADDR_FIELD (0x000F) /* EndPoint ADDRess FIELD */
/* EndPoint REGister MASK (no toggle fields) */
#define EPREG_MASK (EP_CTR_RX|EP_SETUP|EP_T_FIELD|EP_KIND|EP_CTR_TX|EPADDR_FIELD)
/* EP_TYPE[1:0] EndPoint TYPE */
#define EP_TYPE_MASK (0x0600) /* EndPoint TYPE Mask */
#define EP_BULK (0x0000) /* EndPoint BULK */
#define EP_CONTROL (0x0200) /* EndPoint CONTROL */
#define EP_ISOCHRONOUS (0x0400) /* EndPoint ISOCHRONOUS */
#define EP_INTERRUPT (0x0600) /* EndPoint INTERRUPT */
#define EP_T_MASK (~EP_T_FIELD & EPREG_MASK)
/* EP_KIND EndPoint KIND */
#define EPKIND_MASK (~EP_KIND & EPREG_MASK)
/* STAT_TX[1:0] STATus for TX transfer */
#define EP_TX_DIS (0x0000) /* EndPoint TX DISabled */
#define EP_TX_STALL (0x0010) /* EndPoint TX STALLed */
#define EP_TX_NAK (0x0020) /* EndPoint TX NAKed */
#define EP_TX_VALID (0x0030) /* EndPoint TX VALID */
#define EPTX_DTOG1 (0x0010) /* EndPoint TX Data TOGgle bit1 */
#define EPTX_DTOG2 (0x0020) /* EndPoint TX Data TOGgle bit2 */
#define EPTX_DTOGMASK (EPTX_STAT|EPREG_MASK)
/* STAT_RX[1:0] STATus for RX transfer */
#define EP_RX_DIS (0x0000) /* EndPoint RX DISabled */
#define EP_RX_STALL (0x1000) /* EndPoint RX STALLed */
#define EP_RX_NAK (0x2000) /* EndPoint RX NAKed */
#define EP_RX_VALID (0x3000) /* EndPoint RX VALID */
#define EPRX_DTOG1 (0x1000) /* EndPoint RX Data TOGgle bit1 */
#define EPRX_DTOG2 (0x2000) /* EndPoint RX Data TOGgle bit1 */
#define EPRX_DTOGMASK (EPRX_STAT|EPREG_MASK)
/* Exported macro ------------------------------------------------------------*/
/* SetCNTR */
#define _SetCNTR(wRegValue) (*CNTR = (u16)wRegValue)
/* SetISTR */
#define _SetISTR(wRegValue) (*ISTR = (u16)wRegValue)
/* SetDADDR */
#define _SetDADDR(wRegValue) (*DADDR = (u16)wRegValue)
/* SetBTABLE */
#define _SetBTABLE(wRegValue)(*BTABLE = (u16)(wRegValue & 0xFFF8))
/* GetCNTR */
#define _GetCNTR() ((u16) *CNTR)
/* GetISTR */
#define _GetISTR() ((u16) *ISTR)
/* GetFNR */
#define _GetFNR() ((u16) *FNR)
/* GetDADDR */
#define _GetDADDR() ((u16) *DADDR)
/* GetBTABLE */
#define _GetBTABLE() ((u16) *BTABLE)
/* SetENDPOINT */
#define _SetENDPOINT(bEpNum,wRegValue) (*(EP0REG + bEpNum)= \
(u16)wRegValue)
/* GetENDPOINT */
#define _GetENDPOINT(bEpNum) ((u16)(*(EP0REG + bEpNum)))
/*******************************************************************************
* Macro Name : SetEPType
* Description : sets the type in the endpoint register(bits EP_TYPE[1:0])
* Input : bEpNum: Endpoint Number.
* wType
* Output : None.
* Return : None.
*******************************************************************************/
#define _SetEPType(bEpNum,wType) (_SetENDPOINT(bEpNum,\
((_GetENDPOINT(bEpNum) & EP_T_MASK) | wType)))
/*******************************************************************************
* Macro Name : GetEPType
* Description : gets the type in the endpoint register(bits EP_TYPE[1:0])
* Input : bEpNum: Endpoint Number.
* Output : None.
* Return : Endpoint Type
*******************************************************************************/
#define _GetEPType(bEpNum) (_GetENDPOINT(bEpNum) & EP_T_FIELD)
/*******************************************************************************
* Macro Name : SetEPTxStatus
* Description : sets the status for tx transfer (bits STAT_TX[1:0]).
* Input : bEpNum: Endpoint Number.
* wState: new state
* Output : None.
* Return : None.
*******************************************************************************/
#define _SetEPTxStatus(bEpNum,wState) {\
register u16 _wRegVal; \
_wRegVal = _GetENDPOINT(bEpNum) & EPTX_DTOGMASK;\
/* toggle first bit ? */ \
if((EPTX_DTOG1 & wState)!= 0) \
_wRegVal ^= EPTX_DTOG1; \
/* toggle second bit ? */ \
if((EPTX_DTOG2 & wState)!= 0) \
_wRegVal ^= EPTX_DTOG2; \
_SetENDPOINT(bEpNum, _wRegVal); \
} /* _SetEPTxStatus */
/*******************************************************************************
* Macro Name : SetEPRxStatus
* Description : sets the status for rx transfer (bits STAT_TX[1:0])
* Input : bEpNum: Endpoint Number.
* wState: new state.
* Output : None.
* Return : None.
*******************************************************************************/
#define _SetEPRxStatus(bEpNum,wState) {\
register u16 _wRegVal; \
\
_wRegVal = _GetENDPOINT(bEpNum) & EPRX_DTOGMASK;\
/* toggle first bit ? */ \
if((EPRX_DTOG1 & wState)!= 0) \
_wRegVal ^= EPRX_DTOG1; \
/* toggle second bit ? */ \
if((EPRX_DTOG2 & wState)!= 0) \
_wRegVal ^= EPRX_DTOG2; \
_SetENDPOINT(bEpNum, _wRegVal); \
} /* _SetEPRxStatus */
/*******************************************************************************
* Macro Name : GetEPTxStatus / GetEPRxStatus
* Description : gets the status for tx/rx transfer (bits STAT_TX[1:0]
* /STAT_RX[1:0])
* Input : bEpNum: Endpoint Number.
* Output : None.
* Return : status .
*******************************************************************************/
#define _GetEPTxStatus(bEpNum) ((u16)_GetENDPOINT(bEpNum) & EPTX_STAT)
#define _GetEPRxStatus(bEpNum) ((u16)_GetENDPOINT(bEpNum) & EPRX_STAT)
/*******************************************************************************
* Macro Name : SetEPTxValid / SetEPRxValid
* Description : sets directly the VALID tx/rx-status into the enpoint register
* Input : bEpNum: Endpoint Number.
* Output : None.
* Return : None.
*******************************************************************************/
#define _SetEPTxValid(bEpNum) (_SetEPTxStatus(bEpNum, EP_TX_VALID))
#define _SetEPRxValid(bEpNum) (_SetEPRxStatus(bEpNum, EP_RX_VALID))
/*******************************************************************************
* Macro Name : GetTxStallStatus / GetRxStallStatus.
* Description : checks stall condition in an endpoint.
* Input : bEpNum: Endpoint Number.
* Output : None.
* Return : TRUE = endpoint in stall condition.
*******************************************************************************/
#define _GetTxStallStatus(bEpNum) (_GetEPTxStatus(bEpNum) \
== EP_TX_STALL)
#define _GetRxStallStatus(bEpNum) (_GetEPRxStatus(bEpNum) \
== EP_RX_STALL)
/*******************************************************************************
* Macro Name : SetEP_KIND / ClearEP_KIND.
* Description : set & clear EP_KIND bit.
* Input : bEpNum: Endpoint Number.
* Output : None.
* Return : None.
*******************************************************************************/
#define _SetEP_KIND(bEpNum) (_SetENDPOINT(bEpNum, \
(_GetENDPOINT(bEpNum) | EP_KIND) & EPREG_MASK))
#define _ClearEP_KIND(bEpNum) (_SetENDPOINT(bEpNum, \
(_GetENDPOINT(bEpNum) & EPKIND_MASK)))
/*******************************************************************************
* Macro Name : Set_Status_Out / Clear_Status_Out.
* Description : Sets/clears directly STATUS_OUT bit in the endpoint register.
* Input : bEpNum: Endpoint Number.
* Output : None.
* Return : None.
*******************************************************************************/
#define _Set_Status_Out(bEpNum) _SetEP_KIND(bEpNum)
#define _Clear_Status_Out(bEpNum) _ClearEP_KIND(bEpNum)
/*******************************************************************************
* Macro Name : SetEPDoubleBuff / ClearEPDoubleBuff.
* Description : Sets/clears directly EP_KIND bit in the endpoint register.
* Input : bEpNum: Endpoint Number.
* Output : None.
* Return : None.
*******************************************************************************/
#define _SetEPDoubleBuff(bEpNum) _SetEP_KIND(bEpNum)
#define _ClearEPDoubleBuff(bEpNum) _ClearEP_KIND(bEpNum)
/*******************************************************************************
* Macro Name : ClearEP_CTR_RX / ClearEP_CTR_TX.
* Description : Clears bit CTR_RX / CTR_TX in the endpoint register.
* Input : bEpNum: Endpoint Number.
* Output : None.
* Return : None.
*******************************************************************************/
#define _ClearEP_CTR_RX(bEpNum) (_SetENDPOINT(bEpNum,\
_GetENDPOINT(bEpNum) & 0x7FFF & EPREG_MASK))
#define _ClearEP_CTR_TX(bEpNum) (_SetENDPOINT(bEpNum,\
_GetENDPOINT(bEpNum) & 0xFF7F & EPREG_MASK))
/*******************************************************************************
* Macro Name : ToggleDTOG_RX / ToggleDTOG_TX .
* Description : Toggles DTOG_RX / DTOG_TX bit in the endpoint register.
* Input : bEpNum: Endpoint Number.
* Output : None.
* Return : None.
*******************************************************************************/
#define _ToggleDTOG_RX(bEpNum) (_SetENDPOINT(bEpNum, \
EP_DTOG_RX | (_GetENDPOINT(bEpNum) & EPREG_MASK)))
#define _ToggleDTOG_TX(bEpNum) (_SetENDPOINT(bEpNum, \
EP_DTOG_TX | (_GetENDPOINT(bEpNum) & EPREG_MASK)))
/*******************************************************************************
* Macro Name : ClearDTOG_RX / ClearDTOG_TX.
* Description : Clears DTOG_RX / DTOG_TX bit in the endpoint register.
* Input : bEpNum: Endpoint Number.
* Output : None.
* Return : None.
*******************************************************************************/
#define _ClearDTOG_RX(bEpNum) if((_GetENDPOINT(bEpNum) & EP_DTOG_RX) != 0)\
_ToggleDTOG_RX(bEpNum)
#define _ClearDTOG_TX(bEpNum) if((_GetENDPOINT(bEpNum) & EP_DTOG_TX) != 0)\
_ToggleDTOG_TX(bEpNum)
/*******************************************************************************
* Macro Name : SetEPAddress.
* Description : Sets address in an endpoint register.
* Input : bEpNum: Endpoint Number.
* bAddr: Address.
* Output : None.
* Return : None.
*******************************************************************************/
#define _SetEPAddress(bEpNum,bAddr) _SetENDPOINT(bEpNum,\
(_GetENDPOINT(bEpNum) & EPREG_MASK) | bAddr)
/*******************************************************************************
* Macro Name : GetEPAddress.
* Description : Gets address in an endpoint register.
* Input : bEpNum: Endpoint Number.
* Output : None.
* Return : None.
*******************************************************************************/
#define _GetEPAddress(bEpNum) ((u8)(_GetENDPOINT(bEpNum) & EPADDR_FIELD))
#define _pEPTxAddr(bEpNum) ((u32 *)((_GetBTABLE()+bEpNum*8 )*2 + PMAAddr))
#define _pEPTxCount(bEpNum) ((u32 *)((_GetBTABLE()+bEpNum*8+2)*2 + PMAAddr))
#define _pEPRxAddr(bEpNum) ((u32 *)((_GetBTABLE()+bEpNum*8+4)*2 + PMAAddr))
#define _pEPRxCount(bEpNum) ((u32 *)((_GetBTABLE()+bEpNum*8+6)*2 + PMAAddr))
/*******************************************************************************
* Macro Name : SetEPTxAddr / SetEPRxAddr.
* Description : sets address of the tx/rx buffer.
* Input : bEpNum: Endpoint Number.
* wAddr: address to be set (must be word aligned).
* Output : None.
* Return : None.
*******************************************************************************/
#define _SetEPTxAddr(bEpNum,wAddr) (*_pEPTxAddr(bEpNum) = ((wAddr >> 1) << 1))
#define _SetEPRxAddr(bEpNum,wAddr) (*_pEPRxAddr(bEpNum) = ((wAddr >> 1) << 1))
/*******************************************************************************
* Macro Name : GetEPTxAddr / GetEPRxAddr.
* Description : Gets address of the tx/rx buffer.
* Input : bEpNum: Endpoint Number.
* Output : None.
* Return : address of the buffer.
*******************************************************************************/
#define _GetEPTxAddr(bEpNum) ((u16)*_pEPTxAddr(bEpNum))
#define _GetEPRxAddr(bEpNum) ((u16)*_pEPRxAddr(bEpNum))
/*******************************************************************************
* Macro Name : SetEPCountRxReg.
* Description : Sets counter of rx buffer with no. of blocks.
* Input : pdwReg: pointer to counter.
* wCount: Counter.
* Output : None.
* Return : None.
*******************************************************************************/
#define _BlocksOf32(dwReg,wCount,wNBlocks) {\
wNBlocks = wCount >> 5;\
if((wCount & 0x1f) == 0)\
wNBlocks--;\
*pdwReg = (u32)((wNBlocks << 10) | 0x8000);\
}/* _BlocksOf32 */
#define _BlocksOf2(dwReg,wCount,wNBlocks) {\
wNBlocks = wCount >> 1;\
if((wCount & 0x1) != 0)\
wNBlocks++;\
*pdwReg = (u32)(wNBlocks << 10);\
}/* _BlocksOf2 */
#define _SetEPCountRxReg(dwReg,wCount) {\
u16 wNBlocks;\
if(wCount > 62){_BlocksOf32(dwReg,wCount,wNBlocks);}\
else {_BlocksOf2(dwReg,wCount,wNBlocks);}\
}/* _SetEPCountRxReg */
#define _SetEPRxDblBuf0Count(bEpNum,wCount) {\
u32 *pdwReg = _pEPTxCount(bEpNum); \
_SetEPCountRxReg(pdwReg, wCount);\
}
/*******************************************************************************
* Macro Name : SetEPTxCount / SetEPRxCount.
* Description : sets counter for the tx/rx buffer.
* Input : bEpNum: endpoint number.
* wCount: Counter value.
* Output : None.
* Return : None.
*******************************************************************************/
#define _SetEPTxCount(bEpNum,wCount) (*_pEPTxCount(bEpNum) = wCount)
#define _SetEPRxCount(bEpNum,wCount) {\
u32 *pdwReg = _pEPRxCount(bEpNum); \
_SetEPCountRxReg(pdwReg, wCount);\
}
/*******************************************************************************
* Macro Name : GetEPTxCount / GetEPRxCount.
* Description : gets counter of the tx buffer.
* Input : bEpNum: endpoint number.
* Output : None.
* Return : Counter value.
*******************************************************************************/
#define _GetEPTxCount(bEpNum)((u16)(*_pEPTxCount(bEpNum)) & 0x3ff)
#define _GetEPRxCount(bEpNum)((u16)(*_pEPRxCount(bEpNum)) & 0x3ff)
/*******************************************************************************
* Macro Name : SetEPDblBuf0Addr / SetEPDblBuf1Addr.
* Description : Sets buffer 0/1 address in a double buffer endpoint.
* Input : bEpNum: endpoint number.
* : wBuf0Addr: buffer 0 address.
* Output : None.
* Return : None.
*******************************************************************************/
#define _SetEPDblBuf0Addr(bEpNum,wBuf0Addr) {_SetEPTxAddr(bEpNum, wBuf0Addr);}
#define _SetEPDblBuf1Addr(bEpNum,wBuf1Addr) {_SetEPRxAddr(bEpNum, wBuf1Addr);}
/*******************************************************************************
* Macro Name : SetEPDblBuffAddr.
* Description : Sets addresses in a double buffer endpoint.
* Input : bEpNum: endpoint number.
* : wBuf0Addr: buffer 0 address.
* : wBuf1Addr = buffer 1 address.
* Output : None.
* Return : None.
*******************************************************************************/
#define _SetEPDblBuffAddr(bEpNum,wBuf0Addr,wBuf1Addr) { \
_SetEPDblBuf0Addr(bEpNum, wBuf0Addr);\
_SetEPDblBuf1Addr(bEpNum, wBuf1Addr);\
} /* _SetEPDblBuffAddr */
/*******************************************************************************
* Macro Name : GetEPDblBuf0Addr / GetEPDblBuf1Addr.
* Description : Gets buffer 0/1 address of a double buffer endpoint.
* Input : bEpNum: endpoint number.
* Output : None.
* Return : None.
*******************************************************************************/
#define _GetEPDblBuf0Addr(bEpNum) (_GetEPTxAddr(bEpNum))
#define _GetEPDblBuf1Addr(bEpNum) (_GetEPRxAddr(bEpNum))
/*******************************************************************************
* Macro Name : SetEPDblBuffCount / SetEPDblBuf0Count / SetEPDblBuf1Count.
* Description : Gets buffer 0/1 address of a double buffer endpoint.
* Input : bEpNum: endpoint number.
* : bDir: endpoint dir EP_DBUF_OUT = OUT
* EP_DBUF_IN = IN
* : wCount: Counter value
* Output : None.
* Return : None.
*******************************************************************************/
#define _SetEPDblBuf0Count(bEpNum, bDir, wCount) { \
if(bDir == EP_DBUF_OUT)\
/* OUT endpoint */ \
{_SetEPRxDblBuf0Count(bEpNum,wCount);} \
else if(bDir == EP_DBUF_IN)\
/* IN endpoint */ \
*_pEPTxCount(bEpNum) = (u32)wCount; \
} /* SetEPDblBuf0Count*/
#define _SetEPDblBuf1Count(bEpNum, bDir, wCount) { \
if(bDir == EP_DBUF_OUT)\
/* OUT endpoint */ \
{_SetEPRxCount(bEpNum,wCount);}\
else if(bDir == EP_DBUF_IN)\
/* IN endpoint */\
*_pEPRxCount(bEpNum) = (u32)wCount; \
} /* SetEPDblBuf1Count */
#define _SetEPDblBuffCount(bEpNum, bDir, wCount) {\
_SetEPDblBuf0Count(bEpNum, bDir, wCount); \
_SetEPDblBuf1Count(bEpNum, bDir, wCount); \
} /* _SetEPDblBuffCount */
/*******************************************************************************
* Macro Name : GetEPDblBuf0Count / GetEPDblBuf1Count.
* Description : Gets buffer 0/1 rx/tx counter for double buffering.
* Input : bEpNum: endpoint number.
* Output : None.
* Return : None.
*******************************************************************************/
#define _GetEPDblBuf0Count(bEpNum) (_GetEPTxCount(bEpNum))
#define _GetEPDblBuf1Count(bEpNum) (_GetEPRxCount(bEpNum))
/* External variables --------------------------------------------------------*/
extern volatile u16 wIstr; /* ISTR register last read value */
/* Exported functions ------------------------------------------------------- */
void SetCNTR(u16 /*wRegValue*/);
void SetISTR(u16 /*wRegValue*/);
void SetDADDR(u16 /*wRegValue*/);
void SetBTABLE(u16 /*wRegValue*/);
u16 GetCNTR(void);
u16 GetISTR(void);
u16 GetFNR(void);
u16 GetDADDR(void);
u16 GetBTABLE(void);
void SetENDPOINT(u8 /*bEpNum*/, u16 /*wRegValue*/);
u16 GetENDPOINT(u8 /*bEpNum*/);
void SetEPType(u8 /*bEpNum*/, u16 /*wType*/);
u16 GetEPType(u8 /*bEpNum*/);
void SetEPTxStatus(u8 /*bEpNum*/, u16 /*wState*/);
void SetEPRxStatus(u8 /*bEpNum*/, u16 /*wState*/);
void SetDouBleBuffEPStall(u8 /*bEpNum*/, u8 bDir);
u16 GetEPTxStatus(u8 /*bEpNum*/);
u16 GetEPRxStatus(u8 /*bEpNum*/);
void SetEPTxValid(u8 /*bEpNum*/);
void SetEPRxValid(u8 /*bEpNum*/);
u16 GetTxStallStatus(u8 /*bEpNum*/);
u16 GetRxStallStatus(u8 /*bEpNum*/);
void SetEP_KIND(u8 /*bEpNum*/);
void ClearEP_KIND(u8 /*bEpNum*/);
void Set_Status_Out(u8 /*bEpNum*/);
void Clear_Status_Out(u8 /*bEpNum*/);
void SetEPDoubleBuff(u8 /*bEpNum*/);
void ClearEPDoubleBuff(u8 /*bEpNum*/);
void ClearEP_CTR_RX(u8 /*bEpNum*/);
void ClearEP_CTR_TX(u8 /*bEpNum*/);
void ToggleDTOG_RX(u8 /*bEpNum*/);
void ToggleDTOG_TX(u8 /*bEpNum*/);
void ClearDTOG_RX(u8 /*bEpNum*/);
void ClearDTOG_TX(u8 /*bEpNum*/);
void SetEPAddress(u8 /*bEpNum*/, u8 /*bAddr*/);
u8 GetEPAddress(u8 /*bEpNum*/);
void SetEPTxAddr(u8 /*bEpNum*/, u16 /*wAddr*/);
void SetEPRxAddr(u8 /*bEpNum*/, u16 /*wAddr*/);
u16 GetEPTxAddr(u8 /*bEpNum*/);
u16 GetEPRxAddr(u8 /*bEpNum*/);
void SetEPCountRxReg(u32 * /*pdwReg*/, u16 /*wCount*/);
void SetEPTxCount(u8 /*bEpNum*/, u16 /*wCount*/);
void SetEPRxCount(u8 /*bEpNum*/, u16 /*wCount*/);
u16 GetEPTxCount(u8 /*bEpNum*/);
u16 GetEPRxCount(u8 /*bEpNum*/);
void SetEPDblBuf0Addr(u8 /*bEpNum*/, u16 /*wBuf0Addr*/);
void SetEPDblBuf1Addr(u8 /*bEpNum*/, u16 /*wBuf1Addr*/);
void SetEPDblBuffAddr(u8 /*bEpNum*/, u16 /*wBuf0Addr*/, u16 /*wBuf1Addr*/);
u16 GetEPDblBuf0Addr(u8 /*bEpNum*/);
u16 GetEPDblBuf1Addr(u8 /*bEpNum*/);
void SetEPDblBuffCount(u8 /*bEpNum*/, u8 /*bDir*/, u16 /*wCount*/);
void SetEPDblBuf0Count(u8 /*bEpNum*/, u8 /*bDir*/, u16 /*wCount*/);
void SetEPDblBuf1Count(u8 /*bEpNum*/, u8 /*bDir*/, u16 /*wCount*/);
u16 GetEPDblBuf0Count(u8 /*bEpNum*/);
u16 GetEPDblBuf1Count(u8 /*bEpNum*/);
EP_DBUF_DIR GetEPDblBufDir(u8 /*bEpNum*/);
void FreeUserBuffer(u8 bEpNum/*bEpNum*/, u8 bDir);
u16 ToWord(u8, u8);
u16 ByteSwap(u16);
#if defined(__cplusplus)
}
#endif
#endif /* __USB_REGS_H */
/******************* (C) COPYRIGHT 2008 STMicroelectronics *****END OF FILE****/

View File

@@ -0,0 +1,77 @@
/******************** (C) COPYRIGHT 2008 STMicroelectronics ********************
* File Name : usb_type.h
* Author : MCD Application Team
* Version : V2.2.1
* Date : 09/22/2008
* Description : Type definitions used by the USB Library
********************************************************************************
* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME.
* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT,
* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE
* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING
* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
*******************************************************************************/
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __USB_TYPE_H
#define __USB_TYPE_H
#if defined(__cplusplus)
extern "C" {
#endif
/* Exported types ------------------------------------------------------------*/
/* Exported constants --------------------------------------------------------*/
#ifndef NULL
#define NULL ((void *)0)
#endif
typedef signed long s32;
typedef signed short s16;
typedef signed char s8;
typedef volatile signed long vs32;
typedef volatile signed short vs16;
typedef volatile signed char vs8;
typedef unsigned long u32;
typedef unsigned short u16;
typedef unsigned char u8;
typedef unsigned long const uc32; /* Read Only */
typedef unsigned short const uc16; /* Read Only */
typedef unsigned char const uc8; /* Read Only */
typedef volatile unsigned long vu32;
typedef volatile unsigned short vu16;
typedef volatile unsigned char vu8;
typedef volatile unsigned long const vuc32; /* Read Only */
typedef volatile unsigned short const vuc16; /* Read Only */
typedef volatile unsigned char const vuc8; /* Read Only */
typedef enum
{
FALSE = 0, TRUE = !FALSE
}
USB_Bool;
typedef enum { RESET = 0, SET = !RESET } FlagStatus, ITStatus;
typedef enum { DISABLE = 0, ENABLE = !DISABLE} FunctionalState;
typedef enum { ERROR = 0, SUCCESS = !ERROR} ErrorStatus;
/* Exported macro ------------------------------------------------------------*/
/* Exported functions ------------------------------------------------------- */
/* External variables --------------------------------------------------------*/
#if defined(__cplusplus)
}
#endif
#endif /* __USB_TYPE_H */
/******************* (C) COPYRIGHT 2008 STMicroelectronics *****END OF FILE****/