Added STM32F3 port supplied by Frank-Michael. Note this port looks like it is based on LibMaple for Arduino API 0022 and doesn't include more recent API features like the stream class and Serial.peek() etc

This commit is contained in:
rogerclarkmelbourne 2015-02-20 12:26:17 +11:00
parent 4e808480ca
commit 05130a7db9
202 changed files with 31961 additions and 0 deletions

45
STM32F3/README.md Normal file
View File

@ -0,0 +1,45 @@
STM32F3 files have been supplied by Frank-Michael Krause.
The API is not as up to date as in the STM F103 files.
It looks like this port is as the F103 files orginally were when I started work on the project.
The API is for pre- Arduino 1.0 and doesn't include a lot of functions in the 1.0 API, and the class inheritance will
be different in a number of places, most importantly in the Serial class.
Specifically Stream.cpp / .h are not present in this port.
-------------------- Details from Frank-Michael ----------------------------
This port of libmaple for Arduino-IDE is based on the inofficial F3 branch
of libmaple found on
https://github.com/ventosus/libmaple/tree/F3
and supports at the moment the STM32F3Discovery board with programming via ST-link.
Linker is configured for linking to flash, not to RAM
Changes by Frank-Michael Krause (mich dot krause at web dot de):
- renaming some stm32f3 related files because the Arduino build system copy all objects to same directory so the source file names must be different
- selected the correct startup modules and linker scripts for board variant stm32f3discovery
Notes:
- the pin names as noted on stm32f3discovery board (PA0, PA1, ..., PF10) can be used as pin id
- usb is untested because I haven't used it really
- There are some libraries and examples related to the STM32F3discovery board.
They are commented mostly in german only because I wrote them for use at robotic club of a secondary school
and the kids like to have the documentation in german.
gyro: Interface library for the gyro-chip of the stm32f3discovery, setup the gyro in FIFO mode and so
requiring update calls only every < 120ms
lsm303: Interface library for Acceleration sensor of the stm32f3discovery, magnetometer not yet supported (writing this driver is currently under work by a student at school)
ringbuffer: Class impelentig a ringbuffer with functions for adding time stampes per added element, averaging functions, accessing the stored data like an array
roboter: several functionalities needed to program a robot:
- dc motor control as known from Lego NXC language
- support for HC-SR04 ultrasonic sensors driven by interrupt or blocking direct measurement
- function timers based on timer interrupt
- modul for interfacing a 24Cxx I2C eeprom chip

33
STM32F3/boards.txt Normal file
View File

@ -0,0 +1,33 @@
#
##############################################################
discovery_f3.name=STM32F3Discovery
discovery_f3.upload.tool=stlink
discovery_f3.upload.protocol=stlink
#discovery_f407.upload.use_1200bps_touch=false
discovery_f3.upload.file_type=bin
discovery_f3.upload.ram.maximum_size=17000
discovery_f3.upload.flash.maximum_size=108000
discovery_f3.upload.maximum_size=108000
#discovery_f3.upload.usbID=1EAF:0003
#discovery_f3.upload.altID=1
#discovery_f3.upload.auto_reset=true
discovery_f3.build.mcu=cortex-m3
discovery_f3.build.f_cpu=72000000L
discovery_f3.build.core=maple
discovery_f3.build.extra_flags=-DMCU_STM32F303VC -mthumb -DSTM32_XL_DENSITY -march=armv7-m -DSTM32F3 -DF303VC -DBOARD_discovery_f3
discovery_f3.build.ldscript=ld/jtag.ld
discovery_f3.build.variant=discovery_f3
discovery_f3.build.variant_system_lib=lib_f3.a
discovery_f3.build.vect=VECT_TAB_BASE
discovery_f3.build.density=STM32_XL_DENSITY
discovery_f3.build.error_led_port=GPIOE
discovery_f3.build.error_led_pin=8
#discovery_f407.build.gcc_ver=gcc-arm-none-eabi-4.8.3-2014q1
##############################################################

View File

@ -0,0 +1,4 @@
#ifndef Arduino_h
#define Arduino_h
#include "WProgram.h"
#endif

View File

@ -0,0 +1,35 @@
/******************************************************************************
* 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.
*****************************************************************************/
#ifndef _WIRISH_WPROGRAM_H_
#define _WIRISH_WPROGRAM_H_
#include <wirish/wirish.h>
void setup();
void loop();
#endif

View File

@ -0,0 +1,52 @@
/******************************************************************************
* The MIT License
*
* Copyright (c) 2010 Perry Hung.
* Copyright (c) 2011, 2012 LeafLabs, LLC.
* Copyright (c) 2013 OpenMusicKontrollers.
*
* 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/adc.c
* @author Marti Bolivar <mbolivar@leaflabs.com>,
* Perry Hung <perry@leaflabs.com>,
* F3-port by Hanspeter Portner <dev@open-music-kontrollers.ch>
* @brief Analog to digital converter routines
*/
#include <libmaple/adc.h>
#include <libmaple/libmaple.h>
#include <libmaple/rcc.h>
/**
* @brief Initialize an ADC peripheral.
*
* Initializes the RCC clock line for the given peripheral. Resets
* ADC device registers.
*
* @param dev ADC peripheral to initialize
*/
void adc_init(const adc_dev *dev) {
rcc_clk_enable(dev->clk_id);
rcc_reset_dev(dev->clk_id);
}

View File

@ -0,0 +1,69 @@
/******************************************************************************
* The MIT License
*
* Copyright (c) 2010 LeafLabs, LLC.
* Copyright (c) 2013 OpenMusicKontrollers.
*
* 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/bkp.c
* @author F3-port by Hanspeter Portner <dev@open-music-kontrollers.ch>
* @brief Backup register support (STM32F1 & STM32F3 only).
*/
#include <libmaple/pwr.h>
#include <libmaple/bkp.h>
#include <libmaple/bitband.h>
bkp_dev bkp = {
.regs = BKP_BASE,
};
/** Backup device. */
const bkp_dev *BKP = &bkp;
void bkp_enable_writes(void) {
*bb_perip(&PWR_BASE->CR, PWR_CR_DBP_BIT) = 1;
}
void bkp_disable_writes(void) {
*bb_perip(&PWR_BASE->CR, PWR_CR_DBP_BIT) = 0;
}
uint16 bkp_read(uint8 reg) {
__io uint32* dr = bkp_data_register(reg);
if (!dr) {
ASSERT(0); /* nonexistent register */
return 0;
}
return (uint16)*dr;
}
void bkp_write(uint8 reg, uint16 val) {
__io uint32* dr = bkp_data_register(reg);
if (!dr) {
ASSERT(0); /* nonexistent register */
return;
}
*dr = (uint32)val;
}

View File

@ -0,0 +1,120 @@
/******************************************************************************
* The MIT License
*
* Copyright (c) 2010 Bryan Newbold.
* 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/dac.c
* @brief Digital to analog converter support.
*/
#include <libmaple/dac.h>
#include <libmaple/libmaple.h>
#include <libmaple/gpio.h>
#if STM32_HAVE_DAC
dac_dev dac = {
.regs = DAC_BASE,
};
const dac_dev *DAC = &dac;
#endif
/**
* @brief Initialize the digital to analog converter
* @param dev DAC device
* @param flags Flags:
* DAC_CH1: Enable channel 1
* DAC_CH2: Enable channel 2
* @sideeffect May set PA4 or PA5 to INPUT_ANALOG
*/
void dac_init(const dac_dev *dev, uint32 flags) {
/* First turn on the clock */
rcc_clk_enable(RCC_DAC);
rcc_reset_dev(RCC_DAC);
if (flags & DAC_CH1) {
dac_enable_channel(dev, 1);
}
if (flags & DAC_CH2) {
dac_enable_channel(dev, 2);
}
}
/**
* @brief Write a 12-bit value to the DAC to output
* @param dev DAC device
* @param channel channel to select (1 or 2)
* @param val value to write
*/
void dac_write_channel(const dac_dev *dev, uint8 channel, uint16 val) {
switch(channel) {
case 1:
dev->regs->DHR12R1 = DAC_DHR12R1_DACC1DHR & val;
break;
case 2:
dev->regs->DHR12R2 = DAC_DHR12R2_DACC2DHR & val;
break;
}
}
/**
* @brief Enable a DAC channel
* @param dev DAC device
* @param channel channel to enable, either 1 or 2
* @sideeffect May change pin mode of PA4 or PA5
*/
void dac_enable_channel(const dac_dev *dev, uint8 channel) {
/*
* Setup ANALOG mode on PA4 and PA5. This mapping is consistent
* across all supported STM32s with a DAC.
*/
switch (channel) {
case 1:
gpio_set_mode(GPIOA, 4, GPIO_MODE_ANALOG);
dev->regs->CR |= DAC_CR_EN1;
break;
case 2:
gpio_set_mode(GPIOA, 5, GPIO_MODE_ANALOG);
dev->regs->CR |= DAC_CR_EN2;
break;
}
}
/**
* @brief Disable a DAC channel
* @param dev DAC device
* @param channel channel to disable, either 1 or 2
*/
void dac_disable_channel(const dac_dev *dev, uint8 channel) {
switch (channel) {
case 1:
dev->regs->CR &= ~DAC_CR_EN1;
break;
case 2:
dev->regs->CR &= ~DAC_CR_EN2;
break;
}
}

View File

@ -0,0 +1,82 @@
/******************************************************************************
* 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/dma.c
* @author Marti Bolivar <mbolivar@leaflabs.com>;
* Original implementation by Michael Hope
* @brief Portable DMA routines.
*/
#include <libmaple/dma.h>
#include "dma_private.h"
#include "stm32_private.h"
/*
* Convenience routines
*/
/**
* @brief Initialize a DMA device.
* @param dev Device to initialize.
*/
void dma_init(dma_dev *dev) {
rcc_clk_enable(dev->clk_id);
}
/*
* Private API
*/
enum dma_atype _dma_addr_type(__io void *addr) {
switch (stm32_block_purpose((void*)addr)) {
/* Notice we're treating the code block as memory here. That's
* correct for addresses in Flash and in [0x0, 0x7FFFFFF]
* (provided that those addresses are aliased to Flash, SRAM, or
* FSMC, depending on BOOT[01] and possibly SYSCFG_MEMRMP). It's
* not correct for other addresses in the code block, but those
* will (hopefully) just fail-fast with transfer or bus errors. If
* lots of people get confused, it might be worth being more
* careful here. */
case STM32_BLOCK_CODE: /* Fall through */
case STM32_BLOCK_SRAM: /* ... */
case STM32_BLOCK_FSMC_1_2: /* ... */
case STM32_BLOCK_FSMC_3_4:
return DMA_ATYPE_MEM;
case STM32_BLOCK_PERIPH:
return DMA_ATYPE_PER;
case STM32_BLOCK_FSMC_REG: /* Fall through */
/* Is this right? I can't think of a reason to DMA into or out
* of the FSMC registers. [mbolivar] */
case STM32_BLOCK_UNUSED: /* ... */
case STM32_BLOCK_CORTEX_INTERNAL: /* ... */
return DMA_ATYPE_OTHER;
default:
ASSERT(0); /* Can't happen */
return DMA_ATYPE_OTHER;
}
}

View File

@ -0,0 +1,61 @@
/******************************************************************************
* 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 __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,101 @@
/* *****************************************************************************
* 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.
* ****************************************************************************/
# On an exception, push a fake stack thread mode stack frame and redirect
# thread execution to a thread mode error handler
# From RM008:
# The SP is decremented by eight words by the completion of the stack push.
# Figure 5-1 shows the contents of the stack after an exception pre-empts the
# current program flow.
#
# Old SP--> <previous>
# xPSR
# PC
# LR
# r12
# r3
# r2
# r1
# SP--> r0
.text
.globl __exc_hardfault
.globl __exc_nmi
.globl __exc_hardfault
.globl __exc_memmanage
.globl __exc_busfault
.globl __exc_usagefault
.code 16
.thumb_func
__exc_nmi:
mov r0, #1
b __default_exc
.thumb_func
__exc_hardfault:
mov r0, #2
b __default_exc
.thumb_func
__exc_memmanage:
mov r0, #3
b __default_exc
.thumb_func
__exc_busfault:
mov r0, #4
b __default_exc
.thumb_func
__exc_usagefault:
mov r0, #5
b __default_exc
.thumb_func
__default_exc:
ldr r2, NVIC_CCR @ Enable returning to thread mode even if there are
mov r1 ,#1 @ pending exceptions. See flag NONEBASETHRDENA.
str r1, [r2]
cpsid i @ Disable global interrupts
ldr r2, SYSTICK_CSR @ Disable systick handler
mov r1, #0
str r1, [r2]
ldr r1, CPSR_MASK @ Set default CPSR
push {r1}
ldr r1, TARGET_PC @ Set target pc
push {r1}
sub sp, sp, #24 @ Don't care
ldr r1, EXC_RETURN @ Return to thread mode
mov lr, r1
bx lr @ Exception exit
.align 4
CPSR_MASK: .word 0x61000000
EXC_RETURN: .word 0xFFFFFFF9
TARGET_PC: .word __error
NVIC_CCR: .word 0xE000ED14 @ NVIC configuration control register
SYSTICK_CSR: .word 0xE000E010 @ Systick control register

View File

@ -0,0 +1,293 @@
/******************************************************************************
* 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/exti.c
* @brief External interrupt control routines
*/
#include <libmaple/exti.h>
#include <libmaple/libmaple.h>
#include <libmaple/nvic.h>
#include <libmaple/bitband.h>
static inline void dispatch_single_exti(uint32 exti_num);
static inline void dispatch_extis(uint32 start, uint32 stop);
/*
* Internal state
*/
typedef struct exti_channel {
void (*handler)(void *);
void *arg;
} exti_channel;
static exti_channel exti_channels[] = {
{ .handler = NULL, .arg = NULL }, // EXTI0
{ .handler = NULL, .arg = NULL }, // EXTI1
{ .handler = NULL, .arg = NULL }, // EXTI2
{ .handler = NULL, .arg = NULL }, // EXTI3
{ .handler = NULL, .arg = NULL }, // EXTI4
{ .handler = NULL, .arg = NULL }, // EXTI5
{ .handler = NULL, .arg = NULL }, // EXTI6
{ .handler = NULL, .arg = NULL }, // EXTI7
{ .handler = NULL, .arg = NULL }, // EXTI8
{ .handler = NULL, .arg = NULL }, // EXTI9
{ .handler = NULL, .arg = NULL }, // EXTI10
{ .handler = NULL, .arg = NULL }, // EXTI11
{ .handler = NULL, .arg = NULL }, // EXTI12
{ .handler = NULL, .arg = NULL }, // EXTI13
{ .handler = NULL, .arg = NULL }, // EXTI14
{ .handler = NULL, .arg = NULL }, // EXTI15
};
/*
* Portable routines
*/
/**
* @brief Register a handler to run upon external interrupt.
*
* This function assumes that the interrupt request corresponding to
* the given external interrupt is masked.
*
* @param num External interrupt line number.
* @param port Port to use as source input for external interrupt.
* @param handler Function handler to execute when interrupt is triggered.
* @param mode Type of transition to trigger on, one of:
* EXTI_RISING, EXTI_FALLING, EXTI_RISING_FALLING.
* @see exti_num
* @see exti_cfg
* @see voidFuncPtr
* @see exti_trigger_mode
*/
void exti_attach_interrupt(exti_num num,
exti_cfg port,
voidFuncPtr handler,
exti_trigger_mode mode) {
// Call callback version with arg being null
exti_attach_callback(num, port, (voidArgumentFuncPtr)handler, NULL, mode);
}
/**
* @brief Register a handler with an argument to run upon external interrupt.
*
* This function assumes that the interrupt request corresponding to
* the given external interrupt is masked.
*
* @param num External interrupt line number.
* @param port Port to use as source input for external interrupt.
* @param handler Function handler to execute when interrupt is triggered.
* @param arg Argument to pass to the interrupt handler.
* @param mode Type of transition to trigger on, one of:
* EXTI_RISING, EXTI_FALLING, EXTI_RISING_FALLING.
* @see exti_num
* @see exti_cfg
* @see voidFuncPtr
* @see exti_trigger_mode
*/
void exti_attach_callback(exti_num num,
exti_cfg port,
voidArgumentFuncPtr handler,
void *arg,
exti_trigger_mode mode) {
ASSERT(handler);
/* Register the handler */
exti_channels[num].handler = handler;
exti_channels[num].arg = arg;
/* Set trigger mode */
switch (mode) {
case EXTI_RISING:
bb_peri_set_bit(&EXTI_BASE->RTSR, num, 1);
break;
case EXTI_FALLING:
bb_peri_set_bit(&EXTI_BASE->FTSR, num, 1);
break;
case EXTI_RISING_FALLING:
bb_peri_set_bit(&EXTI_BASE->RTSR, num, 1);
bb_peri_set_bit(&EXTI_BASE->FTSR, num, 1);
break;
}
/* Use the chip-specific exti_select() to map num to port */
exti_select(num, port);
/* Unmask external interrupt request */
bb_peri_set_bit(&EXTI_BASE->IMR, num, 1);
/* Enable the interrupt line */
switch(num)
{
case EXTI0:
nvic_irq_enable(NVIC_EXTI0);
break;
case EXTI1:
nvic_irq_enable(NVIC_EXTI1);
break;
case EXTI2:
nvic_irq_enable(NVIC_EXTI2);
break;
case EXTI3:
nvic_irq_enable(NVIC_EXTI3);
break;
case EXTI4:
nvic_irq_enable(NVIC_EXTI4);
break;
case EXTI5:
case EXTI6:
case EXTI7:
case EXTI8:
case EXTI9:
nvic_irq_enable(NVIC_EXTI_9_5);
break;
case EXTI10:
case EXTI11:
case EXTI12:
case EXTI13:
case EXTI14:
case EXTI15:
nvic_irq_enable(NVIC_EXTI_15_10);
break;
}
}
/**
* @brief Unregister an external interrupt handler
* @param num External interrupt line to disable.
* @see exti_num
*/
void exti_detach_interrupt(exti_num num) {
/* First, mask the interrupt request */
bb_peri_set_bit(&EXTI_BASE->IMR, num, 0);
/* Then, clear the trigger selection registers */
bb_peri_set_bit(&EXTI_BASE->FTSR, num, 0);
bb_peri_set_bit(&EXTI_BASE->RTSR, num, 0);
/* Finally, unregister the user's handler */
exti_channels[num].handler = NULL;
exti_channels[num].arg = NULL;
}
/*
* Private routines
*/
void exti_do_select(__io uint32 *exti_cr, exti_num num, exti_cfg port) {
uint32 shift = 4 * (num % 4);
uint32 cr = *exti_cr;
cr &= ~(0xF << shift);
cr |= port << shift;
*exti_cr = cr;
}
/*
* Interrupt handlers
*/
void __irq_exti0(void) {
dispatch_single_exti(EXTI0);
}
void __irq_exti1(void) {
dispatch_single_exti(EXTI1);
}
void __irq_exti2(void) {
dispatch_single_exti(EXTI2);
// FIXME handle capatitive touch IRQ on F302/303
}
void __irq_exti3(void) {
dispatch_single_exti(EXTI3);
}
void __irq_exti4(void) {
dispatch_single_exti(EXTI4);
}
void __irq_exti9_5(void) {
dispatch_extis(5, 9);
}
void __irq_exti15_10(void) {
dispatch_extis(10, 15);
}
/*
* Auxiliary functions
*/
/* Clear the pending bits for EXTIs whose bits are set in exti_msk.
*
* If a pending bit is cleared as the last instruction in an ISR, it
* won't actually be cleared in time and the ISR will fire again. To
* compensate, this function NOPs for 2 cycles after clearing the
* pending bits to ensure it takes effect. */
static __always_inline void clear_pending_msk(uint32 exti_msk) {
EXTI_BASE->PR = exti_msk;
asm volatile("nop");
asm volatile("nop");
}
/* This dispatch routine is for non-multiplexed EXTI lines only; i.e.,
* it doesn't check EXTI_PR. */
static __always_inline void dispatch_single_exti(uint32 exti) {
voidArgumentFuncPtr handler = exti_channels[exti].handler;
if (!handler) {
return;
}
handler(exti_channels[exti].arg);
clear_pending_msk(1U << exti);
}
/* Dispatch routine for EXTIs which share an IRQ. */
static __always_inline void dispatch_extis(uint32 start, uint32 stop) {
uint32 pr = EXTI_BASE->PR;
uint32 handled_msk = 0;
uint32 exti;
/* Dispatch user handlers for pending EXTIs. */
for (exti = start; exti <= stop; exti++) {
uint32 eb = (1U << exti);
if (pr & eb) {
voidArgumentFuncPtr handler = exti_channels[exti].handler;
if (handler) {
handler(exti_channels[exti].arg);
handled_msk |= eb;
}
}
}
/* Clear the pending bits for handled EXTIs. */
clear_pending_msk(handled_msk);
}

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,55 @@
/******************************************************************************
* 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/flash.c
* @brief Flash management functions
*/
#include <libmaple/libmaple_types.h>
#include <libmaple/flash.h>
/**
* @brief Set flash wait states
*
* Note that not all wait states are available on every MCU. See the
* Flash programming manual for your MCU for restrictions on the
* allowed value of wait_states for a given system clock (SYSCLK)
* frequency.
*
* @param wait_states number of wait states (one of
* FLASH_WAIT_STATE_0, FLASH_WAIT_STATE_1,
* ..., FLASH_WAIT_STATE_7).
*/
void flash_set_latency(uint32 wait_states) {
uint32 val = FLASH_BASE->ACR;
val &= ~FLASH_ACR_LATENCY;
val |= wait_states;
FLASH_BASE->ACR = val;
}

View File

@ -0,0 +1,50 @@
/******************************************************************************
* 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/gpio.c
* @brief Generic STM32 GPIO support.
*/
#include <libmaple/gpio.h>
#include <libmaple/rcc.h>
/*
* GPIO routines
*/
/**
* Initialize a GPIO device.
*
* Enables the clock for and resets the given device.
*
* @param dev GPIO device to initialize.
*/
void gpio_init(gpio_dev *dev) {
rcc_clk_enable(dev->clk_id);
rcc_reset_dev(dev->clk_id);
}

View File

@ -0,0 +1,52 @@
/******************************************************************************
* The MIT License
*
* Copyright (c) 2010 Perry Hung.
* Copyright (c) 2012 LeafLabs, LLC.
* Copyright (c) 2013 OpenMusicKontrollers.
*
* 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/i2c.c
* @author Perry Hung <perry@leaflabs.com>,
* F3-port by Hanspeter Portner <dev@open-music-kontrollers.ch>
* @brief Inter-Integrated Circuit (I2C) support.
*
* Currently, only master mode is supported.
*/
#include "i2c_private.h"
#include <libmaple/libmaple.h>
#include <libmaple/rcc.h>
#include <libmaple/gpio.h>
#include <libmaple/nvic.h>
#include <libmaple/i2c.h>
#include <libmaple/systick.h>
#include <string.h>
void i2c_init(i2c_dev *dev) {
rcc_reset_dev(dev->clk_id);
rcc_clk_enable(dev->clk_id);
}

View File

@ -0,0 +1,75 @@
/******************************************************************************
* 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;
}
#endif /* _LIBMAPLE_I2C_PRIVATE_H_ */

View File

@ -0,0 +1,319 @@
/******************************************************************************
* The MIT License
*
* Copyright (c) 2012 LeafLabs, LLC.
* Copyright (c) 2010 Perry Hung.
* Copyright (c) 2013 OpenMusicKontrollers.
*
* 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>,
* F3-port by Hanspeter Portner <dev@open-music-kontrollers.ch>
* @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>
/**
* TODO document
*/
typedef struct adc_callback_data {
uint32 irq_flags;
void *arg;
} adc_callback_data;
/**
* TODO document
*/
typedef struct adc_private_data {
void (*handler)(adc_callback_data*);
uint32 handler_flags;
adc_callback_data cb_data;
} adc_private_data;
/* Pull in the series header
*
* 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.
*/
#include <series/adc.h>
/*
* Routines
*/
extern void adc_init(const adc_dev *dev);
/**
* @brief Set external event select for regular group
* @param dev ADC device
* @param event Event used to trigger the start of conversion.
* @see adc_extsel_event
*/
extern void adc_set_extsel(const adc_dev *dev, adc_extsel_event event);
/**
* @brief Set the sample rate for all channels on an ADC device.
*
* Don't call this during conversion.
*
* @param dev adc device
* @param smp_rate sample rate to set
* @see adc_smp_rate
*/
extern void adc_set_sample_rate(const adc_dev *dev, adc_smp_rate smp_rate);
/**
* @brief Enable scan mode for an ADC.
*
* In scan mode, the ADC converts all channels in a regular or
* injected sequence. After each conversion is done, the ADC
* automatically starts converting the next channel in the sequence.
*
* Scan mode is disabled by default.
*
* @see adc_disable_scan()
*/
extern void adc_enable_scan(const adc_dev *dev);
/**
* @brief Disable scan mode for an ADC.
*
* This is the default setting.
*
* @see adc_enable_scan()
*/
extern void adc_disable_scan(const adc_dev *dev);
/**
* @brief Enable continuous mode for an ADC.
*
* In this mode, the ADC will automatically perform conversions
* continuously until taken out of this mode or disabled.
*
* Continuous mode is disabled by default.
*
* @see adc_disable_continuous()
*/
extern void adc_enable_continuous(const adc_dev *dev);
/**
* @brief Disable continuous mode for an ADC.
*
* This is the default setting.
*
* @see adc_enable_continuous()
*/
extern void adc_disable_continuous(const adc_dev *dev);
/**
* @brief Set the sequence of channels to convert.
*
* This sets the (regular) sequence of up to 16 channels to convert.
*
* @param dev ADC device
* @param channels ADC channels to convert; these can repeat and may
* be in any order.
* @param len Length of `channels', from 1 to 16.
* @see adc_start_conv()
*/
extern void adc_set_conv_seq(const adc_dev *dev, const uint8 *channels, uint8 len);
/**
* @brief Attach an interrupt handler and enable its interrupts.
*
* This function sets `handler' as the function to be called when any
* ADC interrupts for `dev' occur. At most one ADC interrupt handler
* may be attached at any time. Subsequent calls to this function will
* overwrite any previously attached handler.
*
* When `handler' is called, its argument will point to a struct
* adc_callback_data. The .irq_flags field in this struct will be a
* logical OR of adc_interrupt_id values encoding the reason(s) for
* the call. Its .arg field will be the `arg' argument to this
* function.
*
* The interrupt bits set in the adc_callback_data's .irq_flags will
* always be a subset of those set in the `interrupt_flags' argument
* to this function. That is, interrupts not given here in the
* `interrupt_flags' argument will never cause `handler' to be
* called. This has the effect that any enabled ADC interrupts not
* specified in `interrupt_flags' will be ignored.
*
* This function additionally enables the ADC interrupts specified by
* `interrupt_flags'.
*
* @param dev ADC device whose interrupts to attach to.
* @param interrupt_flags Logical or of adc_interrupt_id values
* specifying interrupts to enable.
* @param handler Interrupt handler to call when any interrupt in
* interrupt_flags occurs.
* @param arg Value to store in .arg field of handler's callback data.
* @see enum adc_interrupt_id
* @see struct adc_callback_data
*/
extern void adc_attach_interrupt(const adc_dev *dev, uint32 interrupt_flags,
void (*handler)(adc_callback_data*), void *arg);
/**
* @brief Disable ADC interrupts and detach interrupt handlers.
*
* This function disables all interrupts for `dev', and unsets any
* handler attached with adc_attach_interrupt().
*
* @param dev ADC device whose handler to detach.
*/
extern void adc_detach_interrupt(const adc_dev *dev);
/**
* @brief Enable ADC interrupts
* @param dev ADC device
* @param interrupt_flags Logical or of adc_interrupt_id values to enable.
* @see adc_disable_interrupt()
* @see adc_attach_interrupt()
*/
extern void adc_enable_interrupts(const adc_dev *dev, uint32 interrupt_flags);
/**
* @brief Disable ADC interrupts.
* @param dev ADC device
* @param interrupt_flags Logical or of adc_interrupt_id values to disable.
* @brief adc_enable_interrupt()
*/
extern void adc_disable_interrupts(const adc_dev *dev, uint32 interrupt_flags);
/**
* @brief Perform a single synchronous software triggered conversion on a
* channel.
* @param dev ADC device to use for reading.
* @param channel channel to convert
* @return conversion result
*/
extern uint16 adc_read(const 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)(const adc_dev*));
struct gpio_dev;
/**
* @brief Configure a GPIO pin for ADC conversion.
* @param dev ADC device to use for conversion (currently ignored on
* all targets).
* @param gdev GPIO device to configure.
* @param bit Bit on gdev to configure for ADC conversion.
*/
extern void adc_config_gpio(const 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(const 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.
*/
extern void adc_set_reg_seqlen(const adc_dev *dev, uint8 length);
/**
* @brief Enable an adc peripheral
* @param dev ADC device to enable
*/
extern void adc_enable(const adc_dev *dev);
/**
* @brief Disable an ADC peripheral
* @param dev ADC device to disable
*/
extern void adc_disable(const adc_dev *dev);
/**
* @brief Disable all ADC peripherals.
*/
static inline void adc_disable_all(void) {
adc_foreach(adc_disable);
}
/*
* private
*/
extern void _adc_enable_dev_irq(const adc_dev *dev);
#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,100 @@
/******************************************************************************
* The MIT License
*
* Copyright (c) 2010 LeafLabs, LLC.
* Copyright (c) 2013 OpenMusicKontrollers.
*
* 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
* @author F3-port by Hanspeter Portner <dev@open-music-kontrollers.ch>
* @brief Backup register support (STM32F1 & STM32F3 only).
*/
#ifndef _LIBMAPLE_BKP_H_
#define _LIBMAPLE_BKP_H_
#ifdef __cplusplus
extern "C" {
#endif
#include <libmaple/libmaple.h>
#include <series/bkp.h>
/** Backup peripheral device type. */
typedef struct bkp_dev {
bkp_reg_map *regs; /**< Register map */
} bkp_dev;
extern const struct bkp_dev *BKP;
/*
* this function needs to be implemented for each series separately
*/
extern inline __io uint32* bkp_data_register(uint8 reg);
/**
* @brief Initialize backup interface.
*
* Enables the power and backup interface clocks, and resets the
* backup device.
*/
void bkp_init(void);
/**
* Enable write access to the backup registers. Backup interface must
* be initialized for subsequent register writes to work.
* @see bkp_init()
*/
void bkp_enable_writes(void);
/**
* Disable write access to the backup registers.
*/
void bkp_disable_writes(void);
/**
* Read a value from given backup data register.
* @param reg Data register to read, from 1 to BKP_NR_DATA_REGS (10 on
* medium-density devices, 42 on high-density devices).
*/
uint16 bkp_read(uint8 reg);
/**
* @brief Write a value to given data register.
*
* Write access to backup registers must be enabled.
*
* @param reg Data register to write, from 1 to BKP_NR_DATA_REGS (10
* on medium-density devices, 42 on high-density devices).
* @param val Value to write into the register.
* @see bkp_enable_writes()
*/
void bkp_write(uint8 reg, uint16 val);
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif

View File

@ -0,0 +1,46 @@
/******************************************************************************
* The MIT License
*
* Copyright (c) 2013 OpenMusicKontrollers.
*
* 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/fpu.h
* @author F3-port by Hanspeter Portner <dev@open-music-kontrollers.ch>
* @brief Floating Point Unit (COMP) interace.
*/
#ifndef _LIBMAPLE_COMP_H_
#define _LIBMAPLE_COMP_H_
#ifdef __cplusplus
extern "C"{
#endif
#include <series/comp.h>
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,158 @@
/******************************************************************************
* 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
#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);
#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,444 @@
/******************************************************************************
* 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. */
#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,131 @@
/******************************************************************************
* The MIT License
*
* Copyright (c) 2013 OpenMusicKontrollers.
*
* 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/dsp.h
* @author F3-port by Hanspeter Portner <dev@open-music-kontrollers.ch>
* @brief Convenience macros for the digital signal processing (DSP)
* instruction set of the ARM Cortex M4 microcontroller.
*/
#ifndef _LIBMAPLE_DSP_H_
#define _LIBMAPLE_DSP_H_
#ifdef __cplusplus
extern "C"{
#endif
#define DSP3(ID, A, B, C) \
({ \
uint32_t X; \
asm volatile (ID" %[res], %[val1], %[val2], %[val3]" \
: [res]"=r" (X) \
: [val1]"r" (A), [val2]"r" (B), [val3]"r" (C) \
); \
(uint32_t)X; \
})
#define DSP2(ID, A, B) \
({ \
uint32_t X; \
asm volatile (ID" %[res], %[val1], %[val2]" \
: [res]"=r" (X) \
: [val1]"r" (A), [val2]"r" (B) \
);\
(uint32_t)X; \
})
#define DSP1(ID, A) \
({ \
uint32_t X; \
asm volatile (ID" %[res], %[val1]" \
: [res]"=r" (X) \
: [val1]"r" (A) \
); \
(uint32_t)X; \
})
/* General data processing instructions */
#define __rev16(A) DSP1("REV16", A)
//TODO
/* Multiply and divide instructions */
//TODO
/* Saturating instructions */
//TODO
/* Packing and unpacking instructions */
//TODO
/* Bitfield instructions */
//TODO
/* Floating-point instructions */
//TODO
/* Miscellaneous instructions */
//TODO
/* SIMD instructions (single instruction multiple data) */
#define __sadd16(A, B) DSP2("SADD16", A, B)
#define __shadd16(A, B) DSP2("SHADD16", A, B)
#define __ssub16(A, B) DSP2("SSUB16", A, B)
#define __shsub16(A, B) DSP2("SHSUB16", A, B)
#define __uadd16(A, B) DSP2("UADD16", A, B)
#define __uhadd16(A, B) DSP2("UHADD16", A, B)
#define __usub16(A, B) DSP2("USUB16", A, B)
#define __uhsub16(A, B) DSP2("UHSUB16", A, B)
#define __sadd8(A, B) DSP2("SADD8", A, B)
#define __shadd8(A, B) DSP2("SHADD8", A, B)
#define __ssub8(A, B) DSP2("SSUB8", A, B)
#define __shsub8(A, B) DSP2("SHSUB8", A, B)
#define __uadd8(A, B) DSP2("UADD8", A, B)
#define __uhadd8(A, B) DSP2("UHADD8", A, B)
#define __usub8(A, B) DSP2("USUB8", A, B)
#define __uhsub8(A, B) DSP2("UHSUB8", A, B)
#define __sasx(A, B) DSP2("SASX", A, B)
#define __ssax(A, B) DSP2("SSAX", A, B)
#define __shasx(A, B) DSP2("SHASX", A, B)
#define __shsax(A, B) DSP2("SHSAX", A, B)
#define __uasx(A, B) DSP2("UASX", A, B)
#define __usax(A, B) DSP2("USAX", A, B)
#define __uhasx(A, B) DSP2("UHASX", A, B)
#define __uhsax(A, B) DSP2("UHSAX", A, B)
#define __usad8(A, B) DSP2("USAD8", A, B)
#define __usada8(A, B, C) DSP3("USADA8", A, B, C)
/* MAC instructions (multiply and accumulate) */
/* TODO */
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,143 @@
/******************************************************************************
* 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
#include <series/exti.h> /* provides EXTI_BASE */
#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,106 @@
/******************************************************************************
* 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.
*/
#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,56 @@
/******************************************************************************
* The MIT License
*
* Copyright (c) 2013 OpenMusicKontrollers.
*
* 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/fpu.h
* @author F3-port by Hanspeter Portner <dev@open-music-kontrollers.ch>
* @brief Floating Point Unit (FPU) interace.
*/
#ifndef _LIBMAPLE_FPU_H_
#define _LIBMAPLE_FPU_H_
#ifdef __cplusplus
extern "C"{
#endif
#include <series/fpu.h>
/**
* @brief Enable floating point unit.
*/
void fpu_enable(void);
/**
* @brief Disable floating point unit.
*/
void fpu_disable(void);
#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,121 @@
/******************************************************************************
* 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)
*/
#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);
/**
* @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,304 @@
/******************************************************************************
* The MIT License
*
* Copyright (c) 2010 Perry Hung.
* Copyright (c) 2012 LeafLabs, LLC.
* Copyright (c) 2013 OpenMusicKontrollers.
*
* 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
* @author F3-port by Hanspeter Portner <dev@open-music-kontrollers.ch>
* @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.
*/
#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>
/**
* @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;
/* 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
/* I2C error flags */
#define I2C_ERROR_PROTOCOL (-1)
#define I2C_ERROR_TIMEOUT (-2)
/* Main I2C API */
/**
* @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;
}
/**
* @brief Wait for an I2C event, or time out in case of error.
* @param dev I2C device
* @param state I2C_state state to wait for
* @param timeout Timeout, in milliseconds
* @return 0 if target state is reached, a negative value on error.
*/
extern int32 wait_for_state_change(i2c_dev *dev,
i2c_state state,
uint32 timeout);
/**
* @brief Reset an I2C bus.
*
* Reset is accomplished by clocking out pulses until any hung slaves
* release SDA and SCL, then generating a START condition, then a STOP
* condition.
*
* @param dev I2C device
*/
extern void i2c_bus_reset(const i2c_dev *dev);
/**
* @brief Initialize an I2C device as bus master
* @param dev Device to enable
* @param flags Bitwise or of the following I2C options:
* I2C_FAST_MODE: 400 khz operation,
* I2C_DUTY_16_9: 16/9 Tlow/Thigh duty cycle (only applicable for
* fast mode),
* I2C_BUS_RESET: Reset the bus and clock out any hung slaves on
* initialization,
* I2C_10BIT_ADDRESSING: Enable 10-bit addressing,
* I2C_REMAP: (deprecated, STM32F1 only) Remap I2C1 to SCL/PB8
* SDA/PB9.
*/
extern void i2c_master_enable(i2c_dev *dev, uint32 flags);
/**
* @brief Process an i2c transaction.
*
* Transactions are composed of one or more i2c_msg's, and may be read
* or write tranfers. Multiple i2c_msg's will generate a repeated
* start in between messages.
*
* @param dev I2C device
* @param msgs Messages to send/receive
* @param num Number of messages to send/receive
* @param timeout Bus idle timeout in milliseconds before aborting the
* transfer. 0 denotes no timeout.
* @return 0 on success,
* I2C_ERROR_PROTOCOL if there was a protocol error,
* I2C_ERROR_TIMEOUT if the transfer timed out.
*/
extern int32 i2c_master_xfer(i2c_dev *dev,
i2c_msg *msgs,
uint16 num,
uint32 timeout);
/**
* @brief Fill data register with slave address
* @param dev I2C device
* @param addr Slave address
* @param rw Read/write bit
*/
extern void i2c_send_slave_addr(i2c_dev *dev, uint32 addr, uint32 rw);
/* Start/stop conditions */
/**
* @brief Generate a start condition on the bus.
* @param dev I2C device
*/
extern void i2c_start_condition(i2c_dev *dev);
/**
* @brief Generate a stop condition on the bus
* @param dev I2C device
*/
extern void i2c_stop_condition(i2c_dev *dev);
/* 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
/**
* @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).
*/
extern void i2c_enable_irq(i2c_dev *dev, uint32 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).
*/
extern void i2c_disable_irq(i2c_dev *dev, uint32 irqs);
/* ACK/NACK */
/**
* @brief Enable I2C acknowledgment
* @param dev I2C device
*/
extern void i2c_enable_ack(i2c_dev *dev);
/**
* @brief Disable I2C acknowledgment
* @param dev I2C device
*/
extern void i2c_disable_ack(i2c_dev *dev);
/* 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 */
/**
* @brief Initialize an I2C device and reset its registers to their
* default values.
* @param dev Device to initialize.
*/
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
*/
extern void i2c_write(i2c_dev *dev, uint8 byte);
#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,73 @@
/******************************************************************************
* 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_
#ifdef __cplusplus
extern "C" {
#endif
typedef unsigned char uint8;
typedef unsigned short uint16;
typedef unsigned int 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))
#define __always_inline inline __attribute__((always_inline))
#define __unused __attribute__((unused))
#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,155 @@
/******************************************************************************
* 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).
*/
#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 __always_inline void nvic_globalirq_enable() {
asm volatile("cpsie i");
}
/**
* Disable interrupts and configurable fault handlers (set PRIMASK).
*/
static __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,46 @@
/******************************************************************************
* The MIT License
*
* Copyright (c) 2013 OpenMusicKontrollers.
*
* 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/fpu.h
* @author F3-port by Hanspeter Portner <dev@open-music-kontrollers.ch>
* @brief Floating Point Unit (OPAMP) interace.
*/
#ifndef _LIBMAPLE_OPAMP_H_
#define _LIBMAPLE_OPAMP_H_
#ifdef __cplusplus
extern "C"{
#endif
#include <series/opamp.h>
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,115 @@
/******************************************************************************
* 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>
#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,175 @@
/******************************************************************************
* 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;
#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;
}
#ifdef __cplusplus
} // extern "C"
#endif
#endif

View File

@ -0,0 +1,188 @@
/******************************************************************************
* 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 */
uint16 head; /**< Index of the next item to remove */
uint16 tail; /**< Index where the next item will get inserted */
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;
}
/**
* @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,487 @@
/******************************************************************************
* The MIT License
*
* Copyright (c) 2011, 2012 LeafLabs, LLC.
* Copyright (c) 2010 Perry Hung.
* Copyright (c) 2013 OpenMusicKontrollers.
*
* 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>,
* F3-port by Hanspeter Portner <dev@open-music-kontrollers.ch>
* @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>
#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 /* FIXME F3 incompatibility */
#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()
*/
extern uint16 spi_rx_reg(spi_dev *dev);
/**
* @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 Nonblocking SPI transmit.
* @param dev SPI port to use for transmission
* @param buf Buffer to transmit. The sizeof buf's elements are
* inferred from dev's data frame format (i.e., are
* correctly treated as 8-bit or 16-bit quantities).
* @param len Maximum number of elements to transmit.
* @return Number of elements transmitted.
*/
extern uint32 spi_tx(spi_dev *dev, const void *buf, uint32 len);
/**
* @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; /* FIXME F3 incompatibility */
}
/**
* @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;
}
/*
* SPI auxiliary routines
*/
extern void spi_reconfigure(spi_dev *dev, uint32 cr1_config);
/*
* I2S convenience functions (TODO)
*/
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,239 @@
/******************************************************************************
* 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
/** STM32F3 series. */
#define STM32_SERIES_F3 3
/** STM32F4 series. */
#define STM32_SERIES_F4 4
/* 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.
*/
#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,116 @@
/******************************************************************************
* The MIT License
*
* Copyright (c) 2012 LeafLabs, LLC.
* Copyright (c) 2013 OpenMusicKontrollers.
*
* 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
* @author F3-port by Hanspeter Portner <dev@open-music-kontrollers.ch>
* @brief System configuration controller (SYSCFG)
*
* Availability: STM32F2, STM32F3, STM32F4.
*/
#ifndef _LIBMAPLE_SYSCFG_H_
#define _LIBMAPLE_SYSCFG_H_
#ifdef __cplusplus
extern "C" {
#endif
#include <series/syscfg.h>
#include <libmaple/rcc.h>
/* 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
/*
* Routines
*/
/**
* @brief Initialize the SYSCFG peripheral.
*/
void syscfg_init(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. */
SYSCFG_MEM_MODE_FLASH = 0x0,
/** System flash (i.e. ST's baked-in bootloader) is mapped at 0x0. */
SYSCFG_MEM_MODE_SYSTEM_FLASH = 0x1,
/** FSMC bank 1 (NOR/PSRAM 1 and 2) is mapped at 0x0. */
SYSCFG_MEM_MODE_FSMC_BANK_1 = 0x2,
/** Embedded SRAM (i.e., not backup SRAM) is mapped at 0x0. */
SYSCFG_MEM_MODE_SRAM = 0x3,
} syscfg_mem_mode;
/**
* @brief Set the memory to be mapped at address 0x00000000.
*
* This function can be used to override the BOOT pin
* configuration. Some restrictions apply; see your chip's reference
* manual for the details.
*
* @param mode Mode to set
* @see syscfg_mem_mode
*/
void syscfg_set_mem_mode(syscfg_mem_mode);
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,115 @@
/******************************************************************************
* 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;
}
#ifdef __cplusplus
} // extern "C"
#endif
#endif

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,464 @@
/******************************************************************************
* 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>,
* F3-port by Hanspeter Portner <dev@open-music-kontrollers.ch>
* @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>
#include <series/usart.h>
/*
* Register bit definitions
*/
/* Status register */
/** 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
/** 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 */
/** 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
/** 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)
/* 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)
/* 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
/** USART device type */
typedef struct usart_dev {
usart_reg_map *regs; /**< Register map */
ring_buffer *rb; /**< RX 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. */
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));
/**
* @brief Nonblocking USART transmit
* @param dev Serial port to transmit over
* @param buf Buffer to transmit
* @param len Maximum number of bytes to transmit
* @return Number of bytes transmitted
*/
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 successfully
* transmitted.
*
* @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);
}
/**
* @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);
}
#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,179 @@
/******************************************************************************
* 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_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 __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,62 @@
/******************************************************************************
* 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/iwdg.c
* @brief Independent watchdog (IWDG) support
*/
#include <libmaple/iwdg.h>
/**
* @brief Initialise and start the watchdog
*
* The prescaler and reload set the timeout. For example, a prescaler
* of IWDG_PRE_32 divides the 40 kHz clock by 32 and gives roughly 1
* ms per reload.
*
* @param prescaler Prescaler for the 40 kHz IWDG clock.
* @param reload Independent watchdog counter reload value.
*/
void iwdg_init(iwdg_prescaler prescaler, uint16 reload) {
IWDG_BASE->KR = IWDG_KR_UNLOCK;
IWDG_BASE->PR = prescaler;
IWDG_BASE->RLR = reload;
/* Start things off */
IWDG_BASE->KR = IWDG_KR_START;
iwdg_feed();
}
/**
* @brief Reset the IWDG counter.
*
* Calling this function will cause the IWDG counter to be reset to
* its reload value.
*/
void iwdg_feed(void) {
IWDG_BASE->KR = IWDG_KR_FEED;
}

View File

@ -0,0 +1,103 @@
/******************************************************************************
* 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/nvic.c
* @brief Nested vector interrupt controller support.
*/
#include <libmaple/nvic.h>
#include <libmaple/scb.h>
#include <libmaple/stm32.h>
/**
* @brief Set interrupt priority for an interrupt line
*
* Note: The STM32 only implements 4 bits of priority, ignoring the
* lower 4 bits. This means there are only 16 levels of priority.
* Bits[3:0] read as zero and ignore writes.
*
* @param irqn device to set
* @param priority Priority to set, 0 being highest priority and 15
* being lowest.
*/
void nvic_irq_set_priority(nvic_irq_num irqn, uint8 priority) {
if (irqn < 0) {
/* This interrupt is in the system handler block */
SCB_BASE->SHP[((uint32)irqn & 0xF) - 4] = (priority & 0xF) << 4;
} else {
NVIC_BASE->IP[irqn] = (priority & 0xF) << 4;
}
}
/**
* @brief Initialize the NVIC, setting interrupts to a default priority.
*/
void nvic_init(uint32 address, uint32 offset) {
uint32 i;
nvic_set_vector_table(address, offset);
/*
* Lower priority level for all peripheral interrupts to lowest
* possible.
*/
for (i = 0; i < STM32_NR_INTERRUPTS; i++) {
nvic_irq_set_priority((nvic_irq_num)i, 0xF);
}
/* Lower systick interrupt priority to lowest level */
nvic_irq_set_priority(NVIC_SYSTICK, 0xF);
}
/**
* @brief Set the vector table base address.
*
* For stand-alone products, the vector table base address is normally
* the start of Flash (0x08000000).
*
* @param address Vector table base address.
* @param offset Offset from address. Some restrictions apply to the
* use of nonzero offsets; see the ARM Cortex M3
* Technical Reference Manual.
*/
void nvic_set_vector_table(uint32 address, uint32 offset) {
SCB_BASE->VTOR = address | (offset & 0x1FFFFF80);
}
/**
* @brief Force a system reset.
*
* Resets all major system components, excluding debug.
*/
void nvic_sys_reset() {
uint32 prigroup = SCB_BASE->AIRCR & SCB_AIRCR_PRIGROUP;
SCB_BASE->AIRCR = SCB_AIRCR_VECTKEY | SCB_AIRCR_SYSRESETREQ | prigroup;
asm volatile("dsb");
while (1)
;
}

View File

@ -0,0 +1,41 @@
/******************************************************************************
* 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/pwr.c
* @brief Power control (PWR) support.
*/
#include <libmaple/pwr.h>
#include <libmaple/rcc.h>
/**
* Enables the power interface clock, and resets the power device.
*/
void pwr_init(void) {
rcc_clk_enable(RCC_PWR);
rcc_reset_dev(RCC_PWR);
}

View File

@ -0,0 +1,169 @@
/******************************************************************************
* 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/rcc.c
* @brief Portable RCC routines.
*/
#include <libmaple/rcc.h>
#include "rcc_private.h"
/**
* @brief Get a peripheral's clock domain
* @param id Clock ID of the peripheral whose clock domain to return
* @return Clock source for the given clock ID
*/
rcc_clk_domain rcc_dev_clk(rcc_clk_id id) {
return rcc_dev_table[id].clk_domain;
}
/**
* @brief Switch the clock used as the source of the system clock.
*
* After switching the source, this function blocks until the new
* clock source is in use.
*
* @param sysclk_src New system clock source.
* @see rcc_sysclk_src
*/
void rcc_switch_sysclk(rcc_sysclk_src sysclk_src) {
uint32 cfgr = RCC_BASE->CFGR;
cfgr &= ~RCC_CFGR_SW;
cfgr |= sysclk_src;
/* Switch SYSCLK source. */
RCC_BASE->CFGR = cfgr;
/* Wait for new source to come into use. */
while ((RCC_BASE->CFGR & RCC_CFGR_SWS) != (sysclk_src << 2))
;
}
/*
* Turning clocks off and on, querying their status.
*/
/* IMPORTANT NOTE FOR IMPLEMENTORS:
*
* libmaple assumes that enum rcc_clk enumerators are two-byte
* values, stored in a uint16, in the following way:
*
* - The high-order byte is the byte offset (from RCC_BASE) of the register
* to touch when turning on or off the given clock.
*
* - The low-order byte is the bit in that register that turns the
* clock on or off.
*
* Example for STM32F1: Turning on the high-speed external clock (HSE)
* involves setting HSEON, bit 16, of RCC_CR. The high-order byte is
* then offsetof(struct rcc_reg_map, CR) = 0, and the low-order byte
* is 16.
*
* The corresponding value of RCC_CLK_HSE is thus (0 << 8) | 16 = 16.
*
* On all known STM32 series, this encoding has the property that
* adding one to the low byte also gives the bit to check to determine
* if the clock is ready. For example, on STM32F1, RCC_CR_HSERDY is
* bit 17. If that's not the case on your series, rcc_is_clk_ready()
* won't work for you. */
/* Returns the RCC register which controls the clock source. */
static inline __io uint32* rcc_clk_reg(rcc_clk clock) {
return (__io uint32*)((__io uint8*)RCC_BASE + (clock >> 8));
}
/* Returns a mask in rcc_clk_reg(clock) to be used for turning the
* clock on and off */
static inline uint32 rcc_clk_on_mask(rcc_clk clock) {
return 1 << (clock & 0xFF);
}
/* Returns a mask in rcc_clk_reg(clock) to be used when checking the
* readiness of the clock. */
static inline uint32 rcc_clk_ready_mask(rcc_clk clock) {
return rcc_clk_on_mask(clock) << 1;
}
/**
* @brief Turn on a clock source.
*
* After this routine exits, callers should ensure that the clock
* source is ready by waiting until rcc_is_clk_ready(clock) returns
* true.
*
* @param clock Clock to turn on.
* @see rcc_turn_off_clk()
* @see rcc_is_clk_ready()
*/
void rcc_turn_on_clk(rcc_clk clock) {
*rcc_clk_reg(clock) |= rcc_clk_on_mask(clock);
}
/**
* @brief Turn off a clock source.
*
* In certain configurations, certain clock sources cannot be safely
* turned off. (For example, the main PLL on STM32F1 devices cannot be
* turned off if it has been selected as the SYSCLK source). Consult
* the reference material for your MCU to ensure it is safe to call
* this function.
*
* @param clock Clock to turn off.
* @see rcc_turn_on_clk()
* @see rcc_is_clk_ready()
*/
void rcc_turn_off_clk(rcc_clk clock) {
*rcc_clk_reg(clock) &= ~rcc_clk_on_mask(clock);
}
/**
* @brief Check if a clock is on.
* @param clock Clock to check.
* @return 1 if the clock is on, 0 if the clock is off.
*/
int rcc_is_clk_on(rcc_clk clock) {
return !!(*rcc_clk_reg(clock) & rcc_clk_on_mask(clock));
}
/**
* @brief Check if a clock source is ready.
*
* In general, it is not safe to rely on a clock source unless this
* function returns nonzero. Also note that this function may return
* nonzero for a short period of time after a clock has been turned
* off. Consult the reference material for your MCU for more details.
*
* @param clock Clock whose readiness to check for.
* @return Nonzero if the clock is ready, zero otherwise.
* @see rcc_turn_on_clk()
* @see rcc_turn_off_clk()
*/
int rcc_is_clk_ready(rcc_clk clock) {
return (int)(*rcc_clk_reg(clock) & rcc_clk_ready_mask(clock));
}

View File

@ -0,0 +1,67 @@
/******************************************************************************
* 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;
}
#endif

View File

@ -0,0 +1,53 @@
# 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
ifeq ($(MCU_SERIES),$(filter $(MCU_SERIES),stm32f2 stm32f3)) # SYSCFG peripheral available only on F2, F3
cSRCS_$(d) += syscfg.c
endif
cSRCS_$(d) += timer.c
cSRCS_$(d) += usart.c
cSRCS_$(d) += usart_private.c
cSRCS_$(d) += util.c
sSRCS_$(d) := exc.S
ifeq ($(MCU_SERIES),$(filter $(MCU_SERIES),stm32f1 stm32f3)) # TODO port I2C to F2
cSRCS_$(d) += i2c.c
cSRCS_$(d) += bkp.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,129 @@
/******************************************************************************
* 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/spi.c
* @author Marti Bolivar <mbolivar@leaflabs.com>
* @brief Serial Peripheral Interface (SPI) support.
* Currently, there is no Integrated Interchip Sound (I2S) support.
*/
#include <libmaple/spi.h>
#include <libmaple/bitband.h>
/*
* SPI convenience routines
*/
/**
* @brief Initialize and reset a SPI device.
* @param dev Device to initialize and reset.
*/
void spi_init(spi_dev *dev) {
rcc_clk_enable(dev->clk_id);
rcc_reset_dev(dev->clk_id);
}
/**
* @brief Configure and enable a SPI device as bus master.
*
* The device's peripheral will be disabled before being reconfigured.
*
* @param dev Device to configure as bus master
* @param baud Bus baud rate
* @param mode SPI mode
* @param flags Logical OR of spi_cfg_flag values.
* @see spi_cfg_flag
*/
void spi_master_enable(spi_dev *dev,
spi_baud_rate baud,
spi_mode mode,
uint32 flags) {
spi_reconfigure(dev, baud | flags | SPI_CR1_MSTR | mode);
}
/**
* @brief Configure and enable a SPI device as a bus slave.
*
* The device's peripheral will be disabled before being reconfigured.
*
* @param dev Device to configure as a bus slave
* @param mode SPI mode
* @param flags Logical OR of spi_cfg_flag values.
* @see spi_cfg_flag
*/
void spi_slave_enable(spi_dev *dev, spi_mode mode, uint32 flags) {
spi_reconfigure(dev, flags | mode);
}
/**
* @brief Enable a SPI peripheral
* @param dev Device to enable
*/
void spi_peripheral_enable(spi_dev *dev) {
bb_peri_set_bit(&dev->regs->CR1, SPI_CR1_SPE_BIT, 1);
}
/**
* @brief Disable a SPI peripheral
* @param dev Device to disable
*/
void spi_peripheral_disable(spi_dev *dev) {
bb_peri_set_bit(&dev->regs->CR1, SPI_CR1_SPE_BIT, 0);
}
/**
* @brief Enable DMA requests whenever the transmit buffer is empty
* @param dev SPI device on which to enable TX DMA requests
*/
void spi_tx_dma_enable(spi_dev *dev) {
bb_peri_set_bit(&dev->regs->CR2, SPI_CR2_TXDMAEN_BIT, 1);
}
/**
* @brief Disable DMA requests whenever the transmit buffer is empty
* @param dev SPI device on which to disable TX DMA requests
*/
void spi_tx_dma_disable(spi_dev *dev) {
bb_peri_set_bit(&dev->regs->CR2, SPI_CR2_TXDMAEN_BIT, 0);
}
/**
* @brief Enable DMA requests whenever the receive buffer is empty
* @param dev SPI device on which to enable RX DMA requests
*/
void spi_rx_dma_enable(spi_dev *dev) {
bb_peri_set_bit(&dev->regs->CR2, SPI_CR2_RXDMAEN_BIT, 1);
}
/**
* @brief Disable DMA requests whenever the receive buffer is empty
* @param dev SPI device on which to disable RX DMA requests
*/
void spi_rx_dma_disable(spi_dev *dev) {
bb_peri_set_bit(&dev->regs->CR2, SPI_CR2_RXDMAEN_BIT, 0);
}

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,412 @@
/******************************************************************************
* The MIT License
*
* Copyright (c) 2012 LeafLabs, LLC.
* Copyright (c) 2010 Perry Hung.
* Copyright (c) 2013 OpenMusicKontrollers.
*
* 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/stm32f3/adc.c
* @author Marti Bolivar <mbolivar@leaflabs.com>,
* Perry Hung <perry@leaflabs.com>,
* F3-port by Hanspeter Portner <dev@open-music-kontrollers.ch>
* @brief STM32F3 ADC support.
*/
#include <libmaple/adc.h>
#include <libmaple/gpio.h>
#include <libmaple/nvic.h>
/*
* Devices
*/
static adc_private_data adc1_priv;
static adc_dev adc1 = {
.regs = ADC1_BASE,
.clk_id = RCC_ADC12,
.priv = &adc1_priv
};
/** ADC1 device. */
const adc_dev *ADC1 = &adc1;
static adc_private_data adc2_priv;
static adc_dev adc2 = {
.regs = ADC2_BASE,
.clk_id = RCC_ADC12,
.priv = &adc2_priv
};
/** ADC2 device. */
const adc_dev *ADC2 = &adc2;
#if STM32_F3_LINE == STM32_F3_LINE_303
static adc_private_data adc3_priv;
static adc_dev adc3 = {
.regs = ADC3_BASE,
.clk_id = RCC_ADC34,
.priv = &adc3_priv
};
/** ADC3 device. */
const adc_dev *ADC3 = &adc3;
static adc_private_data adc4_priv;
static adc_dev adc4 = {
.regs = ADC4_BASE,
.clk_id = RCC_ADC34,
.priv = &adc4_priv
};
/** ADC4 device. */
const adc_dev *ADC4 = &adc4;
#endif
/*
* STM32F3 routines
*/
static inline void adc_check_regular_notongoing(const adc_dev *dev) {
adc_reg_map *regs = dev->regs;
if(regs->CR & ADC_CR_ADSTART) /* check for ongoing regular channel conversion */
{
regs->CR |= ADC_CR_ADSTP; /* stop regular channel conversion */
while(regs->CR & ADC_CR_ADSTP)
; /* wait for conversion to stop */
}
}
static inline void adc_check_injected_notongoing(const adc_dev *dev) {
adc_reg_map *regs = dev->regs;
if(regs->CR & ADC_CR_JADSTART) /* check for ongoing injected channel conversion */
{
regs->CR |= ADC_CR_JADSTP; /* stop injected channel conversion */
while(regs->CR & ADC_CR_JADSTP)
; /* wait for conversion to stop */
}
}
void adc_set_extsel(const adc_dev *dev, adc_extsel_event event) {
adc_check_regular_notongoing(dev);
uint32 cfgr = dev->regs->CFGR;
cfgr &= ~ADC_CFGR_EXTSEL;
cfgr |= event;
dev->regs->CFGR = cfgr;
}
void adc_set_resolution(const adc_dev *dev, adc_resolution res) {
adc_check_regular_notongoing(dev);
adc_check_injected_notongoing(dev);
uint32 cfgr = dev->regs->CFGR;
cfgr &= ~ADC_CFGR_RES;
cfgr |= res;
dev->regs->CFGR = cfgr;
}
void adc_set_sample_rate(const adc_dev *dev, adc_smp_rate smp_rate) {
adc_check_regular_notongoing(dev);
adc_check_injected_notongoing(dev);
uint32 adc_smpr1_val = 0, adc_smpr2_val = 0;
int i;
for(i = 0; i < 9; i++) {
/* ADC_SMPR1 determines sample time for channels [1,9] */
adc_smpr1_val |= smp_rate << (i * 3 + 3);
/* ADC_SMPR2 determines sample time for channels [10,18] */
adc_smpr2_val |= smp_rate << (i * 3);
}
dev->regs->SMPR1 = adc_smpr1_val;
dev->regs->SMPR2 = adc_smpr2_val;
}
void adc_enable_scan(const adc_dev *dev) {
/* FIXME nonexistent in F3 series */
}
void adc_disable_scan(const adc_dev *dev) {
/* FIXME nonexistent in F3 series*/
}
void adc_enable_continuous(const adc_dev *dev) {
bb_peri_set_bit(&dev->regs->CFGR, ADC_CFGR_CONT_BIT, 1);
}
void adc_disable_continuous(const adc_dev *dev) {
bb_peri_set_bit(&dev->regs->CFGR, ADC_CFGR_CONT_BIT, 0);
}
#define BITS_PER_SQ 6
#define SQs_PER_SQR 5
void adc_set_conv_seq(const adc_dev *dev, const uint8 *channels, uint8 len) {
ASSERT( (0 < len) && (len <= 16) );
uint8 i;
uint32 val = 0;
uint8 lshift;
__io uint32 *sqr = &dev->regs->SQR1;
for (i=0; i<len; i++)
{
lshift = (i+1) % SQs_PER_SQR;
if (!lshift)
{
*sqr = val;
sqr++;
val = 0;
}
val |= channels[i] << (lshift * BITS_PER_SQ);
}
*sqr = val;
adc_set_reg_seqlen(dev, len);
}
uint16 adc_read(const adc_dev *dev, uint8 channel) {
adc_reg_map *regs = dev->regs;
adc_set_conv_seq(dev, &channel, 1);
regs->CR |= ADC_CR_ADSTART; /* start conversion */
while (!(regs->ISR & ADC_ISR_EOC))
; /* wait until done */
return (uint16)(regs->DR & ADC_DR_RDATA);
}
void adc_attach_interrupt(const adc_dev *dev, uint32 interrupt_flags,
void (*handler)(adc_callback_data*), void *arg) {
adc_private_data *priv = dev->priv;
priv->handler = handler;
priv->handler_flags = interrupt_flags;
priv->cb_data.arg = arg;
adc_enable_interrupts(dev, interrupt_flags);
}
void adc_detach_interrupt(const adc_dev *dev) {
adc_private_data *priv;
adc_disable_interrupts(dev, ADC_ALL_INTERRUPTS);
priv = dev->priv;
priv->handler = NULL;
priv->handler_flags = 0;
}
void adc_enable_interrupts(const adc_dev *dev, uint32 interrupt_flags) {
uint32 ier = dev->regs->IER;
ier |= interrupt_flags;
dev->regs->IER = ier;
_adc_enable_dev_irq(dev);
}
void adc_disable_interrupts(const adc_dev *dev, uint32 interrupt_flags) {
/* Don't use nvic_irq_disable()! IRQs are shared among ADCs. */
uint32 ier = dev->regs->IER;
ier &= ~interrupt_flags;
dev->regs->IER = ier;
}
void adc_calibrate(const adc_dev *dev) {
adc_reg_map *regs = dev->regs;
if( (regs->CR & ADC_CR_ADVREGEN) != ADC_CR_ADVREGEN_ENABLE)
adc_regulator_enable(dev); /* ensure that voltage regulator is enabled */
if(regs->CR & ADC_CR_ADEN)
adc_disable(dev); /* ensure that ADC is disabled */
regs->CR &= ~ADC_CR_ADCALDIF; /* calibrate in single-ended mode */
regs->CR |= ADC_CR_ADCAL; /* start calibration */
while (regs->CR & ADC_CR_ADCAL)
; /* wait until done */
regs->CR |= ADC_CR_ADCALDIF; /* calibrate in differential mode */
regs->CR |= ADC_CR_ADCAL; /* start calibration */
while (regs->CR & ADC_CR_ADCAL)
; /* wait until done */
}
void adc_set_exttrig(const adc_dev *dev, adc_exttrig_mode mode) {
adc_reg_map *regs = dev->regs;
regs->CFGR &= ~ADC_CFGR_EXTEN;
regs->CFGR |= mode;
}
void adc_set_prescaler(adc_prescaler pre) {
if (pre & 0x10) { /* PLL is used as clock source */
ADC12_BASE->CCR &= ~ADC_CCR_CKMODE;
#if STM32_F3_LINE == STM32_F3_LINE_303
ADC34_BASE->CCR &= ~ADC_CCR_CKMODE;
#endif
uint32 cfgr2 = RCC_BASE->CFGR2;
cfgr2 &= ~RCC_CFGR2_ADC12PRES; // clear register
cfgr2 |= (uint32)pre << RCC_CFGR2_ADC12PRES_SHIFT; // set register
#if STM32_F3_LINE == STM32_F3_LINE_303
cfgr2 &= ~RCC_CFGR2_ADC34PRES; // clear register
cfgr2 |= (uint32)pre << RCC_CFGR2_ADC34PRES_SHIFT; // set register
#endif
RCC_BASE->CFGR2 = cfgr2;
} else { /* AHB bus is used as clock source */
/* FIXME does not work with current wirish booting routine */
uint32 tmp;
tmp = ADC12_BASE->CCR;
tmp &= ~ADC_CCR_CKMODE;
tmp |= pre << ADC_CCR_CKMODE_SHIFT;
ADC12_BASE->CCR = tmp;
#if STM32_F3_LINE == STM32_F3_LINE_303
tmp = ADC34_BASE->CCR;
tmp &= ~ADC_CCR_CKMODE;
tmp |= pre << ADC_CCR_CKMODE_SHIFT;
ADC34_BASE->CCR = tmp;
#endif
}
}
void adc_foreach(void (*fn)(const adc_dev*)) {
fn(ADC1);
fn(ADC2);
#if STM32_F3_LINE == STM32_F3_LINE_303
fn(ADC3);
fn(ADC4);
#endif
}
void adc_config_gpio(const adc_dev *ignored, gpio_dev *gdev, uint8 bit) {
gpio_set_modef(gdev, bit, GPIO_MODE_ANALOG, GPIO_MODEF_PUPD_NONE);
}
void adc_enable_single_swstart(const adc_dev *dev) {
#if STM32_F3_LINE == STM32_F3_LINE_303
if ( (dev == ADC1) || (dev == ADC3) )
#else
if (dev == ADC1)
#endif
adc_init(dev); /* FIXME hack needed for wirish, as master and slave ADC share the same reset register */
adc_set_exttrig(dev, ADC_EXTTRIG_MODE_SOFTWARE);
adc_regulator_enable(dev);
adc_calibrate(dev);
adc_enable(dev);
}
void adc_set_reg_seqlen(const adc_dev *dev, uint8 length) {
adc_check_regular_notongoing(dev);
uint32 tmp = dev->regs->SQR1;
tmp &= ~ADC_SQR1_L;
tmp |= (length - 1) & ADC_SQR1_L;
dev->regs->SQR1 = tmp;
}
void adc_enable(const adc_dev *dev) {
adc_reg_map *regs = dev->regs;
while( (regs->CR & ADC_CR_ADVREGEN) != ADC_CR_ADVREGEN_ENABLE)
adc_regulator_enable(dev); /* ensure that voltage regulator is enabled */
regs->CR |= ADC_CR_ADEN; /* enable ADC */
while (!(regs->ISR & ADC_ISR_ADRDY))
; /* wait until ADC is ready */
}
void adc_disable(const adc_dev *dev) {
adc_reg_map *regs = dev->regs;
adc_check_regular_notongoing(dev);
adc_check_injected_notongoing(dev);
regs->CR |= ADC_CR_ADDIS; /* disable ADC */
while(regs->CR & ADC_CR_ADEN)
; /* wait until ADC is effectively disabled */
}
void adc_regulator_enable(const adc_dev *dev) {
adc_reg_map *regs = dev->regs;
regs->CR &= ~ADC_CR_ADVREGEN;
regs->CR |= ADC_CR_ADVREGEN_ENABLE;
delay_us(10); /* 10us are worst case */
}
void adc_regulator_disable(const adc_dev *dev) {
adc_reg_map *regs = dev->regs;
regs->CR &= ~ADC_CR_ADVREGEN;
regs->CR |= ADC_CR_ADVREGEN_DISABLE;
}
/*
* Private API
*/
void _adc_enable_dev_irq(const adc_dev *dev) {
if ( (dev == ADC1) || (dev == ADC2) )
nvic_irq_enable(NVIC_ADC1_2);
#if STM32_F3_LINE == STM32_F3_LINE_303
else {
if (dev == ADC3)
nvic_irq_enable(NVIC_ADC3);
else // dev == ADC4
nvic_irq_enable(NVIC_ADC4);
}
#endif
}
/* IRQ handler for adc_attach_interrupt() */
static __always_inline void adc_irq(const adc_dev *dev) {
adc_private_data *priv = dev->priv;
uint32 irq_flags = dev->regs->ISR & priv->handler_flags;
if (!irq_flags) {
/* The user isn't interested in this IRQ. */
return;
} else if (priv->handler) {
priv->cb_data.irq_flags = irq_flags;
priv->handler(&priv->cb_data);
}
}
/*
* IRQ handlers for adc_attach_interrupt()
*/
/*
void __irq_adc1_2(void) {
adc_irq(ADC1);
adc_irq(ADC2);
}
#if STM32_F3_LINE == STM32_F3_LINE_303
void __irq_adc3(void) {
adc_irq(ADC3);
}
void __irq_adc4(void) {
adc_irq(ADC4);
}
#endif
*/

View File

@ -0,0 +1,49 @@
/******************************************************************************
* The MIT License
*
* Copyright (c) 2010 LeafLabs, LLC.
* Copyright (c) 2013 OpenMusicKontrollers.
*
* 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/stm32f3/bkp.c
* @author F3-port by Hanspeter Portner <dev@open-music-kontrollers.ch>
* @brief STM32F3 backup register support.
*/
#include <libmaple/bkp.h>
#include <libmaple/pwr.h>
#include <libmaple/rcc.h>
void bkp_init(void) {
/* Don't call pwr_init(), or you'll reset the device. We just
* need the clock. */
rcc_clk_enable(RCC_PWR);
}
inline __io uint32* bkp_data_register(uint8 reg) {
if (reg < 1 || reg > BKP_NR_DATA_REGS)
return NULL;
else
return (uint32*)BKP_BASE + (reg-1); // regs are accessed from 1-16
}

View File

@ -0,0 +1,61 @@
/******************************************************************************
* The MIT License
*
* Copyright (c) 2013 OpenMusicKontrollers.
*
* 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/stm32f3/comp.c
* @author F3-port by Hanspeter Portner <dev@open-music-kontrollers.ch>
* @brief STM32F3 Comparator support.
*/
#include <libmaple/comp.h>
/*
* Devices
*/
static comp_dev comp1 = { .regs = COMP1_BASE }; const comp_dev *COMP1 = &comp1;
static comp_dev comp2 = { .regs = COMP2_BASE }; const comp_dev *COMP2 = &comp2;
static comp_dev comp3 = { .regs = COMP3_BASE }; const comp_dev *COMP3 = &comp3;
static comp_dev comp4 = { .regs = COMP4_BASE }; const comp_dev *COMP4 = &comp4;
static comp_dev comp5 = { .regs = COMP5_BASE }; const comp_dev *COMP5 = &comp5;
static comp_dev comp6 = { .regs = COMP6_BASE }; const comp_dev *COMP6 = &comp6;
static comp_dev comp7 = { .regs = COMP7_BASE }; const comp_dev *COMP7 = &comp7;
void __irq_comp123(void) {
//TODO
}
void __irq_com456(void) {
//TODO
}
void __irq_comp7(void) {
//TODO
}
/* TODO
* actually implement me ;-)
*/

View File

@ -0,0 +1,364 @@
/******************************************************************************
* The MIT License
*
* Copyright (c) 2010 Michael Hope.
* Copyright (c) 2012 LeafLabs, LLC.
* Copyright (c) 2013 OpenMusicKontrollers.
*
* 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/stm32f3/dma.c
* @author Marti Bolivar <mbolivar@leaflabs.com>,
* Original implementation by Michael Hope,
* F3-port by Hanspeter Portner <dev@open-music-kontrollers.ch>
* @brief STM32F3 DMA support.
*/
#include <libmaple/dma.h>
#include <libmaple/bitband.h>
/* Hack to ensure inlining in dma_irq_handler() */
#define DMA_GET_HANDLER(dev, tube) (dev->handlers[tube - 1].handler)
#include "dma_private.h"
/*
* Devices
*/
static dma_dev dma1 = {
.regs = DMA1_BASE,
.clk_id = RCC_DMA1,
.handlers = {{ .handler = NULL, .irq_line = NVIC_DMA_CH1 },
{ .handler = NULL, .irq_line = NVIC_DMA_CH2 },
{ .handler = NULL, .irq_line = NVIC_DMA_CH3 },
{ .handler = NULL, .irq_line = NVIC_DMA_CH4 },
{ .handler = NULL, .irq_line = NVIC_DMA_CH5 },
{ .handler = NULL, .irq_line = NVIC_DMA_CH6 },
{ .handler = NULL, .irq_line = NVIC_DMA_CH7 }},
};
/** STM32F3 DMA1 device */
dma_dev *DMA1 = &dma1;
static dma_dev dma2 = {
.regs = DMA2_BASE,
.clk_id = RCC_DMA2,
.handlers = {{ .handler = NULL, .irq_line = NVIC_DMA2_CH1 },
{ .handler = NULL, .irq_line = NVIC_DMA2_CH2 },
{ .handler = NULL, .irq_line = NVIC_DMA2_CH3 },
{ .handler = NULL, .irq_line = NVIC_DMA2_CH4 },
{ .handler = NULL, .irq_line = NVIC_DMA2_CH5 }},
};
/** STM32F3 DMA2 device */
dma_dev *DMA2 = &dma2;
/*
* Auxiliary routines
*/
/* Can channel serve cfg->tube_req_src? */
static int cfg_req_ok(dma_channel channel, dma_tube_config *cfg) {
return (cfg->tube_req_src & 0x7) == channel;
}
/* Can dev serve cfg->tube_req_src? */
static int cfg_dev_ok(dma_dev *dev, dma_tube_config *cfg) {
return (rcc_clk_id)(cfg->tube_req_src >> 3) == dev->clk_id;
}
/* Is addr acceptable for use as DMA src/dst? */
static int cfg_mem_ok(__io void *addr) {
enum dma_atype atype = _dma_addr_type(addr);
return atype == DMA_ATYPE_MEM || atype == DMA_ATYPE_PER;
}
/* Is the direction implied by src->dst supported? */
static int cfg_dir_ok(dma_tube_config *cfg) {
/* We can't do peripheral->peripheral transfers. */
return ((_dma_addr_type(cfg->tube_src) == DMA_ATYPE_MEM) ||
(_dma_addr_type(cfg->tube_dst) == DMA_ATYPE_MEM));
}
static int preconfig_check(dma_dev *dev, dma_channel channel,
dma_tube_config *cfg) {
if (!cfg_req_ok(channel, cfg)) {
return -DMA_TUBE_CFG_EREQ;
}
if (cfg->tube_nr_xfers > 65535) {
return -DMA_TUBE_CFG_ENDATA;
}
if (!cfg_dev_ok(dev, cfg)) {
return -DMA_TUBE_CFG_EDEV;
}
if (!cfg_mem_ok(cfg->tube_src)) {
return -DMA_TUBE_CFG_ESRC;
}
if (!cfg_mem_ok(cfg->tube_dst)) {
return -DMA_TUBE_CFG_EDST;
}
if (!cfg_dir_ok(cfg)) {
return -DMA_TUBE_CFG_EDIR;
}
return DMA_TUBE_CFG_SUCCESS;
}
static inline void set_ccr(dma_tube_reg_map *chregs,
dma_xfer_size msize, int minc,
dma_xfer_size psize, int pinc,
uint32 other_flags) {
chregs->CCR = ((msize << 10) | (psize << 8) |
(minc ? DMA_CCR_MINC : 0) | (pinc ? DMA_CCR_PINC : 0) |
other_flags);
}
static inline uint32 cfg_ccr_flags(unsigned tube_flags) {
/* DMA_CFG_SRC_INC and DMA_CFG_DST_INC are special */
return tube_flags & ~(DMA_CFG_SRC_INC | DMA_CFG_DST_INC);
}
/* Configure chregs according to cfg, where cfg->tube_dst is peripheral. */
static int config_to_per(dma_tube_reg_map *chregs, dma_tube_config *cfg) {
/* Check that ->tube_src is memory (if it's anything else, we
* shouldn't have been called). */
ASSERT(_dma_addr_type(cfg->tube_src) == DMA_ATYPE_MEM);
set_ccr(chregs,
cfg->tube_src_size, cfg->tube_flags & DMA_CFG_SRC_INC,
cfg->tube_dst_size, cfg->tube_flags & DMA_CFG_DST_INC,
(cfg_ccr_flags(cfg->tube_flags) | DMA_CCR_DIR_FROM_MEM));
chregs->CNDTR = cfg->tube_nr_xfers;
chregs->CMAR = (uint32)cfg->tube_src;
chregs->CPAR = (uint32)cfg->tube_dst;
return DMA_TUBE_CFG_SUCCESS;
}
/* Configure chregs according to cfg, where cfg->tube_dst is memory. */
static int config_to_mem(dma_tube_reg_map *chregs, dma_tube_config *cfg) {
uint32 mem2mem;
if ((_dma_addr_type(cfg->tube_src) == DMA_ATYPE_MEM) &&
(cfg->tube_flags & DMA_CFG_CIRC)) {
/* Can't do mem-to-mem and circular mode */
return -DMA_TUBE_CFG_ECFG;
}
mem2mem = (_dma_addr_type(cfg->tube_src) == DMA_ATYPE_MEM ?
DMA_CCR_MEM2MEM : 0);
set_ccr(chregs,
cfg->tube_dst_size, cfg->tube_flags & DMA_CFG_DST_INC,
cfg->tube_src_size, cfg->tube_flags & DMA_CFG_SRC_INC,
(cfg_ccr_flags(cfg->tube_flags) |
DMA_CCR_DIR_FROM_PER |
mem2mem));
chregs->CNDTR = cfg->tube_nr_xfers;
chregs->CMAR = (uint32)cfg->tube_dst;
chregs->CPAR = (uint32)cfg->tube_src;
return DMA_TUBE_CFG_SUCCESS;
}
/*
* Routines
*/
int dma_tube_cfg(dma_dev *dev, dma_channel channel, dma_tube_config *cfg) {
dma_tube_reg_map *chregs;
int ret = preconfig_check(dev, channel, cfg);
if (ret < 0) {
return ret;
}
dma_disable(dev, channel); /* Must disable before reconfiguring */
dma_clear_isr_bits(dev, channel); /* For sanity and consistency
* with STM32F2. */
chregs = dma_tube_regs(dev, channel);
switch (_dma_addr_type(cfg->tube_dst)) {
case DMA_ATYPE_PER:
ret = config_to_per(chregs, cfg);
break;
case DMA_ATYPE_MEM:
ret = config_to_mem(chregs, cfg);
break;
default:
/* Can't happen */
ASSERT(0);
return -DMA_TUBE_CFG_ECFG;
}
if (ret < 0) {
return ret;
}
chregs->CNDTR = cfg->tube_nr_xfers;
return DMA_TUBE_CFG_SUCCESS;
}
void dma_set_priority(dma_dev *dev,
dma_channel channel,
dma_priority priority) {
dma_channel_reg_map *channel_regs;
uint32 ccr;
ASSERT_FAULT(!dma_is_channel_enabled(dev, channel));
channel_regs = dma_channel_regs(dev, channel);
ccr = channel_regs->CCR;
ccr &= ~DMA_CCR_PL;
ccr |= (priority << 12);
channel_regs->CCR = ccr;
}
void dma_set_num_transfers(dma_dev *dev,
dma_channel channel,
uint16 num_transfers) {
dma_channel_reg_map *channel_regs;
ASSERT_FAULT(!dma_is_channel_enabled(dev, channel));
channel_regs = dma_channel_regs(dev, channel);
channel_regs->CNDTR = num_transfers;
}
void dma_attach_interrupt(dma_dev *dev, dma_channel channel,
void (*handler)(void)) {
DMA_GET_HANDLER(dev, channel) = handler;
nvic_irq_enable(dev->handlers[channel - 1].irq_line);
}
void dma_detach_interrupt(dma_dev *dev, dma_channel channel) {
/* Don't use nvic_irq_disable()! Think about DMA2 channels 4 and 5. */
dma_channel_regs(dev, channel)->CCR &= ~0xF;
DMA_GET_HANDLER(dev, channel) = NULL;
}
void dma_enable(dma_dev *dev, dma_channel channel) {
dma_channel_reg_map *chan_regs = dma_channel_regs(dev, channel);
bb_peri_set_bit(&chan_regs->CCR, DMA_CCR_EN_BIT, 1);
}
void dma_disable(dma_dev *dev, dma_channel channel) {
dma_channel_reg_map *chan_regs = dma_channel_regs(dev, channel);
bb_peri_set_bit(&chan_regs->CCR, DMA_CCR_EN_BIT, 0);
}
dma_irq_cause dma_get_irq_cause(dma_dev *dev, dma_channel channel) {
/* Grab and clear the ISR bits. */
uint8 status_bits = dma_get_isr_bits(dev, channel);
dma_clear_isr_bits(dev, channel);
/* If the channel global interrupt flag is cleared, then
* something's very wrong. */
ASSERT(status_bits & 0x1);
/* If GIF is set, then some other flag should be set, barring
* something unexpected (e.g. the user making an unforeseen IFCR
* write). */
ASSERT(status_bits != 0x1);
/* ISR flags get set even if the corresponding interrupt enable
* bits in the channel's configuration register are cleared, so we
* can't use a switch here.
*
* Don't change the order of these if statements. */
if (status_bits & 0x8) {
return DMA_TRANSFER_ERROR;
} else if (status_bits & 0x2) {
return DMA_TRANSFER_COMPLETE;
} else if (status_bits & 0x4) {
return DMA_TRANSFER_HALF_COMPLETE;
}
/* If we get here, one of our assumptions has been violated, but
* the debug level is too low for the above ASSERTs() to have had
* any effect. In order to fail fast, mimic the DMA controller's
* behavior when an error occurs. */
dma_disable(dev, channel);
return DMA_TRANSFER_ERROR;
}
void dma_set_mem_addr(dma_dev *dev, dma_channel channel, __io void *addr) {
dma_channel_reg_map *chan_regs;
ASSERT_FAULT(!dma_is_channel_enabled(dev, channel));
chan_regs = dma_channel_regs(dev, channel);
chan_regs->CMAR = (uint32)addr;
}
void dma_set_per_addr(dma_dev *dev, dma_channel channel, __io void *addr) {
dma_channel_reg_map *chan_regs;
ASSERT_FAULT(!dma_is_channel_enabled(dev, channel));
chan_regs = dma_channel_regs(dev, channel);
chan_regs->CPAR = (uint32)addr;
}
/*
* IRQ handlers
*/
void __irq_dma1_ch1(void) {
dma_irq_handler(DMA1, DMA_CH1);
}
void __irq_dma1_ch2(void) {
dma_irq_handler(DMA1, DMA_CH2);
}
void __irq_dma1_ch3(void) {
dma_irq_handler(DMA1, DMA_CH3);
}
void __irq_dma1_ch4(void) {
dma_irq_handler(DMA1, DMA_CH4);
}
void __irq_dma1_ch5(void) {
dma_irq_handler(DMA1, DMA_CH5);
}
void __irq_dma1_ch6(void) {
dma_irq_handler(DMA1, DMA_CH6);
}
void __irq_dma1_ch7(void) {
dma_irq_handler(DMA1, DMA_CH7);
}
void __irq_dma2_ch1(void) {
dma_irq_handler(DMA2, DMA_CH1);
}
void __irq_dma2_ch2(void) {
dma_irq_handler(DMA2, DMA_CH2);
}
void __irq_dma2_ch3(void) {
dma_irq_handler(DMA2, DMA_CH3);
}
void __irq_dma2_ch4(void) {
dma_irq_handler(DMA2, DMA_CH4);
}
void __irq_dma2_ch5(void) {
dma_irq_handler(DMA2, DMA_CH5);
}

View File

@ -0,0 +1,40 @@
/******************************************************************************
* The MIT License
*
* Copyright (c) 2012 LeafLabs, LLC.
* Copyright (c) 2013 OpenMusicKontrollers.
*
* 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/stm32f3/exti.c
* @author F3-port by Hanspeter Portner <dev@open-music-kontrollers.ch>
* @brief STM32F3 EXTI.
*/
#include <libmaple/exti.h>
#include <libmaple/syscfg.h>
#include "exti_private.h"
void exti_select(exti_num num, exti_cfg cfg) {
exti_do_select(&SYSCFG_BASE->EXTICR[num / 4], num, cfg);
}

View File

@ -0,0 +1,57 @@
/******************************************************************************
* The MIT License
*
* Copyright (c) 2013 OpenMusicKontrollers.
*
* 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/stm32f3/fpu.c
* @author F3-port by Hanspeter Portner <dev@open-music-kontrollers.ch>
* @brief STM32F3 FPU.
*/
#include <libmaple/fpu.h>
void fpu_enable(void) {
/*
* set coprocessor access control registers
*/
asm("\tLDR.W R0, =0xE000ED88\n"
"\tLDR R1, [R0]\n"
"\tORR R1, R1, #(0xF << 20)\n"
"\tSTR R1, [R0]\n"
"\tDSB\n"
"\tISB");
}
void fpu_disable(void) {
/*
* clear coprocessor access control registers
*/
asm("\tLDR.W R0, =0xE000ED88\n"
"\tLDR R1, [R0]\n"
"\tORR R1, R1, #(0x0 << 20)\n"
"\tSTR R1, [R0]\n"
"\tDSB\n"
"\tISB");
}

View File

@ -0,0 +1,169 @@
/******************************************************************************
* The MIT License
*
* Copyright (c) 2011 LeafLabs, LLC.
* Copyright (c) 2013 OpenMusicKontrollers.
*
* 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/stm32f3/gpio.c
* @author F3-port by Hanspeter Portner <dev@open-music-kontrollers.ch>
* @brief STM32F3 GPIO.
*/
#include <libmaple/gpio.h>
#include <libmaple/rcc.h>
#include <libmaple/bitband.h>
/*
* GPIO devices
*/
gpio_dev gpioa = {
.regs = GPIOA_BASE,
.clk_id = RCC_GPIOA,
.exti_port = EXTI_PA,
};
/** GPIO port A device. */
gpio_dev* const GPIOA = &gpioa;
gpio_dev gpiob = {
.regs = GPIOB_BASE,
.clk_id = RCC_GPIOB,
.exti_port = EXTI_PB,
};
/** GPIO port B device. */
gpio_dev* const GPIOB = &gpiob;
gpio_dev gpioc = {
.regs = GPIOC_BASE,
.clk_id = RCC_GPIOC,
.exti_port = EXTI_PC,
};
/** GPIO port C device. */
gpio_dev* const GPIOC = &gpioc;
gpio_dev gpiod = {
.regs = GPIOD_BASE,
.clk_id = RCC_GPIOD,
.exti_port = EXTI_PD,
};
/** GPIO port D device. */
gpio_dev* const GPIOD = &gpiod;
gpio_dev gpioe = {
.regs = GPIOE_BASE,
.clk_id = RCC_GPIOE,
.exti_port = EXTI_PE,
};
/** GPIO port E device. */
gpio_dev* const GPIOE = &gpioe;
gpio_dev gpiof = {
.regs = GPIOF_BASE,
.clk_id = RCC_GPIOF,
.exti_port = EXTI_PF,
};
/** GPIO port F device. */
gpio_dev* const GPIOF = &gpiof;
/*
* GPIO routines
*/
/**
* Initialize and reset all available GPIO devices.
*/
void gpio_init_all(void) {
gpio_init(GPIOA);
gpio_init(GPIOB);
gpio_init(GPIOC);
gpio_init(GPIOD);
gpio_init(GPIOE);
gpio_init(GPIOF);
}
/**
* @brief Set the mode of a GPIO pin.
* @param dev GPIO device.
* @param bit Bit on dev whose mode to set, 0--15.
* @param mode Mode to set the pin to.
* @param flags Flags to modify basic mode configuration
*/
void gpio_set_modef(gpio_dev *dev,
uint8 bit,
gpio_pin_mode mode,
unsigned flags) {
gpio_reg_map *regs = dev->regs;
unsigned shift = bit * 2;
uint32 tmp;
/* Mode */
tmp = regs->MODER;
tmp &= ~(0x3 << shift);
tmp |= mode << shift;
regs->MODER = tmp;
/* Output type */
bb_peri_set_bit(&regs->OTYPER, bit, flags & 0x1);
/* Speed */
tmp = regs->OSPEEDR;
tmp &= ~(0x3 << shift);
tmp |= ((flags >> 1) & 0x3) << shift;
regs->OSPEEDR = tmp;
/* Pull-up/pull-down */
tmp = regs->PUPDR;
tmp &= ~(0x3 << shift);
tmp |= ((flags >> 3) & 0x3) << shift;
regs->PUPDR = tmp;
}
/**
* @brief Set a pin's alternate function.
*
* The pin must have its mode set to GPIO_MODE_AF for this to take
* effect.
*
* @param dev Device whose pin to configure.
* @param bit Pin whose alternate function to set.
* @param af Alternate function to use for pin.
* @see gpio_set_modef()
*/
void gpio_set_af(gpio_dev *dev, uint8 bit, gpio_af af) {
__io uint32 *afr;
unsigned shift;
uint32 tmp;
if (bit >= 8) {
afr = &dev->regs->AFRH;
shift = 4 * (bit - 8);
} else{
afr = &dev->regs->AFRL;
shift = 4 * bit;
}
tmp = *afr;
tmp &= ~(0xF << shift);
tmp |= (af << shift);
*afr = tmp;
}

View File

@ -0,0 +1,319 @@
/******************************************************************************
* The MIT License
*
* Copyright (c) 2013 OpenMusicKontrollers.
*
* 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/stm32f3/i2c.c
* @author F3-port by Hanspeter Portner <dev@open-music-kontrollers.ch>
* @brief STM32F3 I2C support
*/
#include "i2c_private.h"
#include <libmaple/i2c.h>
#include <libmaple/systick.h>
/*
* Devices
*/
/* on GPIO_AF_4 (PA14,PA15) (PB7,PB6) (PB9,PB8)*/
static i2c_dev i2c1 = I2C_DEV_OLD(1, &gpiob, 7, 6);
/** STM32F3 I2C device 1 */
i2c_dev* const I2C1 = &i2c1;
/* on GPIO_AF_4 (PA10,PA9) (PF0,PF1) (PF0,PF6)*/
static i2c_dev i2c2 = I2C_DEV_OLD(2, &gpioa, 10, 9);
/** STM32F3 I2C device 2 */
i2c_dev* const I2C2 = &i2c2;
/*
* Routines
*/
void i2c_config_gpios(const i2c_dev *dev) {
gpio_set_modef(sda_port(dev), dev->sda_pin, GPIO_MODE_AF, GPIO_MODEF_TYPE_OD);
gpio_set_modef(scl_port(dev), dev->scl_pin, GPIO_MODE_AF, GPIO_MODEF_TYPE_OD);
gpio_set_af(sda_port(dev), dev->sda_pin, GPIO_AF_4);
gpio_set_af(scl_port(dev), dev->scl_pin, GPIO_AF_4);
}
void i2c_master_release_bus(const i2c_dev *dev) {
gpio_write_bit(scl_port(dev), dev->scl_pin, 1); /* TODO check this */
gpio_write_bit(sda_port(dev), dev->sda_pin, 1);
i2c_config_gpios(dev);
}
int32 wait_for_state_change(i2c_dev *dev,
i2c_state state,
uint32 timeout) {
//FIXME not yet used on F3
return 1;
}
void i2c_bus_reset(const i2c_dev *dev) {
//FIXME not yet used on F3
}
void _i2c_software_reset(i2c_dev *dev) {
dev->regs->CR1 &= ~I2C_CR1_PE;
while(dev->regs->CR1 & I2C_CR1_PE)
;
dev->regs->CR1 |= I2C_CR1_PE;
}
void i2c_master_enable(i2c_dev *dev, uint32 flags) {
/* Bring the peripheral down for configuration */
i2c_peripheral_disable(dev);
/* Reset the bus when requested so */
if (flags & I2C_BUS_RESET)
i2c_bus_reset(dev);
/* Turn on the clock and set GPIO modes */
i2c_init(dev);
i2c_config_gpios(dev);
/* Configure analog and digital filters */
/* TODO ANFOFF, DNF */
/* Configure the clock and rise time */
dev->regs->TIMINGR = I2C_TIMING_10_kHz;
/* Configure NOSTRETCH behaviour */
/* TODO NOSTRETCH */
/* Enable all interrupts */ /* FIXME not yet used on F3 */
//nvic_irq_enable(dev->ev_nvic_line);
//nvic_irq_enable(dev->er_nvic_line);
//i2c_enable_irq(dev, 0xFE); /* All interrupts */
/* Make it go! */
i2c_peripheral_enable(dev);
dev->state = I2C_STATE_IDLE;
}
static void _i2c_master_xmit(i2c_dev *dev, i2c_msg *msg) {
uint32 cr2;
uint32 isr;
uint16 remaining = msg->length;
msg->xferred = 0;
uint8 *ptr = msg->data; /* pointer to data buffer */
while (remaining > 0) {
uint32 reload = remaining > 0xFF ? I2C_CR2_RELOAD : 0U;
uint16 size = remaining >= 0xFF ? 0xFF : remaining & 0xFF;
uint32 nbytes = size << I2C_CR2_NBYTES_SHIFT;
cr2 = dev->regs->CR2;
cr2 &= ~(I2C_CR2_RELOAD | I2C_CR2_NBYTES | I2C_CR2_RD_WRN);
cr2 |= reload | nbytes;
dev->regs->CR2 = cr2;
if (msg->xferred == 0) /* first loop iteration? */
dev->regs->CR2 |= I2C_CR2_START; /* generate START condition */
while (ptr < msg->data + msg->xferred + size) {
while ( !( (isr = dev->regs->ISR) & (I2C_ISR_NACKF | I2C_ISR_TXIS) ) )
; /* wait until ready for the next byte or NACK*/
if (isr & I2C_ISR_TXIS)
dev->regs->TXDR = *ptr++; /* byte to send */
else { /* NACKF */
dev->regs->ICR |= I2C_ICR_NACKCF; /* clear NACK flag */
dev->regs->CR2 |= I2C_CR2_STOP; /* generate STOP condition */
return; /* STOP condition is automatically generated */
}
}
if (reload)
while ( !(dev->regs->ISR & I2C_ISR_TCR) )
; /* wait for transmission reload complete */
remaining -= size;
msg->xferred += size;
}
while ( !(dev->regs->ISR & I2C_ISR_TC) )
; /* wait for transmission complete */
dev->regs->CR2 |= I2C_CR2_STOP; /* generate STOP condition */
while ( !(dev->regs->ISR & I2C_ISR_STOPF) )
; /* wait for STOP flag */
dev->regs->ICR |= I2C_ICR_STOPCF; /* clear STOP flag */
}
static void _i2c_master_recv(i2c_dev *dev, i2c_msg *msg) {
uint32 cr2;
uint16 remaining = msg->length;
msg->xferred = 0;
uint8 *ptr = msg->data; /* pointer to data buffer */
while (remaining > 0) {
uint32 reload = remaining > 0xFF ? I2C_CR2_RELOAD : 0U;
uint16 size = remaining >= 0xFF ? 0xFF : remaining & 0xFF;
uint32 nbytes = size << I2C_CR2_NBYTES_SHIFT;
cr2 = dev->regs->CR2;
cr2 &= ~(I2C_CR2_RELOAD | I2C_CR2_NBYTES | I2C_CR2_RD_WRN);
cr2 |= reload | nbytes | I2C_CR2_RD_WRN;
dev->regs->CR2 = cr2;
if (msg->xferred == 0) /* first loop iteration? */
dev->regs->CR2 |= I2C_CR2_START; /* generate START condition */
while (ptr < msg->data + msg->xferred + size) {
while ( !(dev->regs->ISR & I2C_ISR_RXNE) )
; /* wait for next byte */
*ptr++ = dev->regs->RXDR & I2C_RXDR_RXDATA; /* read byte */
}
if (reload)
while ( !(dev->regs->ISR & I2C_ISR_TCR) )
; /* wait for transmission reload complete */
remaining -= size;
msg->xferred += size;
}
while ( !(dev->regs->ISR & I2C_ISR_TC))
; /* wait for transmission complete */
dev->regs->CR2 |= I2C_CR2_STOP; /* generate STOP condition */
while ( !(dev->regs->ISR & I2C_ISR_STOPF) )
; /* wait for STOP flag */
dev->regs->ICR |= I2C_ICR_STOPCF; /* clear STOP flag */
}
int32 i2c_master_xfer(i2c_dev *dev,
i2c_msg *msgs,
uint16 num,
uint32 timeout) {
i2c_msg *msg;
ASSERT(dev->state == I2C_STATE_IDLE);
dev->msg = msgs;
dev->msgs_left = num;
dev->timestamp = systick_uptime(); /* FIXME implement handling of timeout */
dev->state = I2C_STATE_BUSY;
/* loop over messages */
for (msg = dev->msg; dev->msgs_left; dev->msgs_left--, msg++) {
/* set slave address and direction*/
uint32 addr = msg->flags & I2C_MSG_10BIT_ADDR
? I2C_CR2_ADD10 | (msg->addr << I2C_CR2_SADD_10_BIT_SHIFT)
: msg->addr << I2C_CR2_SADD_7_BIT_SHIFT;
uint32 rd = msg->flags & I2C_MSG_READ ? I2C_CR2_RD_WRN : 0U;
uint32 cr2 = dev->regs->CR2;
cr2 &= ~(I2C_CR2_HEAD10R | I2C_CR2_ADD10 | I2C_CR2_SADD_10_BIT | I2C_CR2_RD_WRN);
cr2 |= rd | addr;
dev->regs->CR2 = cr2;
if (rd)
_i2c_master_recv(dev, msg);
else
_i2c_master_xmit(dev, msg);
}
dev->state = I2C_STATE_IDLE;
return 0; /* FIXME implement error handling*/
}
void i2c_start_condition(i2c_dev *dev) {
dev->regs->CR2 |= I2C_CR2_START; /* generate START condition */
}
void i2c_stop_condition(i2c_dev *dev) {
dev->regs->CR2 |= I2C_CR2_STOP; /* generate STOP condition */
while ( !(dev->regs->ISR & I2C_ISR_STOPF) )
; /* wait for STOP flag */
dev->regs->ICR |= I2C_ICR_STOPCF; /* clear STOP flag */
}
void i2c_enable_irq(i2c_dev *dev, uint32 irqs) {
dev->regs->CR1 |= irqs;
}
void i2c_disable_irq(i2c_dev *dev, uint32 irqs) {
dev->regs->CR1 &= ~irqs;
}
/* ACK/NACK */
void i2c_enable_ack(i2c_dev *dev) {
//FIXME nonexistant on F3
}
void i2c_disable_ack(i2c_dev *dev) {
//FIXME nonexistant on F3
}
void i2c_write(i2c_dev *dev, uint8 byte) {
//FIXME proper handling of ISR
dev->regs->TXDR = byte;
}
uint8 i2c_read(i2c_dev *dev) {
//FIXME proper handling of ISR
return dev->regs->RXDR & I2C_RXDR_RXDATA;
}
void _i2c_irq_handler(i2c_dev *dev) {
//FIXME not yet used on F3
}
void _i2c_irq_error_handler(i2c_dev *dev) {
//FIXME not yet used on F3
}
/*
* IRQ handlers
*/
void __irq_i2c1_ev(void) {
_i2c_irq_handler(I2C1);
}
void __irq_i2c2_ev(void) {
_i2c_irq_handler(I2C2);
}
void __irq_i2c1_er(void) {
_i2c_irq_error_handler(I2C1);
}
void __irq_i2c2_er(void) {
_i2c_irq_error_handler(I2C2);
}

View File

@ -0,0 +1,46 @@
/******************************************************************************
* The MIT License
*
* Copyright (c) 2013 OpenMusicKontrollers.
*
* 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/stm32f3/opamp.c
* @author F3-port by Hanspeter Portner <dev@open-music-kontrollers.ch>
* @brief STM32F3 OpAmp support.
*/
#include <libmaple/opamp.h>
/*
* Devices
*/
static opamp_dev opamp1 = { .regs = OPAMP1_BASE }; const opamp_dev *OPAMP1 = &opamp1;
static opamp_dev opamp2 = { .regs = OPAMP2_BASE }; const opamp_dev *OPAMP2 = &opamp2;
static opamp_dev opamp3 = { .regs = OPAMP3_BASE }; const opamp_dev *OPAMP3 = &opamp3;
static opamp_dev opamp4 = { .regs = OPAMP4_BASE }; const opamp_dev *OPAMP4 = &opamp4;
/* TODO
* actually implement me ;-)
*/

View File

@ -0,0 +1,149 @@
/******************************************************************************
* The MIT License
*
* Copyright (c) 2010 Perry Hung.
* Copyright (c) 2011 LeafLabs, LLC.
* Copyright (c) 2013 OpenMusicKontrollers.
*
* 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/stm32f3/rcc.c
* @author F3-port by Hanspeter Portner <dev@open-music-kontrollers.ch>
* @brief STM32F3 RCC.
*/
#include <libmaple/rcc.h>
#include <libmaple/libmaple.h>
#include <libmaple/bitband.h>
#include "rcc_private.h"
#define APB1 RCC_APB1
#define APB2 RCC_APB2
#define AHB RCC_AHB
/* Device descriptor table, maps rcc_clk_id onto bus and enable/reset
* register bit numbers. */
const struct rcc_dev_info rcc_dev_table[] = {
[RCC_GPIOA] = { .clk_domain = AHB, .line_num = RCC_AHBENR_IOPAEN_BIT },
[RCC_GPIOB] = { .clk_domain = AHB, .line_num = RCC_AHBENR_IOPBEN_BIT },
[RCC_GPIOC] = { .clk_domain = AHB, .line_num = RCC_AHBENR_IOPCEN_BIT },
[RCC_GPIOD] = { .clk_domain = AHB, .line_num = RCC_AHBENR_IOPDEN_BIT },
[RCC_GPIOE] = { .clk_domain = AHB, .line_num = RCC_AHBENR_IOPEEN_BIT },
[RCC_GPIOF] = { .clk_domain = AHB, .line_num = RCC_AHBENR_IOPFEN_BIT },
[RCC_ADC12] = { .clk_domain = AHB, .line_num = RCC_AHBENR_ADC12EN_BIT},
#if STM32_F3_LINE == STM32_F3_LINE_303
[RCC_ADC34] = { .clk_domain = AHB, .line_num = RCC_AHBENR_ADC34EN_BIT },
#endif
[RCC_DAC] = { .clk_domain = APB1, .line_num = RCC_APB1ENR_DACEN_BIT },
[RCC_DMA1] = { .clk_domain = AHB, .line_num = RCC_AHBENR_DMA1EN_BIT },
[RCC_DMA2] = { .clk_domain = AHB, .line_num = RCC_AHBENR_DMA2EN_BIT },
[RCC_I2C1] = { .clk_domain = APB1, .line_num = RCC_APB1ENR_I2C1EN_BIT },
[RCC_I2C2] = { .clk_domain = APB1, .line_num = RCC_APB1ENR_I2C2EN_BIT },
[RCC_SPI1] = { .clk_domain = APB2, .line_num = RCC_APB2ENR_SPI1EN_BIT },
[RCC_SPI2] = { .clk_domain = APB1, .line_num = RCC_APB1ENR_SPI2EN_BIT },
[RCC_SPI3] = { .clk_domain = APB1, .line_num = RCC_APB1ENR_SPI3EN_BIT },
[RCC_USART1] = { .clk_domain = APB2, .line_num = RCC_APB2ENR_USART1EN_BIT },
[RCC_USART2] = { .clk_domain = APB1, .line_num = RCC_APB1ENR_USART2EN_BIT },
[RCC_USART3] = { .clk_domain = APB1, .line_num = RCC_APB1ENR_USART3EN_BIT },
#if defined(STM32_HIGH_DENSITY) || defined(STM32_XL_DENSITY)
[RCC_UART4] = { .clk_domain = APB1, .line_num = RCC_APB1ENR_UART4EN_BIT },
[RCC_UART5] = { .clk_domain = APB1, .line_num = RCC_APB1ENR_UART5EN_BIT },
#endif
[RCC_TIMER1] = { .clk_domain = APB2, .line_num = RCC_APB2ENR_TIM1EN_BIT },
[RCC_TIMER2] = { .clk_domain = APB1, .line_num = RCC_APB1ENR_TIM2EN_BIT },
[RCC_TIMER3] = { .clk_domain = APB1, .line_num = RCC_APB1ENR_TIM3EN_BIT },
[RCC_TIMER4] = { .clk_domain = APB1, .line_num = RCC_APB1ENR_TIM4EN_BIT },
[RCC_TIMER6] = { .clk_domain = APB1, .line_num = RCC_APB1ENR_TIM6EN_BIT },
#if STM32_F3_LINE == STM32_F3_LINE_303
[RCC_TIMER7] = { .clk_domain = APB1, .line_num = RCC_APB1ENR_TIM7EN_BIT },
[RCC_TIMER8] = { .clk_domain = APB2, .line_num = RCC_APB2ENR_TIM8EN_BIT },
#endif
[RCC_TIMER15] = { .clk_domain = APB2, .line_num = RCC_APB2ENR_TIM15EN_BIT },
[RCC_TIMER16] = { .clk_domain = APB2, .line_num = RCC_APB2ENR_TIM16EN_BIT },
[RCC_TIMER17] = { .clk_domain = APB2, .line_num = RCC_APB2ENR_TIM17EN_BIT },
[RCC_SYSCFG] = { .clk_domain = APB2, .line_num = RCC_APB2ENR_SYSCFGEN_BIT },
[RCC_PWR] = { .clk_domain = APB1, .line_num = RCC_APB1ENR_PWREN_BIT },
[RCC_CRC] = { .clk_domain = AHB, .line_num = RCC_AHBENR_CRCEN_BIT },
[RCC_FLITF] = { .clk_domain = AHB, .line_num = RCC_AHBENR_FLITFEN_BIT },
[RCC_SRAM] = { .clk_domain = AHB, .line_num = RCC_AHBENR_SRAMEN_BIT },
[RCC_USB] = { .clk_domain = APB1, .line_num = RCC_APB1ENR_USBEN_BIT },
};
/* pll_cfg->data must point to a valid struct stm32f3_rcc_pll_data. */
void rcc_configure_pll(rcc_pll_cfg *pll_cfg) {
stm32f3_rcc_pll_data *data = pll_cfg->data;
rcc_pll_multiplier pll_mul = data->pll_mul;
rcc_prediv_divider pclk_prediv = data->pclk_prediv; //TODO use this!!!
uint32 cfgr;
uint32 cfgr2;
/* Check that the PLL is disabled. */
ASSERT_FAULT(!rcc_is_clk_on(RCC_CLK_PLL));
cfgr2 = RCC_BASE->CFGR2;
cfgr2 &= ~(RCC_CFGR2_PREDIV);
cfgr2 |= pclk_prediv;
RCC_BASE->CFGR2 = cfgr2;
cfgr = RCC_BASE->CFGR;
cfgr &= ~(RCC_CFGR_PLLSRC | RCC_CFGR_PLLMUL);
cfgr |= pll_cfg->pllsrc | pll_mul;
RCC_BASE->CFGR = cfgr;
}
void rcc_clk_enable(rcc_clk_id id) {
static __io uint32* enable_regs[] = {
[APB1] = &RCC_BASE->APB1ENR,
[APB2] = &RCC_BASE->APB2ENR,
[AHB] = &RCC_BASE->AHBENR,
};
rcc_do_clk_enable(enable_regs, id);
}
void rcc_reset_dev(rcc_clk_id id) {
static __io uint32* reset_regs[] = {
[APB1] = &RCC_BASE->APB1RSTR,
[APB2] = &RCC_BASE->APB2RSTR,
[AHB] = &RCC_BASE->AHBRSTR,
};
rcc_do_reset_dev(reset_regs, id);
}
void rcc_set_prescaler(rcc_prescaler prescaler, uint32 divider) {
static const uint32 masks[] = {
[RCC_PRESCALER_AHB] = RCC_CFGR_HPRE,
[RCC_PRESCALER_APB1] = RCC_CFGR_PPRE1,
[RCC_PRESCALER_APB2] = RCC_CFGR_PPRE2,
[RCC_PRESCALER_USB] = RCC_CFGR_USBPRE,
};
rcc_do_set_prescaler(masks, prescaler, divider);
}

View File

@ -0,0 +1,143 @@
/******************************************************************************
* The MIT License
*
* Copyright (c) 2011, 2012 LeafLabs, LLC.
* Copyright (c) 2010 Perry Hung.
* Copyright (c) 2013 OpenMusicKontrollers.
*
* 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/stm32f3/spi.c
* @author Marti Bolivar <mbolivar@leaflabs.com>,
* F3-port by Hanspeter Portner <dev@open-music-kontrollers.ch>
* @brief STM32F3 SPI/I2S.
*/
#include <libmaple/spi.h>
#include <libmaple/gpio.h>
#include "spi_private.h"
/*
* Devices
*/
static spi_dev spi1 = SPI_DEV(1);
static spi_dev spi2 = SPI_DEV(2);
static spi_dev spi3 = SPI_DEV(3);
spi_dev *SPI1 = &spi1;
spi_dev *SPI2 = &spi2;
spi_dev *SPI3 = &spi3;
/*
* Routines
*/
void spi_config_gpios(spi_dev *dev,
uint8 as_master,
gpio_dev *nss_dev,
uint8 nss_bit,
gpio_dev *comm_dev,
uint8 sck_bit,
uint8 miso_bit,
uint8 mosi_bit) {
gpio_set_modef(nss_dev, nss_bit, GPIO_MODE_AF, GPIO_MODEF_TYPE_PP);
gpio_set_modef(comm_dev, sck_bit, GPIO_MODE_AF, GPIO_MODEF_TYPE_PP);
gpio_set_modef(comm_dev, miso_bit, GPIO_MODE_AF, GPIO_MODEF_PUPD_NONE);
gpio_set_modef(comm_dev, mosi_bit, GPIO_MODE_AF, GPIO_MODEF_TYPE_PP);
if ( (dev == SPI1) || (dev == SPI2) )
{
gpio_set_af(nss_dev, nss_bit, GPIO_AF_5);
gpio_set_af(comm_dev, sck_bit, GPIO_AF_5);
gpio_set_af(comm_dev, miso_bit, GPIO_AF_5);
gpio_set_af(comm_dev, mosi_bit, GPIO_AF_5);
}
else if (dev == SPI3)
{
gpio_set_af(nss_dev, nss_bit, GPIO_AF_6);
gpio_set_af(comm_dev, sck_bit, GPIO_AF_6);
gpio_set_af(comm_dev, miso_bit, GPIO_AF_6);
gpio_set_af(comm_dev, mosi_bit, GPIO_AF_6);
}
}
void spi_foreach(void (*fn)(spi_dev*)) {
fn(SPI1);
fn(SPI2);
fn(SPI3);
}
void spi_data_size(struct spi_dev *dev, spi_ds ds) {
uint8 byte_frame = ds <= SPI_DATA_SIZE_8_BIT;
uint32 cr2 = dev->regs->CR2;
cr2 &= ~(SPI_CR2_DS | SPI_CR2_FRXTH);
cr2 |= ds;
if (byte_frame)
cr2 |= SPI_CR2_FRXTH;
dev->regs->CR2 = cr2;
}
/*
* SPI auxiliary routines
*/
void spi_reconfigure(spi_dev *dev, uint32 cr1_config) {
spi_irq_disable(dev, SPI_INTERRUPTS_ALL);
spi_peripheral_disable(dev);
uint8 byte_frame = (dev->regs->CR2 & SPI_CR2_DS) <= SPI_DATA_SIZE_8_BIT;
uint32 cr2 = dev->regs->CR2;
cr2 &= ~SPI_CR2_FRXTH;
if (byte_frame)
cr2 |= SPI_CR2_FRXTH;
dev->regs->CR2 = cr2;
dev->regs->CR1 = cr1_config;
spi_peripheral_enable(dev);
}
uint16 spi_rx_reg(spi_dev *dev) {
uint8 byte_frame = (dev->regs->CR2 & SPI_CR2_DS) <= SPI_DATA_SIZE_8_BIT;
if (byte_frame) {
__io uint8 *dr8 = (__io uint8 *)&dev->regs->DR; /* we need to access as byte */
return (uint16)*dr8;
} else {
__io uint16 *dr16 = (__io uint16 *)&dev->regs->DR; /* we need to access as half-word */
return (uint16)*dr16;
}
}
uint32 spi_tx(spi_dev *dev, const void *buf, uint32 len) {
uint32 txed = 0;
uint8 byte_frame = (dev->regs->CR2 & SPI_CR2_DS) <= SPI_DATA_SIZE_8_BIT;
while (spi_is_tx_empty(dev) && (txed < len)) {
if (byte_frame) {
__io uint8 *dr8 = (__io uint8 *)&dev->regs->DR; /* we need to access as byte */
*dr8 = ((const uint8 *)buf)[txed++];
} else {
__io uint16 *dr16 = (__io uint16 *)&dev->regs->DR; /* we need to access as half-word */
*dr16 = ((const uint16 *)buf)[txed++];
}
}
return txed;
}

View File

@ -0,0 +1,43 @@
/******************************************************************************
* The MIT License
*
* Copyright (c) 2012 LeafLabs, LLC.
* Copyright (c) 2013 OpenMusicKontrollers.
*
* 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/stm32f3/syscfg.c
* @author F3-port by Hanspeter Portner <dev@open-music-kontrollers.ch>
* @brief SYSCFG routines.
*/
#include <libmaple/syscfg.h>
#include <libmaple/bitband.h>
#include <libmaple/rcc.h>
void syscfg_set_mem_mode(syscfg_mem_mode mode) {
uint32 memrmp = SYSCFG_BASE->CFGR1;
memrmp &= ~SYSCFG_CFGR1_MEM_MODE;
memrmp |= (uint32)mode;
SYSCFG_BASE->CFGR1 = memrmp;
}

View File

@ -0,0 +1,147 @@
/******************************************************************************
* The MIT License
*
* Copyright (c) 2011, 2012 LeafLabs, LLC.
* Copyright (c) 2013 OpenMusicKontrollers.
*
* 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/stm32f3/timer.c
* @author Marti Bolivar <mbolivar@leaflabs.com>,
* F3-port by Hanspeter Portner <dev@open-music-kontrollers.ch>
* @brief STM32F3 timer.
*/
#include <libmaple/timer.h>
#include <libmaple/stm32.h>
#include <libmaple/gpio.h>
#include "timer_private.h"
/**
* @brief Get the GPIO alternate function corresponding to a timer.
*
* For example, if dev is TIMER1, this function returns
* GPIO_AF_TIM_1_2. This is useful for e.g. using gpio_set_af() to set
* a pin's alternate function to a timer.
*
* @param dev Timer device, must not be TIMER6 or TIMER7.
* @return gpio_af corresponding to dev
* @see gpio_set_af
* @see gpio_af
*/
/* FIXME this has to be inline with the PIN_MAP, but some timers are accessible on different alternate function lanes based on the used pin... */
gpio_af timer_get_af(timer_dev *dev) {
rcc_clk_id clk_id = dev->clk_id;
/* Timers 6 and 7 don't have any capture/compare, so they can't do
* PWM (and in fact have no AF values). */
ASSERT(clk_id != RCC_TIMER6 && clk_id != RCC_TIMER7);
switch(dev->clk_id) {
case RCC_TIMER1:
return GPIO_AF_6;
case RCC_TIMER2: // fall-through
case RCC_TIMER3: // fall-through
case RCC_TIMER4:
return GPIO_AF_2;
case RCC_TIMER8:
return GPIO_AF_4;
case RCC_TIMER15:
return GPIO_AF_3;
case RCC_TIMER16: // fall-through
case RCC_TIMER17:
return GPIO_AF_1;
default:
ASSERT(0); // Can't happen
return (gpio_af)-1;
}
}
/*
* IRQ handlers
*
* Defer to the timer_private dispatch API.
*
* FIXME: The names of these handlers are inaccurate since XL-density
* devices came out. Update these to match the STM32F3 names, maybe
* using some weak symbol magic to preserve backwards compatibility if
* possible. Once that's done, we can just move the IRQ handlers into
* the top-level libmaple/timer.c, and there will be no need for this
* file.
*/
void __irq_tim1_brk_tim15(void) {
dispatch_adv_brk(TIMER1);
dispatch_tim_9_12(TIMER15);
}
void __irq_tim1_up_tim16(void) {
dispatch_adv_up(TIMER1);
dispatch_tim_10_11_13_14(TIMER16);
}
void __irq_tim1_trg_com_tim17(void) {
dispatch_adv_trg_com(TIMER1);
dispatch_tim_10_11_13_14(TIMER17);
}
void __irq_tim1_cc(void) {
dispatch_adv_cc(TIMER1);
}
void __irq_tim2(void) {
dispatch_general(TIMER2);
}
void __irq_tim3(void) {
dispatch_general(TIMER3);
}
void __irq_tim4(void) {
dispatch_general(TIMER4);
}
void __irq_tim6_dacunder(void) {
dispatch_basic(TIMER6);
/* FIXME handle DAC12 underrun */
}
#if STM32_F3_LINE == STM32_F3_LINE_303
void __irq_tim7(void) {
dispatch_basic(TIMER7);
}
void __irq_tim8_brk(void) {
dispatch_adv_brk(TIMER8);
}
void __irq_tim8_up(void) {
dispatch_adv_up(TIMER8);
}
void __irq_tim8_trg_com(void) {
dispatch_adv_trg_com(TIMER8);
}
void __irq_tim8_cc(void) {
dispatch_adv_cc(TIMER8);
}
#endif

View File

@ -0,0 +1,210 @@
/******************************************************************************
* The MIT License
*
* Copyright (c) 2013 OpenMusicKontrollers.
*
* 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/stm32f3/usart.c
* @author F3-port by Hanspeter Portner <dev@open-music-kontrollers.ch>
* @brief STM32F3 USART.
*/
#include <libmaple/usart.h>
#include <libmaple/gpio.h>
#include <libmaple/rcc.h>
#include "usart_private.h"
/*
* Devices
*/
static ring_buffer usart1_rb;
static usart_dev usart1 = {
.regs = USART1_BASE,
.rb = &usart1_rb,
.max_baud = 4500000UL,
.clk_id = RCC_USART1,
.irq_num = NVIC_USART1,
};
/** USART1 device */
usart_dev *USART1 = &usart1;
static ring_buffer usart2_rb;
static usart_dev usart2 = {
.regs = USART2_BASE,
.rb = &usart2_rb,
.max_baud = 2250000UL,
.clk_id = RCC_USART2,
.irq_num = NVIC_USART2,
};
/** USART2 device */
usart_dev *USART2 = &usart2;
static ring_buffer usart3_rb;
static usart_dev usart3 = {
.regs = USART3_BASE,
.rb = &usart3_rb,
.max_baud = 2250000UL,
.clk_id = RCC_USART3,
.irq_num = NVIC_USART3,
};
/** USART3 device */
usart_dev *USART3 = &usart3;
#if defined(STM32_HIGH_DENSITY) || defined(STM32_XL_DENSITY)
static ring_buffer uart4_rb;
static usart_dev uart4 = {
.regs = UART4_BASE,
.rb = &uart4_rb,
.max_baud = 2250000UL,
.clk_id = RCC_UART4,
.irq_num = NVIC_UART4,
};
/** UART4 device */
usart_dev *UART4 = &uart4;
static ring_buffer uart5_rb;
static usart_dev uart5 = {
.regs = UART5_BASE,
.rb = &uart5_rb,
.max_baud = 2250000UL,
.clk_id = RCC_UART5,
.irq_num = NVIC_UART5,
};
/** UART5 device */
usart_dev *UART5 = &uart5;
#endif
/*
* Routines
*/
void usart_config_gpios_async(usart_dev *udev,
gpio_dev *rx_dev, uint8 rx,
gpio_dev *tx_dev, uint8 tx,
unsigned flags) {
gpio_af af = usart_get_af(udev);
gpio_set_modef(rx_dev, rx, GPIO_MODE_AF, GPIO_MODEF_PUPD_NONE);
//gpio_set_modef(tx_dev, tx, GPIO_MODE_AF, GPIO_MODEF_TYPE_PP);
gpio_set_modef(tx_dev, tx, GPIO_MODE_AF, GPIO_MODEF_TYPE_OD);
gpio_set_af(rx_dev, rx, af);
gpio_set_af(tx_dev, tx, af);
}
void usart_set_baud_rate(usart_dev *dev, uint32 clock_speed, uint32 baud) {
/* Figure out the clock speed, if the user doesn't give one. */
if (clock_speed == 0) {
clock_speed = _usart_clock_freq(dev);
}
ASSERT(clock_speed);
uint32 divider = clock_speed / baud;
uint32 tmpreg = clock_speed % baud;
/* round divider : if fractional part i greater than 0.5 increment divider */
if (tmpreg >= baud / 2)
divider++;
dev->regs->BRR = (uint16)divider;
}
uint32 usart_tx(usart_dev *dev, const uint8 *buf, uint32 len) {
usart_reg_map *regs = dev->regs;
uint32 txed = 0;
while ((regs->SR & USART_SR_TXE) && (txed < len)) {
regs->TDR = buf[txed++] & USART_TDR_TDR;
}
return txed;
}
/**
* @brief Call a function on each USART.
* @param fn Function to call.
*/
void usart_foreach(void (*fn)(usart_dev*)) {
fn(USART1);
fn(USART2);
fn(USART3);
#if defined(STM32_HIGH_DENSITY) || defined(STM32_XL_DENSITY)
fn(UART4);
fn(UART5);
#endif
}
/**
* @brief Get GPIO alternate function mode for a USART.
* @param dev USART whose gpio_af to get.
* @return gpio_af corresponding to dev.
*/
gpio_af usart_get_af(usart_dev *dev) {
switch (dev->clk_id) {
case RCC_USART1:
case RCC_USART2:
case RCC_USART3:
return GPIO_AF_7;
#if defined(STM32_HIGH_DENSITY) || defined(STM32_XL_DENSITY)
case RCC_UART4:
case RCC_UART5:
return GPIO_AF_5;
#endif
default:
ASSERT(0); /* Can't happen */
return (gpio_af)-1;
}
}
/*
* Interrupt handlers.
*/
static __always_inline void usart_irq(ring_buffer *rb, usart_reg_map *regs) {
#ifdef USART_SAFE_INSERT
/* If the buffer is full and the user defines USART_SAFE_INSERT,
* ignore new bytes. */
rb_safe_insert(rb, regs->RDR & USART_RDR_RDR);
#else
/* By default, push bytes around in the ring buffer. */
rb_push_insert(rb, regs->RDR & USART_RDR_RDR);
#endif
}
void __irq_usart1(void) {
usart_irq(&usart1_rb, USART1_BASE);
}
void __irq_usart2(void) {
usart_irq(&usart2_rb, USART2_BASE);
}
void __irq_usart3(void) {
usart_irq(&usart3_rb, USART3_BASE);
}
#ifdef STM32_HIGH_DENSITY
void __irq_uart4(void) {
usart_irq(&uart4_rb, UART4_BASE);
}
void __irq_uart5(void) {
usart_irq(&uart5_rb, UART5_BASE);
}
#endif

View File

@ -0,0 +1,696 @@
/******************************************************************************
* The MIT License
*
* Copyright (c) 2013 OpenMusicKontrollers.
*
* 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/stm32f3/include/series/adc.h
* @author F3-port by Hanspeter Portner <dev@open-music-kontrollers.ch>
* @brief STM32F3 ADC support.
*/
#ifndef _LIBMAPLE_STM32F3_ADC_H_
#define _LIBMAPLE_STM32F3_ADC_H_
#include <libmaple/bitband.h>
#include <libmaple/libmaple_types.h>
#include <libmaple/rcc.h> /* For the prescalers */
/*
* Register map
*/
/*
* ADC individual register map type.
*/
typedef struct adc_reg_map {
__io uint32 ISR; /**< */
__io uint32 IER; /**< */
__io uint32 CR; /**< */
__io uint32 CFGR; /**< */
uint32 reserved1;
__io uint32 SMPR1; /**< */
__io uint32 SMPR2; /**< */
uint32 reserved2;
__io uint32 TR1; /**< */
__io uint32 TR2; /**< */
__io uint32 TR3; /**< */
uint32 reserved3;
__io uint32 SQR1; /**< */
__io uint32 SQR2; /**< */
__io uint32 SQR3; /**< */
__io uint32 SQR4; /**< */
__io uint32 DR; /**< */
uint32 reserved4 [2];
__io uint32 JSQR; /**< */
uint32 reserved5 [4];
__io uint32 OFR1; /**< */
__io uint32 OFR2; /**< */
__io uint32 OFR3; /**< */
__io uint32 OFR4; /**< */
uint32 reserved6 [4];
__io uint32 JDR1; /**< */
__io uint32 JDR2; /**< */
__io uint32 JDR3; /**< */
__io uint32 JDR4; /**< */
uint32 reserved7 [4];
__io uint32 AWD2CR; /**< */
__io uint32 AWD3CR; /**< */
uint32 reserved8 [2];
__io uint32 DIFSEL; /**< */
__io uint32 CALFACT; /**< */
} adc_reg_map;
/*
* ADC master and slave common register map type.
*/
typedef struct adc_common_reg_map {
__io uint32 CSR; /**< */
uint32 reserved;
__io uint32 CCR; /**< */
__io uint32 CDR; /**< */
} adc_common_reg_map;
/** ADC device type. */
typedef struct adc_dev {
adc_reg_map *regs; /**< Register map */
rcc_clk_id clk_id; /**< RCC clock information */
adc_private_data *priv; /**< ADC private data */
} adc_dev;
/*
* Devices
*/
extern const struct adc_dev *ADC1; /* master */
extern const struct adc_dev *ADC2; /* slave */
#if STM32_F3_LINE == STM32_F3_LINE_303
extern const struct adc_dev *ADC3; /* master */
extern const struct adc_dev *ADC4; /* slave */
#endif
/*
* Register map base pointers
*/
/** STM32F3 ADC1 individual register map base pointer. */
#define ADC1_BASE ((struct adc_reg_map*)0x50000000)
/** STM32F3 ADC2 individual register map base pointer. */
#define ADC2_BASE ((struct adc_reg_map*)0x50000100)
/** STM32F3 ADC1/ADC2 common register map base pointer. */
#define ADC12_BASE ((struct adc_common_reg_map*)0x50000300)
#if STM32_F3_LINE == STM32_F3_LINE_303
/** STM32F3 ADC3 individual register map base pointer. */
#define ADC3_BASE ((struct adc_reg_map*)0x50000400)
/** STM32F3 ADC4 individual register map base pointer. */
#define ADC4_BASE ((struct adc_reg_map*)0x50000500)
/** STM32F3 ADC3/ADC4 common register map base pointer. */
#define ADC34_BASE ((struct adc_common_reg_map*)0x50000700)
#endif
/*
* Register bit definitions
*/
/* Interrupt and status register */
#define ADC_ISR_JQOVF_BIT 10
#define ADC_ISR_AWD3_BIT 9
#define ADC_ISR_AWD2_BIT 8
#define ADC_ISR_AWD1_BIT 7
#define ADC_ISR_JEOS_BIT 6
#define ADC_ISR_JEOC_BIT 5
#define ADC_ISR_OVR_BIT 4
#define ADC_ISR_EOS_BIT 3
#define ADC_ISR_EOC_BIT 2
#define ADC_ISR_EOSMP_BIT 1
#define ADC_ISR_ADRDY_BIT 0
#define ADC_ISR_JQOVF (1U << ADC_ISR_JQOVF_BIT)
#define ADC_ISR_AWD3 (1U << ADC_ISR_AWD3_BIT)
#define ADC_ISR_AWD2 (1U << ADC_ISR_AWD2_BIT)
#define ADC_ISR_AWD1 (1U << ADC_ISR_AWD1_BIT)
#define ADC_ISR_JEOS (1U << ADC_ISR_JEOS_BIT)
#define ADC_ISR_JEOC (1U << ADC_ISR_JEOC_BIT)
#define ADC_ISR_OVR (1U << ADC_ISR_OVR_BIT)
#define ADC_ISR_EOS (1U << ADC_ISR_EOS_BIT)
#define ADC_ISR_EOC (1U << ADC_ISR_EOC_BIT)
#define ADC_ISR_EOSMP (1U << ADC_ISR_EOSMP_BIT)
#define ADC_ISR_ADRDY (1U << ADC_ISR_ADRDY_BIT)
/* FIXME make an enum out of this */
#define ADC_WATCHDOG_1_INTERRUPT ADC_ISR_AWD1
#define ADC_WATCHDOG_2_INTERRUPT ADC_ISR_AWD2
#define ADC_WATCHDOG_3_INTERRUPT ADC_ISR_AWD3
#define ADC_CONV_INTERRUPT ADC_ISR_EOC
#define ADC_INJ_CONV_INTERRUPT ADC_ISR_JEOC
#define ADC_OVERRUN_INTERRUPT ADC_ISR_OVR
#define ADC_ALL_INTERRUPTS (ADC_CONV_INTERRUPT | ADC_WATCHDOG_1_INTERRUPT | ADC_WATCHDOG_2_INTERRUPT | ADC_WATCHDOG_3_INTERRUPT | ADC_INJ_CONV_INTERRUPT | ADC_OVERRUN_INTERRUPT)
/* Interrupt enable register */
#define ADC_IER_JQOVF_BIT 10
#define ADC_IER_AWD3_BIT 9
#define ADC_IER_AWD2_BIT 8
#define ADC_IER_AWD1_BIT 7
#define ADC_IER_JEOS_BIT 6
#define ADC_IER_JEOC_BIT 5
#define ADC_IER_OVR_BIT 4
#define ADC_IER_EOS_BIT 3
#define ADC_IER_EOC_BIT 2
#define ADC_IER_EOSMP_BIT 1
#define ADC_IER_ADRDY_BIT 0
#define ADC_IER_JQOVF (1U << ADC_IER_JQOVF_BIT)
#define ADC_IER_AWD3 (1U << ADC_IER_AWD3_BIT)
#define ADC_IER_AWD2 (1U << ADC_IER_AWD2_BIT)
#define ADC_IER_AWD1 (1U << ADC_IER_AWD1_BIT)
#define ADC_IER_JEOS (1U << ADC_IER_JEOS_BIT)
#define ADC_IER_JEOC (1U << ADC_IER_JEOC_BIT)
#define ADC_IER_OVR (1U << ADC_IER_OVR_BIT)
#define ADC_IER_EOS (1U << ADC_IER_EOS_BIT)
#define ADC_IER_EOC (1U << ADC_IER_EOC_BIT)
#define ADC_IER_EOSMP (1U << ADC_IER_EOSMP_BIT)
#define ADC_IER_ADRDY (1U << ADC_IER_ADRDY_BIT)
/* Control register */
#define ADC_CR_ADCAL_BIT 31
#define ADC_CR_ADCALDIF_BIT 30
#define ADC_CR_ADVREGEN_SHIFT 28
#define ADC_CR_JADSTP_BIT 5
#define ADC_CR_ADSTP_BIT 4
#define ADC_CR_JADSTART_BIT 3
#define ADC_CR_ADSTART_BIT 2
#define ADC_CR_ADDIS_BIT 1
#define ADC_CR_ADEN_BIT 0
#define ADC_CR_ADCAL (1U << ADC_CR_ADCAL_BIT)
#define ADC_CR_ADCALDIF (1U << ADC_CR_ADCALDIF_BIT)
#define ADC_CR_ADVREGEN (0x3 << ADC_CR_ADVREGEN_SHIFT)
#define ADC_CR_ADVREGEN_ENABLE (0x1 << ADC_CR_ADVREGEN_SHIFT)
#define ADC_CR_ADVREGEN_DISABLE (0x2 << ADC_CR_ADVREGEN_SHIFT)
#define ADC_CR_JADSTP (1U << ADC_CR_JADSTP_BIT)
#define ADC_CR_ADSTP (1U << ADC_CR_ADSTP_BIT)
#define ADC_CR_JADSTART (1U << ADC_CR_JADSTART_BIT)
#define ADC_CR_ADSTART (1U << ADC_CR_ADSTART_BIT)
#define ADC_CR_ADDIS (1U << ADC_CR_ADDIS_BIT)
#define ADC_CR_ADEN (1U << ADC_CR_ADEN_BIT)
/* Configuration register */
#define ADC_CFGR_AWD1CH_SHIFT 26
#define ADC_CFGR_JAUTO_BIT 25
#define ADC_CFGR_JAWD1EN_BIT 24
#define ADC_CFGR_AWD1EN_BIT 23
#define ADC_CFGR_AWD1SGL_BIT 22
#define ADC_CFGR_JQM_BIT 21
#define ADC_CFGR_JDISCEN_BIT 20
#define ADC_CFGR_JDISCNUM_SHIFT 17
#define ADC_CFGR_DISCEN_BIT 16
#define ADC_CFGR_AUTDLY_BIT 14
#define ADC_CFGR_CONT_BIT 13
#define ADC_CFGR_OVRMOD_BIT 12
#define ADC_CFGR_EXTEN_SHIFT 10
#define ADC_CFGR_EXTSEL_SHIFT 6
#define ADC_CFGR_ALIGN_BIT 5
#define ADC_CFGR_RES_SHIFT 3
#define ADC_CFGR_DMACFG_BIT 1
#define ADC_CFGR_DMAEN_BIT 0
#define ADC_CFGR_AWD1CH (0x1F << ADC_CFGR_AWD1CH_SHIFT)
#define ADC_CFGR_JAUTO (1U << ADC_CFGR_JAUTO_BIT)
#define ADC_CFGR_JAWD1EN (1U << ADC_CFGR_JAWD1EN_BIT)
#define ADC_CFGR_AWD1EN (1U << ADC_CFGR_AWD1EN_BIT)
#define ADC_CFGR_AWD1SGL (1U << ADC_CFGR_AWD1SGL_BIT)
#define ADC_CFGR_JQM (1U << ADC_CFGR_JQM_BIT)
#define ADC_CFGR_JDISCEN (1U << ADC_CFGR_JDISCEN_BIT)
#define ADC_CFGR_JDISCNUM (0x7 << ADC_CFGR_JDISCNUM_SHIFT)
#define ADC_CFGR_DISCEN (1U << ADC_CFGR_DISCEN_BIT)
#define ADC_CFGR_AUTODLY (1U << ADC_CFGR_AUTODLY_BIT)
#define ADC_CFGR_CONT (1U << ADC_CFGR_CONT_BIT)
#define ADC_CFGR_OVRMOD (1U << ADC_CFGR_OVRMOD_BIT)
#define ADC_CFGR_EXTEN (0x3 << ADC_CFGR_EXTEN_SHIFT)
#define ADC_CFGR_EXTSEL (0xF << ADC_CFGR_EXTSEL_SHIFT)
#define ADC_CFGR_ALIGN (1U << ADC_CFGR_ALIGN_BIT)
#define ADC_CFGR_RES (0x3 << ADC_CFGR_RES_SHIFT)
#define ADC_CFGR_DMACFG (1U << ADC_CFGR_DMACFG_BIT)
#define ADC_CFGR_DMAEN (1U << ADC_CFGR_DMAEN_BIT)
/* Sample time register 1 */
#define ADC_SMPR1_SMP9 (0x7 << 27)
#define ADC_SMPR1_SMP8 (0x7 << 24)
#define ADC_SMPR1_SMP7 (0x7 << 21)
#define ADC_SMPR1_SMP6 (0x7 << 18)
#define ADC_SMPR1_SMP5 (0x7 << 15)
#define ADC_SMPR1_SMP4 (0x7 << 12)
#define ADC_SMPR1_SMP3 (0x7 << 9)
#define ADC_SMPR1_SMP2 (0x7 << 6)
#define ADC_SMPR1_SMP1 (0x7 << 3)
/* Sample time register 2 */
#define ADC_SMPR2_SMP18 (0x7 << 24)
#define ADC_SMPR2_SMP17 (0x7 << 21)
#define ADC_SMPR2_SMP16 (0x7 << 18)
#define ADC_SMPR2_SMP15 (0x7 << 15)
#define ADC_SMPR2_SMP14 (0x7 << 12)
#define ADC_SMPR2_SMP13 (0x7 << 9)
#define ADC_SMPR2_SMP12 (0x7 << 6)
#define ADC_SMPR2_SMP11 (0x7 << 3)
#define ADC_SMPR2_SMP10 0x7
/* Analog watchdog 1 threshold register */
#define ADC_TR1_HT1 (0xFFF << 16) /* 12bit watchdog */
#define ADC_TR1_LT1 0xFFF
/* Analog watchdog 2 threshold register */
#define ADC_TR2_HT2 (0xFF << 16) /* 8bit watchdog */
#define ADC_TR2_LT2 0xFF
/* Analog watchdog 3 threshold register */
#define ADC_TR3_HT3 (0xFF << 16) /* 8bit watchdog */
#define ADC_TR3_LT3 0xFF
/* Regular sequence register 1 */
#define ADC_SQR1_SQ4 (0x1F << 24)
#define ADC_SQR1_SQ3 (0x1F << 18)
#define ADC_SQR1_SQ2 (0x1F << 12)
#define ADC_SQR1_SQ1 (0x1F << 6)
#define ADC_SQR1_L 0xF
/* Regular sequence register 2 */
#define ADC_SQR2_SQ9 (0x1F << 24)
#define ADC_SQR2_SQ8 (0x1F << 18)
#define ADC_SQR2_SQ7 (0x1F << 12)
#define ADC_SQR2_SQ6 (0x1F << 6)
#define ADC_SQR2_SQ5 0x1F
/* Regular sequence register 3 */
#define ADC_SQR3_SQ14 (0x1F << 24)
#define ADC_SQR3_SQ13 (0x1F << 18)
#define ADC_SQR3_SQ12 (0x1F << 12)
#define ADC_SQR3_SQ11 (0x1F << 6)
#define ADC_SQR3_SQ10 0x1F
/* Regular sequence register 4 */
#define ADC_SQR4_SQ16 (0x1F << 6)
#define ADC_SQR4_SQ15 0x1F
/* Regular data register */
#define ADC_DR_RDATA 0xFFFF
/* Injected sequence register */
#define ADC_JSQR_JEXTEN_SHIFT 6
#define ADC_JSQR_JEXTSEL_SHIFT 2
#define ADC_JSQR_SQ4 (0x1F << 26)
#define ADC_JSQR_SQ3 (0x1F << 20)
#define ADC_JSQR_SQ2 (0x1F << 14)
#define ADC_JSQR_SQ1 (0x1F << 8)
#define ADC_JSQR_JEXTEN (0x3 << ADC_JSQR_JEXTEN_SHIFT)
#define ADC_JSQR_JEXTSEL (0xF << ADC_JSQR_JEXTSEL_SHIFT)
#define ADC_JSQR_JL 0x3
/* Offset register 1 */
#define ADC_OFR1_OFFSET1EN_BIT 31
#define ADC_OFR1_OFFSET1ENT (1U << ADC_OFR1_OFFSET1EN_BIT)
#define ADC_OFR1_OFFSET1_CH (0x1F << 26)
#define ADC_OFR1_OFFSET1 0xFFF
/* Offset register 2 */
#define ADC_OFR2_OFFSET2EN_BIT 31
#define ADC_OFR2_OFFSET2EN (1U << ADC_OFR2_OFFSET2EN_BIT)
#define ADC_OFR2_OFFSET2_CH (0x1F << 26)
#define ADC_OFR2_OFFSET2 0xFFF
/* Offset register 3 */
#define ADC_OFR3_OFFSET3EN_BIT 31
#define ADC_OFR3_OFFSET3EN (1U << ADC_OFR3_OFFSET3EN_BIT)
#define ADC_OFR3_OFFSET3_CH (0x1F << 26)
#define ADC_OFR3_OFFSET3 0xFFF
/* Offset register 4 */
#define ADC_OFR4_OFFSET4EN_BIT 31
#define ADC_OFR4_OFFSET4EN (1U << ADC_OFR4_OFFSET4EN_BIT)
#define ADC_OFR4_OFFSET4_CH (0x1F << 26)
#define ADC_OFR4_OFFSET4 0xFFF
/* Injected data register 1 */
#define ADC_JDR1_JDATA1 0xFFFF
/* Injected data register 2 */
#define ADC_JDR2_JDATA2 0xFFFF
/* Injected data register 3 */
#define ADC_JDR3_JDATA3 0xFFFF
/* Injected data register 4 */
#define ADC_JDR4_JDATA4 0xFFFF
/* Analog watchdog 2 configuration register */
#define ADC_AWD2CR_AWD2CH (0x1FFFF << 1)
/* Analog watchdog 3 configuration register */
#define ADC_AWD3CR_AWD3CH (0x1FFFF << 1)
/* Differential mode selection register */
#define ADC_DIFSEL_DIFSEL (0x1FFFF << 1)
/* Calibration factors */
#define ADC_CALFACT_CALFACT_D (0x7F << 16)
#define ADC_CALFACT_CALFACT_S 0x7F
/* Common status register */
#define ADC_CSR_JQOVF_SLV_BIT 26
#define ADC_CSR_AWD3_SLV_BIT 25
#define ADC_CSR_AWD2_SLV_BIT 24
#define ADC_CSR_AWD1_SLV_BIT 23
#define ADC_CSR_JEOS_SLV_BIT 22
#define ADC_CSR_JEOC_SLV_BIT 21
#define ADC_CSR_OVR_SLV_BIT 20
#define ADC_CSR_EOS_SLV_BIT 19
#define ADC_CSR_EOC_SLV_BIT 18
#define ADC_CSR_EOSMP_SLV_BIT 17
#define ADC_CSR_ADRDY_SLV_BIT 16
#define ADC_CSR_JQOVF_MST_BIT 10
#define ADC_CSR_AWD3_MST_BIT 9
#define ADC_CSR_AWD2_MST_BIT 8
#define ADC_CSR_AWD1_MST_BIT 7
#define ADC_CSR_JEOS_MST_BIT 6
#define ADC_CSR_JEOC_MST_BIT 5
#define ADC_CSR_OVR_MST_BIT 4
#define ADC_CSR_EOS_MST_BIT 3
#define ADC_CSR_EOC_MST_BIT 2
#define ADC_CSR_EOSMP_MST_BIT 1
#define ADC_CSR_ADRDY_MST_BIT 0
#define ADC_CSR_JQOVF_SLV (1U << ADC_CSR_JQOVF_SLV_BIT)
#define ADC_CSR_AWD3_SLV (1U << ADC_CSR_AWD3_SLV_BIT)
#define ADC_CSR_AWD2_SLV (1U << ADC_CSR_AWD2_SLV_BIT)
#define ADC_CSR_AWD1_SLV (1U << ADC_CSR_AWD1_SLV_BIT)
#define ADC_CSR_JEOS_SLV (1U << ADC_CSR_JEOS_SLV_BIT)
#define ADC_CSR_JEOC_SLV (1U << ADC_CSR_JEOC_SLV_BIT)
#define ADC_CSR_OVR_SLV (1U << ADC_CSR_OVR_SLV_BIT)
#define ADC_CSR_EOS_SLV (1U << ADC_CSR_EOS_SLV_BIT)
#define ADC_CSR_EOC_SLV (1U << ADC_CSR_EOC_SLV_BIT)
#define ADC_CSR_EOSMP_SLV (1U << ADC_CSR_EOS_MP_SLV_BIT)
#define ADC_CSR_ADRDY_SLV (1U << ADC_CSR_ADRDY_SLV_BIT)
#define ADC_CSR_JQOVF_MST (1U << ADC_CSR_JQOVF_MST_BIT)
#define ADC_CSR_AWD3_MST (1U << ADC_CSR_AWD3_MST_BIT)
#define ADC_CSR_AWD2_MST (1U << ADC_CSR_AWD2_MST_BIT)
#define ADC_CSR_AWD1_MST (1U << ADC_CSR_AWD1_MST_BIT)
#define ADC_CSR_JEOS_MST (1U << ADC_CSR_JEOS_MST_BIT)
#define ADC_CSR_JEOC_MST (1U << ADC_CSR_JEOC_MST_BIT)
#define ADC_CSR_OVR_MST (1U << ADC_CSR_OVR_MST_BIT)
#define ADC_CSR_EOS_MST (1U << ADC_CSR_EOS_MST_BIT)
#define ADC_CSR_EOC_MST (1U << ADC_CSR_EOC_MST_BIT)
#define ADC_CSR_EOSMP_MST (1U << ADC_CSR_EOS_MP_MST_BIT)
#define ADC_CSR_ADRDY_MST (1U << ADC_CSR_ADRDY_MST_BIT)
/* Common control register */
#define ADC_CCR_VBATEN_BIT 24
#define ADC_CCR_TSEN_BIT 23
#define ADC_CCR_VREFEN_BIT 22
#define ADC_CCR_CKMODE_SHIFT 16
#define ADC_CCR_MDMA_SHIFT 14
#define ADC_CCR_DMACFG_BIT 13
#define ADC_CCR_DELAY_SHIFT 8
#define ADC_CCR_DUAL_SHIFT 0
#define ADC_CCR_VBATEN (1U << ADC_CCR_VBATEN_BIT)
#define ADC_CCR_TSEN (1U << ADC_CCR_TSEN_BIT)
#define ADC_CCR_VREFEN (1U << ADC_CCR_VREFEN_BIT)
#define ADC_CCR_CKMODE (0x3 << ADC_CCR_CKMODE_SHIFT)
#define ADC_CCR_MDMA (0x3 << ADC_CCR_MDMA_SHIFT)
#define ADC_CCR_DMACFG (1U << ADC_CCR_DMACFG_BIT)
#define ADC_CCR_DELAY (0xF << ADC_CCR_DELAY_SHIFT)
#define ADC_CCR_DUAL 0X1F
/* Common regular data register for dual mode */
#define ADC_CDR_RDATA_SLV (0xFFFF << 16)
#define ADC_CDR_RDATA_MST 0xFFFF
/*
* Other types
*/
/**
* @brief STM32F3 external event selectors for regular group
* conversion.
*
* 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 {
/* ADC1 (master) and ADC2 (slave) regular channels */
ADC12_EXT_EV_TIM1_CC1 = 0x0 << ADC_CFGR_EXTSEL_SHIFT,
ADC12_EXT_EV_TIM1_CC2 = 0x1 << ADC_CFGR_EXTSEL_SHIFT,
ADC12_EXT_EV_TIM1_CC3 = 0x2 << ADC_CFGR_EXTSEL_SHIFT,
ADC12_EXT_EV_TIM2_CC2 = 0x3 << ADC_CFGR_EXTSEL_SHIFT,
ADC12_EXT_EV_TIM3_TRGO = 0x4 << ADC_CFGR_EXTSEL_SHIFT,
ADC12_EXT_EV_TIM4_CC4 = 0x5 << ADC_CFGR_EXTSEL_SHIFT,
ADC12_EXT_EV_EXTI_11 = 0x6 << ADC_CFGR_EXTSEL_SHIFT,
ADC12_EXT_EV_TIM8_TRGO = 0x7 << ADC_CFGR_EXTSEL_SHIFT,
ADC12_EXT_EV_TIM8_TRGO2 = 0x8 << ADC_CFGR_EXTSEL_SHIFT,
ADC12_EXT_EV_TIM1_TRGO = 0x9 << ADC_CFGR_EXTSEL_SHIFT,
ADC12_EXT_EV_TIM1_TRGO2 = 0xA << ADC_CFGR_EXTSEL_SHIFT,
ADC12_EXT_EV_TIM2_TRGO = 0xB << ADC_CFGR_EXTSEL_SHIFT,
ADC12_EXT_EV_TIM4_TRGO = 0xC << ADC_CFGR_EXTSEL_SHIFT,
ADC12_EXT_EV_TIM6_TRGO = 0xD << ADC_CFGR_EXTSEL_SHIFT,
ADC12_EXT_EV_TIM15_TRGO = 0xE << ADC_CFGR_EXTSEL_SHIFT,
ADC12_EXT_EV_TIM3_CC4 = 0xF << ADC_CFGR_EXTSEL_SHIFT,
/* ADC1 (master) and ADC2 (slave) injected channels */
ADC12_JEXT_EV_TIM1_TRGO = 0x0 << ADC_JSQR_JEXTSEL_SHIFT,
ADC12_JEXT_EV_TIM1_CC4 = 0x1 << ADC_JSQR_JEXTSEL_SHIFT,
ADC12_JEXT_EV_TIM2_TRGO = 0x2 << ADC_JSQR_JEXTSEL_SHIFT,
ADC12_JEXT_EV_TIM2_CC1 = 0x3 << ADC_JSQR_JEXTSEL_SHIFT,
ADC12_JEXT_EV_TIM3_CC4 = 0x4 << ADC_JSQR_JEXTSEL_SHIFT,
ADC12_JEXT_EV_TIM4_TRGO = 0x5 << ADC_JSQR_JEXTSEL_SHIFT,
ADC12_JEXT_EV_EXTI_15 = 0x6 << ADC_JSQR_JEXTSEL_SHIFT,
ADC12_JEXT_EV_TIM8_CC4 = 0x7 << ADC_JSQR_JEXTSEL_SHIFT,
ADC12_JEXT_EV_TIM1_TRGO2 = 0x8 << ADC_JSQR_JEXTSEL_SHIFT,
ADC12_JEXT_EV_TIM8_TRGO = 0x9 << ADC_JSQR_JEXTSEL_SHIFT,
ADC12_JEXT_EV_TIM8_TRGO2 = 0xA << ADC_JSQR_JEXTSEL_SHIFT,
ADC12_JEXT_EV_TIM3_CC3 = 0xB << ADC_JSQR_JEXTSEL_SHIFT,
ADC12_JEXT_EV_TIM3_TRGO = 0xC << ADC_JSQR_JEXTSEL_SHIFT,
ADC12_JEXT_EV_TIM3_CC1 = 0xD << ADC_JSQR_JEXTSEL_SHIFT,
ADC12_JEXT_EV_TIM6_TRGO = 0xE << ADC_JSQR_JEXTSEL_SHIFT,
ADC12_JEXT_EV_TIM15_TRGO = 0xF << ADC_JSQR_JEXTSEL_SHIFT,
/* ADC3 (master) and ADC4 (slave) injected channels */
ADC34_EXT_EV_TIM3_CC1 = 0x0 << ADC_CFGR_EXTSEL_SHIFT,
ADC34_EXT_EV_TIM3_CC3 = 0x1 << ADC_CFGR_EXTSEL_SHIFT,
ADC34_EXT_EV_TIM1_cc3 = 0x2 << ADC_CFGR_EXTSEL_SHIFT,
ADC34_EXT_EV_TIM8_CC1 = 0x3 << ADC_CFGR_EXTSEL_SHIFT,
ADC34_EXT_EV_TIM8_TRGO = 0x4 << ADC_CFGR_EXTSEL_SHIFT,
ADC34_EXT_EV_EXTI_2 = 0x5 << ADC_CFGR_EXTSEL_SHIFT,
ADC34_EXT_EV_TIM4_CC1 = 0x6 << ADC_CFGR_EXTSEL_SHIFT,
ADC34_EXT_EV_TIM2_TRGO = 0x7 << ADC_CFGR_EXTSEL_SHIFT,
ADC34_EXT_EV_TIM8_TRGO2 = 0x8 << ADC_CFGR_EXTSEL_SHIFT,
ADC34_EXT_EV_TIM1_TRGO = 0x9 << ADC_CFGR_EXTSEL_SHIFT,
ADC34_EXT_EV_TIM1_TRGO2 = 0xA << ADC_CFGR_EXTSEL_SHIFT,
ADC34_EXT_EV_TIM3_TRGO = 0xB << ADC_CFGR_EXTSEL_SHIFT,
ADC34_EXT_EV_TIM4_TRGO = 0xC << ADC_CFGR_EXTSEL_SHIFT,
ADC34_EXT_EV_TIM7_TRGO = 0xD << ADC_CFGR_EXTSEL_SHIFT,
ADC34_EXT_EV_TIM15_TRGO = 0xE << ADC_CFGR_EXTSEL_SHIFT,
ADC34_EXT_EV_TIM2_CC1 = 0xF << ADC_CFGR_EXTSEL_SHIFT,
/* ADC3 (master) and ADC4 (slave) injected channels */
ADC34_JEXT_EV_TIM1_TRGO = 0x0 << ADC_JSQR_JEXTSEL_SHIFT,
ADC34_JEXT_EV_TIM1_CC4 = 0x1 << ADC_JSQR_JEXTSEL_SHIFT,
ADC34_JEXT_EV_TIM4_CC3 = 0x2 << ADC_JSQR_JEXTSEL_SHIFT,
ADC34_JEXT_EV_TIM8_CC2 = 0x3 << ADC_JSQR_JEXTSEL_SHIFT,
ADC34_JEXT_EV_TIM8_CC4 = 0x4 << ADC_JSQR_JEXTSEL_SHIFT,
/* ADC34_JEXT_EV_TIM4_CC3 = 0x5 << ADC_JSQR_JEXTSEL_SHIFT, */ /* FIXME duplicate or typo in manual? */
ADC34_JEXT_EV_TIM4_CC4 = 0x6 << ADC_JSQR_JEXTSEL_SHIFT,
ADC34_JEXT_EV_TIM4_TRGO = 0x7 << ADC_JSQR_JEXTSEL_SHIFT,
ADC34_JEXT_EV_TIM1_TRGO2 = 0x8 << ADC_JSQR_JEXTSEL_SHIFT,
ADC34_JEXT_EV_TIM8_TRGO = 0x9 << ADC_JSQR_JEXTSEL_SHIFT,
ADC34_JEXT_EV_TIM8_TRGO2 = 0xA << ADC_JSQR_JEXTSEL_SHIFT,
ADC34_JEXT_EV_TIM1_CC3 = 0xB << ADC_JSQR_JEXTSEL_SHIFT,
ADC34_JEXT_EV_TIM3_TRGO = 0xC << ADC_JSQR_JEXTSEL_SHIFT,
ADC34_JEXT_EV_TIM2_TRGO = 0xD << ADC_JSQR_JEXTSEL_SHIFT,
ADC34_JEXT_EV_TIM7_TRGO = 0xE << ADC_JSQR_JEXTSEL_SHIFT,
ADC34_JEXT_EV_TIM15_TRGO = 0xF << ADC_JSQR_JEXTSEL_SHIFT,
} adc_extsel_event;
/**
* @brief STM32F3 ADC trigger mode.
*
* These control the trigger mode of the ADC, which can be set to:
* Software trigger, hardware trigger on rising, falling or both edges.
*/
typedef enum adc_exttrig_mode {
ADC_EXTTRIG_MODE_SOFTWARE = 0x0 << ADC_CFGR_EXTEN_SHIFT, /**< .. */
ADC_EXTTRIG_MODE_HARDWARE_RISING = 0x1 << ADC_CFGR_EXTEN_SHIFT, /**< .. */
ADC_EXTTRIG_MODE_HARDWARE_FALLING = 0x2 << ADC_CFGR_EXTEN_SHIFT, /**< .. */
ADC_EXTTRIG_MODE_HARDWARE_BOTH = 0x3 << ADC_CFGR_EXTEN_SHIFT, /**< .. */
} adc_exttrig_mode;
/**
* @brief STM32F3 ADC resolution.
*
* These control the ADC resolution, which can be set to:
* 6, 8, 10 or 12 bit.
*/
typedef enum adc_resolution {
ADC_RESOLUTION_12_BIT = 0x0 << ADC_CFGR_RES_SHIFT, /**< .. */
ADC_RESOLUTION_10_BIT = 0x1 << ADC_CFGR_RES_SHIFT, /**< .. */
ADC_RESOLUTION_8_BIT = 0x2 << ADC_CFGR_RES_SHIFT, /**< .. */
ADC_RESOLUTION_6_BIT = 0x3 << ADC_CFGR_RES_SHIFT, /**< .. */
} adc_resolution;
/**
* @brief STM32F3 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 = 0x0, /**< 1.5 ADC cycles */
ADC_SMPR_2_5 = 0x1, /**< 2.5 ADC cycles */
ADC_SMPR_4_5 = 0x2, /**< 4.5 ADC cycles */
ADC_SMPR_7_5 = 0x3, /**< 7.5 ADC cycles */
ADC_SMPR_19_5 = 0x4, /**< 19.5 ADC cycles */
ADC_SMPR_61_5 = 0x5, /**< 61.5 ADC cycles */
ADC_SMPR_181_5 = 0x6, /**< 181.5 ADC cycles */
ADC_SMPR_601_5 = 0x7, /**< 601.5 ADC cycles */
} adc_smp_rate;
/*
* FIXME SHIFT
*/
/**
* @brief STM32F3 ADC clock mode.
*/
typedef enum adc_clock_mode {
ADC_CLOCK_MODE_ASYNCHRONOUS = 0x0, /**< . */
ADC_CLOCK_MODE_SYNCHRONOUS_DIV_1 = 0x1, /**< . */
ADC_CLOCK_MODE_SYNCHRONOUS_DIV_2 = 0x2, /**< . */
ADC_CLOCK_MODE_SYNCHRONOUS_DIV_4 = 0x3, /**< . */
} adc_clock_mode;
/**
* @brief STM32F3 ADC DMA mode.
*/
typedef enum adc_dma_mode {
ADC_MDMA_MODE_DISABLE = (0x0 << ADC_CCR_MDMA_SHIFT), /**< . */
ADC_MDMA_MODE_ENABLE_12_10_BIT = (0x2 << ADC_CCR_MDMA_SHIFT), /**< . */
ADC_MDMA_MODE_ENABLE_8_6_BIT = (0x3 << ADC_CCR_MDMA_SHIFT), /**< . */
} adc_dma_mode;
/**
* @brief STM32F3 ADC mode.
*/
typedef enum adc_mode {
ADC_MODE_INDEPENDENT = 0x0, /**< . */
ADC_MODE_DUAL_REGULAR_INJECTED = 0x1, /**< . */
ADC_MODE_DUAL_REGULAR_ALTERNATE_TRIGGER = 0x2, /**< . */
ADC_MODE_DUAL_INJECTED_ONLY = 0x5, /**< . */
ADC_MODE_DUAL_REGULAR_ONLY = 0x6, /**< . */
ADC_MODE_DUAL_INTERLEAVED_ONLY = 0x7, /**< . */
ADC_MODE_DUAL_ALTERNATE_TRIGGER_ONLY = 0x9, /**< . */
} adc_mode;
/**
* @brief STM32F3 ADC prescalers, as divisors of PCLK2.
*/
typedef enum adc_prescaler {
/** ADC clock disabled, AHB clock enabled */
ADC_PRE_AHBCLK_DIV_1 = ADC_CLOCK_MODE_SYNCHRONOUS_DIV_1,
ADC_PRE_AHBCLK_DIV_2 = ADC_CLOCK_MODE_SYNCHRONOUS_DIV_2,
ADC_PRE_AHBCLK_DIV_4 = ADC_CLOCK_MODE_SYNCHRONOUS_DIV_4,
/** ADC clock enabled, AHB clock disabled */
ADC_PRE_PCLK_DIV_1 = RCC_ADCPRE_PCLK_DIV_1, /** PCLK divided by 1 */
ADC_PRE_PCLK_DIV_2 = RCC_ADCPRE_PCLK_DIV_2, /** PCLK divided by 2 */
ADC_PRE_PCLK_DIV_4 = RCC_ADCPRE_PCLK_DIV_4, /** PCLK divided by 4 */
ADC_PRE_PCLK_DIV_6 = RCC_ADCPRE_PCLK_DIV_6, /** PCLK divided by 6 */
ADC_PRE_PCLK_DIV_8 = RCC_ADCPRE_PCLK_DIV_8, /** PCLK divided by 8 */
ADC_PRE_PCLK_DIV_10 = RCC_ADCPRE_PCLK_DIV_10, /** PCLK divided by 10 */
ADC_PRE_PCLK_DIV_12 = RCC_ADCPRE_PCLK_DIV_12, /** PCLK divided by 12 */
ADC_PRE_PCLK_DIV_16 = RCC_ADCPRE_PCLK_DIV_16, /** PCLK divided by 16 */
ADC_PRE_PCLK_DIV_32 = RCC_ADCPRE_PCLK_DIV_32, /** PCLK divided by 32 */
ADC_PRE_PCLK_DIV_64 = RCC_ADCPRE_PCLK_DIV_64, /** PCLK divided by 64 */
ADC_PRE_PCLK_DIV_128 = RCC_ADCPRE_PCLK_DIV_128, /** PCLK divided by 128 */
ADC_PRE_PCLK_DIV_256 = RCC_ADCPRE_PCLK_DIV_256, /** PCLK divided by 256 */
} adc_prescaler;
/*
* Routines
*/
/**
* @brief Calibrate an ADC peripheral
*
* Availability: STM32F1, STM32F3.
*
* @param dev adc device
*/
void adc_calibrate(const adc_dev *dev);
/**
* @brief Set external trigger conversion mode event for regular channels
*
* Availability: STM32F1, STM32F3.
*
* @param dev ADC device
* @param mode external trigger disabled, on rising edge, on falling edge or on both
*/
void adc_set_exttrig(const adc_dev *dev, adc_exttrig_mode mode);
/**
* @brief Set ADC resolution of an ADC peripheral
*
* Availability: STM32F3.
*
* @param dev adc device
* @param resolution ADC resolution (6, 8, 10 or 12 bit)
*/
void adc_set_resolution(const adc_dev *dev, adc_resolution res);
/**
* @brief Enable the voltage regulatr of an ADC peripheral
*
* Availability: STM32F3.
*
* @param dev adc device
*/
void adc_regulator_enable(const adc_dev *dev);
/**
* @brief Disable the voltage regulatr of an ADC peripheral
*
* Availability: STM32F3.
*
* @param dev adc device
*/
void adc_regulator_disable(const adc_dev *dev);
#endif

View File

@ -0,0 +1,62 @@
/******************************************************************************
* The MIT License
*
* Copyright (c) 2010 LeafLabs, LLC.
* Copyright (c) 2013 OpenMusicKontrollers.
*
* 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/stm32f3/include/series/bkp.h
* @author F3-port by Hanspeter Portner <dev@open-music-kontrollers.ch>
* @brief STM32F3 backup register support.
*/
#ifndef _LIBMAPLE_STM32F3_BKP_H_
#define _LIBMAPLE_STM32F3_BKP_H_
#define BKP_NR_DATA_REGS 16
/** Backup peripheral register map type. */
typedef struct bkp_reg_map {
__io uint32 DR0; ///< Data register 0
__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 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
} bkp_reg_map;
/** Backup peripheral register map base pointer. */
#define BKP_BASE ((struct bkp_reg_map*)0x40002850) //is part of RTC memory map
#endif

View File

@ -0,0 +1,119 @@
/******************************************************************************
* The MIT License
*
* Copyright (c) 2013 OpenMusicKontrollers.
*
* 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/stm32f3/include/series/comp.h
* @author F3-port by Hanspeter Portner <dev@open-music-kontrollers.ch>
* @brief STM32F3 Comparator support.
*/
#ifndef _LIBMAPLE_STM32F3_COMP_H_
#define _LIBMAPLE_STM32F3_COMP_H_
#ifdef __cplusplus
extern "C"{
#endif
#include <libmaple/libmaple_types.h>
/*
* Register map
*/
/*
* COMP individual register map type.
*/
typedef struct comp_reg_map {
__io uint32 CSR; /**< */
} comp_reg_map;
/** COMP device type. */
typedef struct comp_dev {
comp_reg_map *regs; /**< Register map */
} comp_dev;
/*
* Devices
*/
extern const struct comp_dev *COMP1; /* comparator 1 */
extern const struct comp_dev *COMP2; /* comparator 2 */
extern const struct comp_dev *COMP3; /* comparator 3 */
extern const struct comp_dev *COMP4; /* comparator 4 */
extern const struct comp_dev *COMP5; /* comparator 5 */
extern const struct comp_dev *COMP6; /* comparator 6 */
extern const struct comp_dev *COMP7; /* comparator 7 */
/*
* Register map base pointers
*/
#define COMP1_BASE ((struct comp_reg_map*)0x4001001C)
#define COMP2_BASE ((struct comp_reg_map*)0x40010020)
#define COMP3_BASE ((struct comp_reg_map*)0x40010024)
#define COMP4_BASE ((struct comp_reg_map*)0x40010028)
#define COMP5_BASE ((struct comp_reg_map*)0x4001002C)
#define COMP6_BASE ((struct comp_reg_map*)0x40010030)
#define COMP7_BASE ((struct comp_reg_map*)0x40010034)
/*
* Register bit definitions
*/
/* Control and status register */
#define COMP_CSR_LOCK_BIT 31
#define COMP_CSR_OUT_BIT 30
#define COMP_CSR_BLANKING_SHIFT 18
#define COMP_CSR_HIST_SHIFT 16
#define COMP_CSR_POL_BIT 15
#define COMP_CSR_OUTSEL_SHIFT 10
#define COMP_CSR_WINMODE_BIT 9
#define COMP_CSR_INPSEL_BIT 7
#define COMP_CSR_INMSEL_SHIFT 4
#define COMP_CSR_MODE_SHIFT 2
#define COMP_CSR_EN_BIT 0
#define COMP_CSR_LOCK (1U << COMP_CSR_LOCK_BIT)
#define COMP_CSR_OUT (1U << COMP_CSR_OUT_BIT)
#define COMP_CSR_BLANKING (0x7 << COMP_CSR_BLANKING_SHIFT)
#define COMP_CSR_HIST (0x3 << COMP_CSR_HIST_SHIFT)
#define COMP_CSR_POL (1U << COMP_CSR_POL_BIT)
#define COMP_CSR_OUTSEL (0xF << COMP_CSR_OUTSEL_SHIFT)
#define COMP_CSR_WINMODE (0xF << COMP_CSR_WINMODE_SHIFT)
#define COMP_CSR_INPSEL (1U << COMP_CSR_INPSEL_BIT)
#define COMP_CSR_INMSEL (0x7 << COMP_CSR_INMSEL_SHIFT)
#define COMP_CSR_MODE (0x3 << COMP_CSR_MODE_SHIFT)
#define COMP_CSR_EN (1U << COMP_CSR_EN_BIT)
/* TODO
* actually implement me ;-)
*/
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,94 @@
/******************************************************************************
* The MIT License
*
* Copyright (c) 2013 OpenMusicKontrollers.
*
* 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/stm32f3/include/series/crc.h
* @author F3-port by Hanspeter Portner <dev@open-music-kontrollers.ch>
* @brief STM32F3 Cylic Redundancy Check (CRC) support.
*/
#ifndef _LIBMAPLE_STM32F3_CRC_H_
#define _LIBMAPLE_STM32F3_CRC_H_
#ifdef __cplusplus
extern "C"{
#endif
/*
* Register maps
*/
/** CRC register map type */
typedef struct crc_reg_map {
__io uint32 DR; /**< Data register */
__io uint32 IDR; /**< Independent data register */
__io uint32 CR; /**< Control register */
uint32 reserved;
__io uint32 INIT; /**< Initial data register */
__io uint32 POL; /**< Polynomial register */
} crc_reg_map;
/*
* Register map base pointers
*/
/** CRC register map base pointer */
#define CRC_BASE ((struct crc_reg_map*)0x40013800) //TODO
/*
* Register bit definitions
*/
/* Data register */
#define CRC_DR_DATA 0xFFFFFFFF
/* Independent data register */
#define CRC_IDR_DATA 0xFF
/* Control register */
#define CRC_CR_REV_OUT_BIT 7
#define CRC_CR_REV_IN_SHIFT 5
#define CRC_CR_POLYSIZE_SHIFT 3
#define CRC_CR_RESET_BIT 0
#define CRC_CR_REV_OUT (1U << CRC_CR_REV_OUT_BIT)
#define CRC_CR_REV_IN (0x3 << CRC_CR_REV_IN_SHIFT)
#define CRC_CR_POLYSIZE (0x3 << CRC_CR_POLYSIZE_SHIFT)
#define CRC_CR_RESET (1U << CRC_CR_RESET_BIT)
/* Initial data register */
#define CRC_INIT_DATA 0xFFFFFFFF
/* Polynomial register */
#define CRC_POL_DATA 0xFFFFFFFF
/* TODO add some routines */
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,74 @@
/******************************************************************************
* 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/stm32f3/include/series/dac.h
* @brief STM32F3 DAC support
*/
#ifndef _LIBMAPLE_STM32F3_DAC_H_
#define _LIBMAPLE_STM32F3_DAC_H_
#ifdef __cplusplus
extern "C"{
#endif
#include <libmaple/libmaple_types.h>
/** STM32F3 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;
//#define DAC1_BASE ((struct dac_reg_map*)0x40007400)
//#define DAC2_BASE ((struct dac_reg_map*)0x40009800) //TODO STM32F37/38xx
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,557 @@
/******************************************************************************
* The MIT License
*
* Copyright (c) 2010 Michael Hope.
* Copyright (c) 2012 LeafLabs, LLC
* Copyright (c) 2013 OpenMusicKontrollers.
*
* 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/stm32f3/include/series/dma.h
* @author Marti Bolivar <mbolivar@leaflabs.com>,
* Original implementation by Michael Hope,
* F3-port by Hanspeter Portner <dev@open-music-kontrollers.ch>
* @brief STM32F3 DMA series header.
*/
#ifndef _LIBMAPLE_STM32F3_DMA_H_
#define _LIBMAPLE_STM32F3_DMA_H_
#ifdef __cplusplus
extern "C"{
#endif
#include <libmaple/libmaple_types.h>
#include <libmaple/dma_common.h>
/*
* Register maps and base pointers
*/
/**
* @brief STM32F3 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 STM32F3 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;
extern dma_dev *DMA2;
/*
* Other types needed by, or useful for, <libmaple/dma.h>.
*/
/**
* @brief STM32F3 dma_tube.
* On STM32F3, DMA tubes are just channels.
*/
#define dma_tube dma_channel
/**
* @brief On STM32F3, 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 STM32F3 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 STM32F3 DMA request sources.
*
* IMPORTANT:
*
* 1. On STM32F3, 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 STM32F3,
* dma_tube_cfg() will fail.
*
* 2. In general, a DMA tube can only serve a single request source at
* a time, and on STM32F3, 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,
DMA_REQ_SRC_TIM17_CH1 = (RCC_DMA1 << 3) | 1,
DMA_REQ_SRC_TIM17_UP = (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,
/*DMA_REQ_SRC_TIM6_UP = (RCC_DMA1 << 3) | 3,*/ /* remap in SYSCFGR */
/*DMA_REQ_SRC_DAC_CH1 = (RCC_DMA1 << 3) | 3,*/ /* remap in SYSCFGR */
DMA_REQ_SRC_TIM16_CH1 = (RCC_DMA1 << 3) | 3,
DMA_REQ_SRC_TIM16_UP = (RCC_DMA1 << 3) | 3,
/**@}*/
/**@{*/
/** (DMA1, tube 4)*/
DMA_REQ_SRC_SPI2_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,
/*DMA_REQ_SRC_TIM7_UP = (RCC_DMA1 << 3) | 4,*/ /* remap in SYSCFGR */
/*DMA_REQ_SRC_DAC_CH2 = (RCC_DMA1 << 3) | 4,*/ /* remap in SYSCFGR */
/**@}*/
/**@{*/
/** (DMA1, tube 5)*/
DMA_REQ_SRC_SPI2_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,
DMA_REQ_SRC_TIM15_CH1 = (RCC_DMA1 << 3) | 5,
DMA_REQ_SRC_TIM15_UP = (RCC_DMA1 << 3) | 5,
DMA_REQ_SRC_TIM15_TRIG = (RCC_DMA1 << 3) | 5,
DMA_REQ_SRC_TIM15_COM = (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,
/*DMA_REQ_SRC_TIM16_CH1 = (RCC_DMA1 << 3) | 6,*/ /* remap in SYSCFGR */
/*DMA_REQ_SRC_TIM16_UP = (RCC_DMA1 << 3) | 6,*/ /* remap in SYSCFGR */
/**@}*/
/**@{*/
/* 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_ADC2 = (RCC_DMA2 << 3) | 1,
DMA_REQ_SRC_SPI3_RX = (RCC_DMA2 << 3) | 1,
DMA_REQ_SRC_TIM8_CH3 = (RCC_DMA2 << 3) | 1,
DMA_REQ_SRC_TIM8_UP = (RCC_DMA2 << 3) | 1,
/**@}*/
/**@{*/
/** (DMA2, tube 2)*/
DMA_REQ_SRC_ADC4 = (RCC_DMA2 << 3) | 2,
DMA_REQ_SRC_SPI3_TX = (RCC_DMA2 << 3) | 2,
DMA_REQ_SRC_TIM8_CH4 = (RCC_DMA2 << 3) | 2,
DMA_REQ_SRC_TIM8_TRIG = (RCC_DMA2 << 3) | 2,
DMA_REQ_SRC_TIM8_COM = (RCC_DMA2 << 3) | 2,
/**@}*/
/**@{*/
/** (DMA2, tube 3)*/
/* DMA_REQ_SRC_ADC2 = (RCC_DMA2 << 3) | 3,*/ /* remap in SYSCFGR */
DMA_REQ_SRC_UART4_RX = (RCC_DMA2 << 3) | 3,
DMA_REQ_SRC_TIM6_UP = (RCC_DMA2 << 3) | 3,
DMA_REQ_SRC_DAC1_CH1 = (RCC_DMA2 << 3) | 3,
DMA_REQ_SRC_TIM8_CH1 = (RCC_DMA2 << 3) | 3,
/**@}*/
/**@{*/
/** (DMA2, tube 4)*/
/*DMA_REQ_SRC_ADC4 = (RCC_DMA2 << 3) | 4,*/ /* remap in SYSCFGR */
DMA_REQ_SRC_TIM7_UP = (RCC_DMA2 << 3) | 4,
DMA_REQ_SRC_DAC1_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_TIM8_CH2 = (RCC_DMA2 << 3) | 5,
/**@}*/
} dma_request_src;
/*
* Convenience routines.
*/
/**
* @brief On STM32F3, 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 STM32F3, 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)));
}
#ifdef __cplusplus
} // extern "C"
#endif
#endif

View File

@ -0,0 +1,49 @@
/******************************************************************************
* The MIT License
*
* Copyright (c) 2012 LeafLabs, LLC.
* Copyright (c) 2013 OpenMusicKontrollers.
*
* 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/stm32f3/include/series/exti.h
* @author F3-port by Hanspeter Portner <dev@open-music-kontrollers.ch>
* @brief STM32F3 external interrupts
*/
#ifndef _LIBMAPLE_STM32F3_EXTI_H_
#define _LIBMAPLE_STM32F3_EXTI_H_
#ifdef __cpluspus
extern "C" {
#endif
//FIXME F3 has up to 36 EXTIs, expose and handle internal EXTIs 16-35
struct exti_reg_map;
#define EXTI_BASE ((struct exti_reg_map*)0x40010400)
#ifdef __cpluspus
}
#endif
#endif

View File

@ -0,0 +1,164 @@
/******************************************************************************
* The MIT License
*
* Copyright (c) 2010 Perry Hung.
* Copyright (c) 2013 OpenMusicKontrollers.
*
* 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/stm32f3/include/series/flash.h
* @author F3-port by Hanspeter Portner <dev@open-music-kontrollers.ch>
* @brief STM32F3 Flash header.
*
* Provides register map, base pointer, and register bit definitions
* for the Flash controller on the STM32F3 line, along with
* series-specific configuration values.
*/
#ifndef _LIBMAPLE_STM32F3_FLASH_H_
#define _LIBMAPLE_STM32F3_FLASH_H_
#ifdef __cplusplus
extern "C"{
#endif
#include <libmaple/libmaple_types.h>
/*
* Register map
*/
/** @brief STM32F3 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_OBL_LAUNCH_BIT 13
#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_OBL_LAUNCH (1U << FLASH_CR_OBL_LAUNCH_BIT)
#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_DATA1_SHIFT 24
#define FLASH_OBR_DATA0_SHIFT 16
#define FLASH_OBR_BYTE_SHIFT 8
#define FLASH_OBR_SRAM_PE_BIT 14
#define FLASH_OBR_VDDA_MONITOR_BIT 13
#define FLASH_OBR_nBOOT1_BIT 12
#define FLASH_OBR_nRST_STDBY_BIT 10
#define FLASH_OBR_nRST_STOP_BIT 9
#define FLASH_OBR_WDG_SW_BIT 8
#define FLASH_OBR_RDPRT_SHIFT 1
#define FLASH_OBR_OPTERR_BIT 0
#define FLASH_OBR_DATA1 (0xFF << FLASH_OBR_DATA1_SHIFT)
#define FLASH_OBR_DATA0 (0xFF << FLASH_OBR_DATA0_SHIFT)
#define FLASH_OBR_BYTE (0xFF << FLASH_OBR_BYTE_SHIFT)
#define FLASH_OBR_SRAM_PE_STDBY (1U << FLASH_OBR_SRAM_PE_STDBY_BIT)
#define FLASH_OBR_VDDA_MONITOR_STDBY (1U << FLASH_OBR_VDDA_MONITOR_STDBY_BIT)
#define FLASH_OBR_nBOOT1_STDBY (1U << FLASH_OBR_nBOOT1_STDBY_BIT)
#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 (0x3 << FLASH_OBR_RDPRT_SHIFT)
#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 STM32F3 */
FLASH_DCACHE = 0x0, /* Not available on STM32F3 */
};
/* TODO add routines for option byte handling, e.g. nBoot1 */
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,65 @@
/******************************************************************************
* The MIT License
*
* Copyright (c) 2013 OpenMusicKontrollers.
*
* 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/stm32f3/include/series/fpu.h
* @author F3-port by Hanspeter Portner <dev@open-music-kontrollers.ch>
* @brief STM32F3 Floating Point Unit support.
*/
#ifndef _LIBMAPLE_STM32F3_FPU_H_
#define _LIBMAPLE_STM32F3_FPU_H_
#ifdef __cplusplus
extern "C"{
#endif
#include <libmaple/libmaple_types.h>
#include <libmaple/scb.h>
/*
* FPU register maps and devices
*/
/** FPU register map type */
typedef struct fpu_reg_map {
__io uint32 CPACR; /**< coprocessor access control register */
__io uint32 FPCCR; /**< floating-point context control register */
__io uint32 FPCAR; /**< floating-point context address register */
__io uint32 FPDSCR; /**< floating-point default status control register */
} fpu_reg_map;
#define FPU_BASE ((struct fpu_reg_map*)(SCB_BASE + 0x88))
/* TODO
* give registry bitfields here
*/
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,255 @@
/******************************************************************************
* The MIT License
*
* Copyright (c) 2011, 2012 LeafLabs, LLC.
* Copyright (c) 2013 OpenMusicKontrollers.
*
* 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/stm32f3/include/series/gpio.h
* @author F3-port by Hanspeter Portner <dev@open-music-kontrollers.ch>
* @brief STM32F3 GPIO support.
*/
#ifndef _LIBMAPLE_STM32F3_GPIO_H_
#define _LIBMAPLE_STM32F3_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 */
__io uint32 BRR; /**< Port bit reset register */
} gpio_reg_map;
/** GPIO port A register map base pointer */
#define GPIOA_BASE ((struct gpio_reg_map*)0x48000000)
/** GPIO port B register map base pointer */
#define GPIOB_BASE ((struct gpio_reg_map*)0x48000400)
/** GPIO port C register map base pointer */
#define GPIOC_BASE ((struct gpio_reg_map*)0x48000800)
/** GPIO port D register map base pointer */
#define GPIOD_BASE ((struct gpio_reg_map*)0x48000C00)
/** GPIO port E register map base pointer */
#define GPIOE_BASE ((struct gpio_reg_map*)0x48001000)
/** GPIO port F register map base pointer */
#define GPIOF_BASE ((struct gpio_reg_map*)0x48001400)
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;
/*
* 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: FIXME one of those does not exist on the F3
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_0 = 0x0, /**< alternate function 0. */
GPIO_AF_1 = 0x1, /**< alternate function 1. */
GPIO_AF_2 = 0x2, /**< alternate function 2. */
GPIO_AF_3 = 0x3, /**< alternate function 3. */
GPIO_AF_4 = 0x4, /**< alternate function 4. */
GPIO_AF_5 = 0x5, /**< alternate function 5. */
GPIO_AF_6 = 0x6, /**< alternate function 6. */
GPIO_AF_7 = 0x7, /**< alternate function 7. */
GPIO_AF_8 = 0x8, /**< alternate function 8. */
GPIO_AF_9 = 0x9, /**< alternate function 9. */
GPIO_AF_10 = 0xA, /**< alternate function 10. */
GPIO_AF_11 = 0xB, /**< alternate function 11. */
GPIO_AF_12 = 0xC, /**< alternate function 12. */
GPIO_AF_13 = 0xD, /**< alternate function 13. */
GPIO_AF_14 = 0xE, /**< alternate function 14. */
GPIO_AF_15 = 0xF, /**< alternate function 14. */
} gpio_af;
void gpio_set_af(struct gpio_dev *dev, uint8 bit, gpio_af af);
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,315 @@
/******************************************************************************
* The MIT License
*
* Copyright (c) 2013 OpenMusicKontrollers.
*
* 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/stm32f3/include/series/i2c.h
* @author F3-port by Hanspeter Portner <dev@open-music-kontrollers.ch>
* @brief STM32F3 I2C
*/
#ifndef _LIBMAPLE_STM32F3_I2C_H_
#define _LIBMAPLE_STM32F3_I2C_H_
#ifdef __cplusplus
extern "C"{
#endif
#include <libmaple/i2c_common.h>
#include <libmaple/gpio.h>
#include <libmaple/stm32.h>
/*
* Register maps
*/
/** 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 TIMINGR; /**< Timing register */
__io uint32 TIMEOUTR; /**< Timeout register */
__io uint32 ISR; /**< Interrupt and status register */
__io uint32 ICR; /**< Interrupt clear register */
__io uint32 PECR; /**< PEC register */
__io uint32 RXDR; /**< Receive data register */
__io uint32 TXDR; /**< Transmit data register */
} i2c_reg_map;
extern i2c_dev* const I2C1;
extern i2c_dev* const I2C2;
/*
* Register map base pointers
*/
/** STM32F3 I2C1 register map base pointer */
#define I2C1_BASE ((struct i2c_reg_map*)0x40005400)
/** STM32F3 I2C2 register map base pointer */
#define I2C2_BASE ((struct i2c_reg_map*)0x40005800)
/*
* Register bit definitions
*/
/* Control register 1 */
#define I2C_CR1_PECEN_BIT 23
#define I2C_CR1_ALERTEN_BIT 22
#define I2C_CR1_SMBDEN_BIT 21
#define I2C_CR1_SMBHEN_BIT 20
#define I2C_CR1_GCEN_BIT 19
#define I2C_CR1_WUPEN_BIT 18
#define I2C_CR1_NOSTRETCH_BIT 17
#define I2C_CR1_SBC_BIT 16
#define I2C_CR1_RXDMAEN_BIT 15
#define I2C_CR1_TXDMAEN_BIT 14
#define I2C_CR1_ANFOFF_BIT 12
#define I2C_CR1_DNF_SHIFT 8
#define I2C_CR1_ERRIE_BIT 7
#define I2C_CR1_TCIE_BIT 6
#define I2C_CR1_STOPIE_BIT 5
#define I2C_CR1_NACKIE_BIT 4
#define I2C_CR1_ADDRIE_BIT 3
#define I2C_CR1_RXIE_BIT 2
#define I2C_CR1_TXIE_BIT 1
#define I2C_CR1_PE_BIT 0
#define I2C_CR1_PECEN (1U << I2C_CR1_PECEN_BIT)
#define I2C_CR1_ALERTEN (1U << I2C_CR1_ALERTEN_BIT)
#define I2C_CR1_SMBDEN (1U << I2C_CR1_SMBDEN_BIT)
#define I2C_CR1_SMBHEN (1U << I2C_CR1_SMBHEN_BIT)
#define I2C_CR1_GCEN (1U << I2C_CR1_GCEN_BIT)
#define I2C_CR1_WUPEN (1U << I2C_CR1_WUPEN_BIT)
#define I2C_CR1_NOSTRETCH (1U << I2C_CR1_NOSTRETCH_BIT)
#define I2C_CR1_SBC (1U << I2C_CR1_SBC_BIT)
#define I2C_CR1_RXDMAEN (1U << I2C_CR1_RXDMAEN_BIT)
#define I2C_CR1_TXDMAEN (1U << I2C_CR1_TXDMAEN_BIT)
#define I2C_CR1_ANFOFF (1U << I2C_CR1_ANFOFF_BIT)
#define I2C_CR1_DNF (0xF << I2C_CR1_DNF_SHIFT)
#define I2C_CR1_ERRIE (1U << I2C_CR1_ERRIE_BIT)
#define I2C_CR1_TCIE (1U << I2C_CR1_TCIE_BIT)
#define I2C_CR1_STOPIE (1U << I2C_CR1_STOPIE_BIT)
#define I2C_CR1_NACKIE (1U << I2C_CR1_NACKIE_BIT)
#define I2C_CR1_ADDRIE (1U << I2C_CR1_ADDRIE_BIT)
#define I2C_CR1_RXIE (1U << I2C_CR1_RXIE_BIT)
#define I2C_CR1_TXIE (1U << I2C_CR1_TXIE_BIT)
#define I2C_CR1_PE (1U << I2C_CR1_PE_BIT)
/* Control register 2 */
#define I2C_CR2_PECBYTE_BIT 26
#define I2C_CR2_AUTOEND_BIT 25
#define I2C_CR2_RELOAD_BIT 24
#define I2C_CR2_NBYTES_SHIFT 16
#define I2C_CR2_NACK_BIT 15
#define I2C_CR2_STOP_BIT 14
#define I2C_CR2_START_BIT 13
#define I2C_CR2_HEAD10R_BIT 12
#define I2C_CR2_ADD10_BIT 11
#define I2C_CR2_RD_WRN_BIT 10
#define I2C_CR2_SADD_7_BIT_SHIFT 1
#define I2C_CR2_SADD_10_BIT_SHIFT 0
#define I2C_CR2_PECBYTE (1U << I2C_CR2_PECBYTE_BIT)
#define I2C_CR2_AUTOEND (1U << I2C_CR2_AUTOEND_BIT)
#define I2C_CR2_RELOAD (1U << I2C_CR2_RELOAD_BIT)
#define I2C_CR2_NBYTES (0xFF << I2C_CR2_NBYTES_SHIFT)
#define I2C_CR2_NACK (1U << I2C_CR2_NACK_BIT)
#define I2C_CR2_STOP (1U << I2C_CR2_STOP_BIT)
#define I2C_CR2_START (1U << I2C_CR2_START_BIT)
#define I2C_CR2_HEAD10R (1U << I2C_CR2_HEAD10R_BIT)
#define I2C_CR2_ADD10 (1U << I2C_CR2_ADD10_BIT)
#define I2C_CR2_RD_WRN (1U << I2C_CR2_RD_WRN_BIT)
#define I2C_CR2_SADD_7_BIT (0x7F << I2C_CR2_SADD_7_BIT_SHIFT)
#define I2C_CR2_SADD_10_BIT (0x3FF << I2C_CR2_SADD_10_BIT_SHIFT)
/* Own address register 1 */
#define I2C_OAR1_OA1EN_BIT 15
#define I2C_OAR1_OA1MODE_BIT 10
#define I2C_OAR1_OA1_7_BIT_SHIFT 1
#define I2C_OAR1_OA1_10_BIT_SHIFT 0
#define I2C_OAR1_OA1EN (1U << I2C_OAR1_OA1EN_BIT)
#define I2C_OAR1_OA1MODE (1U << I2C_OAR1_OA1MODE_BIT)
#define I2C_OAR1_OA1_7_BIT (0x7F << I2C_OAR1_OA1_7_BIT_SHIFT)
#define I2C_OAR1_OA1_10_BIT (0x3FF << I2C_OAR1_OA1_10_BIT_SHIFT)
/* Own address register 2 */
#define I2C_OAR2_OA2EN_BIT 15
#define I2C_OAR2_OA2MSK_SHIFT 8
#define I2C_OAR2_OA2_7_BIT_SHIFT 1
#define I2C_OAR2_OA2EN (1U << I2C_OAR2_OA2EN_BIT)
#define I2C_OAR2_OA2MSK (0x7 << I2C_OAR2_OA2MSK_SHIFT)
#define I2C_OAR2_OA2_7_BIT (0x7F << I2C_OAR2_OA2_7_BIT_SHIFT)
/* Timing register */
#define I2C_TIMINGR_PRESC_SHIFT 28
#define I2C_TIMINGR_SCLDEL_SHIFT 20
#define I2C_TIMINGR_SDADEL_SHIFT 16
#define I2C_TIMINGR_SCLH_SHIFT 8
#define I2C_TIMINGR_SCLL_SHIFT 0
#define I2C_TIMINGR_PRESC (0xF << I2C_TIMINGR_PRESC_SHIFT)
#define I2C_TIMINGR_SCLDEL (0xF << I2C_TIMINGR_SCLDEL_SHIFT)
#define I2C_TIMINGR_SCADEL (0xF << I2C_TIMINGR_SCADEL_SHIFT)
#define I2C_TIMINGR_SCLH (0xFF << I2C_TIMINGR_SCLH_SHIFT)
#define I2C_TIMINGR_SCLL (0xFF << I2C_TIMINGR_SCLL_SHIFT)
/* Timeout register */
#define I2C_TIMEOUTR_TEXTEN_BIT 31
#define I2C_TIMEOUTR_TIMEOUTB_SHIFT 16
#define I2C_TIMEOUTR_TIMOUTEN_BIT 15
#define I2C_TIMEOUTR_TIDLE_BIT 12
#define I2C_TIMEOUTR_TIMEOUTA_SHIFT 0
#define I2C_TIMEOUTR_TEXTEN (1U << I2C_TIMEOUTR_TEXTEN_BIT)
#define I2C_TIMEOUTR_TIMEOUTB (0xFFF << I2C_TIMEOUTR_TIMEOUTB_SHIFT)
#define I2C_TIMEOUTR_TIMOUTEN (1U << I2C_TIMEOUTR_TIMOUTEN_BIT)
#define I2C_TIMEOUTR_TIDLE (1U << I2C_TIMEOUTR_TIDLE_BIT)
#define I2C_TIMEOUTR_TIMEOUTA (0xFFF << I2C_TIMEOUTR_TIMEOUTA_SHIFT)
/* Interrupt and status register */
#define I2C_ISR_ADDCODE_SHIFT 17
#define I2C_ISR_DIR_BIT 16
#define I2C_ISR_BUSY_BIT 15
#define I2C_ISR_ALERT_BIT 13
#define I2C_ISR_TIMEOUT_BIT 12
#define I2C_ISR_PECERR_BIT 11
#define I2C_ISR_OVR_BIT 10
#define I2C_ISR_ARLO_BIT 9
#define I2C_ISR_BERR_BIT 8
#define I2C_ISR_TCR_BIT 7
#define I2C_ISR_TC_BIT 6
#define I2C_ISR_STOPF_BIT 5
#define I2C_ISR_NACKF_BIT 4
#define I2C_ISR_ADDR_BIT 3
#define I2C_ISR_RXNE_BIT 2
#define I2C_ISR_TXIS_BIT 1
#define I2C_ISR_TXE_BIT 0
#define I2C_ISR_ADDCODE (0x7F << I2C_ISR_ADDCODE_SHIFT)
#define I2C_ISR_ALERTCF (1U << I2C_ISR_ALERTCF_BIT)
#define I2C_ISR_DIR (1U << I2C_ISR_DIR_BIT)
#define I2C_ISR_BUSY (1U << I2C_ISR_BUSY_BIT)
#define I2C_ISR_ALERT (1U << I2C_ISR_ALERT_BIT)
#define I2C_ISR_TIMEOUT (1U << I2C_ISR_TIMEOUT_BIT)
#define I2C_ISR_PECERR (1U << I2C_ISR_PECERR_BIT)
#define I2C_ISR_OVR (1U << I2C_ISR_OVR_BIT)
#define I2C_ISR_ARLO (1U << I2C_ISR_ARLO_BIT)
#define I2C_ISR_BERR (1U << I2C_ISR_BERR_BIT)
#define I2C_ISR_TCR (1U << I2C_ISR_TCR_BIT)
#define I2C_ISR_TC (1U << I2C_ISR_TC_BIT)
#define I2C_ISR_STOPF (1U << I2C_ISR_STOPF_BIT)
#define I2C_ISR_NACKF (1U << I2C_ISR_NACKF_BIT)
#define I2C_ISR_ADDR (1U << I2C_ISR_ADDR_BIT)
#define I2C_ISR_RXNE (1U << I2C_ISR_RXNE_BIT)
#define I2C_ISR_TXIS (1U << I2C_ISR_TXIS_BIT)
#define I2C_ISR_TXE (1U << I2C_ISR_TXE_BIT)
/* Interrupt clear register */
#define I2C_ICR_ALERTCF_BIT 13
#define I2C_ICR_TIMOUTCF_BIT 12
#define I2C_ICR_PECCF_BIT 11
#define I2C_ICR_OVRCF_BIT 10
#define I2C_ICR_ARLOCF_BIT 9
#define I2C_ICR_BERRCF_BIT 8
#define I2C_ICR_STOPCF_BIT 5
#define I2C_ICR_NACKCF_BIT 4
#define I2C_ICR_ADDRCF_BIT 3
#define I2C_ICR_ALERTCF (1U << I2C_ICR_ALERTCF_BIT)
#define I2C_ICR_TIMOUTCF (1U << I2C_ICR_TIMOUTCF_BIT)
#define I2C_ICR_PECCF (1U << I2C_ICR_PECERRCF_BIT)
#define I2C_ICR_OVRCF (1U << I2C_ICR_OVRCF_BIT)
#define I2C_ICR_ARLOCF (1U << I2C_ICR_ARLOCF_BIT)
#define I2C_ICR_BERRCF (1U << I2C_ICR_BERRCF_BIT)
#define I2C_ICR_STOPCF (1U << I2C_ICR_STOPCF_BIT)
#define I2C_ICR_NACKCF (1U << I2C_ICR_NACKCF_BIT)
#define I2C_ICR_ADDRCF (1U << I2C_ICR_ADDRCF_BIT)
/* PEC register */
#define I2C_PEC_PEC 0xFF
/* Receive data register */
#define I2C_RXDR_RXDATA 0xFF
/* Transmit data register */
#define I2C_TXDR_TXDATA 0xFF
/*
* Timing configurations
*/
/* Timing configuration for I2C clock running at 8MHz */
/* NOTE:
* I2C is clocked by HSI (8MHz) by default
* if clock source is changed with RCC_CFGR_I2C1SW/I2C2SW,
* these values have to be adapted
*/
typedef enum i2c_timing {
I2C_TIMING_10_kHz = (0x01 << I2C_TIMINGR_PRESC_SHIFT)
+ (0x04 << I2C_TIMINGR_SCLDEL_SHIFT)
+ (0x02 << I2C_TIMINGR_SDADEL_SHIFT)
+ (0xC3 << I2C_TIMINGR_SCLH_SHIFT)
+ (0xC7 << I2C_TIMINGR_SCLL_SHIFT),
I2C_TIMING_100_kHz = (0x01 << I2C_TIMINGR_PRESC_SHIFT)
+ (0x04 << I2C_TIMINGR_SCLDEL_SHIFT)
+ (0x02 << I2C_TIMINGR_SDADEL_SHIFT)
+ (0x0F << I2C_TIMINGR_SCLH_SHIFT)
+ (0x13 << I2C_TIMINGR_SCLL_SHIFT),
I2C_TIMING_400_kHz = (0x00 << I2C_TIMINGR_PRESC_SHIFT)
+ (0x03 << I2C_TIMINGR_SCLDEL_SHIFT)
+ (0x01 << I2C_TIMINGR_SDADEL_SHIFT)
+ (0x03 << I2C_TIMINGR_SCLH_SHIFT)
+ (0x09 << I2C_TIMINGR_SCLL_SHIFT),
I2C_TIMING_500_kHz = (0x00 << I2C_TIMINGR_PRESC_SHIFT)
+ (0x01 << I2C_TIMINGR_SCLDEL_SHIFT)
+ (0x01 << I2C_TIMINGR_SDADEL_SHIFT)
+ (0x03 << I2C_TIMINGR_SCLH_SHIFT)
+ (0x06 << I2C_TIMINGR_SCLL_SHIFT),
} i2c_timing;
/*
* For internal use
*/
static inline uint32 _i2c_bus_clk(i2c_dev *dev) { /* FIXME remove, is a remainder of F1 code */
/* Both I2C peripherals are on APB1 */
return STM32_PCLK1 / (1000 * 1000);
}
extern uint8 i2c_read(i2c_dev *dev);
#ifdef __cplusplus
}
#endif
#endif /* _LIBMAPLE_STM32F3_I2C_H_ */

View File

@ -0,0 +1,153 @@
/******************************************************************************
* The MIT License
*
* Copyright (c) 2010 Perry Hung.
* Copyright (c) 2013 OpenMusicKontrollers.
*
* 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/stm32f3/include/series/nvic.h
* @author F3-port by Hanspeter Portner <dev@open-music-kontrollers.ch>
* @brief STM32F3 Nested Vectored Interrupt Controller (NVIC) support.
*/
#ifndef _LIBMAPLE_STM32F3_NVIC_H_
#define _LIBMAPLE_STM32F3_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_TAMP_STAMP = 2, /**< Tamper */
NVIC_RTC_WKUP = 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 */ //FIXME capacitive touch
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_ADC1_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_TIMER15 = 24, // FIXME hack
NVIC_TIMER1_BRK_TIMER9 = 24, /**< Timer 1 break, Timer 9. */ // FIXME rm
//NVIC_TIMER1_UP_TIMER16 = 25, // FIXME hack
NVIC_TIMER1_UP_TIMER10 = 25, /**< Timer 1 update, Timer 10. */ //FIXME rm
//NVIC_TIMER1_TRG_COM_TIMER17 = 26, // FIXME hack
NVIC_TIMER1_TRG_COM_TIMER11 = 26, /**<
* Timer 1 trigger and commutation,
* Timer 11. */ // FIXME rm
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_RTC_ALARM = 41, /**< RTC alarm through EXTI line */
NVIC_USB_WKUP = 42, /**< USB wakeup from suspend through
EXTI line */
NVIC_TIMER8_BRK_TIMER12 = 43, /**< Timer 8 break, timer 12 */ //TODO rm TIMER12
NVIC_TIMER8_UP_TIMER13 = 44, /**< Timer 8 update, timer 13 */ // TODO rm TIMER13
NVIC_TIMER8_TRG_COM_TIMER14 = 45, /**<
* Timer 8 trigger and commutation,
* Timer 14. */ //TODO rm TIMER14
NVIC_TIMER8_CC = 46, /**< Timer 8 capture/compare */
NVIC_ADC3 = 47, /**< ADC3 */
NVIC_SPI3 = 51, /**< SPI3 */
NVIC_UART4 = 52, /**< UART4 */
NVIC_UART5 = 53, /**< UART5 */
//NVIC_TIMER6_DAC = 54, // TODO hack
NVIC_TIMER6 = 54, /**< Timer 6 */ //TODO add DAC
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_CH4 = 59, /**< DMA2 channel 4 */
NVIC_DMA2_CH5 = 60, /**< DMA2 channel 5 */
NVIC_ADC4 = 61, /**< DMA2 channels 4 and 5 */
NVIC_COMP123 = 64, /**< DMA2 channels 4 and 5 */
NVIC_COMP456 = 65, /**< DMA2 channels 4 and 5 */
NVIC_COMP7 = 66, /**< DMA2 channels 4 and 5 */
NVIC_USB_HP = 74, /**< DMA2 channels 4 and 5 */
NVIC_USB_LP = 75, /**< DMA2 channels 4 and 5 */
NVIC_USB_WKUP2 = 76, /**< DMA2 channels 4 and 5 */
NVIC_FPU = 81, /**< DMA2 channels 4 and 5 */
} 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,123 @@
/******************************************************************************
* The MIT License
*
* Copyright (c) 2013 OpenMusicKontrollers.
*
* 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/stm32f3/include/series/ompamp.h
* @author F3-port by Hanspeter Portner <dev@open-music-kontrollers.ch>
* @brief STM32F3 Operational Amplifier support.
*/
#ifndef _LIBMAPLE_STM32F3_OPAMP_H_
#define _LIBMAPLE_STM32F3_OPAMP_H_
#ifdef __cplusplus
extern "C"{
#endif
#include <libmaple/libmaple_types.h>
/*
* Register map
*/
/*
* OpAmp individual register map type.
*/
typedef struct opamp_reg_map {
__io uint32 CSR; /**< */
} opamp_reg_map;
/** OpAmp device type. */
typedef struct opamp_dev {
opamp_reg_map *regs; /**< Register map */
} opamp_dev;
/*
* Devices
*/
extern const struct opamp_dev *OPAMP1; /* OpAmp amplifier 1 */
extern const struct opamp_dev *OPAMP2; /* OpAmp amplifier 2 */
extern const struct opamp_dev *OPAMP3; /* OpAmp amplifier 3 */
extern const struct opamp_dev *OPAMP4; /* OpAmp amplifier 4 */
/*
* Register map base pointers
*/
#define OPAMP1_BASE ((struct opamp_reg_map*)0x40010038)
#define OPAMP2_BASE ((struct opamp_reg_map*)0x4001003C)
#define OPAMP3_BASE ((struct opamp_reg_map*)0x40010040)
#define OPAMP4_BASE ((struct opamp_reg_map*)0x40010044)
/*
* Register bit definitions
*/
/* Control and status register */
#define OPAMP_CSR_LOCK_BIT 31
#define OPAMP_CSR_OUTCAL_BIT 30
#define OPAMP_CSR_TSTREF_BIT 29
#define OPAMP_CSR_TRIMOFFSETN_SHIFT 24
#define OPAMP_CSR_TRIMOFFSETP_SHIFT 19
#define OPAMP_CSR_USER_TRIM_BIT 18
#define OPAMP_CSR_PGA_GAIN_SHIFT 14
#define OPAMP_CSR_CAL_SEL_SHIFT 12
#define OPAMP_CSR_CAL_ON_BIT 11
#define OPAMP_CSR_VPS_SEL_SHIFT 9
#define OPAMP_CSR_VMS_SEL_BIT 8
#define OPAMP_CSR_TCM_EN_BIT 7
#define OPAMP_CSR_VM_SEL_SHIFT 5
#define OPAMP_CSR_VP_SEL_SHIFT 2
#define OPAMP_CSR_FORCE_VP_BIT 1
#define OPAMP_CSR_EN_BIT 0
#define OPAMP_CSR_LOCK (1U << OPAMP_CSR_LOCK_BIT)
#define OPAMP_CSR_OUTCAL (1U << OPAMP_CSR_OUTCAL_BIT)
#define OPAMP_CSR_TSTREF (1U << OPAMP_CSR_TSTREF_BIT)
#define COMP_CSR_TRIMOFFSETN (0x1F << COMP_CSR_TRIMOFFSETN_SHIFT)
#define COMP_CSR_TRIMOFFSETP (0x1F << COMP_CSR_TRIMOFFSETP_SHIFT)
#define OPAMP_CSR_USER_TRIM (1U << OPAMP_CSR_USER_TRIM_BIT)
#define COMP_CSR_PGA_GAIN (0xF << COMP_CSR_PGA_GAIN_SHIFT)
#define COMP_CSR_CAL_SEL (0x3 << COMP_CSR_CAL_SEL_SHIFT)
#define OPAMP_CSR_CAL_ON (1U << OPAMP_CSR_CAL_ON_BIT)
#define COMP_CSR_VPS_SEL (0x3 << COMP_CSR_VPS_SEL_SHIFT)
#define OPAMP_CSR_VMS_SEL (1U << OPAMP_CSR_VMS_SEL_BIT)
#define OPAMP_CSR_TCM_EN (1U << OPAMP_CSR_TCM_EN_BIT)
#define COMP_CSR_VM_SEL (0x3 << COMP_CSR_VM_SEL_SHIFT)
#define COMP_CSR_VP_SEL (0x3 << COMP_CSR_VP_SEL_SHIFT)
#define OPAMP_CSR_FORCE_VP (1U << OPAMP_CSR_FORCE_VP_BIT)
#define OPAMP_CSR_EN (1U << OPAMP_CSR_EN_BIT)
/* TODO
* actually implement me ;-)
*/
#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 STM32F3 Power control (PWR) support.
*/
#ifndef _LIBMAPLE_STM32F3_PWR_H_
#define _LIBMAPLE_STM32F3_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,632 @@
/******************************************************************************
* The MIT License
*
* Copyright (c) 2010 Perry Hung.
* Copyright (c) 2011 LeafLabs, LLC.
* Copyright (c) 2013 OpenMusicKontrollers.
*
* 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/stm32f3/include/series/rcc.h
* @author F3-port by Hanspeter Portner <dev@open-music-kontrollers.ch>
* @brief STM32F3 reset and clock control (RCC) support.
*/
#ifndef _LIBMAPLE_STM32F3_RCC_H_
#define _LIBMAPLE_STM32F3_RCC_H_
#ifdef __cplusplus
extern "C"{
#endif
#include <libmaple/libmaple_types.h>
/*
* Register map
*/
/** STM32F3 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 */
__io uint32 AHBRSTR; /**< AHB peripheral reset register */
__io uint32 CFGR2; /**< Control/status register 2 */
__io uint32 CFGR3; /**< Control/status register 3 */
} 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_I2SSRC_BIT 23
#define RCC_CFGR_USBPRE_BIT 22
#define RCC_CFGR_PLLMUL_BIT 18
#define RCC_CFGR_PLLXTPRE_BIT 17
#define RCC_CFGR_PLLSRC_BIT 16
#define RCC_CFGR_PPRE2_BIT 11
#define RCC_CFGR_PPRE1_BIT 8
#define RCC_CFGR_HPRE_BIT 4
#define RCC_CFGR_MCO (0x3 << 24)
#define RCC_CFGR_I2SSRC (1U << RCC_CFGR_I2CSRC_BIT)
#define RCC_CFGR_USBPRE (1U << RCC_CFGR_USBPRE_BIT)
#define RCC_CFGR_PLLMUL (0xF << RCC_CFGR_PLLMUL_BIT)
#define RCC_CFGR_PLLXTPRE (1U << RCC_CFGR_PLLXTPRE_BIT)
#define RCC_CFGR_PLLSRC (1U << RCC_CFGR_PLLSRC_BIT)
#define RCC_CFGR_PPRE2 (0x7 << RCC_CFGR_PPRE2_BIT)
#define RCC_CFGR_PPRE1 (0x7 << RCC_CFGR_PPRE1_BIT)
#define RCC_CFGR_HPRE (0xF << RCC_CFGR_HPRE_BIT)
#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_TIM17RST_BIT 18
#define RCC_APB2RSTR_TIM16RST_BIT 17
#define RCC_APB2RSTR_TIM15RST_BIT 16
#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_SYSCFGRST_BIT 0
#define RCC_APB2RSTR_TIM17RST (1U << RCC_APB2RSTR_TIM17RST_BIT)
#define RCC_APB2RSTR_TIM16RST (1U << RCC_APB2RSTR_TIM16RST_BIT)
#define RCC_APB2RSTR_TIM15RST (1U << RCC_APB2RSTR_TIM15RST_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_SYSCFGRST (1U << RCC_APB2RSTR_SYSCFGRST_BIT)
/* APB1 peripheral reset register */
#define RCC_APB1RSTR_DACRST_BIT 29
#define RCC_APB1RSTR_PWRRST_BIT 28
#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_TIM7RST_BIT 5
#define RCC_APB1RSTR_TIM6RST_BIT 4
#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_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_TIM7RST (1U << RCC_APB1RSTR_TIM7RST_BIT)
#define RCC_APB1RSTR_TIM6RST (1U << RCC_APB1RSTR_TIM6RST_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_ADC34EN_BIT 29
#define RCC_AHBENR_ADC12EN_BIT 28
#define RCC_AHBENR_TSCEN_BIT 24
#define RCC_AHBENR_IOPFEN_BIT 22
#define RCC_AHBENR_IOPEEN_BIT 21
#define RCC_AHBENR_IOPDEN_BIT 20
#define RCC_AHBENR_IOPCEN_BIT 19
#define RCC_AHBENR_IOPBEN_BIT 18
#define RCC_AHBENR_IOPAEN_BIT 17
#define RCC_AHBENR_CRCEN_BIT 6
#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_ADC34EN (1U << RCC_AHBENR_ADC34EN_BIT)
#define RCC_AHBENR_ADC12EN (1U << RCC_AHBENR_ADC12EN_BIT)
#define RCC_AHBENR_TSCEN (1U << RCC_AHBENR_TSCEN_BIT)
#define RCC_AHBENR_IOPFEN (1U << RCC_AHBENR_IOPFEN_BIT)
#define RCC_AHBENR_IOPEEN (1U << RCC_AHBENR_IOPEEN_BIT)
#define RCC_AHBENR_IOPDEN (1U << RCC_AHBENR_IOPDEN_BIT)
#define RCC_AHBENR_IOPCEN (1U << RCC_AHBENR_IOPCEN_BIT)
#define RCC_AHBENR_IOPBEN (1U << RCC_AHBENR_IOPBEN_BIT)
#define RCC_AHBENR_IOPAEN (1U << RCC_AHBENR_IOPAEN_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_TIM17EN_BIT 18
#define RCC_APB2ENR_TIM16EN_BIT 17
#define RCC_APB2ENR_TIM15EN_BIT 16
#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_SYSCFGEN_BIT 0
#define RCC_APB2ENR_TIM17EN (1U << RCC_APB2ENR_TIM17EN_BIT)
#define RCC_APB2ENR_TIM16EN (1U << RCC_APB2ENR_TIM16EN_BIT)
#define RCC_APB2ENR_TIM15EN (1U << RCC_APB2ENR_TIM15EN_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_SYSCFGEN (1U << RCC_APB2ENR_SYSCFGEN_BIT)
/* APB1 peripheral clock enable register */
#define RCC_APB1ENR_DACEN_BIT 29
#define RCC_APB1ENR_PWREN_BIT 28
#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_TIM7EN_BIT 5
#define RCC_APB1ENR_TIM6EN_BIT 4
#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_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_TIM7EN (1U << RCC_APB1ENR_TIM7EN_BIT)
#define RCC_APB1ENR_TIM6EN (1U << RCC_APB1ENR_TIM6EN_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_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_OBLRSTF_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_OBLRSTF (1U << RCC_CSR_OBLRSTF_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)
/* AHB peripheral reset register */
#define RCC_AHBRSTR_ADC34RST_BIT 29
#define RCC_AHBRSTR_ADC12RST_BIT 28
#define RCC_AHBRSTR_TSCRST_BIT 24
#define RCC_AHBRSTR_IOPFRST_BIT 22
#define RCC_AHBRSTR_IOPERST_BIT 21
#define RCC_AHBRSTR_IOPDRST_BIT 20
#define RCC_AHBRSTR_IOPCRST_BIT 19
#define RCC_AHBRSTR_IOPBRST_BIT 18
#define RCC_AHBRSTR_IOPARST_BIT 17
#define RCC_AHBRSTR_ADC34RST (1U << RCC_AHBRSTR_ADC34RST_BIT)
#define RCC_AHBRSTR_ADC12RST (1U << RCC_AHBRSTR_ADC12RST_BIT)
#define RCC_AHBRSTR_TSCRST (1U << RCC_AHBRSTR_TSCRST_BIT)
#define RCC_AHBRSTR_IOPFRST (1U << RCC_AHBRSTR_IOPFRST_BIT)
#define RCC_AHBRSTR_IOPERST (1U << RCC_AHBRSTR_IOPERST_BIT)
#define RCC_AHBRSTR_IOPDRST (1U << RCC_AHBRSTR_IOPDRST_BIT)
#define RCC_AHBRSTR_IOPCRST (1U << RCC_AHBRSTR_IOPCRST_BIT)
#define RCC_AHBRSTR_IOPBRST (1U << RCC_AHBRSTR_IOPBRST_BIT)
#define RCC_AHBRSTR_IOPARST (1U << RCC_AHBRSTR_IOPARST_BIT)
/* Clock configuration register 2 */
#define RCC_CFGR2_ADC34PRES_SHIFT 9
#define RCC_CFGR2_ADC12PRES_SHIFT 4
#define RCC_CFGR2_ADC34PRES (0x1f << RCC_CFGR2_ADC34PRES_SHIFT)
#define RCC_CFGR2_ADC12PRES (0x1f << RCC_CFGR2_ADC12PRES_SHIFT)
#define RCC_CFGR2_PREDIV 0xf
/* Clock configuration register 3 */ //TODO make clock sources configurable
#define RCC_CFGR3_TIM8SW_BIT 9
#define RCC_CFGR3_TIM1SW_BIT 8
#define RCC_CFGR3_I2C2SW_BIT 5
#define RCC_CFGR3_I2C1SW_BIT 4
#define RCC_CFGR3_UART5SW (0x3 << 22)
#define RCC_CFGR3_UART4SW (0x3 << 20)
#define RCC_CFGR3_USART3SW (0x3 << 18)
#define RCC_CFGR3_USART2SW (0x3 << 16)
#define RCC_CFGR_TIM8SW (1U << RCC_CFGR3_TIM8SW_BIT)
#define RCC_CFGR_TIM1SW (1U << RCC_CFGR3_TIM1SW_BIT)
#define RCC_CFGR_I2C2SW (1U << RCC_CFGR3_I2C2SW_BIT)
#define RCC_CFGR_I2C1SW (1U << RCC_CFGR3_I2C1SW_BIT)
#define RCC_CFGR3_USART1SW 0x3
/*
* libmaple-mandated enumeration types.
*/
/**
* @brief STM32F3 rcc_clk_id.
*/
typedef enum rcc_clk_id {
RCC_GPIOA,
RCC_GPIOB,
RCC_GPIOC,
RCC_GPIOD,
RCC_GPIOE,
RCC_GPIOF,
RCC_ADC12,
RCC_ADC34,
RCC_DAC,
RCC_DMA1,
RCC_DMA2,
RCC_I2C1,
RCC_I2C2,
RCC_SPI1,
RCC_SPI2,
RCC_SPI3,
RCC_USART1,
RCC_USART2,
RCC_USART3,
RCC_UART4,
RCC_UART5,
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_TIMER15,
RCC_TIMER16,
RCC_TIMER17,
RCC_SYSCFG,
RCC_CRC,
RCC_FLITF,
RCC_PWR,
RCC_SRAM,
RCC_USB,
} rcc_clk_id;
/**
* @brief STM32F3 PLL clock sources.
* @see rcc_configure_pll()
*/
typedef enum rcc_pllsrc {
RCC_PLLSRC_HSE = (0x1 << RCC_CFGR_PLLSRC_BIT),
RCC_PLLSRC_HSI_DIV_2 = (0x0 << RCC_CFGR_PLLSRC_BIT)
} rcc_pllsrc;
/**
* @brief STM32F3 clock domains.
* @see rcc_dev_clk()
*/
typedef enum rcc_clk_domain {
RCC_APB1,
RCC_APB2,
RCC_AHB
} rcc_clk_domain;
/**
* @brief STM32F3 Prescaler identifiers
* @see rcc_set_prescaler()
*/
typedef enum rcc_prescaler {
RCC_PRESCALER_AHB,
RCC_PRESCALER_APB1,
RCC_PRESCALER_APB2,
RCC_PRESCALER_USB,
} rcc_prescaler;
/**
* @brief STM32F3 ADC prescaler dividers
* @see rcc_set_prescaler()
*/
typedef enum rcc_adc_divider {
RCC_ADCPRE_PCLK_DISABLED = 0x00,
RCC_ADCPRE_PCLK_DIV_1 = 0x10,
RCC_ADCPRE_PCLK_DIV_2 = 0x11,
RCC_ADCPRE_PCLK_DIV_4 = 0x12,
RCC_ADCPRE_PCLK_DIV_6 = 0x13,
RCC_ADCPRE_PCLK_DIV_8 = 0x14,
RCC_ADCPRE_PCLK_DIV_10 = 0x15,
RCC_ADCPRE_PCLK_DIV_12 = 0x16,
RCC_ADCPRE_PCLK_DIV_16 = 0x17,
RCC_ADCPRE_PCLK_DIV_32 = 0x18,
RCC_ADCPRE_PCLK_DIV_64 = 0x19,
RCC_ADCPRE_PCLK_DIV_128 = 0x1A,
RCC_ADCPRE_PCLK_DIV_256 = 0x1B,
} rcc_adc_divider;
/**
* @brief STM32F3 PREDIV prescaler dividers
* @see rcc_set_prescaler()
*/
typedef enum rcc_prediv_divider {
RCC_PREDIV_PCLK_DIV_1 = 0x0,
RCC_PREDIV_PCLK_DIV_2 = 0x1,
RCC_PREDIV_PCLK_DIV_3 = 0x2,
RCC_PREDIV_PCLK_DIV_4 = 0x3,
RCC_PREDIV_PCLK_DIV_5 = 0x4,
RCC_PREDIV_PCLK_DIV_6 = 0x5,
RCC_PREDIV_PCLK_DIV_7 = 0x6,
RCC_PREDIV_PCLK_DIV_8 = 0x7,
RCC_PREDIV_PCLK_DIV_9 = 0x8,
RCC_PREDIV_PCLK_DIV_10 = 0x9,
RCC_PREDIV_PCLK_DIV_11 = 0xA,
RCC_PREDIV_PCLK_DIV_12 = 0xB,
RCC_PREDIV_PCLK_DIV_13 = 0xC,
RCC_PREDIV_PCLK_DIV_14 = 0xD,
RCC_PREDIV_PCLK_DIV_15 = 0xE,
RCC_PREDIV_PCLK_DIV_16 = 0xF,
} rcc_prediv_divider;
/**
* @brief STM32F3 APB1 prescaler dividers
* @see rcc_set_prescaler()
*/
typedef enum rcc_apb1_divider {
RCC_APB1_HCLK_DIV_1 = 0x0 << RCC_CFGR_PPRE1_BIT,
RCC_APB1_HCLK_DIV_2 = 0x4 << RCC_CFGR_PPRE1_BIT,
RCC_APB1_HCLK_DIV_4 = 0x5 << RCC_CFGR_PPRE1_BIT,
RCC_APB1_HCLK_DIV_8 = 0x6 << RCC_CFGR_PPRE1_BIT,
RCC_APB1_HCLK_DIV_16 = 0x7 << RCC_CFGR_PPRE1_BIT,
} rcc_apb1_divider;
/**
* @brief STM32F3 APB2 prescaler dividers
* @see rcc_set_prescaler()
*/
typedef enum rcc_apb2_divider {
RCC_APB2_HCLK_DIV_1 = 0x0 << RCC_CFGR_PPRE2_BIT,
RCC_APB2_HCLK_DIV_2 = 0x4 << RCC_CFGR_PPRE2_BIT,
RCC_APB2_HCLK_DIV_4 = 0x5 << RCC_CFGR_PPRE2_BIT,
RCC_APB2_HCLK_DIV_8 = 0x6 << RCC_CFGR_PPRE2_BIT,
RCC_APB2_HCLK_DIV_16 = 0x7 << RCC_CFGR_PPRE2_BIT,
} rcc_apb2_divider;
/**
* @brief STM32F3 AHB prescaler dividers
* @see rcc_set_prescaler()
*/
typedef enum rcc_ahb_divider {
RCC_AHB_SYSCLK_DIV_1 = 0x0 << RCC_CFGR_HPRE_BIT,
RCC_AHB_SYSCLK_DIV_2 = 0x8 << RCC_CFGR_HPRE_BIT,
RCC_AHB_SYSCLK_DIV_4 = 0x9 << RCC_CFGR_HPRE_BIT,
RCC_AHB_SYSCLK_DIV_8 = 0xA << RCC_CFGR_HPRE_BIT,
RCC_AHB_SYSCLK_DIV_16 = 0xB << RCC_CFGR_HPRE_BIT,
RCC_AHB_SYSCLK_DIV_32 = 0xC << RCC_CFGR_HPRE_BIT,
RCC_AHB_SYSCLK_DIV_64 = 0xD << RCC_CFGR_HPRE_BIT,
RCC_AHB_SYSCLK_DIV_128 = 0xD << RCC_CFGR_HPRE_BIT,
RCC_AHB_SYSCLK_DIV_256 = 0xE << RCC_CFGR_HPRE_BIT,
RCC_AHB_SYSCLK_DIV_512 = 0xF << RCC_CFGR_HPRE_BIT,
} rcc_ahb_divider;
/**
* @brief STM32F3 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 STM32F3 PLL multipliers.
*/
typedef enum rcc_pll_multiplier {
RCC_PLLMUL_2 = (0x0 << RCC_CFGR_PLLMUL_BIT),
RCC_PLLMUL_3 = (0x1 << RCC_CFGR_PLLMUL_BIT),
RCC_PLLMUL_4 = (0x2 << RCC_CFGR_PLLMUL_BIT),
RCC_PLLMUL_5 = (0x3 << RCC_CFGR_PLLMUL_BIT),
RCC_PLLMUL_6 = (0x4 << RCC_CFGR_PLLMUL_BIT),
RCC_PLLMUL_7 = (0x5 << RCC_CFGR_PLLMUL_BIT),
RCC_PLLMUL_8 = (0x6 << RCC_CFGR_PLLMUL_BIT),
RCC_PLLMUL_9 = (0x7 << RCC_CFGR_PLLMUL_BIT),
RCC_PLLMUL_10 = (0x8 << RCC_CFGR_PLLMUL_BIT),
RCC_PLLMUL_11 = (0x9 << RCC_CFGR_PLLMUL_BIT),
RCC_PLLMUL_12 = (0xA << RCC_CFGR_PLLMUL_BIT),
RCC_PLLMUL_13 = (0xB << RCC_CFGR_PLLMUL_BIT),
RCC_PLLMUL_14 = (0xC << RCC_CFGR_PLLMUL_BIT),
RCC_PLLMUL_15 = (0xD << RCC_CFGR_PLLMUL_BIT),
RCC_PLLMUL_16 = (0xE << RCC_CFGR_PLLMUL_BIT),
} rcc_pll_multiplier;
/* FIXME [0.0.13] Just have data point to an rcc_pll_multiplier! */
/**
* @brief STM32F3 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 stm32f3_rcc_pll_data {
rcc_pll_multiplier pll_mul; /**< PLL multiplication factor. */
rcc_prediv_divider pclk_prediv; /**< PCLK predivider. */
} stm32f3_rcc_pll_data;
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,109 @@
/******************************************************************************
* The MIT License
*
* Copyright (c) 2013 OpenMusicKontrollers.
*
* 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/simd.h
* @author F3-port by Hanspeter Portner <dev@open-music-kontrollers.ch>
* @brief Convenience macros for the digital signal processing (DSP)
* instruction set of the ARM Cortex M4 microcontroller.
*/
#ifndef _LIBMAPLE_DSP_H_
#define _LIBMAPLE_DSP_H_
#ifdef __cplusplus
extern "C"{
#endif
#define DSP3(ID, A, B, C) \
({ \
uint32_t X; \
asm volatile (ID" %[res], %[val1], %[val2], %[val3]" \
: [res]"=r" (X) \
: [val1]"r" (A), [val2]"r" (B), [val3]"r" (C) \
); \
(uint32_t)X; \
})
#define DSP2(ID, A, B) \
({ \
uint32_t X; \
asm volatile (ID" %[res], %[val1], %[val2]" \
: [res]"=r" (X) \
: [val1]"r" (A), [val2]"r" (B) \
);\
(uint32_t)X; \
})
#define DSP1(ID, A) \
({ \
uint32_t X; \
asm volatile (ID" %[res], %[val1]" \
: [res]"=r" (X) \
: [val1]"r" (A) \
); \
(uint32_t)X; \
})
/* General data processing instructions */
#define __rev16(A) DSP1("REV16", A)
/* SIMD instructions (single instruction multiple data) */
#define __sadd16(A, B) DSP2("SADD16", A, B)
#define __shadd16(A, B) DSP2("SHADD16", A, B)
#define __ssub16(A, B) DSP2("SSUB16", A, B)
#define __shsub16(A, B) DSP2("SHSUB16", A, B)
#define __uadd16(A, B) DSP2("UADD16", A, B)
#define __uhadd16(A, B) DSP2("UHADD16", A, B)
#define __usub16(A, B) DSP2("USUB16", A, B)
#define __uhsub16(A, B) DSP2("UHSUB16", A, B)
#define __sadd8(A, B) DSP2("SADD8", A, B)
#define __shadd8(A, B) DSP2("SHADD8", A, B)
#define __ssub8(A, B) DSP2("SSUB8", A, B)
#define __shsub8(A, B) DSP2("SHSUB8", A, B)
#define __uadd8(A, B) DSP2("UADD8", A, B)
#define __uhadd8(A, B) DSP2("UHADD8", A, B)
#define __usub8(A, B) DSP2("USUB8", A, B)
#define __uhsub8(A, B) DSP2("UHSUB8", A, B)
#define __sasx(A, B) DSP2("SASX", A, B)
#define __ssax(A, B) DSP2("SSAX", A, B)
#define __shasx(A, B) DSP2("SHASX", A, B)
#define __shsax(A, B) DSP2("SHSAX", A, B)
#define __uasx(A, B) DSP2("UASX", A, B)
#define __usax(A, B) DSP2("USAX", A, B)
#define __uhasx(A, B) DSP2("UHASX", A, B)
#define __uhsax(A, B) DSP2("UHSAX", A, B)
#define __usad8(A, B) DSP2("USAD8", A, B)
#define __usada8(A, B, C) DSP3("USADA8", A, B, C)
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,178 @@
/******************************************************************************
* The MIT License
*
* Copyright (c) 2011, 2012 LeafLabs, LLC.
* Copyright (c) 2010 Perry Hung.
* Copyright (c) 2013 OpenMusicKontrollers.
*
* 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/stm32f3/include/series/spi.h
* @author Marti Bolivar <mbolivar@leaflabs.com>,
* F3-port by Hanspeter Portner <dev@open-music-kontrollers.ch>
* @brief STM32F3 SPI/I2S series header.
*/
#ifndef _LIBMAPLE_STM32F3_SPI_H_
#define _LIBMAPLE_STM32F3_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)
/*
* F3 additional registry items
*/
/* Control register 1 */
/* CRC length bitfield in F3 overwrites the data length field in F1/F2 */
#define SPI_CR1_CRCL_BIT 11
#define SPI_CR1_CRCL (1U << SPI_CR1_CRCL_BIT)
/* Control register 2 */
#define SPI_CR2_LDMA_TX_BIT 14
#define SPI_CR2_LDMA_RX_BIT 13
#define SPI_CR2_FRXTH_BIT 12
#define SPI_CR2_DS_SHIFT 8
#define SPI_CR2_FRF_BIT 4
#define SPI_CR2_NSSP_BIT 3
#define SPI_CR2_LDMA_TX (1U << SPI_CR2_LDMA_TX_BIT)
#define SPI_CR2_LDMA_RX (1U << SPI_CR2_LDMA_RX_BIT)
#define SPI_CR2_FRXTH (1U << SPI_CR2_FRXTH_BIT)
#define SPI_CR2_DS (0x7 << SPI_CR2_DS_SHIFT)
#define SPI_CR2_FRF (1U << SPI_CR2_FRF_BIT)
#define SPI_CR2_NSSP (1U << SPI_CR2_NSSP_BIT)
/* Status register */
#define SPI_SR_FTLVL_SHIFT 11
#define SPI_SR_FRLVL_SHIFT 9
#define SPI_SR_FRE_BIT 8
#define SPI_SR_FTLVL (0x3 << SPI_SR_FTLVL_SHIFT)
#define SPI_SR_FRLVL (0x3 << SPI_SR_FRLVL_SHIFT)
#define SPI_SR_FRE (1U << SPI_SR_FRE_SHIFT)
/**
* @brief TODO document me
*/
typedef enum spi_crc_size {
SPI_CRC_SIZE_8_BIT = (0x0 << SPI_CR1_CRCL_BIT),
SPI_CRC_SIZE_16_BIT = (0x1 << SPI_CR1_CRCL_BIT),
} spi_crc_size;
/**
* @brief TODO document me
*/
typedef enum spi_frame_format {
SPI_FRAME_FORMAT_MOTOROLA = (0x0 << SPI_CR2_FRF_BIT),
SPI_FRAME_FORMAT_TI = (0x1 << SPI_CR2_FRF_BIT),
} spi_frame_format;
/**
* @brief TODO document me
*/
typedef enum spi_ds {
SPI_DATA_SIZE_DEFAULT = (0x0 << SPI_CR2_DS_SHIFT),
SPI_DATA_SIZE_4_BIT = (0x3 << SPI_CR2_DS_SHIFT),
SPI_DATA_SIZE_5_BIT = (0x4 << SPI_CR2_DS_SHIFT),
SPI_DATA_SIZE_6_BIT = (0x5 << SPI_CR2_DS_SHIFT),
SPI_DATA_SIZE_7_BIT = (0x6 << SPI_CR2_DS_SHIFT),
SPI_DATA_SIZE_8_BIT = (0x7 << SPI_CR2_DS_SHIFT),
SPI_DATA_SIZE_9_BIT = (0x8 << SPI_CR2_DS_SHIFT),
SPI_DATA_SIZE_10_BIT = (0x9 << SPI_CR2_DS_SHIFT),
SPI_DATA_SIZE_11_BIT = (0xA << SPI_CR2_DS_SHIFT),
SPI_DATA_SIZE_12_BIT = (0xB << SPI_CR2_DS_SHIFT),
SPI_DATA_SIZE_13_BIT = (0xC << SPI_CR2_DS_SHIFT),
SPI_DATA_SIZE_14_BIT = (0xD << SPI_CR2_DS_SHIFT),
SPI_DATA_SIZE_15_BIT = (0xE << SPI_CR2_DS_SHIFT),
SPI_DATA_SIZE_16_BIT = (0xF << SPI_CR2_DS_SHIFT),
} spi_ds;
/**
* @brief TODO document me
*/
typedef enum spi_fifo_transmission_level {
SPI_FIFO_TRANSMISSION_LEVEL_EMPTY = (0x0 << SPI_SR_FTLVL_SHIFT),
SPI_FIFO_TRANSMISSION_LEVEL_QUARTER = (0x1 << SPI_SR_FTLVL_SHIFT),
SPI_FIFO_TRANSMISSION_LEVEL_HALF = (0x2 << SPI_SR_FTLVL_SHIFT),
SPI_FIFO_TRANSMISSION_LEVEL_FULL = (0x3 << SPI_SR_FTLVL_SHIFT),
} spi_fifo_transmission_level;
/**
* @brief TODO document me
*/
typedef enum spi_fifo_reception_level {
SPI_FIFO_RECEPTION_LEVEL_EMPTY = (0x0 << SPI_SR_FRLVL_SHIFT),
SPI_FIFO_RECEPTION_LEVEL_QUARTER = (0x1 << SPI_SR_FRLVL_SHIFT),
SPI_FIFO_RECEPTION_LEVEL_HALF = (0x2 << SPI_SR_FRLVL_SHIFT),
SPI_FIFO_RECEPTION_LEVEL_FULL = (0x3 << SPI_SR_FRLVL_SHIFT),
} spi_fifo_reception_level;
/*
* Device pointers
*/
struct spi_dev;
extern struct spi_dev *SPI1;
extern struct spi_dev *SPI2;
extern struct spi_dev *SPI3;
/*
* Routines
*/
struct gpio_dev;
extern void spi_config_gpios(struct spi_dev*, uint8,
struct gpio_dev*, uint8,
struct gpio_dev*, uint8, uint8, uint8);
/**
* @brief Set the data size of the given SPI device.
*
* @param dev SPI device
* @param ds SPI data size
* @see spi_ds
* @see spi_reconfigure()
*/
extern void spi_data_size(struct spi_dev *, spi_ds);
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,238 @@
/******************************************************************************
* The MIT License
*
* Copyright (c) 2010, 2011 LeafLabs, LLC.
* Copyright (c) 2013 OpenMusicKontrollers.
*
* 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
* @author F3-port by Hanspeter Portner <dev@open-music-kontrollers.ch>
* @brief STM32F3 chip- and series-specific definitions.
*/
#ifndef _LIBMAPLE_STM32F3_H_
#define _LIBMAPLE_STM32F3_H_
#ifdef __cplusplus
extern "C" {
#endif
#define __CCM__ __attribute__((section(".CCM")))
#define STM32_MCU_SERIES STM32_SERIES_F3
/* The STM32F3 series is subdivided into "lines". libmaple currently
* officially supports STM32F303 performance line MCUs (see the
* MCU-specific value section below).
*
* You can use these F3 line defines if porting libmaple to support
* MCUs on other lines. */
/** STM32F3 302 line (STM32F302 MCUs). */
#define STM32_F3_LINE_302 0
/** STM32F3 303 line (STM32F303 MCUs). */
#define STM32_F3_LINE_303 1
/*
* 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
* STM32F303 microcontrollers set below won't take effect.
*/
#if defined(MCU_STM32F302CB)
# define STM32_F3_LINE STM32_F3_LINE_302
# define STM32_NR_GPIO_PORTS 20
# define STM32_SRAM_END ((void*)0x20008000)
# define STM32_MEDIUM_DENSITY // 48pin package
#elif defined(MCU_STM32F302RB)
# define STM32_F3_LINE STM32_F3_LINE_302
# define STM32_NR_GPIO_PORTS 27
# define STM32_SRAM_END ((void*)0x20008000)
# define STM32_HIGH_DENSITY // 64pin package
#elif defined(MCU_STM32F302VB)
# define STM32_F3_LINE STM32_F3_LINE_302
# define STM32_NR_GPIO_PORTS 45
# define STM32_SRAM_END ((void*)0x20008000)
# define STM32_XL_DENSITY // 100pin package
#elif defined(MCU_STM32F302CC)
# define STM32_F3_LINE STM32_F3_LINE_302
# define STM32_NR_GPIO_PORTS 20
# define STM32_SRAM_END ((void*)0x2000A000)
# define STM32_MEDIUM_DENSITY // 48pin package
#elif defined(MCU_STM32F302RC)
# define STM32_F3_LINE STM32_F3_LINE_302
# define STM32_NR_GPIO_PORTS 27
# define STM32_SRAM_END ((void*)0x2000A000)
# define STM32_HIGH_DENSITY // 64pin package
#elif defined(MCU_STM32F302VC)
# define STM32_F3_LINE STM32_F3_LINE_302
# define STM32_NR_GPIO_PORTS 45
# define STM32_SRAM_END ((void*)0x2000A000)
# define STM32_XL_DENSITY // 100pin package
#elif defined(MCU_STM32F303CB)
# define STM32_F3_LINE STM32_F3_LINE_303
# define STM32_NR_GPIO_PORTS 20
# define STM32_SRAM_END ((void*)0x2000A000)
# define STM32_MEDIUM_DENSITY // 48pin package
#elif defined(MCU_STM32F303RB)
# define STM32_F3_LINE STM32_F3_LINE_303
# define STM32_NR_GPIO_PORTS 27
# define STM32_SRAM_END ((void*)0x2000A000)
# define STM32_HIGH_DENSITY // 64pin package
#elif defined(MCU_STM32F303VB)
# define STM32_F3_LINE STM32_F3_LINE_303
# define STM32_NR_GPIO_PORTS 45
# define STM32_SRAM_END ((void*)0x2000A000)
# define STM32_XL_DENSITY // 100pin package
#elif defined(MCU_STM32F303CC)
# define STM32_F3_LINE STM32_F3_LINE_303
# define STM32_NR_GPIO_PORTS 20
# define STM32_SRAM_END ((void*)0x2000C000)
# define STM32_MEDIUM_DENSITY // 48pin package
#elif defined(MCU_STM32F303RC)
# define STM32_F3_LINE STM32_F3_LINE_303
# define STM32_NR_GPIO_PORTS 27
# define STM32_SRAM_END ((void*)0x2000C000)
# define STM32_HIGH_DENSITY // 64pin package
#elif defined(MCU_STM32F303VC)
# define STM32_F3_LINE STM32_F3_LINE_303
# define STM32_NR_GPIO_PORTS 45
# define STM32_SRAM_END ((void*)0x2000C000)
// # define STM32_XL_DENSITY // 100pin package
#else
#warning "Unsupported or unspecified STM32F3 MCU."
#endif
/*
* Derived values.
*/
#if STM32_F3_LINE == STM32_F3_LINE_302
# define STM32_HAVE_USB 1
# ifdef STM32_MEDIUM_DENSITY
# define STM32_NR_INTERRUPTS 82
# define STM32_TIMER_MASK 0b111000000001011110
# define STM32_HAVE_FSMC 0
# define STM32_HAVE_DAC 1
# elif defined(STM32_HIGH_DENSITY)
# define STM32_NR_INTERRUPTS 82
# define STM32_TIMER_MASK 0b111000000001011110
# define STM32_HAVE_FSMC 0
# define STM32_HAVE_DAC 1
# elif defined(STM32_XL_DENSITY)
# define STM32_NR_INTERRUPTS 82
# define STM32_TIMER_MASK 0b111000000001011110
# define STM32_HAVE_FSMC 0
# define STM32_HAVE_DAC 1
# endif
#elif STM32_F3_LINE == STM32_F3_LINE_303
# define STM32_HAVE_USB 1
# ifdef STM32_MEDIUM_DENSITY
# define STM32_NR_INTERRUPTS 82
# define STM32_TIMER_MASK 0b111000000111011110
# define STM32_HAVE_FSMC 0
# define STM32_HAVE_DAC 1
# elif defined(STM32_HIGH_DENSITY)
# define STM32_NR_INTERRUPTS 82
# define STM32_TIMER_MASK 0b111000000111011110
# define STM32_HAVE_FSMC 0
# define STM32_HAVE_DAC 1
# elif defined(STM32_XL_DENSITY)
# define STM32_NR_INTERRUPTS 82
# define STM32_TIMER_MASK 0b111000000111011110
# define STM32_HAVE_FSMC 0
# 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.
*/
#ifndef STM32_PCLK1
#define STM32_PCLK1 36000000U
#endif
#ifndef STM32_PCLK2
#define STM32_PCLK2 72000000U
#endif
#ifndef STM32_DELAY_US_MULT
#define STM32_DELAY_US_MULT 12 /* FIXME: value is incorrect. */
#endif
/*
* Sanity checks.
*
* Make sure we have the F3-specific defines we need.
* <libmaple/stm32.h> will check that we've defined everything it needs.
*/
#if !defined(STM32_F3_LINE)
#error "Bad STM32F3 configuration. Check STM32F3 <series/stm32.h> header."
#endif
/*
* Doxygen
*/
#ifdef __DOXYGEN__
/**
* @brief STM32 line value for the STM32F3 MCU being targeted.
*
* At time of writing, allowed values are: STM32_F3_LINE_303,
* STM32_F3_LINE_302. This set of values may expand as libmaple adds
* support for more STM32F3 lines.
*/
#define STM32_F3_LINE
#endif /* __DOXYGEN__ */
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,138 @@
/******************************************************************************
* The MIT License
*
* Copyright (c) 2013 OpenMusicKontrollers.
*
* 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/stm32f3/include/series/syscfg.h
* @author F3-port by Hanspeter Portner <dev@open-music-kontrollers.ch>
* @brief System configuration controller (SYSCFG)
*/
#ifndef _LIBMAPLE_STM32F3_SYSCFG_H_
#define _LIBMAPLE_STM32F3_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 CFGR1; /**< Configuration register 1*/
__io uint32 RCR; /**< CCM SRAM protection register */
__io uint32 EXTICR[4]; /**< External Interrupt configuration register */
__io uint32 CFGR2; /**< Configuration register 2 */
} syscfg_reg_map;
/** SYSCFG register map base pointer */
#define SYSCFG_BASE ((struct syscfg_reg_map*)0x40010000)
/*
* Register bit definitions
*/
/* Configuration register 1 */
#define SYSCFG_CFGR1_FPU_IE_SHIFT 26
#define SYSCFG_CFGR1_ENCODE_MODE_SHIFT 22
#define SYSCFG_CFGR1_I2C2_FM_PLUS_BIT 21
#define SYSCFG_CFGR1_I2C1_FM_PLUS_BIT 20
#define SYSCFG_CFGR1_I2C_PB9_FM_PLUS_BIT 19
#define SYSCFG_CFGR1_I2C_PB8_FM_PLUS_BIT 18
#define SYSCFG_CFGR1_I2C_PB7_FM_PLUS_BIT 17
#define SYSCFG_CFGR1_I2C_PB6_FM_PLUS_BIT 16
#define SYSCFG_CFGR1_TIM7_DAC2_DMA_RMP_BIT 14
#define SYSCFG_CFGR1_TIM6_DAC1_DMA_RMP_BIT 13
#define SYSCFG_CFGR1_TIM17_DMA_RMP_BIT 12
#define SYSCFG_CFGR1_TIM16_DMA_RMP_BIT 11
#define SYSCFG_CFGR1_ADC24_DMA_RMP_BIT 8
#define SYSCFG_CFGR1_DAC_TRIG_RMP_BIT 7
#define SYSCFG_CFGR1_TIM1_ITR3_RMP_BIT 6
#define SYSCFG_CFGR1_USB_IT_RMP_BIT 5
//FIXME FPU_IE
//FIXME ENCODE_MODE
#define SYSCFG_CFGR1_I2C2_FM_PLUS (1U << SYSCFG_CFGR1_I2C2_FM_PLUS_BIT)
#define SYSCFG_CFGR1_I2C1_FM_PLUS (1U << SYSCFG_CFGR1_I2C1_FM_PLUS_BIT)
#define SYSCFG_CFGR1_I2C1_PB9_FM_PLUS (1U << SYSCFG_CFGR1_I2C1_PB9_FM_PLUS_BIT)
#define SYSCFG_CFGR1_I2C1_PB8_FM_PLUS (1U << SYSCFG_CFGR1_I2C1_PB8_FM_PLUS_BIT)
#define SYSCFG_CFGR1_I2C1_PB7_FM_PLUS (1U << SYSCFG_CFGR1_I2C1_PB7_FM_PLUS_BIT)
#define SYSCFG_CFGR1_I2C1_PB6_FM_PLUS (1U << SYSCFG_CFGR1_I2C1_PB6_FM_PLUS_BIT)
#define SYSCFG_CFGR1_TIM7_DAC2_DMA_RMP (1U << SYSCFG_CFGR1_TIM7_DAC2_DMA_RMP_BIT)
#define SYSCFG_CFGR1_TIM6_DAC1_DMA_RMP (1U << SYSCFG_CFGR1_TIM6_DAC1_DMA_RMP_BIT)
#define SYSCFG_CFGR1_TIM17_DMA_RMP (1U << SYSCFG_CFGR1_TIM17_DMA_RMP_BIT)
#define SYSCFG_CFGR1_TIM16_DMA_RMP (1U << SYSCFG_CFGR1_TIM16_DMA_RMP_BIT)
#define SYSCFG_CFGR1_ADC23_DMA_RMP (1U << SYSCFG_CFGR1_ADC23_DMA_RMP_BIT)
#define SYSCFG_CFGR1_DAC_TRIG_RMP (1U << SYSCFG_CFGR1_DAC_TRIG_RMP_BIT)
#define SYSCFG_CFGR1_TIM1_ITR3_RMP (1U << SYSCFG_CFGR1_TIM1_ITR3_RMP_BIT)
#define SYSCFG_CFGR1_USB_IT_RMP (1U << SYSCFG_CFGR1_USB_IT_RMP_BIT)
#define SYSCFG_CFGR1_MEM_MODE 0X3
/* CCM SRAM protection register */
#define SYSCFG_RCR_PAGE7_WP_BIT 7
#define SYSCFG_RCR_PAGE6_WP_BIT 6
#define SYSCFG_RCR_PAGE5_WP_BIT 5
#define SYSCFG_RCR_PAGE4_WP_BIT 4
#define SYSCFG_RCR_PAGE3_WP_BIT 3
#define SYSCFG_RCR_PAGE2_WP_BIT 2
#define SYSCFG_RCR_PAGE1_WP_BIT 1
#define SYSCFG_RCR_PAGE0_WP_BIT 0
#define SYSCFG_RCR_PAGE_7 (1U << SYSCFG_RCR_PAGE7_WP_BIT)
#define SYSCFG_RCR_PAGE_6 (1U << SYSCFG_RCR_PAGE6_WP_BIT)
#define SYSCFG_RCR_PAGE_5 (1U << SYSCFG_RCR_PAGE5_WP_BIT)
#define SYSCFG_RCR_PAGE_4 (1U << SYSCFG_RCR_PAGE4_WP_BIT)
#define SYSCFG_RCR_PAGE_3 (1U << SYSCFG_RCR_PAGE3_WP_BIT)
#define SYSCFG_RCR_PAGE_2 (1U << SYSCFG_RCR_PAGE2_WP_BIT)
#define SYSCFG_RCR_PAGE_1 (1U << SYSCFG_RCR_PAGE1_WP_BIT)
#define SYSCFG_RCR_PAGE_0 (1U << SYSCFG_RCR_PAGE0_WP_BIT)
/* Configuration register 2 */
#define SYSCFG_CFGR2_SRAM_PEF_BIT 8
#define SYSCFG_CFGR2_BYP_ADDR_PAR_BIT 4
#define SYSCFG_CFGR2_PVD_LOCK_BIT 2
#define SYSCFG_CFGR2_SRAM_PARITY_LOCK_BIT 1
#define SYSCFG_CFGR2_LOCKUP_LOCK_BIT 0
#define SYSCFG_CFGR2_SRAM_PEF (1U << SYSCFG_CFGR2_SRAM_PEF_BIT)
#define SYSCFG_CFGR2_BYP_ADDR_PAR (1U << SYSCFG_CFGR2_BYP_ADDR_PAR_BIT)
#define SYSCFG_CFGR2_PVD_LOCK (1U << SYSCFG_CFGR2_PVD_LOCK_BIT)
#define SYSCFG_CFGR2_SRAM_PARITY_LOCK (1U << SYSCFG_CFGR2_SRAM_PARITY_LOCK_BIT)
#define SYSCFG_CFGR2_LOCKUP_LOCK (1U << SYSCFG_CFGR2_LOCKUP_LOCK_BIT)
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,123 @@
/******************************************************************************
* The MIT License
*
* Copyright (c) 2012 LeafLabs, LLC.
* Copyright (c) 2013 OpenMusicKontrollers.
*
* 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/stm32f3/include/series/timer.h
* @author Marti Bolivar <mbolivar@leaflabs.com>,
* F3-port by Hanspeter Portner <dev@open-music-kontrollers.ch>
* @brief STM32F3 timer support.
*/
#ifndef _LIBMAPLE_STM32F3_TIMER_H_
#define _LIBMAPLE_STM32F3_TIMER_H_
#include <libmaple/libmaple_types.h>
#include <libmaple/gpio.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 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 15 register map base pointer */
#define TIMER15_BASE ((struct timer_gen_reg_map*)0x40014000)
/** Timer 16 register map base pointer */
#define TIMER16_BASE ((struct timer_gen_reg_map*)0x40014400)
/** Timer 17 register map base pointer */
#define TIMER17_BASE ((struct timer_gen_reg_map*)0x40014800)
/*
* Device pointers
*
* We only declare device pointers to timers which actually exist on
* the target MCU.
*/
struct timer_dev;
extern struct timer_dev *TIMER1;
extern struct timer_dev *TIMER2; /* FIXME 32bit-capable counter */
extern struct timer_dev *TIMER3;
extern struct timer_dev *TIMER4;
extern struct timer_dev *TIMER6;
#if STM32_F3_LINE == STM32_F3_LINE_303
extern struct timer_dev *TIMER7;
extern struct timer_dev *TIMER8;
#endif
extern struct timer_dev *TIMER15;
extern struct timer_dev *TIMER16;
extern struct timer_dev *TIMER17;
/*
* Routines
*/
gpio_af timer_get_af(struct timer_dev *dev);
#endif

View File

@ -0,0 +1,277 @@
/******************************************************************************
* The MIT License
*
* Copyright (c) 2013 OpenMusicKontrollers.
*
* 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/stm32f3/include/series/usart.h
* @author F3-port by Hanspeter Portner <dev@open-music-kontrollers.ch>
* @brief STM32F3 USART support.
*/
#ifndef _LIBMAPLE_STM32F3_USART_H_
#define _LIBMAPLE_STM32F3_USART_H_
#ifdef __cplusplus
extern "C"{
#endif
#include <libmaple/gpio.h> /* for gpio_af */
/*
* Register maps
*/
/** USART register map type */
typedef struct usart_reg_map {
__io uint32 CR1; /**< Control register 1 */
__io uint32 CR2; /**< Control register 2 */
__io uint32 CR3; /**< Control register 3 */
__io uint32 BRR; /**< Baud rate register */
__io uint32 GTPR; /**< Guard time and prescaler register */
__io uint32 RTOR; /**< Receiver timeout register */
__io uint32 RQR; /**< Request register */
__io uint32 SR; /**< ISR Interrupt and status register */
__io uint32 ICR; /**< Interrupt clear register */
__io uint16 RDR; /**< Receive data register */
uint16 RESERVED1;
__io uint16 TDR; /**< Transmit data register */
uint16 RESERVED2;
} usart_reg_map;
/*
* Register map base pointers
*/
/** 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)
#if defined(STM32_HIGH_DENSITY) || defined(STM32_XL_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
/*
* F3-only register bit definitions.
*/
/* Control register 1 */
#define USART_CR1_EOBIE_BIT 27
#define USART_CR1_RTOIE_BIT 26
#define USART_CR1_DEAT4_BIT 25
#define USART_CR1_DEAT3_BIT 24
#define USART_CR1_DEAT2_BIT 23
#define USART_CR1_DEAT1_BIT 22
#define USART_CR1_DEAT0_BIT 21
#define USART_CR1_DEDT4_BIT 20
#define USART_CR1_DEDT3_BIT 19
#define USART_CR1_DEDT2_BIT 18
#define USART_CR1_DEDT1_BIT 17
#define USART_CR1_DEDT0_BIT 16
#define USART_CR1_OVER8_BIT 15
#define USART_CR1_CMIE_BIT 14
#define USART_CR1_MME_BIT 13
#define USART_CR1_UESM_BIT 1
#define USART_CR1_UE_BIT 0
#define USART_CR1_EOBIE (1UL << USART_CR1_EOBIE_BIT)
#define USART_CR1_RTOIE (1UL << USART_CR1_RTOIE_BIT)
#define USART_CR1_DEAT4 (1UL << USART_CR1_DEAT4_BIT)
#define USART_CR1_DEAT3 (1UL << USART_CR1_DEAT3_BIT)
#define USART_CR1_DEAT2 (1UL << USART_CR1_DEAT2_BIT)
#define USART_CR1_DEAT1 (1UL << USART_CR1_DEAT1_BIT)
#define USART_CR1_DEAT0 (1UL << USART_CR1_DEAT0_BIT)
#define USART_CR1_DEDT4 (1UL << USART_CR1_DEDT4_BIT)
#define USART_CR1_DEDT3 (1UL << USART_CR1_DEDT3_BIT)
#define USART_CR1_DEDT2 (1UL << USART_CR1_DEDT2_BIT)
#define USART_CR1_DEDT1 (1UL << USART_CR1_DEDT1_BIT)
#define USART_CR1_DEDT0 (1UL << USART_CR1_DEDT0_BIT)
#define USART_CR1_OVER8 (1UL << USART_CR1_OVER8_BIT)
#define USART_CR1_CMIE (1UL << USART_CR1_CMIE_BIT)
#define USART_CR1_MME (1UL << USART_CR1_MME_BIT)
#define USART_CR1_UESM (1UL << USART_CR1_UESM_BIT)
#define USART_CR1_UE (1UL << USART_CR1_UE_BIT)
/* Control register 2 */
#define USART_CR2_ADD_SHIFT 24
#define USART_CR2_RTOEN_BIT 23
#define USART_CR2_ABRMOD1_BIT 22
#define USART_CR2_ABRMOD0_BIT 21
#define USART_CR2_ABREN_BIT 20
#define USART_CR2_MSBFIRST_BIT 19
#define USART_CR2_DATAINV_BIT 18
#define USART_CR2_TXINV_BIT 17
#define USART_CR2_RXINV_BIT 16
#define USART_CR2_SWAP_BIT 15
#define USART_CR2_ADDM7_BIT 4
#define USART_CR2_ADD (0xFF << USART_CR2_ADD_SHIFT)
#define USART_CR2_RTOEN (1UL << USART_CR2_RTOEN_BIT)
#define USART_CR2_ABRMOD1 (1UL << USART_CR2_ABRMOD1_BIT)
#define USART_CR2_ABRMOD0 (1UL << USART_CR2_ABRMOD0_BIT)
#define USART_CR2_ABREN (1UL << USART_CR2_ABREN_BIT)
#define USART_CR2_MSBFIRST (1UL << USART_CR2_MSBFIRST_BIT)
#define USART_CR2_DATAINV (1UL << USART_CR2_DATAINV_BIT)
#define USART_CR2_TXINV (1UL << USART_CR2_TXINV_BIT)
#define USART_CR2_RXINV (1UL << USART_CR2_RXINV_BIT)
#define USART_CR2_SWAP (1UL << USART_CR2_SWAP_BIT)
#define USART_CR2_ADDM7 (1UL << USART_CR2_ADDM7_BIT)
/* Control register 3 */
#define USART_CR3_WUFIE_BIT 22
#define USART_CR3_WUS_SHIFT 20
#define USART_CR3_SCAR_SHIFT 17
#define USART_CR3_DEP_BIT 15
#define USART_CR3_DEM_BIT 14
#define USART_CR3_DDRE_BIT 13
#define USART_CR3_OVRDIS_BIT 12
#define USART_CR3_ONEBIT_BIT 11
#define USART_CR3_WUFIE (1UL << USART_CR3_WUFIE_BIT)
#define USART_CR3_WUS (0x3 << USART_CR3_WUS_SHIFT)
#define USART_CR3_SCAR (0x7 << USART_CR3_SCAR_SHIFT)
#define USART_CR3_DEP (1UL << USART_CR3_DEP_BIT)
#define USART_CR3_DEM (1UL << USART_CR3_DEM_BIT)
#define USART_CR3_DDRE (1UL << USART_CR3_DDRE_BIT)
#define USART_CR3_OVRDIS (1UL << USART_CR3_OVRDIS_BIT)
#define USART_CR3_ONEBIT (1UL << USART_CR3_ONEBIT_BIT)
/* Receive timeout register */
#define USART_RTOR_BLEN_SHIFT 24
#define USART_RTOR_RTO_SHIFT 0
#define USART_RTOR_BLEN (0xF << USART_RTOR_BLEN_SHIFT)
#define USART_RTOR_RTO (0xFFF << USART_RTOR_RTO_SHIFT)
/* Request register */
#define USART_RQR_TXFRQ_BIT 4
#define USART_RQR_RXFRQ_BIT 3
#define USART_RQR_MMRQ_BIT 2
#define USART_RQR_SBKRQ_BIT 1
#define USART_RQR_ABRRQ_BIT 0
#define USART_RQR_TXFRQ (1UL << USART_RQR_TXFRQ_BIT)
#define USART_RQR_RXFRQ (1UL << USART_RQR_RXFRQ_BIT)
#define USART_RQR_MMRQ (1UL << USART_RQR_MMRQ_BIT)
#define USART_RQR_SBKRQ (1UL << USART_RQR_SBKRQ_BIT)
#define USART_RQR_ABRRQ (1UL << USART_RQR_ABRRQ_BIT)
/* Interrupt and status register */
// common register bits with other STM32 series are defined as USART_SR_* for compatibility
#define USART_SR_REACK_BIT 22
#define USART_SR_TEACK_BIT 21
#define USART_SR_WUF_BIT 20
#define USART_SR_RWU_BIT 19
#define USART_SR_SBKF_BIT 18
#define USART_SR_CMF_BIT 17
#define USART_SR_BUSY_BIT 16
#define USART_SR_ABRF_BIT 15
#define USART_SR_ABRE_BIT 14
#define USART_SR_EOBF_BIT 12
#define USART_SR_RTOF_BIT 11
#define USART_SR_CTS_BIT 10
#define USART_SR_CTSIF_BIT 9
#define USART_SR_REACK (1UL << USART_ISR_REACK_BIT)
#define USART_SR_TEACK (1UL << USART_ISR_TEACK_BIT)
#define USART_SR_WUF (1UL << USART_ISR_WUF_BIT)
#define USART_SR_RWU (1UL << USART_ISR_RWU_BIT)
#define USART_SR_SBKF (1UL << USART_ISR_SBKF_BIT)
#define USART_SR_CMF (1UL << USART_ISR_CMF_BIT)
#define USART_SR_BUSY (1UL << USART_ISR_BUSY_BIT)
#define USART_SR_ABRF (1UL << USART_ISR_ABRF_BIT)
#define USART_SR_ABRE (1UL << USART_ISR_ABRE_BIT)
#define USART_SR_EOBF (1UL << USART_ISR_EOBF_BIT)
#define USART_SR_RTOF (1UL << USART_ISR_RTOF_BIT)
#define USART_SR_CTS (1UL << USART_ISR_CTS_BIT)
#define USART_SR_CTSIF (1UL << USART_ISR_CTSIF_BIT)
/* Interrupt clear register */
#define USART_ICR_WUFCF_BIT 20
#define USART_ICR_CMCF_BIT 17
#define USART_ICR_EOBCF_BIT 12
#define USART_ICR_RTOCF_BIT 11
#define USART_ICR_CTSCF_BIT 9
#define USART_ICR_LBDCF_BIT 8
#define USART_ICR_TCCF_BIT 6
#define USART_ICR_IDLECF_BIT 4
#define USART_ICR_ORECF_BIT 3
#define USART_ICR_NCF_BIT 2
#define USART_ICR_FECF_BIT 1
#define USART_ICR_PECF_BIT 0
#define USART_ICR_WUFCF (1UL << USART_ICR_WUFCF_BIT)
#define USART_ICR_CMCF (1UL << USART_ICR_CMCF_BIT)
#define USART_ICR_EOBCF (1UL << USART_ICR_EOBCF_BIT)
#define USART_ICR_RTOCF (1UL << USART_ICR_RTOCF_BIT)
#define USART_ICR_CTSCF (1UL << USART_ICR_CTSCF_BIT)
#define USART_ICR_LBDCF (1UL << USART_ICR_LBDCF_BIT)
#define USART_ICR_TCCF (1UL << USART_ICR_TCCF_BIT)
#define USART_ICR_IDLECF (1UL << USART_ICR_IDLECF_BIT)
#define USART_ICR_ORECF (1UL << USART_ICR_ORECF_BIT)
#define USART_ICR_NCF (1UL << USART_ICR_NCF_BIT)
#define USART_ICR_FECF (1UL << USART_ICR_FECF_BIT)
#define USART_ICR_PECF (1UL << USART_ICR_PECF_BIT)
/* Receive data register */
#define USART_RDR_RDR_SHIFT 0
#define USART_RDR_RDR (0x1FF << USART_RDR_RDR_SHIFT)
/* Transmit data register */
#define USART_TDR_TDR_SHIFT 0
#define USART_TDR_TDR (0x1FF << USART_TDR_TDR_SHIFT)
/*
* Routines
*/
gpio_af usart_get_af(struct usart_dev *dev);
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,48 @@
# 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)/F30xxx
# Local rules and targets
sSRCS_$(d) := F30xxx/isrs.S
sSRCS_$(d) += F30xxx/vector_table.S
cSRCS_$(d) := adc.c
cSRCS_$(d) += dma.c
cSRCS_$(d) += exti.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
cSRCS_$(d) += syscfg.c
cSRCS_$(d) += fpu.c
cSRCS_$(d) += comp.c
cSRCS_$(d) += opamp.c
cSRCS_$(d) += bkp.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,41 @@
/******************************************************************************
* The MIT License
*
* Copyright (c) 2013 OpenMusicKontrollers.
*
* 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/syscfg.c
* @brief System configuration controller (SYSCFG)
* @author F3-port by Hanspeter Portner <dev@open-music-kontrollers.ch>
*
* Availability: STM32F2, STM32F3, STM32F4.
*/
#include <libmaple/syscfg.h>
#include <libmaple/rcc.h>
void syscfg_init(void) {
rcc_clk_enable(RCC_SYSCFG);
rcc_reset_dev(RCC_SYSCFG);
}

View File

@ -0,0 +1,88 @@
/******************************************************************************
* The MIT License
*
* Copyright (c) 2010 Perry Hung.
* 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/systick.c
* @brief System timer (SysTick).
*/
#include <libmaple/systick.h>
volatile uint32 systick_uptime_millis;
static void (*systick_user_callback)(void);
/**
* @brief Initialize and enable SysTick.
*
* Clocks the system timer with the core clock, turns it on, and
* enables interrupts.
*
* @param reload_val Appropriate reload counter to tick every 1 ms.
*/
void systick_init(uint32 reload_val) {
SYSTICK_BASE->RVR = reload_val;
systick_enable();
}
/**
* Clock the system timer with the core clock, but don't turn it
* on or enable interrupt.
*/
void systick_disable() {
SYSTICK_BASE->CSR = SYSTICK_CSR_CLKSOURCE_CORE;
}
/**
* Clock the system timer with the core clock and turn it on;
* interrupt every 1 ms, for systick_timer_millis.
*/
void systick_enable() {
/* re-enables init registers without changing reload val */
SYSTICK_BASE->CSR = (SYSTICK_CSR_CLKSOURCE_CORE |
SYSTICK_CSR_ENABLE |
SYSTICK_CSR_TICKINT_PEND);
}
/**
* @brief Attach a callback to be called from the SysTick exception handler.
*
* To detach a callback, call this function again with a null argument.
*/
void systick_attach_callback(void (*callback)(void)) {
systick_user_callback = callback;
}
/*
* SysTick ISR
*/
void __exc_systick(void) {
systick_uptime_millis++;
if (systick_user_callback) {
systick_user_callback();
}
}

View File

@ -0,0 +1,456 @@
/******************************************************************************
* 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/timer.c
* @author Marti Bolivar <mbolivar@leaflabs.com>
* @brief Portable timer routines.
*/
#include <libmaple/timer.h>
#include <libmaple/stm32.h>
#include "timer_private.h"
static void disable_channel(timer_dev *dev, uint8 channel);
static void pwm_mode(timer_dev *dev, uint8 channel);
static void output_compare_mode(timer_dev *dev, uint8 channel);
static inline void enable_irq(timer_dev *dev, uint8 interrupt);
/*
* Devices
*
* Defer to the timer_private API for declaring these.
*/
#if STM32_HAVE_TIMER(1)
static timer_dev timer1 = ADVANCED_TIMER(1);
/** Timer 1 device (advanced) */
timer_dev *TIMER1 = &timer1;
#endif
#if STM32_HAVE_TIMER(2)
static timer_dev timer2 = GENERAL_TIMER(2);
/** Timer 2 device (general-purpose) */
timer_dev *TIMER2 = &timer2;
#endif
#if STM32_HAVE_TIMER(3)
static timer_dev timer3 = GENERAL_TIMER(3);
/** Timer 3 device (general-purpose) */
timer_dev *TIMER3 = &timer3;
#endif
#if STM32_HAVE_TIMER(4)
static timer_dev timer4 = GENERAL_TIMER(4);
/** Timer 4 device (general-purpose) */
timer_dev *TIMER4 = &timer4;
#endif
#if STM32_HAVE_TIMER(5)
static timer_dev timer5 = GENERAL_TIMER(5);
/** Timer 5 device (general-purpose) */
timer_dev *TIMER5 = &timer5;
#endif
#if STM32_HAVE_TIMER(6)
static timer_dev timer6 = BASIC_TIMER(6);
/** Timer 6 device (basic) */
timer_dev *TIMER6 = &timer6;
#endif
#if STM32_HAVE_TIMER(7)
static timer_dev timer7 = BASIC_TIMER(7);
/** Timer 7 device (basic) */
timer_dev *TIMER7 = &timer7;
#endif
#if STM32_HAVE_TIMER(8)
static timer_dev timer8 = ADVANCED_TIMER(8);
/** Timer 8 device (advanced) */
timer_dev *TIMER8 = &timer8;
#endif
#if STM32_HAVE_TIMER(9)
static timer_dev timer9 = RESTRICTED_GENERAL_TIMER(9, TIMER_DIER_TIE_BIT);
/** Timer 9 device (general-purpose) */
timer_dev *TIMER9 = &timer9;
#endif
#if STM32_HAVE_TIMER(10)
static timer_dev timer10 = RESTRICTED_GENERAL_TIMER(10, TIMER_DIER_CC1IE_BIT);
/** Timer 10 device (general-purpose) */
timer_dev *TIMER10 = &timer10;
#endif
#if STM32_HAVE_TIMER(11)
static timer_dev timer11 = RESTRICTED_GENERAL_TIMER(11, TIMER_DIER_CC1IE_BIT);
/** Timer 11 device (general-purpose) */
timer_dev *TIMER11 = &timer11;
#endif
#if STM32_HAVE_TIMER(12)
static timer_dev timer12 = RESTRICTED_GENERAL_TIMER(12, TIMER_DIER_TIE_BIT);
/** Timer 12 device (general-purpose) */
timer_dev *TIMER12 = &timer12;
#endif
#if STM32_HAVE_TIMER(13)
static timer_dev timer13 = RESTRICTED_GENERAL_TIMER(13, TIMER_DIER_CC1IE_BIT);
/** Timer 13 device (general-purpose) */
timer_dev *TIMER13 = &timer13;
#endif
#if STM32_HAVE_TIMER(14)
static timer_dev timer14 = RESTRICTED_GENERAL_TIMER(14, TIMER_DIER_CC1IE_BIT);
/** Timer 14 device (general-purpose) */
timer_dev *TIMER14 = &timer14;
#endif
#if STM32_HAVE_TIMER(15)
static timer_dev timer15 = RESTRICTED_GENERAL_TIMER(15, TIMER_DIER_TIE_BIT); //XXX
/** Timer 15 device (general-purpose) */
timer_dev *TIMER15 = &timer15;
#endif
#if STM32_HAVE_TIMER(16)
static timer_dev timer16 = RESTRICTED_GENERAL_TIMER(16, TIMER_DIER_CC1IE_BIT); //XXX
/** Timer 16 device (general-purpose) */
timer_dev *TIMER16 = &timer16;
#endif
#if STM32_HAVE_TIMER(17)
static timer_dev timer17 = RESTRICTED_GENERAL_TIMER(17, TIMER_DIER_CC1IE_BIT); //XXX
/** Timer 17 device (general-purpose) */
timer_dev *TIMER17 = &timer17;
#endif
/*
* Routines
*/
/**
* @brief Call a function on timer devices.
* @param fn Function to call on each timer device.
*/
void timer_foreach(void (*fn)(timer_dev*)) {
#if STM32_HAVE_TIMER(1)
fn(TIMER1);
#endif
#if STM32_HAVE_TIMER(2)
fn(TIMER2);
#endif
#if STM32_HAVE_TIMER(3)
fn(TIMER3);
#endif
#if STM32_HAVE_TIMER(4)
fn(TIMER4);
#endif
#if STM32_HAVE_TIMER(5)
fn(TIMER5);
#endif
#if STM32_HAVE_TIMER(6)
fn(TIMER6);
#endif
#if STM32_HAVE_TIMER(7)
fn(TIMER7);
#endif
#if STM32_HAVE_TIMER(8)
fn(TIMER8);
#endif
#if STM32_HAVE_TIMER(9)
fn(TIMER9);
#endif
#if STM32_HAVE_TIMER(10)
fn(TIMER10);
#endif
#if STM32_HAVE_TIMER(11)
fn(TIMER11);
#endif
#if STM32_HAVE_TIMER(12)
fn(TIMER12);
#endif
#if STM32_HAVE_TIMER(13)
fn(TIMER13);
#endif
#if STM32_HAVE_TIMER(14)
fn(TIMER14);
#endif
#if STM32_HAVE_TIMER(15)
fn(TIMER15);
#endif
#if STM32_HAVE_TIMER(16)
fn(TIMER16);
#endif
#if STM32_HAVE_TIMER(17)
fn(TIMER17);
#endif
}
/**
* Initialize a timer, and reset its register map.
* @param dev Timer to initialize
*/
void timer_init(timer_dev *dev) {
rcc_clk_enable(dev->clk_id);
rcc_reset_dev(dev->clk_id);
}
/**
* @brief Disable a timer.
*
* The timer will stop counting, all DMA requests and interrupts will
* be disabled, and no state changes will be output.
*
* @param dev Timer to disable.
*/
void timer_disable(timer_dev *dev) {
(dev->regs).bas->CR1 = 0;
(dev->regs).bas->DIER = 0;
switch (dev->type) {
case TIMER_ADVANCED: /* fall-through */
case TIMER_GENERAL:
(dev->regs).gen->CCER = 0;
break;
case TIMER_BASIC:
break;
}
}
/**
* Sets the mode of an individual timer channel.
*
* Note that not all timers can be configured in every mode. For
* example, basic timers cannot be configured to output compare mode.
* Be sure to use a timer which is appropriate for the mode you want.
*
* @param dev Timer whose channel mode to set
* @param channel Relevant channel
* @param mode New timer mode for channel
*/
void timer_set_mode(timer_dev *dev, uint8 channel, timer_mode mode) {
ASSERT_FAULT(channel > 0 && channel <= 4);
/* TODO decide about the basic timers */
ASSERT(dev->type != TIMER_BASIC);
if (dev->type == TIMER_BASIC)
return;
switch (mode) {
case TIMER_DISABLED:
disable_channel(dev, channel);
break;
case TIMER_PWM:
pwm_mode(dev, channel);
break;
case TIMER_OUTPUT_COMPARE:
output_compare_mode(dev, channel);
break;
}
}
/**
* @brief Determine whether a timer has a particular capture/compare channel.
*
* Different timers have different numbers of capture/compare channels
* (and some have none at all). Use this function to test whether a
* given timer/channel combination will work.
*
* @param dev Timer device
* @param channel Capture/compare channel, from 1 to 4
* @return Nonzero if dev has channel, zero otherwise.
*/
int timer_has_cc_channel(timer_dev *dev, uint8 channel) {
/* On all currently supported series: advanced and "full-featured"
* general purpose timers have all four channels. Of the
* restricted general timers, timers 9, 12 and 15 have channels 1 and
* 2; the others have channel 1 only. Basic timers have none. */
rcc_clk_id id = dev->clk_id;
ASSERT((1 <= channel) && (channel <= 4));
if (id <= RCC_TIMER5 || id == RCC_TIMER8) {
return 1; /* 1 and 8 are advanced, 2-5 are "full" general */
} else if (id <= RCC_TIMER7) {
return 0; /* 6 and 7 are basic */
}
/* The rest are restricted general. */
return (((id == RCC_TIMER9 || id == RCC_TIMER12 || id == RCC_TIMER15) && channel <= 2) ||
channel == 1);
}
/**
* @brief Attach a timer interrupt.
* @param dev Timer device
* @param interrupt Interrupt number to attach to; this may be any
* timer_interrupt_id or timer_channel value appropriate
* for the timer.
* @param handler Handler to attach to the given interrupt.
* @see timer_interrupt_id
* @see timer_channel
*/
void timer_attach_interrupt(timer_dev *dev,
uint8 interrupt,
voidFuncPtr handler) {
dev->handlers[interrupt] = handler;
timer_enable_irq(dev, interrupt);
enable_irq(dev, interrupt);
}
/**
* @brief Detach a timer interrupt.
* @param dev Timer device
* @param interrupt Interrupt number to detach; this may be any
* timer_interrupt_id or timer_channel value appropriate
* for the timer.
* @see timer_interrupt_id
* @see timer_channel
*/
void timer_detach_interrupt(timer_dev *dev, uint8 interrupt) {
timer_disable_irq(dev, interrupt);
dev->handlers[interrupt] = NULL;
}
/*
* Utilities
*/
static void disable_channel(timer_dev *dev, uint8 channel) {
timer_detach_interrupt(dev, channel);
timer_cc_disable(dev, channel);
}
static void pwm_mode(timer_dev *dev, uint8 channel) {
timer_disable_irq(dev, channel);
timer_oc_set_mode(dev, channel, TIMER_OC_MODE_PWM_1, TIMER_OC_PE);
timer_cc_enable(dev, channel);
}
static void output_compare_mode(timer_dev *dev, uint8 channel) {
timer_oc_set_mode(dev, channel, TIMER_OC_MODE_ACTIVE_ON_MATCH, 0);
timer_cc_enable(dev, channel);
}
static void enable_adv_irq(timer_dev *dev, timer_interrupt_id id);
static void enable_bas_gen_irq(timer_dev *dev);
static inline void enable_irq(timer_dev *dev, timer_interrupt_id iid) {
if (dev->type == TIMER_ADVANCED) {
enable_adv_irq(dev, iid);
} else {
enable_bas_gen_irq(dev);
}
}
/* Advanced control timers have several IRQ lines corresponding to
* different timer interrupts.
*
* Note: This function assumes that the only advanced timers are TIM1
* and TIM8, and needs the obvious changes if that assumption is
* violated by a later STM32 series. */
static void enable_adv_irq(timer_dev *dev, timer_interrupt_id id) {
uint8 is_tim1 = dev->clk_id == RCC_TIMER1;
nvic_irq_num irq_num;
switch (id) {
case TIMER_UPDATE_INTERRUPT:
irq_num = (is_tim1 ?
NVIC_TIMER1_UP_TIMER10 :
NVIC_TIMER8_UP_TIMER13);
break;
case TIMER_CC1_INTERRUPT: /* Fall through */
case TIMER_CC2_INTERRUPT: /* ... */
case TIMER_CC3_INTERRUPT: /* ... */
case TIMER_CC4_INTERRUPT:
irq_num = is_tim1 ? NVIC_TIMER1_CC : NVIC_TIMER8_CC;
break;
case TIMER_COM_INTERRUPT: /* Fall through */
case TIMER_TRG_INTERRUPT:
irq_num = (is_tim1 ?
NVIC_TIMER1_TRG_COM_TIMER11 :
NVIC_TIMER8_TRG_COM_TIMER14);
break;
case TIMER_BREAK_INTERRUPT:
irq_num = (is_tim1 ?
NVIC_TIMER1_BRK_TIMER9 :
NVIC_TIMER8_BRK_TIMER12);
break;
default:
/* Can't happen, but placate the compiler */
ASSERT(0);
return;
}
nvic_irq_enable(irq_num);
}
/* Basic and general purpose timers have a single IRQ line, which is
* shared by all interrupts supported by a particular timer. */
static void enable_bas_gen_irq(timer_dev *dev) {
nvic_irq_num irq_num;
switch (dev->clk_id) {
case RCC_TIMER2:
irq_num = NVIC_TIMER2;
break;
case RCC_TIMER3:
irq_num = NVIC_TIMER3;
break;
case RCC_TIMER4:
irq_num = NVIC_TIMER4;
break;
#if STM32_HAVE_TIMER(5)
case RCC_TIMER5:
irq_num = NVIC_TIMER5;
break;
#endif
case RCC_TIMER6:
irq_num = NVIC_TIMER6;
break;
case RCC_TIMER7:
irq_num = NVIC_TIMER7;
break;
case RCC_TIMER9:
irq_num = NVIC_TIMER1_BRK_TIMER9;
break;
case RCC_TIMER10:
irq_num = NVIC_TIMER1_UP_TIMER10;
break;
case RCC_TIMER11:
irq_num = NVIC_TIMER1_TRG_COM_TIMER11;
break;
case RCC_TIMER12:
irq_num = NVIC_TIMER8_BRK_TIMER12;
break;
case RCC_TIMER13:
irq_num = NVIC_TIMER8_UP_TIMER13;
break;
case RCC_TIMER14:
irq_num = NVIC_TIMER8_TRG_COM_TIMER14;
break;
#if STM32_HAVE_TIMER(15)
case RCC_TIMER15:
//irq_num = NVIC_TIMER1_BRK_TIMER15;
irq_num = NVIC_TIMER1_BRK_TIMER9;
break;
#endif
#if STM32_HAVE_TIMER(16)
case RCC_TIMER16:
//irq_num = NVIC_TIMER1_UP_TIMER16;
irq_num = NVIC_TIMER1_UP_TIMER10;
break;
#endif
#if STM32_HAVE_TIMER(17)
case RCC_TIMER17:
//irq_num = NVIC_TIMER1_TRG_COM_TIMER17;
irq_num = NVIC_TIMER1_TRG_COM_TIMER11;
break;
#endif
default:
ASSERT_FAULT(0);
return;
}
nvic_irq_enable(irq_num);
}

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 __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 __always_inline void dispatch_adv_brk(timer_dev *dev) {
dispatch_single_irq(dev, TIMER_BREAK_INTERRUPT, TIMER_SR_BIF);
}
static __always_inline void dispatch_adv_up(timer_dev *dev) {
dispatch_single_irq(dev, TIMER_UPDATE_INTERRUPT, TIMER_SR_UIF);
}
static __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 __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 __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 __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 __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 __always_inline void dispatch_basic(timer_dev *dev) {
dispatch_single_irq(dev, TIMER_UPDATE_INTERRUPT, TIMER_SR_UIF);
}
#endif

View File

@ -0,0 +1,122 @@
/******************************************************************************
* 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/usart.c
* @author Marti Bolivar <mbolivar@leaflabs.com>,
* Perry Hung <perry@leaflabs.com>
* @brief Portable USART routines
*/
#include <libmaple/usart.h>
/**
* @brief Initialize a serial port.
* @param dev Serial port to be initialized
*/
void usart_init(usart_dev *dev) {
rb_init(dev->rb, USART_RX_BUF_SIZE, dev->rx_buf);
rcc_clk_enable(dev->clk_id);
nvic_irq_enable(dev->irq_num);
}
/**
* @brief Enable a serial port.
*
* USART is enabled in single buffer transmission mode, multibuffer
* receiver mode, 8n1.
*
* Serial port must have a baud rate configured to work properly.
*
* @param dev Serial port to enable.
* @see usart_set_baud_rate()
*/
void usart_enable(usart_dev *dev) {
usart_reg_map *regs = dev->regs;
regs->CR1 = (USART_CR1_TE | USART_CR1_RE | USART_CR1_RXNEIE |
USART_CR1_M_8N1);
regs->CR1 |= USART_CR1_UE;
}
/**
* @brief Turn off a serial port.
* @param dev Serial port to be disabled
*/
void usart_disable(usart_dev *dev) {
/* FIXME this misbehaves (on F1) if you try to use PWM on TX afterwards */
usart_reg_map *regs = dev->regs;
/* TC bit must be high before disabling the USART */
while((regs->CR1 & USART_CR1_UE) && !(regs->SR & USART_SR_TC))
;
/* Disable UE */
regs->CR1 &= ~USART_CR1_UE;
/* Clean up buffer */
usart_reset_rx(dev);
}
/**
* @brief Nonblocking USART receive.
* @param dev Serial port to receive bytes from
* @param buf Buffer to store received bytes into
* @param len Maximum number of bytes to store
* @return Number of bytes received
*/
uint32 usart_rx(usart_dev *dev, uint8 *buf, uint32 len) {
uint32 rxed = 0;
while (usart_data_available(dev) && rxed < len) {
*buf++ = usart_getc(dev);
rxed++;
}
return rxed;
}
/**
* @brief Transmit an unsigned integer to the specified serial port in
* decimal format.
*
* This function blocks until the integer's digits have been
* completely transmitted.
*
* @param dev Serial port to send on
* @param val Number to print
*/
void usart_putudec(usart_dev *dev, uint32 val) {
char digits[12];
int i = 0;
do {
digits[i++] = val % 10 + '0';
val /= 10;
} while (val > 0);
while (--i >= 0) {
usart_putc(dev, digits[i]);
}
}

Some files were not shown because too many files have changed in this diff Show More