renamed target from "black" to generic f407v + removed unused files

This commit is contained in:
stevstrong 2017-04-15 12:35:06 +02:00
parent 065f58684d
commit 5c9dc5ebfc
38 changed files with 165 additions and 5816 deletions

View File

@ -30,32 +30,32 @@ discovery_f407.build.error_led_pin=14
discovery_f407.build.board=STM32DiscoveryF407
##############################################################
black_f407vet6.name=STM32 Black F407VET6
generic_f407v.name=Generic STM32F407V series
black_f407vet6.upload.tool=stlink_upload
black_f407vet6.upload.protocol=stlink
generic_f407v.upload.tool=stlink_upload
generic_f407v.upload.protocol=stlink
black_f407vet6.upload.file_type=bin
black_f407vet6.upload.ram.maximum_size=65535
black_f407vet6.upload.flash.maximum_size=514288
black_f407vet6.upload.maximum_size=514288
generic_f407v.upload.file_type=bin
generic_f407v.upload.ram.maximum_size=131072
generic_f407v.upload.flash.maximum_size=514288
generic_f407v.upload.maximum_size=514288
#black_f407vet6.upload.usbID=0483:3748
#black_f407vet6.upload.altID=1
#black_f407vet6.upload.auto_reset=true
#generic_f407v.upload.usbID=0483:3748
#generic_f407v.upload.altID=1
#generic_f407v.upload.auto_reset=true
black_f407vet6.build.mcu=cortex-m4
black_f407vet6.build.f_cpu=168000000L
black_f407vet6.build.core=maple
black_f407vet6.build.extra_flags=-mthumb -DSTM32_HIGH_DENSITY -DSTM32F4 -DBOARD_black_f4
black_f407vet6.build.ldscript=ld/jtag.ld
black_f407vet6.build.variant=black_f407vet6
black_f407vet6.build.variant_system_lib=lib_f407.a
black_f407vet6.build.vect=VECT_TAB_BASE
black_f407vet6.build.density=STM32_HIGH_DENSITY
black_f407vet6.build.error_led_port=GPIOA
black_f407vet6.build.error_led_pin=7
black_f407vet6.build.board=STM32BlackF407VET6
generic_f407v.build.mcu=cortex-m4
generic_f407v.build.f_cpu=168000000L
generic_f407v.build.core=maple
generic_f407v.build.extra_flags=-mthumb -DSTM32_HIGH_DENSITY -DSTM32F4 -DBOARD_generic_f407v
generic_f407v.build.ldscript=ld/jtag.ld
generic_f407v.build.variant=generic_f407v
generic_f407v.build.variant_system_lib=lib_f407.a
generic_f407v.build.vect=VECT_TAB_BASE
generic_f407v.build.density=STM32_HIGH_DENSITY
generic_f407v.build.error_led_port=GPIOA
generic_f407v.build.error_led_pin=7
generic_f407v.build.board=STM32GenericF407VET6
##############################################################
stm32f4stamp.name=STM32F4Stamp F405

View File

@ -67,7 +67,7 @@ void init(void) {
setupADC();
setupTimers();
//setupUSB();
setupUSB();
}
/* You could farm this out to the files in boards/ if e.g. it takes

View File

@ -140,8 +140,8 @@ bool boardUsesPin(uint8 pin);
#include "aeroquad32mini.h"
#elif defined(BOARD_discovery_f4)
#include "discovery_f4.h"
#elif defined(BOARD_black_f4)
#include "black_f4.h"
#elif defined(BOARD_generic_f407v)
#include "generic_f407v.h"
#elif defined(BOARD_freeflight)
#include "freeflight.h"
#else

View File

@ -180,7 +180,7 @@ static inline void toggleLED() {
* accomplished portably over all LeafLabs boards by calling
* pinMode(BOARD_BUTTON_PIN, INPUT).
*
* @param button - one of available on-board buttons (up to 3 for black F4)
* @param button - one of available on-board buttons (up to 3 for generic F4)
*
* @see pinMode()
*/
@ -198,7 +198,7 @@ uint8 isButtonPressed(uint8_t button);
* button is pressed. If timeout_millis is left out (or 0), wait
* forever.
*
* @param button - one of available on-board buttons (up to 3 for black F4)
* @param button - one of available on-board buttons (up to 3 for generic F4)
*
* @return true, if the button was pressed; false, if the timeout was
* reached.

View File

@ -1,424 +0,0 @@
/******************************************************************************
* 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.
*****************************************************************************/
/**
* @author Marti Bolivar <mbolivar@leaflabs.com>
* @brief Wirish SPI implementation.
*/
#include "HardwareSPI.h"
#include "timer.h"
#include "util.h"
#include "rcc.h"
#include "wirish.h"
#include "boards.h"
struct spi_pins {
uint8 nss;
uint8 sck;
uint8 miso;
uint8 mosi;
};
static const spi_pins* dev_to_spi_pins(spi_dev *dev);
static void enable_device(spi_dev *dev,
bool as_master,
SPIFrequency frequency,
spi_cfg_flag endianness,
spi_mode mode);
static const spi_pins board_spi_pins[] __FLASH__ = {
{BOARD_SPI1_NSS_PIN,
BOARD_SPI1_SCK_PIN,
BOARD_SPI1_MISO_PIN,
BOARD_SPI1_MOSI_PIN},
#ifdef BOARD_SPI2_NSS_PIN
{BOARD_SPI2_NSS_PIN,
BOARD_SPI2_SCK_PIN,
BOARD_SPI2_MISO_PIN,
BOARD_SPI2_MOSI_PIN},
#endif
#ifdef STM32_HIGH_DENSITY
{BOARD_SPI3B_NSS_PIN,
BOARD_SPI3B_SCK_PIN,
BOARD_SPI3B_MISO_PIN,
BOARD_SPI3B_MOSI_PIN},
#endif
#ifdef STM32F4
{BOARD_SPI3B_NSS_PIN,
BOARD_SPI3B_SCK_PIN,
BOARD_SPI3B_MISO_PIN,
BOARD_SPI3B_MOSI_PIN},
#endif
};
/*
* Constructor
*/
HardwareSPI::HardwareSPI(uint32 spi_num) {
switch (spi_num) {
case 1:
this->spi_d = SPI1;
break;
case 2:
this->spi_d = SPI2;
break;
#ifdef STM32_HIGH_DENSITY
case 3:
this->spi_d = SPI3;
break;
#endif
#ifdef STM32F4
// case 4:
// this->spi_d = SPI4;
// break;
#endif
default:
ASSERT(0);
}
}
/*
* Set up/tear down
*/
void HardwareSPI::begin(SPIFrequency frequency, uint32 bitOrder, uint32 mode) {
if (mode >= 4) {
ASSERT(0);
return;
}
spi_cfg_flag end = bitOrder == MSBFIRST ? SPI_FRAME_MSB : SPI_FRAME_LSB;
spi_mode m = (spi_mode)mode;
enable_device(this->spi_d, true, frequency, end, m);
}
void HardwareSPI::begin(void) {
this->begin(SPI_1_125MHZ, MSBFIRST, 0);
}
void HardwareSPI::beginSlave(uint32 bitOrder, uint32 mode) {
if (mode >= 4) {
ASSERT(0);
return;
}
spi_cfg_flag end = bitOrder == MSBFIRST ? SPI_FRAME_MSB : SPI_FRAME_LSB;
spi_mode m = (spi_mode)mode;
enable_device(this->spi_d, false, (SPIFrequency)0, end, m);
}
void HardwareSPI::beginSlave(void) {
this->beginSlave(MSBFIRST, 0);
}
/*
void HardwareSPI::beginTransaction(uint8_t pin, SPISettings settings)
{
// this->begin(settings.clock, settings.bitOrder, settings.dataMode);
this->begin(SPI_1_125MHZ, settings.bitOrder, settings.dataMode);
}
*/
void HardwareSPI::end(void) {
if (!spi_is_enabled(this->spi_d)) {
return;
}
// Follows RM0008's sequence for disabling a SPI in master/slave
// full duplex mode.
while (spi_is_rx_nonempty(this->spi_d)) {
// FIXME [0.1.0] remove this once you have an interrupt based driver
volatile uint16 rx __attribute__((unused)) = spi_rx_reg(this->spi_d);
}
while (!spi_is_tx_empty(this->spi_d))
;
while (spi_is_busy(this->spi_d))
;
spi_peripheral_disable(this->spi_d);
}
/*
* I/O
*/
uint8 HardwareSPI::read(void) {
uint8 buf[1];
this->read(buf, 1);
return buf[0];
}
void HardwareSPI::read(uint8 *buf, uint32 len) {
uint32 rxed = 0;
while (rxed < len) {
while (!spi_is_rx_nonempty(this->spi_d))
;
buf[rxed++] = (uint8)spi_rx_reg(this->spi_d);
}
}
#if 0
void HardwareSPI::readMaster(uint8 *buf, uint32 len) {
uint32 rxed = 0;
while (rxed < len) {
spi_tx_reg(this->spi_d, 0xff);
while (!spi_is_rx_nonempty(this->spi_d))
;
buf[rxed++] = (uint8)spi_rx_reg(this->spi_d);
buf[rxed++] = this->spi_d->regs->DR;
}
}
#endif
void HardwareSPI::readMaster(uint8 *buf, uint32 len) {
spi_reg_map *r = this->spi_d->regs;
uint32 rxed = 0;
while (rxed < len) {
r->DR = 0xff;
while (!(r->SR & SPI_SR_RXNE))
;
buf[rxed++] = r->DR;
}
}
void HardwareSPI::waitReady() {
while (!spi_is_rx_nonempty(this->spi_d))
;
}
void HardwareSPI::write(uint8 byte) {
this->write(&byte, 1);
}
void HardwareSPI::write(const uint8 *data, uint32 length) {
uint32 txed = 0;
while (txed < length) {
txed += spi_tx(this->spi_d, data + txed, length - txed);
}
}
uint8 HardwareSPI::transfer(uint8 byte) {
this->write(byte);
return this->read();
}
/*
* Pin accessors
*/
uint8 HardwareSPI::misoPin(void) {
return dev_to_spi_pins(this->spi_d)->miso;
}
uint8 HardwareSPI::mosiPin(void) {
return dev_to_spi_pins(this->spi_d)->mosi;
}
uint8 HardwareSPI::sckPin(void) {
return dev_to_spi_pins(this->spi_d)->sck;
}
uint8 HardwareSPI::nssPin(void) {
return dev_to_spi_pins(this->spi_d)->nss;
}
/*
* Deprecated functions
*/
uint8 HardwareSPI::send(uint8 data) {
uint8 buf[] = {data};
return this->send(buf, 1);
}
#if 1
uint8 HardwareSPI::send(const uint8 *buf, uint32 len) {
uint32 txed = 0;
uint8 ret = 0;
while (txed < len) {
this->write(buf[txed++]);
ret = this->read();
}
return ret;
}
#else
// this does not work for an unknown reason
uint8 HardwareSPI::send(const uint8 *buf, uint32 len) {
volatile uint32 *dr = &(this->spi_d->regs->DR);
volatile uint32 *sr = &(this->spi_d->regs->SR);
uint32 txed = 0;
uint32 rx=0;
while (txed < len) {
//while (!(*sr & SPI_SR_TXE))
// ;
//*dr = buf[txed++];
this->write(buf[txed++]);
while (!(*sr & SPI_SR_RXNE))
;
rx = *dr;
//rx = this->read();
}
return rx;
}
#endif
uint8 HardwareSPI::recv(void) {
return this->read();
}
/*
* Auxiliary functions
*/
static void configure_gpios(spi_dev *dev, bool as_master);
static spi_baud_rate determine_baud_rate(spi_dev *dev, SPIFrequency freq);
static const spi_pins* dev_to_spi_pins(spi_dev *dev) {
switch (dev->clk_id) {
case RCC_SPI1: return board_spi_pins;
case RCC_SPI2: return board_spi_pins + 1;
#ifdef STM32_HIGH_DENSITY
case RCC_SPI3: return board_spi_pins + 2;
#endif
#ifdef STM32F4
case RCC_SPI4: return board_spi_pins + 3;
#endif
default: return NULL;
}
}
/* Enables the device in master or slave full duplex mode. If you
* change this code, you must ensure that appropriate changes are made
* to HardwareSPI::end(). */
static void enable_device(spi_dev *dev,
bool as_master,
SPIFrequency freq,
spi_cfg_flag endianness,
spi_mode mode) {
spi_baud_rate baud = determine_baud_rate(dev, freq);
uint32 cfg_flags = (endianness | SPI_DFF_8_BIT | SPI_SW_SLAVE |
(as_master ? SPI_SOFT_SS : 0));
spi_init(dev);
configure_gpios(dev, as_master);
if (as_master) {
spi_master_enable(dev, baud, mode, cfg_flags);
} else {
spi_slave_enable(dev, mode, cfg_flags);
}
}
static void disable_pwm(const stm32_pin_info *i) {
if (i->timer_device) {
timer_set_mode(i->timer_device, i->timer_channel, TIMER_DISABLED);
}
}
static void configure_gpios(spi_dev *dev, bool as_master) {
const spi_pins *pins = dev_to_spi_pins(dev);
if (!pins) {
return;
}
const stm32_pin_info *nssi = (pins->nss >= 0) ? &PIN_MAP[pins->nss] : NULL;
const stm32_pin_info *scki = &PIN_MAP[pins->sck];
const stm32_pin_info *misoi = &PIN_MAP[pins->miso];
const stm32_pin_info *mosii = &PIN_MAP[pins->mosi];
if(nssi) {
disable_pwm(nssi);
}
disable_pwm(scki);
disable_pwm(misoi);
disable_pwm(mosii);
#ifdef STM32F4
if(dev->clk_id <= RCC_SPI2) {
if(nssi) {
if(!as_master) {
gpio_set_af_mode(nssi->gpio_device, scki->gpio_bit, 5);
}
}
gpio_set_af_mode(scki->gpio_device, scki->gpio_bit, 5);
gpio_set_af_mode(misoi->gpio_device, misoi->gpio_bit, 5);
gpio_set_af_mode(mosii->gpio_device, mosii->gpio_bit, 5);
} else {
if(nssi) {
if(!as_master) {
gpio_set_af_mode(nssi->gpio_device, scki->gpio_bit, 6);
}
}
gpio_set_af_mode(scki->gpio_device, scki->gpio_bit, 6);
gpio_set_af_mode(misoi->gpio_device, misoi->gpio_bit, 6);
gpio_set_af_mode(mosii->gpio_device, mosii->gpio_bit, 6);
}
#endif
if(nssi) {
spi_config_gpios(dev, as_master, nssi->gpio_device, nssi->gpio_bit,
scki->gpio_device, scki->gpio_bit,
misoi->gpio_device, misoi->gpio_bit,
mosii->gpio_device, mosii->gpio_bit);
} else {
spi_config_gpios(dev, as_master, NULL, -1,
scki->gpio_device, scki->gpio_bit,
misoi->gpio_device, misoi->gpio_bit,
mosii->gpio_device, mosii->gpio_bit);
}
}
static const spi_baud_rate baud_rates[MAX_SPI_FREQS] __FLASH__ = {
SPI_BAUD_PCLK_DIV_2,
SPI_BAUD_PCLK_DIV_4,
SPI_BAUD_PCLK_DIV_8,
SPI_BAUD_PCLK_DIV_16,
SPI_BAUD_PCLK_DIV_32,
SPI_BAUD_PCLK_DIV_64,
SPI_BAUD_PCLK_DIV_128,
SPI_BAUD_PCLK_DIV_256,
};
/*
* Note: This assumes you're on a LeafLabs-style board
* (CYCLES_PER_MICROSECOND == 72, APB2 at 72MHz, APB1 at 36MHz).
*/
static spi_baud_rate determine_baud_rate(spi_dev *dev, SPIFrequency freq) {
if (rcc_dev_clk(dev->clk_id) == RCC_APB2 && freq == SPI_140_625KHZ) {
/* APB2 peripherals are too fast for 140.625 KHz */
ASSERT(0);
return (spi_baud_rate)~0;
}
return (rcc_dev_clk(dev->clk_id) == RCC_APB2 ?
baud_rates[freq + 1] :
baud_rates[freq]);
}

View File

@ -1,279 +0,0 @@
/******************************************************************************
* 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 HardwareSPI.h
* @brief High-level SPI interface
*
* This is a "bare essentials" polling driver for now.
*/
/* TODO [0.1.0] Remove deprecated methods. */
#include "libmaple_types.h"
#include "spi.h"
#include "boards.h"
#include "wirish.h"
#ifndef _HARDWARESPI_H_
#define _HARDWARESPI_H_
/**
* @brief Defines the possible SPI communication speeds.
*/
typedef enum SPIFrequency {
SPI_18MHZ = 0, /**< 18 MHz */
SPI_9MHZ = 1, /**< 9 MHz */
SPI_4_5MHZ = 2, /**< 4.5 MHz */
SPI_2_25MHZ = 3, /**< 2.25 MHz */
SPI_1_125MHZ = 4, /**< 1.125 MHz */
SPI_562_500KHZ = 5, /**< 562.500 KHz */
SPI_281_250KHZ = 6, /**< 281.250 KHz */
SPI_140_625KHZ = 7, /**< 140.625 KHz */
} SPIFrequency;
#define MAX_SPI_FREQS 8
#if CYCLES_PER_MICROSECOND != 72
/* TODO [0.2.0?] something smarter than this */
//#warning "Unexpected clock speed; SPI frequency calculation will be incorrect"
#endif
//#define BOARD_SPI_DEFAULT_SS PC13
#define BOARD_SPI_DEFAULT_SS PB0
#define SPI_MODE0 SPI_MODE_0
#define SPI_MODE1 SPI_MODE_1
#define SPI_MODE2 SPI_MODE_2
#define SPI_MODE3 SPI_MODE_3
/*
class SPISettings {
public:
SPISettings(uint32 clock, BitOrder bitOrder, uint8 dataMode) {
if (__builtin_constant_p(clock)) {
init_AlwaysInline(clock, bitOrder, dataMode);
} else {
init_MightInline(clock, bitOrder, dataMode);
}
}
SPISettings() { init_AlwaysInline(4000000, MSBFIRST, SPI_MODE0); }
private:
void init_MightInline(uint32 clock, BitOrder bitOrder, uint8 dataMode) {
init_AlwaysInline(clock, bitOrder, dataMode);
}
void init_AlwaysInline(uint32 clock, BitOrder bitOrder, uint8 dataMode) __attribute__((__always_inline__)) {
this->clock = clock;
this->bitOrder = bitOrder;
this->dataMode = dataMode;
}
uint32 clock;
BitOrder bitOrder;
uint8 dataMode;
friend class HardwareSPI;
};
*/
/**
* @brief Wirish SPI interface.
*
* This implementation uses software slave management, so the caller
* is responsible for controlling the slave select line.
*/
class HardwareSPI {
public:
/**
* @param spiPortNumber Number of the SPI port to manage.
*/
HardwareSPI(uint32 spiPortNumber);
/*
* Set up/tear down
*/
/**
* @brief Turn on a SPI port and set its GPIO pin modes for use as master.
*
* SPI port is enabled in full duplex mode, with software slave management.
*
* @param frequency Communication frequency
* @param bitOrder Either LSBFIRST (little-endian) or MSBFIRST (big-endian)
* @param mode SPI mode to use, one of SPI_MODE_0, SPI_MODE_1,
* SPI_MODE_2, and SPI_MODE_3.
*/
void begin(SPIFrequency frequency, uint32 bitOrder, uint32 mode);
/**
* @brief Equivalent to begin(SPI_1_125MHZ, MSBFIRST, 0).
*/
void begin(void);
/**
* @brief Turn on a SPI port and set its GPIO pin modes for use as a slave.
*
* SPI port is enabled in full duplex mode, with software slave management.
*
* @param bitOrder Either LSBFIRST (little-endian) or MSBFIRST(big-endian)
* @param mode SPI mode to use
*/
void beginSlave(uint32 bitOrder, uint32 mode);
/**
* @brief Equivalent to beginSlave(MSBFIRST, 0).
*/
void beginSlave(void);
/**
* @brief Disables the SPI port, but leaves its GPIO pin modes unchanged.
*/
void end(void);
/*
* I/O
*/
/**
* @brief Return the next unread byte.
*
* If there is no unread byte waiting, this function will block
* until one is received.
*/
uint8 read(void);
/**
* @brief Read length bytes, storing them into buffer.
* @param buffer Buffer to store received bytes into.
* @param length Number of bytes to store in buffer. This
* function will block until the desired number of
* bytes have been read.
*/
void read(uint8 *buffer, uint32 length);
/**
* @brief Read length bytes, storing them into buffer.
* @param buffer Buffer to store received bytes into.
* @param length Number of bytes to store in buffer. This
* function will block until the desired number of
* bytes have been read.
*/
void readMaster(uint8 *buffer, uint32 length);
void waitReady();
/**
* @brief Transmit a byte.
* @param data Byte to transmit.
*/
void write(uint8 data);
/**
* @brief Transmit multiple bytes.
* @param buffer Bytes to transmit.
* @param length Number of bytes in buffer to transmit.
*/
void write(const uint8 *buffer, uint32 length);
/**
* @brief Transmit a byte, then return the next unread byte.
*
* This function transmits before receiving.
*
* @param data Byte to transmit.
* @return Next unread byte.
*/
uint8 transfer(uint8 data);
/*
* Pin accessors
*/
/**
* @brief Return the number of the MISO (master in, slave out) pin
*/
uint8 misoPin(void);
/**
* @brief Return the number of the MOSI (master out, slave in) pin
*/
uint8 mosiPin(void);
/**
* @brief Return the number of the SCK (serial clock) pin
*/
uint8 sckPin(void);
/**
* @brief Return the number of the NSS (slave select) pin
*/
uint8 nssPin(void);
/* -- The following methods are deprecated --------------------------- */
/**
* @brief Deprecated.
*
* Use HardwareSPI::transfer() instead.
*
* @see HardwareSPI::transfer()
*/
uint8 send(uint8 data);
/**
* @brief Deprecated.
*
* Use HardwareSPI::write() in combination with
* HardwareSPI::read() (or HardwareSPI::transfer()) instead.
*
* @see HardwareSPI::write()
* @see HardwareSPI::read()
* @see HardwareSPI::transfer()
*/
uint8 send(const uint8 *data, uint32 length);
/**
* @brief Deprecated.
*
* Use HardwareSPI::read() instead.
*
* @see HardwareSPI::read()
*/
uint8 recv(void);
// void beginTransaction(SPISettings settings) { beginTransaction(BOARD_SPI_DEFAULT_SS, settings); }
// void beginTransaction(uint8 pin, SPISettings settings);
void endTransaction(void) { }
private:
spi_dev *spi_d;
};
extern HardwareSPI SPI;
#endif

View File

@ -1,383 +0,0 @@
/******************************************************************************
* 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.
*****************************************************************************/
#ifdef STM32F1
/**
* @file dma.c
* @author Marti Bolivar <mbolivar@leaflabs.com>;
* Original implementation by Michael Hope
* @brief Direct Memory Access peripheral support
*/
#include "dma.h"
#include "bitband.h"
#include "util.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 }}
};
/** DMA1 device */
dma_dev *DMA1 = &dma1;
#ifdef STM32_HIGH_DENSITY
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_CH_4_5 },
{ .handler = NULL, .irq_line = NVIC_DMA2_CH_4_5 }} /* !@#$ */
};
/** DMA2 device */
dma_dev *DMA2 = &dma2;
#endif
/*
* Convenience routines
*/
/**
* @brief Initialize a DMA device.
* @param dev Device to initialize.
*/
void dma_init(dma_dev *dev) {
rcc_clk_enable(dev->clk_id);
}
/**
* @brief Set up a DMA transfer.
*
* The channel will be disabled before being reconfigured. The
* transfer will have low priority by default. You may choose another
* priority before the transfer begins using dma_set_priority(), as
* well as performing any other configuration you desire. When the
* channel is configured to your liking, enable it using dma_enable().
*
* @param dev DMA device.
* @param channel DMA channel.
* @param peripheral_address Base address of peripheral data register
* involved in the transfer.
* @param peripheral_size Peripheral data transfer size.
* @param memory_address Base memory address involved in the transfer.
* @param memory_size Memory data transfer size.
* @param mode Logical OR of dma_mode_flags
* @sideeffect Disables the given DMA channel.
* @see dma_xfer_size
* @see dma_mode_flags
* @see dma_set_num_transfers()
* @see dma_set_priority()
* @see dma_attach_interrupt()
* @see dma_enable()
*/
void dma_setup_transfer(dma_dev *dev,
dma_channel channel,
__io void *peripheral_address,
dma_xfer_size peripheral_size,
__io void *memory_address,
dma_xfer_size memory_size,
uint32 mode) {
dma_channel_reg_map *channel_regs = dma_channel_regs(dev, channel);
dma_disable(dev, channel); /* can't write to CMAR/CPAR otherwise */
channel_regs->CCR = (memory_size << 10) | (peripheral_size << 8) | mode;
channel_regs->CMAR = (uint32)memory_address;
channel_regs->CPAR = (uint32)peripheral_address;
}
/**
* @brief Set the number of data to be transferred on a DMA channel.
*
* You may not call this function while the channel is enabled.
*
* @param dev DMA device
* @param channel Channel through which the transfer occurs.
* @param num_transfers
*/
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;
}
/**
* @brief Set the priority of a DMA transfer.
*
* You may not call this function while the channel is enabled.
*
* @param dev DMA device
* @param channel DMA channel
* @param priority priority to set.
*/
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;
channel_regs->CCR = ccr;
}
/**
* @brief Attach an interrupt to a DMA transfer.
*
* Interrupts are enabled using appropriate mode flags in
* dma_setup_transfer().
*
* @param dev DMA device
* @param channel Channel to attach handler to
* @param handler Interrupt handler to call when channel interrupt fires.
* @see dma_setup_transfer()
* @see dma_get_irq_cause()
* @see dma_detach_interrupt()
*/
void dma_attach_interrupt(dma_dev *dev,
dma_channel channel,
void (*handler)(void)) {
dev->handlers[channel - 1].handler = handler;
nvic_irq_enable(dev->handlers[channel - 1].irq_line);
}
/**
* @brief Detach a DMA transfer interrupt handler.
*
* After calling this function, the given channel's interrupts will be
* disabled.
*
* @param dev DMA device
* @param channel Channel whose handler to detach
* @sideeffect Clears interrupt enable bits in the channel's CCR register.
* @see dma_attach_interrupt()
*/
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;
dev->handlers[channel - 1].handler = NULL;
}
/**
* @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 channel Channel whose interrupt is being handled.
* @return Reason why the interrupt fired.
* @sideeffect Clears channel status flags in dev->regs->ISR.
* @see dma_attach_interrupt()
* @see dma_irq_cause
*/
dma_irq_cause dma_get_irq_cause(dma_dev *dev, dma_channel channel) {
uint8 status_bits = dma_get_isr_bits(dev, channel);
/* If the channel global interrupt flag is cleared, then
* something's very wrong. */
ASSERT(status_bits & BIT(0));
dma_clear_isr_bits(dev, channel);
/* 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 & BIT(3)) {
return DMA_TRANSFER_ERROR;
} else if (status_bits & BIT(1)) {
return DMA_TRANSFER_COMPLETE;
} else if (status_bits & BIT(2)) {
return DMA_TRANSFER_HALF_COMPLETE;
} else if (status_bits & BIT(0)) {
/* Shouldn't happen (unless someone messed up an IFCR write). */
throb();
}
#if DEBUG_LEVEL < DEBUG_ALL
else {
/* We shouldn't have been called, but the debug level is too
* low for the above ASSERT() to have had any effect. In
* order to fail fast, mimic the DMA controller's behavior
* when an error occurs. */
dma_disable(dev, channel);
}
#endif
return DMA_TRANSFER_ERROR;
}
/**
* @brief Enable a DMA channel.
* @param dev DMA device
* @param channel Channel to enable
*/
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);
}
/**
* @brief Disable a DMA channel.
* @param dev DMA device
* @param channel Channel to disable
*/
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);
}
/**
* @brief Set the base memory address where data will be read from or
* written to.
*
* You must not call this function while the channel 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 channel Channel whose base memory address to set.
* @param addr Memory base address to use.
*/
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;
}
/**
* @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 channel Channel whose peripheral data register base address to set.
* @param addr Peripheral memory base address to use.
*/
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
*/
static inline void dispatch_handler(dma_dev *dev, dma_channel channel) {
void (*handler)(void) = dev->handlers[channel - 1].handler;
if (handler) {
handler();
dma_clear_isr_bits(dev, channel); /* in case handler doesn't */
}
}
void __irq_dma1_channel1(void) {
dispatch_handler(DMA1, DMA_CH1);
}
void __irq_dma1_channel2(void) {
dispatch_handler(DMA1, DMA_CH2);
}
void __irq_dma1_channel3(void) {
dispatch_handler(DMA1, DMA_CH3);
}
void __irq_dma1_channel4(void) {
dispatch_handler(DMA1, DMA_CH4);
}
void __irq_dma1_channel5(void) {
dispatch_handler(DMA1, DMA_CH5);
}
void __irq_dma1_channel6(void) {
dispatch_handler(DMA1, DMA_CH6);
}
void __irq_dma1_channel7(void) {
dispatch_handler(DMA1, DMA_CH7);
}
#ifdef STM32_HIGH_DENSITY
void __irq_dma2_channel1(void) {
dispatch_handler(DMA2, DMA_CH1);
}
void __irq_dma2_channel2(void) {
dispatch_handler(DMA2, DMA_CH2);
}
void __irq_dma2_channel3(void) {
dispatch_handler(DMA2, DMA_CH3);
}
void __irq_dma2_channel4_5(void) {
dispatch_handler(DMA2, DMA_CH4);
dispatch_handler(DMA2, DMA_CH5);
}
#endif
#endif

View File

@ -1,453 +0,0 @@
/******************************************************************************
* 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 dma.h
*
* @author Marti Bolivar <mbolivar@leaflabs.com>;
* Original implementation by Michael Hope
*
* @brief Direct Memory Access peripheral support
*/
/*
* See /notes/dma.txt for more information.
*/
#ifndef _DMA_H_
#define _DMA_H_
#include "libmaple_types.h"
#include "rcc.h"
#include "nvic.h"
#ifdef __cplusplus
extern "C"{
#endif
/*
* Register maps
*/
/**
* @brief 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)
#ifdef STM32_HIGH_DENSITY
/** DMA controller 2 register map base pointer */
#define DMA2_BASE ((struct dma_reg_map*)0x40020400)
#endif
/*
* Register bit definitions
*/
/* Interrupt status register */
#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 BIT(DMA_ISR_TEIF7_BIT)
#define DMA_ISR_HTIF7 BIT(DMA_ISR_HTIF7_BIT)
#define DMA_ISR_TCIF7 BIT(DMA_ISR_TCIF7_BIT)
#define DMA_ISR_GIF7 BIT(DMA_ISR_GIF7_BIT)
#define DMA_ISR_TEIF6 BIT(DMA_ISR_TEIF6_BIT)
#define DMA_ISR_HTIF6 BIT(DMA_ISR_HTIF6_BIT)
#define DMA_ISR_TCIF6 BIT(DMA_ISR_TCIF6_BIT)
#define DMA_ISR_GIF6 BIT(DMA_ISR_GIF6_BIT)
#define DMA_ISR_TEIF5 BIT(DMA_ISR_TEIF5_BIT)
#define DMA_ISR_HTIF5 BIT(DMA_ISR_HTIF5_BIT)
#define DMA_ISR_TCIF5 BIT(DMA_ISR_TCIF5_BIT)
#define DMA_ISR_GIF5 BIT(DMA_ISR_GIF5_BIT)
#define DMA_ISR_TEIF4 BIT(DMA_ISR_TEIF4_BIT)
#define DMA_ISR_HTIF4 BIT(DMA_ISR_HTIF4_BIT)
#define DMA_ISR_TCIF4 BIT(DMA_ISR_TCIF4_BIT)
#define DMA_ISR_GIF4 BIT(DMA_ISR_GIF4_BIT)
#define DMA_ISR_TEIF3 BIT(DMA_ISR_TEIF3_BIT)
#define DMA_ISR_HTIF3 BIT(DMA_ISR_HTIF3_BIT)
#define DMA_ISR_TCIF3 BIT(DMA_ISR_TCIF3_BIT)
#define DMA_ISR_GIF3 BIT(DMA_ISR_GIF3_BIT)
#define DMA_ISR_TEIF2 BIT(DMA_ISR_TEIF2_BIT)
#define DMA_ISR_HTIF2 BIT(DMA_ISR_HTIF2_BIT)
#define DMA_ISR_TCIF2 BIT(DMA_ISR_TCIF2_BIT)
#define DMA_ISR_GIF2 BIT(DMA_ISR_GIF2_BIT)
#define DMA_ISR_TEIF1 BIT(DMA_ISR_TEIF1_BIT)
#define DMA_ISR_HTIF1 BIT(DMA_ISR_HTIF1_BIT)
#define DMA_ISR_TCIF1 BIT(DMA_ISR_TCIF1_BIT)
#define DMA_ISR_GIF1 BIT(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 BIT(DMA_IFCR_CTEIF7_BIT)
#define DMA_IFCR_CHTIF7 BIT(DMA_IFCR_CHTIF7_BIT)
#define DMA_IFCR_CTCIF7 BIT(DMA_IFCR_CTCIF7_BIT)
#define DMA_IFCR_CGIF7 BIT(DMA_IFCR_CGIF7_BIT)
#define DMA_IFCR_CTEIF6 BIT(DMA_IFCR_CTEIF6_BIT)
#define DMA_IFCR_CHTIF6 BIT(DMA_IFCR_CHTIF6_BIT)
#define DMA_IFCR_CTCIF6 BIT(DMA_IFCR_CTCIF6_BIT)
#define DMA_IFCR_CGIF6 BIT(DMA_IFCR_CGIF6_BIT)
#define DMA_IFCR_CTEIF5 BIT(DMA_IFCR_CTEIF5_BIT)
#define DMA_IFCR_CHTIF5 BIT(DMA_IFCR_CHTIF5_BIT)
#define DMA_IFCR_CTCIF5 BIT(DMA_IFCR_CTCIF5_BIT)
#define DMA_IFCR_CGIF5 BIT(DMA_IFCR_CGIF5_BIT)
#define DMA_IFCR_CTEIF4 BIT(DMA_IFCR_CTEIF4_BIT)
#define DMA_IFCR_CHTIF4 BIT(DMA_IFCR_CHTIF4_BIT)
#define DMA_IFCR_CTCIF4 BIT(DMA_IFCR_CTCIF4_BIT)
#define DMA_IFCR_CGIF4 BIT(DMA_IFCR_CGIF4_BIT)
#define DMA_IFCR_CTEIF3 BIT(DMA_IFCR_CTEIF3_BIT)
#define DMA_IFCR_CHTIF3 BIT(DMA_IFCR_CHTIF3_BIT)
#define DMA_IFCR_CTCIF3 BIT(DMA_IFCR_CTCIF3_BIT)
#define DMA_IFCR_CGIF3 BIT(DMA_IFCR_CGIF3_BIT)
#define DMA_IFCR_CTEIF2 BIT(DMA_IFCR_CTEIF2_BIT)
#define DMA_IFCR_CHTIF2 BIT(DMA_IFCR_CHTIF2_BIT)
#define DMA_IFCR_CTCIF2 BIT(DMA_IFCR_CTCIF2_BIT)
#define DMA_IFCR_CGIF2 BIT(DMA_IFCR_CGIF2_BIT)
#define DMA_IFCR_CTEIF1 BIT(DMA_IFCR_CTEIF1_BIT)
#define DMA_IFCR_CHTIF1 BIT(DMA_IFCR_CHTIF1_BIT)
#define DMA_IFCR_CTCIF1 BIT(DMA_IFCR_CTCIF1_BIT)
#define DMA_IFCR_CGIF1 BIT(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 BIT(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 BIT(DMA_CCR_MINC_BIT)
#define DMA_CCR_PINC BIT(DMA_CCR_PINC_BIT)
#define DMA_CCR_CIRC BIT(DMA_CCR_CIRC_BIT)
#define DMA_CCR_DIR BIT(DMA_CCR_DIR_BIT)
#define DMA_CCR_TEIE BIT(DMA_CCR_TEIE_BIT)
#define DMA_CCR_HTIE BIT(DMA_CCR_HTIE_BIT)
#define DMA_CCR_TCIE BIT(DMA_CCR_TCIE_BIT)
#define DMA_CCR_EN BIT(DMA_CCR_EN_BIT)
/*
* Devices
*/
/** Encapsulates state related to a DMA channel interrupt. */
typedef struct dma_handler_config {
void (*handler)(void); /**< User-specified channel interrupt
handler */
nvic_irq_num irq_line; /**< Channel's NVIC interrupt number */
} dma_handler_config;
/** DMA device type */
typedef struct dma_dev {
dma_reg_map *regs; /**< Register map */
rcc_clk_id clk_id; /**< Clock ID */
dma_handler_config handlers[]; /**<
* @brief IRQ handlers and NVIC numbers.
*
* @see dma_attach_interrupt()
* @see dma_detach_interrupt()
*/
} dma_dev;
extern dma_dev *DMA1;
#ifdef STM32_HIGH_DENSITY
extern dma_dev *DMA2;
#endif
/*
* Convenience functions
*/
void dma_init(dma_dev *dev);
/** Flags for DMA transfer configuration. */
typedef enum dma_mode_flags {
DMA_MEM_2_MEM = 1 << 14, /**< Memory to memory mode */
DMA_MINC_MODE = 1 << 7, /**< Auto-increment memory address */
DMA_PINC_MODE = 1 << 6, /**< Auto-increment peripheral address */
DMA_CIRC_MODE = 1 << 5, /**< Circular mode */
DMA_FROM_MEM = 1 << 4, /**< Read from memory to peripheral */
DMA_TRNS_ERR = 1 << 3, /**< Interrupt on transfer error */
DMA_HALF_TRNS = 1 << 2, /**< Interrupt on half-transfer */
DMA_TRNS_CMPLT = 1 << 1 /**< Interrupt on transfer completion */
} dma_mode_flags;
/** Source and destination transfer sizes. */
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;
/** DMA channel */
typedef enum dma_channel {
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;
void dma_setup_transfer(dma_dev *dev,
dma_channel channel,
__io void *peripheral_address,
dma_xfer_size peripheral_size,
__io void *memory_address,
dma_xfer_size memory_size,
uint32 mode);
void dma_set_num_transfers(dma_dev *dev,
dma_channel channel,
uint16 num_transfers);
/** DMA transfer priority. */
typedef enum dma_priority {
DMA_PRIORITY_LOW = DMA_CCR_PL_LOW, /**< Low priority */
DMA_PRIORITY_MEDIUM = DMA_CCR_PL_MEDIUM, /**< Medium priority */
DMA_PRIORITY_HIGH = DMA_CCR_PL_HIGH, /**< High priority */
DMA_PRIORITY_VERY_HIGH = DMA_CCR_PL_VERY_HIGH /**< Very high priority */
} dma_priority;
void dma_set_priority(dma_dev *dev,
dma_channel channel,
dma_priority priority);
void dma_attach_interrupt(dma_dev *dev,
dma_channel channel,
void (*handler)(void));
void dma_detach_interrupt(dma_dev *dev, dma_channel channel);
/**
* 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_irq_cause;
dma_irq_cause dma_get_irq_cause(dma_dev *dev, dma_channel channel);
void dma_enable(dma_dev *dev, dma_channel channel);
void dma_disable(dma_dev *dev, dma_channel channel);
void dma_set_mem_addr(dma_dev *dev, dma_channel channel, __io void *address);
void dma_set_per_addr(dma_dev *dev, dma_channel channel, __io void *address);
/**
* @brief DMA channel register map type.
*
* Provides access to an individual channel's registers.
*/
typedef struct dma_channel_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_channel_reg_map;
#define DMA_CHANNEL_NREGS 5
/**
* @brief Obtain a pointer to an individual DMA channel's registers.
*
* For example, dma_channel_regs(DMA1, DMA_CH1)->CCR is DMA1_BASE->CCR1.
*
* @param dev DMA device
* @param channel DMA channel whose channel register map to obtain.
*/
static inline dma_channel_reg_map* dma_channel_regs(dma_dev *dev,
dma_channel channel) {
__io uint32 *ccr1 = &dev->regs->CCR1;
return (dma_channel_reg_map*)(ccr1 + DMA_CHANNEL_NREGS * (channel - 1));
}
/**
* @brief Check if a DMA channel is enabled
* @param dev DMA device
* @param channel Channel whose enabled bit to check.
*/
static inline uint8 dma_is_channel_enabled(dma_dev *dev, dma_channel channel) {
return (uint8)(dma_channel_regs(dev, channel)->CCR & DMA_CCR_EN);
}
/**
* @brief Get the ISR status bits for a DMA channel.
*
* The bits are returned right-aligned, in the following order:
* transfer error flag, half-transfer flag, transfer complete flag,
* global interrupt flag.
*
* If you're attempting to figure out why a DMA interrupt fired; you
* may find dma_get_irq_cause() more convenient.
*
* @param dev DMA device
* @param channel Channel whose ISR bits to return.
* @see dma_get_irq_cause().
*/
static inline uint8 dma_get_isr_bits(dma_dev *dev, dma_channel channel) {
uint8 shift = (channel - 1) * 4;
return (dev->regs->ISR >> shift) & 0xF;
}
/**
* @brief Clear the ISR status bits for a given DMA channel.
*
* If you're attempting to clean up after yourself in a DMA interrupt,
* you may find dma_get_irq_cause() more convenient.
*
* @param dev DMA device
* @param channel Channel whose ISR bits to clear.
* @see dma_get_irq_cause()
*/
static inline void dma_clear_isr_bits(dma_dev *dev, dma_channel channel) {
dev->regs->IFCR = BIT(4 * (channel - 1));
}
#ifdef __cplusplus
} // extern "C"
#endif
#endif

View File

@ -1,241 +0,0 @@
/******************************************************************************
* 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.
*****************************************************************************/
#ifdef STM32F2
/**
* @file dmaF2.c
* @brief Direct Memory Access peripheral support
*/
#include "dma.h"
#include "bitband.h"
#include "util.h"
/*
* Devices
*/
static dma_dev dma1 = {
.regs = DMA1_BASE,
.clk_id = RCC_DMA1,
.handlers = {{ .handler = NULL, .irq_line = 11 },
{ .handler = NULL, .irq_line = 12 },
{ .handler = NULL, .irq_line = 13 },
{ .handler = NULL, .irq_line = 14 },
{ .handler = NULL, .irq_line = 15 },
{ .handler = NULL, .irq_line = 16 },
{ .handler = NULL, .irq_line = 17 },
{ .handler = NULL, .irq_line = 47 }}
};
/** DMA1 device */
dma_dev *DMA1 = &dma1;
static dma_dev dma2 = {
.regs = DMA2_BASE,
.clk_id = RCC_DMA2,
.handlers = {{ .handler = NULL, .irq_line = 56 },
{ .handler = NULL, .irq_line = 57 },
{ .handler = NULL, .irq_line = 58 },
{ .handler = NULL, .irq_line = 59 },
{ .handler = NULL, .irq_line = 60 },
{ .handler = NULL, .irq_line = 68 },
{ .handler = NULL, .irq_line = 69 },
{ .handler = NULL, .irq_line = 70 }} /* !@#$ */
};
/** DMA2 device */
dma_dev *DMA2 = &dma2;
/*
* Convenience routines
*/
/**
* @brief Initialize a DMA device.
* @param dev Device to initialize.
*/
void dma_init(dma_dev *dev) {
rcc_clk_enable(dev->clk_id);
}
/**
* @brief Attach an interrupt to a DMA transfer.
*
* Interrupts are enabled using appropriate mode flags in
* dma_setup_transfer().
*
* @param dev DMA device
* @param stream Stream to attach handler to
* @param handler Interrupt handler to call when channel interrupt fires.
* @see dma_setup_transfer()
* @see dma_detach_interrupt()
*/
void dma_attach_interrupt(dma_dev *dev,
dma_stream stream,
void (*handler)(void)) {
dev->handlers[stream].handler = handler;
nvic_irq_enable(dev->handlers[stream].irq_line);
}
/**
* @brief Detach a DMA transfer interrupt handler.
*
* After calling this function, the given channel's interrupts will be
* disabled.
*
* @param dev DMA device
* @param stream Stream whose handler to detach
* @sideeffect Clears interrupt enable bits in the channel's CCR register.
* @see dma_attach_interrupt()
*/
void dma_detach_interrupt(dma_dev *dev, dma_stream stream) {
nvic_irq_disable(dev->handlers[stream].irq_line);
dev->handlers[stream].handler = NULL;
}
void dma_clear_isr_bits(dma_dev *dev, dma_stream stream) {
switch (stream) {
case 0:
dev->regs->LIFCR|=0x0000003d;
break;
case 1:
dev->regs->LIFCR|=0x00000f40;
break;
case 2:
dev->regs->LIFCR|=0x003d0000;
break;
case 3:
dev->regs->LIFCR|=0x0f400000;
break;
case 4:
dev->regs->HIFCR|=0x0000003d;
break;
case 5:
dev->regs->HIFCR|=0x00000f40;
break;
case 6:
dev->regs->HIFCR|=0x003d0000;
break;
case 7:
dev->regs->HIFCR|=0x0f400000;
break;
}
}
/*
* IRQ handlers
*/
static inline void dispatch_handler(dma_dev *dev, dma_stream stream) {
void (*handler)(void) = dev->handlers[stream].handler;
if (handler) {
handler();
dma_clear_isr_bits(dev, stream); /* in case handler doesn't */
}
}
//void __irq_dma1_stream0(void) {
void __irq_dma1_channel1(void) {
dispatch_handler(DMA1, DMA_STREAM0);
}
//void __irq_dma1_stream1(void) {
void __irq_dma1_channel2(void) {
dispatch_handler(DMA1, DMA_STREAM1);
}
//void __irq_dma1_stream2(void) {
void __irq_dma1_channel3(void) {
dispatch_handler(DMA1, DMA_STREAM2);
}
//void __irq_dma1_stream3(void) {
void __irq_dma1_channel4(void) {
dispatch_handler(DMA1, DMA_STREAM3);
}
//void __irq_dma1_stream4(void) {
void __irq_dma1_channel5(void) {
dispatch_handler(DMA1, DMA_STREAM4);
}
//void __irq_dma1_stream5(void) {
void __irq_dma1_channel6(void) {
dispatch_handler(DMA1, DMA_STREAM5);
}
//void __irq_dma1_stream6(void) {
void __irq_dma1_channel7(void) {
dispatch_handler(DMA1, DMA_STREAM6);
}
//void __irq_dma1_stream7(void) {
void __irq_adc3(void) {
dispatch_handler(DMA1, DMA_STREAM7);
}
//void __irq_dma2_stream0(void) {
void __irq_dma2_channel1(void) {
dispatch_handler(DMA2, DMA_STREAM0);
}
//void __irq_dma2_stream1(void) {
void __irq_dma2_channel2(void) {
dispatch_handler(DMA2, DMA_STREAM1);
}
//void __irq_dma2_stream2(void) {
void __irq_dma2_channel3(void) {
dispatch_handler(DMA2, DMA_STREAM2);
}
//void __irq_dma2_stream3(void) {
void __irq_dma2_channel4_5(void) {
dispatch_handler(DMA2, DMA_STREAM3);
}
//void __irq_dma2_stream4(void) {
void __irq_DMA2_Stream4_IRQHandler(void) {
dispatch_handler(DMA2, DMA_STREAM4);
}
//void __irq_dma2_stream5(void) {
void __irq_DMA2_Stream5_IRQHandler(void) {
dispatch_handler(DMA2, DMA_STREAM5);
}
//void __irq_dma2_stream6(void) {
void __irq_DMA2_Stream6_IRQHandler(void) {
dispatch_handler(DMA2, DMA_STREAM6);
}
//void __irq_dma2_stream7(void) {
void __irq_DMA2_Stream7_IRQHandler(void) {
dispatch_handler(DMA2, DMA_STREAM7);
}
#endif

View File

@ -1,270 +0,0 @@
/******************************************************************************
* 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 dma.h
*
* @author Marti Bolivar <mbolivar@leaflabs.com>;
* Original implementation by Michael Hope
*
* @brief Direct Memory Access peripheral support
*/
/*
* See /notes/dma.txt for more information.
*/
#ifndef _DMA_H_
#define _DMA_H_
#include "libmaple_types.h"
#include "rcc.h"
#include "nvic.h"
#ifdef __cplusplus
extern "C"{
#endif
/*
* Register maps
*/
/**
* @brief DMA stream type.
*
*/
typedef struct dma_stream_t {
__io uint32 CR; /**< Stream configuration register */
__io uint32 NDTR; /**< Stream number of data register */
__io uint32 PAR; /**< Stream peripheral address register */
__io uint32 M0AR; /**< Stream memory address register 0 */
__io uint32 M1AR; /**< Stream memory address register 1 */
__io uint32 FCR; /**< Stream FIFO configuration register */
} dma_stream_t;
/**
* @brief DMA register map type.
*
*/
typedef struct dma_reg_map {
__io uint32 LISR; /**< Low interrupt status register */
__io uint32 HISR; /**< High interrupt status register */
__io uint32 LIFCR; /**< Low interrupt flag clear register */
__io uint32 HIFCR; /**< High interrupt flag clear register */
dma_stream_t STREAM[8];
} dma_reg_map;
/** DMA controller register map base pointers */
#define DMA1_BASE ((struct dma_reg_map*)0x40026000)
#define DMA2_BASE ((struct dma_reg_map*)0x40026400)
/*
* Register bit definitions
*/
/* Channel configuration register */
#define DMA_CR_CH0 (0x0 << 25)
#define DMA_CR_CH1 (0x1 << 25)
#define DMA_CR_CH2 (0x2 << 25)
#define DMA_CR_CH3 (0x3 << 25)
#define DMA_CR_CH4 (0x4 << 25)
#define DMA_CR_CH5 (0x5 << 25)
#define DMA_CR_CH6 (0x6 << 25)
#define DMA_CR_CH7 (0x7 << 25)
#define DMA_CR_MBURST0 (0x0 << 23)
#define DMA_CR_MBURST4 (0x1 << 23)
#define DMA_CR_MBURST8 (0x2 << 23)
#define DMA_CR_MBURST16 (0x3 << 23)
#define DMA_CR_PBURST0 (0x0 << 21)
#define DMA_CR_PBURST4 (0x1 << 21)
#define DMA_CR_PBURST8 (0x2 << 21)
#define DMA_CR_PBURST16 (0x3 << 21)
#define DMA_CR_CT0 (0x0 << 19)
#define DMA_CR_CT1 (0x1 << 19)
#define DMA_CR_DBM (0x1 << 18)
#define DMA_CR_PL_LOW (0x0 << 16)
#define DMA_CR_PL_MEDIUM (0x1 << 16)
#define DMA_CR_PL_HIGH (0x2 << 16)
#define DMA_CR_PL_VERY_HIGH (0x3 << 16)
#define DMA_CR_PL_MASK (0x3 << 16)
#define DMA_CR_PINCOS (0x1 << 15)
#define DMA_CR_MSIZE_8BITS (0x0 << 13)
#define DMA_CR_MSIZE_16BITS (0x1 << 13)
#define DMA_CR_MSIZE_32BITS (0x2 << 13)
#define DMA_CR_PSIZE_8BITS (0x0 << 11)
#define DMA_CR_PSIZE_16BITS (0x1 << 11)
#define DMA_CR_PSIZE_32BITS (0x2 << 11)
#define DMA_CR_MINC (0x1 << 10)
#define DMA_CR_PINC (0x1 << 9)
#define DMA_CR_CIRC (0x1 << 8)
#define DMA_CR_DIR_P2M (0x0 << 6)
#define DMA_CR_DIR_M2P (0x1 << 6)
#define DMA_CR_DIR_M2M (0x2 << 6)
#define DMA_CR_PFCTRL (0x1 << 5)
#define DMA_CR_TCIE (0x1 << 4)
#define DMA_CR_HTIE (0x1 << 3)
#define DMA_CR_TEIE (0x1 << 2)
#define DMA_CR_DMEIE (0x1 << 1)
#define DMA_CR_EN (0x1)
/*
* Devices
*/
/** Encapsulates state related to a DMA channel interrupt. */
typedef struct dma_handler_config {
void (*handler)(void); /**< User-specified channel interrupt
handler */
nvic_irq_num irq_line; /**< Channel's NVIC interrupt number */
} dma_handler_config;
/** DMA device type */
typedef struct dma_dev {
dma_reg_map *regs; /**< Register map */
rcc_clk_id clk_id; /**< Clock ID */
dma_handler_config handlers[]; /**<
* @brief IRQ handlers and NVIC numbers.
*
* @see dma_attach_interrupt()
* @see dma_detach_interrupt()
*/
} dma_dev;
extern dma_dev *DMA1;
extern dma_dev *DMA2;
/*
* Convenience functions
*/
void dma_init(dma_dev *dev);
/** Flags for DMA transfer configuration. */
typedef enum dma_mode_flags {
DMA_MEM_2_MEM = 1 << 14, /**< Memory to memory mode */
DMA_MINC_MODE = 1 << 7, /**< Auto-increment memory address */
DMA_PINC_MODE = 1 << 6, /**< Auto-increment peripheral address */
DMA_CIRC_MODE = 1 << 5, /**< Circular mode */
DMA_FROM_MEM = 1 << 4, /**< Read from memory to peripheral */
DMA_TRNS_ERR = 1 << 3, /**< Interrupt on transfer error */
DMA_HALF_TRNS = 1 << 2, /**< Interrupt on half-transfer */
DMA_TRNS_CMPLT = 1 << 1 /**< Interrupt on transfer completion */
} dma_mode_flags;
/** Source and destination transfer sizes. */
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;
/** DMA channel */
typedef enum dma_stream {
DMA_STREAM0 = 0, /**< Stream 0 */
DMA_STREAM1 = 1, /**< Stream 1 */
DMA_STREAM2 = 2, /**< Stream 2 */
DMA_STREAM3 = 3, /**< Stream 3 */
DMA_STREAM4 = 4, /**< Stream 4 */
DMA_STREAM5 = 5, /**< Stream 5 */
DMA_STREAM6 = 6, /**< Stream 6 */
DMA_STREAM7 = 7, /**< Stream 7 */
} dma_stream;
static inline void dma_setup_transfer(dma_dev *dev,
dma_stream stream,
__io void *peripheral_address,
__io void *memory_address0,
__io void *memory_address1,
uint32 flags,
uint32 fifo_flags) {
dev->regs->STREAM[stream].CR &= ~DMA_CR_EN; // disable
dev->regs->STREAM[stream].PAR = (uint32)peripheral_address;
dev->regs->STREAM[stream].M0AR = (uint32)memory_address0;
dev->regs->STREAM[stream].M1AR = (uint32)memory_address1;
dev->regs->STREAM[stream].FCR = fifo_flags & 0x87; // mask out reserved bits
dev->regs->STREAM[stream].CR = flags & 0x0feffffe; // mask out reserved and enable
}
static inline void dma_set_num_transfers(dma_dev *dev,
dma_stream stream,
uint16 num_transfers) {
dev->regs->STREAM[stream].NDTR = num_transfers;
}
void dma_attach_interrupt(dma_dev *dev,
dma_stream stream,
void (*handler)(void));
void dma_detach_interrupt(dma_dev *dev, dma_stream stream);
static inline void dma_enable(dma_dev *dev, dma_stream stream) {
dev->regs->STREAM[stream].CR |= DMA_CR_EN;
}
static inline void dma_disable(dma_dev *dev, dma_stream stream) {
dev->regs->STREAM[stream].CR &= ~DMA_CR_EN;
}
/**
* @brief Check if a DMA stream is enabled
* @param dev DMA device
* @param stream Stream whose enabled bit to check.
*/
static inline uint8 dma_is_stream_enabled(dma_dev *dev, dma_stream stream) {
return (uint8)(dev->regs->STREAM[stream].CR & DMA_CR_EN);
}
/**
* @brief Get the ISR status bits for a DMA stream.
*
* The bits are returned right-aligned, in the following order:
* transfer error flag, half-transfer flag, transfer complete flag,
* global interrupt flag.
*
* @param dev DMA device
* @param stream Stream whose ISR bits to return.
*/
uint8 dma_get_isr_bits(dma_dev *dev, dma_stream stream);
/**
* @brief Clear the ISR status bits for a given DMA stream.
*
* @param dev DMA device
* @param stream Stream whose ISR bits to clear.
*/
void dma_clear_isr_bits(dma_dev *dev, dma_stream stream);
#ifdef __cplusplus
} // extern "C"
#endif
#endif

View File

@ -1,36 +0,0 @@
/******************************************************************************
* 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 gpio.c
* @brief GPIO initialization routine
*/
// #ifdef STM32F2
// #include "gpioF2.c"
// #else
// #include "gpioF1.c"
// #endif

View File

@ -1,200 +0,0 @@
/******************************************************************************
* 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.
*****************************************************************************/
#ifdef STM32F1
/**
* @file gpio.c
* @brief GPIO initialization routine
*/
#include "gpio.h"
#include "rcc.h"
/*
* GPIO devices
*/
gpio_dev gpioa = {
.regs = GPIOA_BASE,
.clk_id = RCC_GPIOA,
.exti_port = AFIO_EXTI_PA,
};
/** GPIO port A device. */
gpio_dev* const GPIOA = &gpioa;
gpio_dev gpiob = {
.regs = GPIOB_BASE,
.clk_id = RCC_GPIOB,
.exti_port = AFIO_EXTI_PB,
};
/** GPIO port B device. */
gpio_dev* const GPIOB = &gpiob;
gpio_dev gpioc = {
.regs = GPIOC_BASE,
.clk_id = RCC_GPIOC,
.exti_port = AFIO_EXTI_PC,
};
/** GPIO port C device. */
gpio_dev* const GPIOC = &gpioc;
gpio_dev gpiod = {
.regs = GPIOD_BASE,
.clk_id = RCC_GPIOD,
.exti_port = AFIO_EXTI_PD,
};
/** GPIO port D device. */
gpio_dev* const GPIOD = &gpiod;
#ifdef STM32_HIGH_DENSITY
gpio_dev gpioe = {
.regs = GPIOE_BASE,
.clk_id = RCC_GPIOE,
.exti_port = AFIO_EXTI_PE,
};
/** GPIO port E device. */
gpio_dev* const GPIOE = &gpioe;
gpio_dev gpiof = {
.regs = GPIOF_BASE,
.clk_id = RCC_GPIOF,
.exti_port = AFIO_EXTI_PF,
};
/** GPIO port F device. */
gpio_dev* const GPIOF = &gpiof;
gpio_dev gpiog = {
.regs = GPIOG_BASE,
.clk_id = RCC_GPIOG,
.exti_port = AFIO_EXTI_PG,
};
/** GPIO port G device. */
gpio_dev* const GPIOG = &gpiog;
#endif
/*
* GPIO convenience 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);
}
/**
* Initialize and reset all available GPIO devices.
*/
void gpio_init_all(void) {
gpio_init(GPIOA);
gpio_init(GPIOB);
gpio_init(GPIOC);
gpio_init(GPIOD);
#ifdef STM32_HIGH_DENSITY
gpio_init(GPIOE);
gpio_init(GPIOF);
gpio_init(GPIOG);
#endif
}
/**
* Set the mode of a GPIO pin.
*
* @param dev GPIO device.
* @param pin Pin on the device whose mode to set, 0--15.
* @param mode General purpose or alternate function mode to set the pin to.
* @see gpio_pin_mode
*/
void gpio_set_mode(gpio_dev *dev, uint8 pin, gpio_pin_mode mode) {
gpio_reg_map *regs = dev->regs;
__io uint32 *cr = &regs->CRL + (pin >> 3);
uint32 shift = (pin & 0x7) * 4;
uint32 tmp = *cr;
tmp &= ~(0xF << shift);
tmp |= (mode == GPIO_INPUT_PU ? GPIO_INPUT_PD : mode) << shift;
*cr = tmp;
if (mode == GPIO_INPUT_PD) {
regs->ODR &= ~BIT(pin);
} else if (mode == GPIO_INPUT_PU) {
regs->ODR |= BIT(pin);
}
}
/*
* AFIO
*/
/**
* @brief Initialize the AFIO clock, and reset the AFIO registers.
*/
void afio_init(void) {
rcc_clk_enable(RCC_AFIO);
rcc_reset_dev(RCC_AFIO);
}
#define AFIO_EXTI_SEL_MASK 0xF
/**
* @brief Select a source input for an external interrupt.
*
* @param exti External interrupt.
* @param gpio_port Port which contains pin to use as source input.
* @see afio_exti_num
* @see afio_exti_port
*/
void afio_exti_select(afio_exti_num exti, afio_exti_port gpio_port) {
__io uint32 *exti_cr = &AFIO_BASE->EXTICR1 + exti / 4;
uint32 shift = 4 * (exti % 4);
uint32 cr = *exti_cr;
cr &= ~(AFIO_EXTI_SEL_MASK << shift);
cr |= gpio_port << shift;
*exti_cr = cr;
}
/**
* @brief Perform an alternate function remap.
* @param remapping Remapping to perform.
*/
void afio_remap(afio_remap_peripheral remapping) {
if (remapping & AFIO_REMAP_USE_MAPR2) {
remapping &= ~AFIO_REMAP_USE_MAPR2;
AFIO_BASE->MAPR2 |= remapping;
} else {
AFIO_BASE->MAPR |= remapping;
}
}
#endif

View File

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

View File

@ -1,224 +0,0 @@
/******************************************************************************
* 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.
*****************************************************************************/
#ifdef STM32F2
/**
* @file gpio.c
* @brief GPIO initialization routine
*/
#include "gpio.h"
#include "rcc.h"
/*
* GPIO devices
*/
gpio_dev gpioa = {
.regs = GPIOA_BASE,
.clk_id = RCC_GPIOA,
.exti_port = AFIO_EXTI_PA,
};
/** GPIO port A device. */
gpio_dev* const GPIOA = &gpioa;
gpio_dev gpiob = {
.regs = GPIOB_BASE,
.clk_id = RCC_GPIOB,
.exti_port = AFIO_EXTI_PB,
};
/** GPIO port B device. */
gpio_dev* const GPIOB = &gpiob;
gpio_dev gpioc = {
.regs = GPIOC_BASE,
.clk_id = RCC_GPIOC,
.exti_port = AFIO_EXTI_PC,
};
/** GPIO port C device. */
gpio_dev* const GPIOC = &gpioc;
gpio_dev gpiod = {
.regs = GPIOD_BASE,
.clk_id = RCC_GPIOD,
.exti_port = AFIO_EXTI_PD,
};
/** GPIO port D device. */
gpio_dev* const GPIOD = &gpiod;
#ifdef STM32_HIGH_DENSITY
gpio_dev gpioe = {
.regs = GPIOE_BASE,
.clk_id = RCC_GPIOE,
.exti_port = AFIO_EXTI_PE,
};
/** GPIO port E device. */
gpio_dev* const GPIOE = &gpioe;
gpio_dev gpiof = {
.regs = GPIOF_BASE,
.clk_id = RCC_GPIOF,
.exti_port = AFIO_EXTI_PF,
};
/** GPIO port F device. */
gpio_dev* const GPIOF = &gpiof;
gpio_dev gpiog = {
.regs = GPIOG_BASE,
.clk_id = RCC_GPIOG,
.exti_port = AFIO_EXTI_PG,
};
/** GPIO port G device. */
gpio_dev* const GPIOG = &gpiog;
#endif
/*
* GPIO convenience 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);
}
/**
* Initialize and reset all available GPIO devices.
*/
void gpio_init_all(void) {
gpio_init(GPIOA);
gpio_init(GPIOB);
gpio_init(GPIOC);
gpio_init(GPIOD);
#ifdef STM32_HIGH_DENSITY
gpio_init(GPIOE);
gpio_init(GPIOF);
gpio_init(GPIOG);
#endif
#ifdef ARDUINO_STM32F4_NETDUINO2PLUS
// PA8 Output the Master Clock MCO1
gpio_set_af_mode(GPIOA, 8, 0);
gpio_set_mode(GPIOA, 8, GPIO_MODE_AF | GPIO_OTYPE_PP | GPIO_OSPEED_100MHZ);
// PB4 as alternate MISO Input
gpio_set_af_mode(GPIOB, 4, 5);
// PA5 as alternate SCK Output
gpio_set_af_mode(GPIOA, 5, 5);
// PA7 as alternate MOSI Output
gpio_set_af_mode(GPIOA, 7, 5);
#endif
}
/**
* Set the mode of a GPIO pin.
*
* @param dev GPIO device.
* @param pin Pin on the device whose mode to set, 0--15.
* @param mode General purpose or alternate function mode to set the pin to.
* @see gpio_pin_mode
*/
void gpio_set_mode(gpio_dev *dev, uint8 pin, gpio_pin_mode mode) {
gpio_reg_map *regs = dev->regs;
//regs->AFR[pin/8] = (regs->AFR[pin/8] & ~(15 << (4*(pin&7)))) | (((mode >> 8) & 15) << (4*(pin&7)));
//gpio_set_af_mode(dev, pin, mode>>8);
regs->MODER = (regs->MODER & ~( 3 << (2*pin))) | (((mode >> 0) & 3) << (2*pin));
regs->PUPDR = (regs->PUPDR & ~( 3 << (2*pin))) | (((mode >> 2) & 3) << (2*pin));
regs->OSPEEDR = (regs->OSPEEDR & ~( 3 << (2*pin))) | (((mode >> 4) & 3) << (2*pin));
regs->OTYPER = (regs->OTYPER & ~( 1 << (1*pin))) | (((mode >> 6) & 1) << (1*pin));
}
/**
* Set the alternate function mode of a GPIO pin.
*
* @param dev GPIO device.
* @param pin Pin on the device whose mode to set, 0--15.
* @param mode alternate function mode to set the pin to.
* @see gpio_pin_mode
*/
void gpio_set_af_mode(gpio_dev *dev, uint8 pin, int mode) {
gpio_reg_map *regs = dev->regs;
regs->AFR[pin/8] = (regs->AFR[pin/8] & ~(15 << (4*(pin&7)))) | (((mode >> 0) & 15) << (4*(pin&7)));
}
/*
* AFIO
*/
/**
* @brief Initialize the AFIO clock, and reset the AFIO registers.
*/
void afio_init(void) {
//rcc_clk_enable(RCC_AFIO);
//rcc_reset_dev(RCC_AFIO);
}
#define AFIO_EXTI_SEL_MASK 0xF
/**
* @brief Select a source input for an external interrupt.
*
* @param exti External interrupt.
* @param gpio_port Port which contains pin to use as source input.
* @see afio_exti_num
* @see afio_exti_port
*/
void afio_exti_select(afio_exti_num exti, afio_exti_port gpio_port) {
__io uint32 *exti_cr = &SYSCFG_BASE->EXTICR1 + exti / 4;
uint32 shift = 4 * (exti % 4);
uint32 cr = *exti_cr;
cr &= ~(AFIO_EXTI_SEL_MASK << shift);
cr |= gpio_port << shift;
*exti_cr = cr;
}
/**
* @brief Perform an alternate function remap.
* @param remapping Remapping to perform.
*/
#if 0
void afio_remap(afio_remap_peripheral remapping) {
if (remapping & AFIO_REMAP_USE_MAPR2) {
remapping &= ~AFIO_REMAP_USE_MAPR2;
AFIO_BASE->MAPR2 |= remapping;
} else {
AFIO_BASE->MAPR |= remapping;
}
}
#endif
#endif

View File

@ -1,550 +0,0 @@
/******************************************************************************
* 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 gpio.h
*
* @brief General purpose I/O (GPIO) and Alternate Function I/O
* (AFIO) prototypes, defines, and inlined access functions.
*/
#ifndef _GPIO_H_
#define _GPIO_H_
#include "libmaple.h"
#include "rcc.h"
#ifdef __cplusplus
extern "C"{
#endif
/*
* GPIO register maps and devices
*/
/** GPIO register map type */
typedef struct gpio_reg_map {
__io uint32 MODER; /*!< GPIO port mode register, Address offset: 0x00 */
__io uint32 OTYPER; /*!< GPIO port output type register, Address offset: 0x04 */
__io uint32 OSPEEDR; /*!< GPIO port output speed register, Address offset: 0x08 */
__io uint32 PUPDR; /*!< GPIO port pull-up/pull-down register, Address offset: 0x0C */
__io uint32 IDR; /*!< GPIO port input data register, Address offset: 0x10 */
__io uint32 ODR; /*!< GPIO port output data register, Address offset: 0x14 */
__io uint16 BSRRL; /*!< GPIO port bit set/reset low register, Address offset: 0x18 */
__io uint16 BSRRH; /*!< GPIO port bit set/reset high register, Address offset: 0x1A */
__io uint32 LCKR; /*!< GPIO port configuration lock register, Address offset: 0x1C */
__io uint32 AFR[2]; /*!< GPIO alternate function registers, Address offset: 0x24-0x28 */
} gpio_reg_map;
/**
* @brief External interrupt line port selector.
*
* Used to determine which GPIO port to map an external interrupt line
* onto. */
/* (See AFIO sections, below) */
typedef enum afio_exti_port {
AFIO_EXTI_PA, /**< Use port A (PAx) pin. */
AFIO_EXTI_PB, /**< Use port B (PBx) pin. */
AFIO_EXTI_PC, /**< Use port C (PCx) pin. */
AFIO_EXTI_PD, /**< Use port D (PDx) pin. */
#ifdef STM32_HIGH_DENSITY
AFIO_EXTI_PE, /**< Use port E (PEx) pin. */
AFIO_EXTI_PF, /**< Use port F (PFx) pin. */
AFIO_EXTI_PG, /**< Use port G (PGx) pin. */
#endif
} afio_exti_port;
/** GPIO device type */
typedef struct gpio_dev {
gpio_reg_map *regs; /**< Register map */
rcc_clk_id clk_id; /**< RCC clock information */
afio_exti_port exti_port; /**< AFIO external interrupt port value */
} gpio_dev;
extern gpio_dev gpioa;
extern gpio_dev* const GPIOA;
extern gpio_dev gpiob;
extern gpio_dev* const GPIOB;
extern gpio_dev gpioc;
extern gpio_dev* const GPIOC;
extern gpio_dev gpiod;
extern gpio_dev* const GPIOD;
#ifdef STM32_HIGH_DENSITY
extern gpio_dev gpioe;
extern gpio_dev* const GPIOE;
extern gpio_dev gpiof;
extern gpio_dev* const GPIOF;
extern gpio_dev gpiog;
extern gpio_dev* const GPIOG;
#endif
/** GPIO port register map base pointer */
#define GPIOA_BASE ((struct gpio_reg_map*)0x40020000)
#define GPIOB_BASE ((struct gpio_reg_map*)0x40020400)
#define GPIOC_BASE ((struct gpio_reg_map*)0x40020800)
#define GPIOD_BASE ((struct gpio_reg_map*)0x40020C00)
#ifdef STM32_HIGH_DENSITY
#define GPIOE_BASE ((struct gpio_reg_map*)0x40021000)
#define GPIOF_BASE ((struct gpio_reg_map*)0x40021400)
#define GPIOG_BASE ((struct gpio_reg_map*)0x40021800)
#endif
/*
* GPIO register bit definitions
*/
#define GPIO_MODE_INPUT 0
#define GPIO_MODE_OUTPUT 1
#define GPIO_MODE_AF 2
#define GPIO_MODE_ANALOG 3
#define GPIO_PUPD_INPUT_FLOATING (0 << 2)
#define GPIO_PUPD_INPUT_PU (1 << 2)
#define GPIO_PUPD_INPUT_PD (2 << 2)
#define GPIO_OSPEED_2MHZ (0 << 4)
#define GPIO_OSPEED_25MHZ (1 << 4)
#define GPIO_OSPEED_50MHZ (2 << 4)
#define GPIO_OSPEED_100MHZ (3 << 4)
#define GPIO_OTYPE_PP (0 << 6)
#define GPIO_OTYPE_OD (1 << 6)
/*
MODER
00: Input (reset state)
01: General purpose output mode
10: Alternate function mode
11: Analog mode
OTYPER
0: Output push-pull (reset state)
1: Output open-drain
OSPEEDR
00: 2 MHz Low speed
01: 25 MHz Medium speed
10: 50 MHz Fast speed
11: 100 MHz High speed on 30 pF (80 MHz Output max speed on 15 pF)
PUPDR
00: No pull-up, pull-down
01: Pull-up
10: Pull-down
AFRL 4 bit AF00-AF15
AFRH 4 bit AF00-AF15
*/
/**
* @brief GPIO Pin modes.
*
* These only allow for 50MHZ max output speeds; if you want slower,
* use direct register access.
*/
typedef enum gpio_pin_mode {
GPIO_OUTPUT_PP = (GPIO_MODE_OUTPUT | GPIO_OTYPE_PP |
GPIO_OSPEED_50MHZ), /**< Output push-pull. */
GPIO_OUTPUT_OD = (GPIO_MODE_OUTPUT | GPIO_OTYPE_OD |
GPIO_OSPEED_50MHZ), /**< Output open-drain. */
GPIO_AF_OUTPUT_PP = (GPIO_MODE_AF | GPIO_OTYPE_PP |
GPIO_OSPEED_50MHZ), /**< Alternate function
output push-pull. */
GPIO_AF_OUTPUT_OD = (GPIO_MODE_AF | GPIO_OTYPE_OD |
GPIO_OSPEED_50MHZ), /**< Alternate function
output open drain. */
GPIO_INPUT_ANALOG = (GPIO_MODE_ANALOG), /**< Analog input. */
GPIO_INPUT_FLOATING = (GPIO_MODE_INPUT |
GPIO_PUPD_INPUT_FLOATING), /**< Input floating. */
GPIO_INPUT_PD = (GPIO_MODE_INPUT |
GPIO_PUPD_INPUT_PD), /**< Input pull-down. */
GPIO_INPUT_PU = (GPIO_MODE_INPUT |
GPIO_PUPD_INPUT_PU), /**< Input pull-up. */
GPIO_AF_INPUT_PD = (GPIO_MODE_AF |
GPIO_PUPD_INPUT_PD), /**< Input pull-down. */
GPIO_BIGNUMBER = 0xfff
} gpio_pin_mode;
/*
* GPIO Convenience routines
*/
void gpio_init(gpio_dev *dev);
void gpio_init_all(void);
void gpio_set_mode(gpio_dev *dev, uint8 pin, gpio_pin_mode mode);
void gpio_set_af_mode(gpio_dev *dev, uint8 pin, int mode);
/**
* @brief Get a GPIO port's corresponding afio_exti_port.
* @param dev GPIO device whose afio_exti_port to return.
*/
static inline afio_exti_port gpio_exti_port(gpio_dev *dev) {
return dev->exti_port;
}
/**
* 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) {
if (val) {
dev->regs->BSRRL = BIT(pin);
} else {
dev->regs->BSRRH = BIT(pin);
}
}
/**
* 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 & BIT(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 ^ BIT(pin);
}
/*
* AFIO register map
*/
/** AFIO register map */
typedef struct syscfg_reg_map {
__io uint32 MEMRM; /**< memory remap register */
__io uint32 PMC; /**< peripheral mode configuration register */
__io uint32 EXTICR1; /**< External interrupt configuration register 1. */
__io uint32 EXTICR2; /**< External interrupt configuration register 2. */
__io uint32 EXTICR3; /**< External interrupt configuration register 3. */
__io uint32 EXTICR4; /**< External interrupt configuration register 4. */
__io uint32 CMPCR; /**< Compensation cell control register */
} syscfg_reg_map;
/** AFIO register map base pointer. */
#define SYSCFG_BASE ((struct syscfg_reg_map *)0x40013800)
/*
* AFIO register bit definitions
*/
/* Event control register */
#define AFIO_EVCR_EVOE (0x1 << 7)
#define AFIO_EVCR_PORT_PA (0x0 << 4)
#define AFIO_EVCR_PORT_PB (0x1 << 4)
#define AFIO_EVCR_PORT_PC (0x2 << 4)
#define AFIO_EVCR_PORT_PD (0x3 << 4)
#define AFIO_EVCR_PORT_PE (0x4 << 4)
#define AFIO_EVCR_PIN_0 0x0
#define AFIO_EVCR_PIN_1 0x1
#define AFIO_EVCR_PIN_2 0x2
#define AFIO_EVCR_PIN_3 0x3
#define AFIO_EVCR_PIN_4 0x4
#define AFIO_EVCR_PIN_5 0x5
#define AFIO_EVCR_PIN_6 0x6
#define AFIO_EVCR_PIN_7 0x7
#define AFIO_EVCR_PIN_8 0x8
#define AFIO_EVCR_PIN_9 0x9
#define AFIO_EVCR_PIN_10 0xA
#define AFIO_EVCR_PIN_11 0xB
#define AFIO_EVCR_PIN_12 0xC
#define AFIO_EVCR_PIN_13 0xD
#define AFIO_EVCR_PIN_14 0xE
#define AFIO_EVCR_PIN_15 0xF
/* AF remap and debug I/O configuration register */
#define AFIO_MAPR_SWJ_CFG (0x7 << 24)
#define AFIO_MAPR_SWJ_CFG_FULL_SWJ (0x0 << 24)
#define AFIO_MAPR_SWJ_CFG_FULL_SWJ_NO_NJRST (0x1 << 24)
#define AFIO_MAPR_SWJ_CFG_NO_JTAG_SW (0x2 << 24)
#define AFIO_MAPR_SWJ_CFG_NO_JTAG_NO_SW (0x4 << 24)
#define AFIO_MAPR_ADC2_ETRGREG_REMAP BIT(20)
#define AFIO_MAPR_ADC2_ETRGINJ_REMAP BIT(19)
#define AFIO_MAPR_ADC1_ETRGREG_REMAP BIT(18)
#define AFIO_MAPR_ADC1_ETRGINJ_REMAP BIT(17)
#define AFIO_MAPR_TIM5CH4_IREMAP BIT(16)
#define AFIO_MAPR_PD01_REMAP BIT(15)
#define AFIO_MAPR_CAN_REMAP (0x3 << 13)
#define AFIO_MAPR_CAN_REMAP_NONE (0x0 << 13)
#define AFIO_MAPR_CAN_REMAP_PB8_PB9 (0x2 << 13)
#define AFIO_MAPR_CAN_REMAP_PD0_PD1 (0x3 << 13)
#define AFIO_MAPR_TIM4_REMAP BIT(12)
#define AFIO_MAPR_TIM3_REMAP (0x3 << 10)
#define AFIO_MAPR_TIM3_REMAP_NONE (0x0 << 10)
#define AFIO_MAPR_TIM3_REMAP_PARTIAL (0x2 << 10)
#define AFIO_MAPR_TIM3_REMAP_FULL (0x3 << 10)
#define AFIO_MAPR_TIM2_REMAP (0x3 << 8)
#define AFIO_MAPR_TIM2_REMAP_NONE (0x0 << 8)
#define AFIO_MAPR_TIM2_REMAP_PA15_PB3_PA2_PA3 (0x1 << 8)
#define AFIO_MAPR_TIM2_REMAP_PA0_PA1_PB10_PB11 (0x2 << 8)
#define AFIO_MAPR_TIM2_REMAP_FULL (0x3 << 8)
#define AFIO_MAPR_TIM1_REMAP (0x3 << 6)
#define AFIO_MAPR_TIM1_REMAP_NONE (0x0 << 6)
#define AFIO_MAPR_TIM1_REMAP_PARTIAL (0x1 << 6)
#define AFIO_MAPR_TIM1_REMAP_FULL (0x3 << 6)
#define AFIO_MAPR_USART3_REMAP (0x3 << 4)
#define AFIO_MAPR_USART3_REMAP_NONE (0x0 << 4)
#define AFIO_MAPR_USART3_REMAP_PARTIAL (0x1 << 4)
#define AFIO_MAPR_USART3_REMAP_FULL (0x3 << 4)
#define AFIO_MAPR_USART2_REMAP BIT(3)
#define AFIO_MAPR_USART1_REMAP BIT(2)
#define AFIO_MAPR_I2C1_REMAP BIT(1)
#define AFIO_MAPR_SPI1_REMAP BIT(0)
/* External interrupt configuration register 1 */
#define AFIO_EXTICR1_EXTI3 (0xF << 12)
#define AFIO_EXTICR1_EXTI3_PA (0x0 << 12)
#define AFIO_EXTICR1_EXTI3_PB (0x1 << 12)
#define AFIO_EXTICR1_EXTI3_PC (0x2 << 12)
#define AFIO_EXTICR1_EXTI3_PD (0x3 << 12)
#define AFIO_EXTICR1_EXTI3_PE (0x4 << 12)
#define AFIO_EXTICR1_EXTI3_PF (0x5 << 12)
#define AFIO_EXTICR1_EXTI3_PG (0x6 << 12)
#define AFIO_EXTICR1_EXTI2 (0xF << 8)
#define AFIO_EXTICR1_EXTI2_PA (0x0 << 8)
#define AFIO_EXTICR1_EXTI2_PB (0x1 << 8)
#define AFIO_EXTICR1_EXTI2_PC (0x2 << 8)
#define AFIO_EXTICR1_EXTI2_PD (0x3 << 8)
#define AFIO_EXTICR1_EXTI2_PE (0x4 << 8)
#define AFIO_EXTICR1_EXTI2_PF (0x5 << 8)
#define AFIO_EXTICR1_EXTI2_PG (0x6 << 8)
#define AFIO_EXTICR1_EXTI1 (0xF << 4)
#define AFIO_EXTICR1_EXTI1_PA (0x0 << 4)
#define AFIO_EXTICR1_EXTI1_PB (0x1 << 4)
#define AFIO_EXTICR1_EXTI1_PC (0x2 << 4)
#define AFIO_EXTICR1_EXTI1_PD (0x3 << 4)
#define AFIO_EXTICR1_EXTI1_PE (0x4 << 4)
#define AFIO_EXTICR1_EXTI1_PF (0x5 << 4)
#define AFIO_EXTICR1_EXTI1_PG (0x6 << 4)
#define AFIO_EXTICR1_EXTI0 0xF
#define AFIO_EXTICR1_EXTI0_PA 0x0
#define AFIO_EXTICR1_EXTI0_PB 0x1
#define AFIO_EXTICR1_EXTI0_PC 0x2
#define AFIO_EXTICR1_EXTI0_PD 0x3
#define AFIO_EXTICR1_EXTI0_PE 0x4
#define AFIO_EXTICR1_EXTI0_PF 0x5
#define AFIO_EXTICR1_EXTI0_PG 0x6
/* External interrupt configuration register 2 */
#define AFIO_EXTICR2_EXTI7 (0xF << 12)
#define AFIO_EXTICR2_EXTI7_PA (0x0 << 12)
#define AFIO_EXTICR2_EXTI7_PB (0x1 << 12)
#define AFIO_EXTICR2_EXTI7_PC (0x2 << 12)
#define AFIO_EXTICR2_EXTI7_PD (0x3 << 12)
#define AFIO_EXTICR2_EXTI7_PE (0x4 << 12)
#define AFIO_EXTICR2_EXTI7_PF (0x5 << 12)
#define AFIO_EXTICR2_EXTI7_PG (0x6 << 12)
#define AFIO_EXTICR2_EXTI6 (0xF << 8)
#define AFIO_EXTICR2_EXTI6_PA (0x0 << 8)
#define AFIO_EXTICR2_EXTI6_PB (0x1 << 8)
#define AFIO_EXTICR2_EXTI6_PC (0x2 << 8)
#define AFIO_EXTICR2_EXTI6_PD (0x3 << 8)
#define AFIO_EXTICR2_EXTI6_PE (0x4 << 8)
#define AFIO_EXTICR2_EXTI6_PF (0x5 << 8)
#define AFIO_EXTICR2_EXTI6_PG (0x6 << 8)
#define AFIO_EXTICR2_EXTI5 (0xF << 4)
#define AFIO_EXTICR2_EXTI5_PA (0x0 << 4)
#define AFIO_EXTICR2_EXTI5_PB (0x1 << 4)
#define AFIO_EXTICR2_EXTI5_PC (0x2 << 4)
#define AFIO_EXTICR2_EXTI5_PD (0x3 << 4)
#define AFIO_EXTICR2_EXTI5_PE (0x4 << 4)
#define AFIO_EXTICR2_EXTI5_PF (0x5 << 4)
#define AFIO_EXTICR2_EXTI5_PG (0x6 << 4)
#define AFIO_EXTICR2_EXTI4 0xF
#define AFIO_EXTICR2_EXTI4_PA 0x0
#define AFIO_EXTICR2_EXTI4_PB 0x1
#define AFIO_EXTICR2_EXTI4_PC 0x2
#define AFIO_EXTICR2_EXTI4_PD 0x3
#define AFIO_EXTICR2_EXTI4_PE 0x4
#define AFIO_EXTICR2_EXTI4_PF 0x5
#define AFIO_EXTICR2_EXTI4_PG 0x6
/* AF remap and debug I/O configuration register 2 */
#define AFIO_MAPR2_FSMC_NADV BIT(10)
#define AFIO_MAPR2_TIM14_REMAP BIT(9)
#define AFIO_MAPR2_TIM13_REMAP BIT(8)
#define AFIO_MAPR2_TIM11_REMAP BIT(7)
#define AFIO_MAPR2_TIM10_REMAP BIT(6)
#define AFIO_MAPR2_TIM9_REMAP BIT(5)
/*
* AFIO convenience routines
*/
void afio_init(void);
/**
* External interrupt line numbers.
*/
typedef enum afio_exti_num {
AFIO_EXTI_0, /**< External interrupt line 0. */
AFIO_EXTI_1, /**< External interrupt line 1. */
AFIO_EXTI_2, /**< External interrupt line 2. */
AFIO_EXTI_3, /**< External interrupt line 3. */
AFIO_EXTI_4, /**< External interrupt line 4. */
AFIO_EXTI_5, /**< External interrupt line 5. */
AFIO_EXTI_6, /**< External interrupt line 6. */
AFIO_EXTI_7, /**< External interrupt line 7. */
AFIO_EXTI_8, /**< External interrupt line 8. */
AFIO_EXTI_9, /**< External interrupt line 9. */
AFIO_EXTI_10, /**< External interrupt line 10. */
AFIO_EXTI_11, /**< External interrupt line 11. */
AFIO_EXTI_12, /**< External interrupt line 12. */
AFIO_EXTI_13, /**< External interrupt line 13. */
AFIO_EXTI_14, /**< External interrupt line 14. */
AFIO_EXTI_15, /**< External interrupt line 15. */
} afio_exti_num;
void afio_exti_select(afio_exti_num exti, afio_exti_port gpio_port);
/* HACK: Use upper bit to denote MAPR2, Bit 31 is reserved and
* not used in either MAPR or MAPR2 */
#define AFIO_REMAP_USE_MAPR2 (1 << 31)
/**
* @brief Available peripheral remaps.
* @see afio_remap()
*/
typedef enum afio_remap_peripheral {
AFIO_REMAP_ADC2_ETRGREG = AFIO_MAPR_ADC2_ETRGREG_REMAP, /**<
ADC 2 external trigger regular conversion remapping */
AFIO_REMAP_ADC2_ETRGINJ = AFIO_MAPR_ADC2_ETRGINJ_REMAP, /**<
ADC 2 external trigger injected conversion remapping */
AFIO_REMAP_ADC1_ETRGREG = AFIO_MAPR_ADC1_ETRGREG_REMAP, /**<
ADC 1 external trigger regular conversion remapping */
AFIO_REMAP_ADC1_ETRGINJ = AFIO_MAPR_ADC1_ETRGINJ_REMAP, /**<
ADC 1 external trigger injected conversion remapping */
AFIO_REMAP_TIM5CH4_I = AFIO_MAPR_TIM5CH4_IREMAP, /**<
Timer 5 channel 4 internal remapping */
AFIO_REMAP_PD01 = AFIO_MAPR_PD01_REMAP, /**<
Port D0/Port D1 mapping on OSC_IN/OSC_OUT */
AFIO_REMAP_CAN_1 = AFIO_MAPR_CAN_REMAP_PB8_PB9, /**<
CAN alternate function remapping 1 (RX on PB8, TX on PB9) */
AFIO_REMAP_CAN_2 = AFIO_MAPR_CAN_REMAP_PD0_PD1, /**<
CAN alternate function remapping 2 (RX on PD0, TX on PD1) */
AFIO_REMAP_TIM4 = AFIO_MAPR_TIM4_REMAP, /**<
Timer 4 remapping */
AFIO_REMAP_TIM3_PARTIAL = AFIO_MAPR_TIM3_REMAP_PARTIAL, /**<
Timer 3 partial remapping */
AFIO_REMAP_TIM3_FULL = AFIO_MAPR_TIM3_REMAP_FULL, /**<
Timer 3 full remapping */
AFIO_REMAP_TIM2_PARTIAL_1 = AFIO_MAPR_TIM2_REMAP_PA15_PB3_PA2_PA3, /**<
Timer 2 partial remapping 1 (CH1 and ETR on PA15, CH2 on PB3, CH3
on PA2, CH4 on PA3) */
AFIO_REMAP_TIM2_PARTIAL_2 = AFIO_MAPR_TIM2_REMAP_PA0_PA1_PB10_PB11, /**<
Timer 2 partial remapping 2 (CH1 and ETR on PA0, CH2 on PA1, CH3
on PB10, CH4 on PB11) */
AFIO_REMAP_TIM2_FULL = AFIO_MAPR_TIM2_REMAP_FULL, /**<
Timer 2 full remapping */
AFIO_REMAP_USART2 = AFIO_MAPR_USART2_REMAP, /**<
USART 2 remapping */
AFIO_REMAP_USART1 = AFIO_MAPR_USART1_REMAP, /**<
USART 1 remapping */
AFIO_REMAP_I2C1 = AFIO_MAPR_I2C1_REMAP, /**<
I2C 1 remapping */
AFIO_REMAP_SPI1 = AFIO_MAPR_SPI1_REMAP, /**<
SPI 1 remapping */
AFIO_REMAP_FSMC_NADV = (AFIO_MAPR2_FSMC_NADV |
AFIO_REMAP_USE_MAPR2), /**<
NADV signal not connected */
AFIO_REMAP_TIM14 = (AFIO_MAPR2_TIM14_REMAP |
AFIO_REMAP_USE_MAPR2), /**<
Timer 14 remapping */
AFIO_REMAP_TIM13 = (AFIO_MAPR2_TIM13_REMAP |
AFIO_REMAP_USE_MAPR2), /**<
Timer 13 remapping */
AFIO_REMAP_TIM11 = (AFIO_MAPR2_TIM11_REMAP |
AFIO_REMAP_USE_MAPR2), /**<
Timer 11 remapping */
AFIO_REMAP_TIM10 = (AFIO_MAPR2_TIM10_REMAP |
AFIO_REMAP_USE_MAPR2), /**<
Timer 10 remapping */
AFIO_REMAP_TIM9 = (AFIO_MAPR2_TIM9_REMAP |
AFIO_REMAP_USE_MAPR2) /**<
Timer 9 */
} afio_remap_peripheral;
void afio_remap(afio_remap_peripheral p);
/**
* @brief Debug port configuration
*
* Used to configure the behavior of JTAG and Serial Wire (SW) debug
* ports and their associated GPIO pins.
*
* @see afio_cfg_debug_ports()
*/
typedef enum afio_debug_cfg {
AFIO_DEBUG_FULL_SWJ = AFIO_MAPR_SWJ_CFG_FULL_SWJ, /**<
Full Serial Wire and JTAG debug */
AFIO_DEBUG_FULL_SWJ_NO_NJRST = AFIO_MAPR_SWJ_CFG_FULL_SWJ_NO_NJRST, /**<
Full Serial Wire and JTAG, but no NJTRST. */
AFIO_DEBUG_SW_ONLY = AFIO_MAPR_SWJ_CFG_NO_JTAG_SW, /**<
Serial Wire debug only (JTAG-DP disabled,
SW-DP enabled) */
AFIO_DEBUG_NONE = AFIO_MAPR_SWJ_CFG_NO_JTAG_NO_SW /**<
No debug; all JTAG and SW pins are free
for use as GPIOs. */
} afio_debug_cfg;
/**
* @brief Enable or disable the JTAG and SW debug ports.
* @param config Desired debug port configuration
* @see afio_debug_cfg
*/
static inline void afio_cfg_debug_ports(afio_debug_cfg config) {
//__io uint32 *mapr = &AFIO_BASE->MAPR;
//*mapr = (*mapr & ~AFIO_MAPR_SWJ_CFG) | config;
}
#ifdef __cplusplus
}
#endif
#endif

View File

@ -1,37 +0,0 @@
/******************************************************************************
* 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 rcc.c
* @brief Implements pretty much only the basic clock setup on the
* stm32, clock enable/disable and peripheral reset commands.
*/
// #ifdef STM32F2
// #include "rccF2.c"
// #else
// #include "rccF1.c"
// #endif

View File

@ -1,233 +0,0 @@
/******************************************************************************
* 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.
*****************************************************************************/
#ifdef STM32F1
/**
* @file rcc.c
* @brief Implements pretty much only the basic clock setup on the
* stm32, clock enable/disable and peripheral reset commands.
*/
#include "libmaple.h"
#include "flash.h"
#include "rcc.h"
#include "bitband.h"
#define APB1 RCC_APB1
#define APB2 RCC_APB2
#define AHB RCC_AHB
struct rcc_dev_info {
const rcc_clk_domain clk_domain;
const uint8 line_num;
};
/* Device descriptor table, maps rcc_clk_id onto bus and enable/reset
* register bit numbers. */
static const struct rcc_dev_info rcc_dev_table[] = {
[RCC_GPIOA] = { .clk_domain = APB2, .line_num = 2 },
[RCC_GPIOB] = { .clk_domain = APB2, .line_num = 3 },
[RCC_GPIOC] = { .clk_domain = APB2, .line_num = 4 },
[RCC_GPIOD] = { .clk_domain = APB2, .line_num = 5 },
[RCC_AFIO] = { .clk_domain = APB2, .line_num = 0 },
[RCC_ADC1] = { .clk_domain = APB2, .line_num = 9 },
[RCC_ADC2] = { .clk_domain = APB2, .line_num = 10 },
[RCC_ADC3] = { .clk_domain = APB2, .line_num = 15 },
[RCC_USART1] = { .clk_domain = APB2, .line_num = 14 },
[RCC_USART2] = { .clk_domain = APB1, .line_num = 17 },
[RCC_USART3] = { .clk_domain = APB1, .line_num = 18 },
[RCC_TIMER1] = { .clk_domain = APB2, .line_num = 11 },
[RCC_TIMER2] = { .clk_domain = APB1, .line_num = 0 },
[RCC_TIMER3] = { .clk_domain = APB1, .line_num = 1 },
[RCC_TIMER4] = { .clk_domain = APB1, .line_num = 2 },
[RCC_SPI1] = { .clk_domain = APB2, .line_num = 12 },
[RCC_SPI2] = { .clk_domain = APB1, .line_num = 14 },
[RCC_DMA1] = { .clk_domain = AHB, .line_num = 0 },
[RCC_PWR] = { .clk_domain = APB1, .line_num = 28},
[RCC_BKP] = { .clk_domain = APB1, .line_num = 27},
[RCC_I2C1] = { .clk_domain = APB1, .line_num = 21 },
[RCC_I2C2] = { .clk_domain = APB1, .line_num = 22 },
[RCC_CRC] = { .clk_domain = AHB, .line_num = 6},
[RCC_FLITF] = { .clk_domain = AHB, .line_num = 4},
[RCC_SRAM] = { .clk_domain = AHB, .line_num = 2},
#if defined(STM32_HIGH_DENSITY) || defined(STM32_XL_DENSITY)
[RCC_GPIOE] = { .clk_domain = APB2, .line_num = 6 },
[RCC_GPIOF] = { .clk_domain = APB2, .line_num = 7 },
[RCC_GPIOG] = { .clk_domain = APB2, .line_num = 8 },
[RCC_UART4] = { .clk_domain = APB1, .line_num = 19 },
[RCC_UART5] = { .clk_domain = APB1, .line_num = 20 },
[RCC_TIMER5] = { .clk_domain = APB1, .line_num = 3 },
[RCC_TIMER6] = { .clk_domain = APB1, .line_num = 4 },
[RCC_TIMER7] = { .clk_domain = APB1, .line_num = 5 },
[RCC_TIMER8] = { .clk_domain = APB2, .line_num = 13 },
[RCC_FSMC] = { .clk_domain = AHB, .line_num = 8 },
[RCC_DAC] = { .clk_domain = APB1, .line_num = 29 },
[RCC_DMA2] = { .clk_domain = AHB, .line_num = 1 },
[RCC_SDIO] = { .clk_domain = AHB, .line_num = 10 },
[RCC_SPI3] = { .clk_domain = APB1, .line_num = 15 },
#endif
#ifdef STM32_XL_DENSITY
[RCC_TIMER9] = { .clk_domain = APB2, .line_num = 19 },
[RCC_TIMER10] = { .clk_domain = APB2, .line_num = 20 },
[RCC_TIMER11] = { .clk_domain = APB2, .line_num = 21 },
[RCC_TIMER12] = { .clk_domain = APB1, .line_num = 6 },
[RCC_TIMER13] = { .clk_domain = APB1, .line_num = 7 },
[RCC_TIMER14] = { .clk_domain = APB1, .line_num = 8 },
#endif
};
/**
* @brief Initialize the clock control system. Initializes the system
* clock source to use the PLL driven by an external oscillator
* @param sysclk_src system clock source, must be PLL
* @param pll_src pll clock source, must be HSE
* @param pll_mul pll multiplier
*/
void rcc_clk_init(rcc_sysclk_src sysclk_src,
rcc_pllsrc pll_src,
rcc_pll_multiplier pll_mul) {
uint32 cfgr = 0;
uint32 cr;
/* Assume that we're going to clock the chip off the PLL, fed by
* the HSE */
ASSERT(sysclk_src == RCC_CLKSRC_PLL &&
pll_src == RCC_PLLSRC_HSE);
RCC_BASE->CFGR = pll_src | pll_mul;
/* Turn on the HSE */
cr = RCC_BASE->CR;
cr |= RCC_CR_HSEON;
RCC_BASE->CR = cr;
while (!(RCC_BASE->CR & RCC_CR_HSERDY))
;
/* Now the PLL */
cr |= RCC_CR_PLLON;
RCC_BASE->CR = cr;
while (!(RCC_BASE->CR & RCC_CR_PLLRDY))
;
/* Finally, let's switch over to the PLL */
cfgr &= ~RCC_CFGR_SW;
cfgr |= RCC_CFGR_SW_PLL;
RCC_BASE->CFGR = cfgr;
while ((RCC_BASE->CFGR & RCC_CFGR_SWS) != RCC_CFGR_SWS_PLL)
;
}
/**
* @brief Turn on the clock line on a peripheral
* @param id Clock ID of the peripheral to turn on.
*/
void rcc_clk_enable(rcc_clk_id id) {
static const __io uint32* enable_regs[] = {
[APB1] = &RCC_BASE->APB1ENR,
[APB2] = &RCC_BASE->APB2ENR,
[AHB] = &RCC_BASE->AHBENR,
};
rcc_clk_domain clk_domain = rcc_dev_clk(id);
__io uint32* enr = (__io uint32*)enable_regs[clk_domain];
uint8 lnum = rcc_dev_table[id].line_num;
bb_peri_set_bit(enr, lnum, 1);
}
/**
* @brief Reset a peripheral.
* @param id Clock ID of the peripheral to reset.
*/
void rcc_reset_dev(rcc_clk_id id) {
static const __io uint32* reset_regs[] = {
[APB1] = &RCC_BASE->APB1RSTR,
[APB2] = &RCC_BASE->APB2RSTR,
};
rcc_clk_domain clk_domain = rcc_dev_clk(id);
__io void* addr = (__io void*)reset_regs[clk_domain];
uint8 lnum = rcc_dev_table[id].line_num;
bb_peri_set_bit(addr, lnum, 1);
bb_peri_set_bit(addr, lnum, 0);
}
/**
* @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 Get a peripheral's clock domain speed
* @param id Clock ID of the peripheral whose clock domain speed to return
* @return Clock speed for the given clock ID
*/
uint32 rcc_dev_clk_speed(rcc_clk_id id) {
static const uint32 rcc_dev_clk_speed_table[] = {
[RCC_AHB] = 72000000,
[RCC_APB1] = 36000000,
[RCC_APB2] = 72000000
};
return rcc_dev_clk_speed_table[rcc_dev_clk(id)];
}
/**
* @brief Get a peripheral's timer clock domain speed
* @param id Clock ID of the peripheral whose clock domain speed to return
* @return Clock speed for the given clock ID
*/
uint32 rcc_dev_timer_clk_speed(rcc_clk_id id) {
return rcc_dev_clk_speed(RCC_APB2); // 72 MHz for all counter
}
/**
* @brief Set the divider on a peripheral prescaler
* @param prescaler prescaler to set
* @param divider prescaler divider
*/
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_PRESCALER_ADC] = RCC_CFGR_ADCPRE,
};
uint32 cfgr = RCC_BASE->CFGR;
cfgr &= ~masks[prescaler];
cfgr |= divider;
RCC_BASE->CFGR = cfgr;
}
#endif

View File

@ -1,572 +0,0 @@
/******************************************************************************
* 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 rcc.h
* @brief reset and clock control definitions and prototypes
*/
#include "libmaple_types.h"
#ifndef _RCC_H_
#define _RCC_H_
#ifdef __cplusplus
extern "C"{
#endif
/** RCC register map type */
typedef struct rcc_reg_map {
__io uint32 CR; /**< Clock control register */
__io uint32 CFGR; /**< Clock configuration register */
__io uint32 CIR; /**< Clock interrupt register */
__io uint32 APB2RSTR; /**< APB2 peripheral reset register */
__io uint32 APB1RSTR; /**< APB1 peripheral reset register */
__io uint32 AHBENR; /**< AHB peripheral clock enable register */
__io uint32 APB2ENR; /**< APB2 peripheral clock enable register */
__io uint32 APB1ENR; /**< APB1 peripheral clock enable register */
__io uint32 BDCR; /**< Backup domain control register */
__io uint32 CSR; /**< Control/status register */
} rcc_reg_map;
/** RCC register map base pointer */
#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 BIT(RCC_CR_PLLRDY_BIT)
#define RCC_CR_PLLON BIT(RCC_CR_PLLON_BIT)
#define RCC_CR_CSSON BIT(RCC_CR_CSSON_BIT)
#define RCC_CR_HSEBYP BIT(RCC_CR_HSEBYP_BIT)
#define RCC_CR_HSERDY BIT(RCC_CR_HSERDY_BIT)
#define RCC_CR_HSEON BIT(RCC_CR_HSEON_BIT)
#define RCC_CR_HSICAL (0xFF << 8)
#define RCC_CR_HSITRIM (0x1F << 3)
#define RCC_CR_HSIRDY BIT(RCC_CR_HSIRDY_BIT)
#define RCC_CR_HSION BIT(RCC_CR_HSION_BIT)
/* Clock configuration register */
#define RCC_CFGR_USBPRE_BIT 22
#define RCC_CFGR_PLLXTPRE_BIT 17
#define RCC_CFGR_PLLSRC_BIT 16
#define RCC_CFGR_MCO (0x3 << 24)
#define RCC_CFGR_USBPRE BIT(RCC_CFGR_USBPRE_BIT)
#define RCC_CFGR_PLLMUL (0xF << 18)
#define RCC_CFGR_PLLXTPRE BIT(RCC_CFGR_PLLXTPRE_BIT)
#define RCC_CFGR_PLLSRC BIT(RCC_CFGR_PLLSRC_BIT)
#define RCC_CFGR_ADCPRE (0x3 << 14)
#define RCC_CFGR_PPRE2 (0x7 << 11)
#define RCC_CFGR_PPRE1 (0x7 << 8)
#define RCC_CFGR_HPRE (0xF << 4)
#define RCC_CFGR_SWS (0x3 << 2)
#define RCC_CFGR_SWS_PLL (0x2 << 2)
#define RCC_CFGR_SWS_HSE (0x1 << 2)
#define RCC_CFGR_SW 0x3
#define RCC_CFGR_SW_PLL 0x2
#define RCC_CFGR_SW_HSE 0x1
/* Clock interrupt register */
#define RCC_CIR_CSSC_BIT 23
#define RCC_CIR_PLLRDYC_BIT 20
#define RCC_CIR_HSERDYC_BIT 19
#define RCC_CIR_HSIRDYC_BIT 18
#define RCC_CIR_LSERDYC_BIT 17
#define RCC_CIR_LSIRDYC_BIT 16
#define RCC_CIR_PLLRDYIE_BIT 12
#define RCC_CIR_HSERDYIE_BIT 11
#define RCC_CIR_HSIRDYIE_BIT 10
#define RCC_CIR_LSERDYIE_BIT 9
#define RCC_CIR_LSIRDYIE_BIT 8
#define RCC_CIR_CSSF_BIT 7
#define RCC_CIR_PLLRDYF_BIT 4
#define RCC_CIR_HSERDYF_BIT 3
#define RCC_CIR_HSIRDYF_BIT 2
#define RCC_CIR_LSERDYF_BIT 1
#define RCC_CIR_LSIRDYF_BIT 0
#define RCC_CIR_CSSC BIT(RCC_CIR_CSSC_BIT)
#define RCC_CIR_PLLRDYC BIT(RCC_CIR_PLLRDYC_BIT)
#define RCC_CIR_HSERDYC BIT(RCC_CIR_HSERDYC_BIT)
#define RCC_CIR_HSIRDYC BIT(RCC_CIR_HSIRDYC_BIT)
#define RCC_CIR_LSERDYC BIT(RCC_CIR_LSERDYC_BIT)
#define RCC_CIR_LSIRDYC BIT(RCC_CIR_LSIRDYC_BIT)
#define RCC_CIR_PLLRDYIE BIT(RCC_CIR_PLLRDYIE_BIT)
#define RCC_CIR_HSERDYIE BIT(RCC_CIR_HSERDYIE_BIT)
#define RCC_CIR_HSIRDYIE BIT(RCC_CIR_HSIRDYIE_BIT)
#define RCC_CIR_LSERDYIE BIT(RCC_CIR_LSERDYIE_BIT)
#define RCC_CIR_LSIRDYIE BIT(RCC_CIR_LSIRDYIE_BIT)
#define RCC_CIR_CSSF BIT(RCC_CIR_CSSF_BIT)
#define RCC_CIR_PLLRDYF BIT(RCC_CIR_PLLRDYF_BIT)
#define RCC_CIR_HSERDYF BIT(RCC_CIR_HSERDYF_BIT)
#define RCC_CIR_HSIRDYF BIT(RCC_CIR_HSIRDYF_BIT)
#define RCC_CIR_LSERDYF BIT(RCC_CIR_LSERDYF_BIT)
#define RCC_CIR_LSIRDYF BIT(RCC_CIR_LSIRDYF_BIT)
/* APB2 peripheral reset register */
#define RCC_APB2RSTR_TIM11RST_BIT 21
#define RCC_APB2RSTR_TIM10RST_BIT 20
#define RCC_APB2RSTR_TIM9RST_BIT 19
#define RCC_APB2RSTR_ADC3RST_BIT 15
#define RCC_APB2RSTR_USART1RST_BIT 14
#define RCC_APB2RSTR_TIM8RST_BIT 13
#define RCC_APB2RSTR_SPI1RST_BIT 12
#define RCC_APB2RSTR_TIM1RST_BIT 11
#define RCC_APB2RSTR_ADC2RST_BIT 10
#define RCC_APB2RSTR_ADC1RST_BIT 9
#define RCC_APB2RSTR_IOPGRST_BIT 8
#define RCC_APB2RSTR_IOPFRST_BIT 7
#define RCC_APB2RSTR_IOPERST_BIT 6
#define RCC_APB2RSTR_IOPDRST_BIT 5
#define RCC_APB2RSTR_IOPCRST_BIT 4
#define RCC_APB2RSTR_IOPBRST_BIT 3
#define RCC_APB2RSTR_IOPARST_BIT 2
#define RCC_APB2RSTR_AFIORST_BIT 0
#define RCC_APB2RSTR_TIM11RST BIT(RCC_APB2RSTR_TIM11RST_BIT)
#define RCC_APB2RSTR_TIM10RST BIT(RCC_APB2RSTR_TIM10RST_BIT)
#define RCC_APB2RSTR_TIM9RST BIT(RCC_APB2RSTR_TIM9RST_BIT)
#define RCC_APB2RSTR_ADC3RST BIT(RCC_APB2RSTR_ADC3RST_BIT)
#define RCC_APB2RSTR_USART1RST BIT(RCC_APB2RSTR_USART1RST_BIT)
#define RCC_APB2RSTR_TIM8RST BIT(RCC_APB2RSTR_TIM8RST_BIT)
#define RCC_APB2RSTR_SPI1RST BIT(RCC_APB2RSTR_SPI1RST_BIT)
#define RCC_APB2RSTR_TIM1RST BIT(RCC_APB2RSTR_TIM1RST_BIT)
#define RCC_APB2RSTR_ADC2RST BIT(RCC_APB2RSTR_ADC2RST_BIT)
#define RCC_APB2RSTR_ADC1RST BIT(RCC_APB2RSTR_ADC1RST_BIT)
#define RCC_APB2RSTR_IOPGRST BIT(RCC_APB2RSTR_IOPGRST_BIT)
#define RCC_APB2RSTR_IOPFRST BIT(RCC_APB2RSTR_IOPFRST_BIT)
#define RCC_APB2RSTR_IOPERST BIT(RCC_APB2RSTR_IOPERST_BIT)
#define RCC_APB2RSTR_IOPDRST BIT(RCC_APB2RSTR_IOPDRST_BIT)
#define RCC_APB2RSTR_IOPCRST BIT(RCC_APB2RSTR_IOPCRST_BIT)
#define RCC_APB2RSTR_IOPBRST BIT(RCC_APB2RSTR_IOPBRST_BIT)
#define RCC_APB2RSTR_IOPARST BIT(RCC_APB2RSTR_IOPARST_BIT)
#define RCC_APB2RSTR_AFIORST BIT(RCC_APB2RSTR_AFIORST_BIT)
/* APB1 peripheral reset register */
#define RCC_APB1RSTR_DACRST_BIT 29
#define RCC_APB1RSTR_PWRRST_BIT 28
#define RCC_APB1RSTR_BKPRST_BIT 27
#define RCC_APB1RSTR_CANRST_BIT 25
#define RCC_APB1RSTR_USBRST_BIT 23
#define RCC_APB1RSTR_I2C2RST_BIT 22
#define RCC_APB1RSTR_I2C1RST_BIT 21
#define RCC_APB1RSTR_UART5RST_BIT 20
#define RCC_APB1RSTR_UART4RST_BIT 19
#define RCC_APB1RSTR_USART3RST_BIT 18
#define RCC_APB1RSTR_USART2RST_BIT 17
#define RCC_APB1RSTR_SPI3RST_BIT 15
#define RCC_APB1RSTR_SPI2RST_BIT 14
#define RCC_APB1RSTR_WWDRST_BIT 11
#define RCC_APB1RSTR_TIM14RST_BIT 8
#define RCC_APB1RSTR_TIM13RST_BIT 7
#define RCC_APB1RSTR_TIM12RST_BIT 6
#define RCC_APB1RSTR_TIM7RST_BIT 5
#define RCC_APB1RSTR_TIM6RST_BIT 4
#define RCC_APB1RSTR_TIM5RST_BIT 3
#define RCC_APB1RSTR_TIM4RST_BIT 2
#define RCC_APB1RSTR_TIM3RST_BIT 1
#define RCC_APB1RSTR_TIM2RST_BIT 0
#define RCC_APB1RSTR_DACRST BIT(RCC_APB1RSTR_DACRST_BIT)
#define RCC_APB1RSTR_PWRRST BIT(RCC_APB1RSTR_PWRRST_BIT)
#define RCC_APB1RSTR_BKPRST BIT(RCC_APB1RSTR_BKPRST_BIT)
#define RCC_APB1RSTR_CANRST BIT(RCC_APB1RSTR_CANRST_BIT)
#define RCC_APB1RSTR_USBRST BIT(RCC_APB1RSTR_USBRST_BIT)
#define RCC_APB1RSTR_I2C2RST BIT(RCC_APB1RSTR_I2C2RST_BIT)
#define RCC_APB1RSTR_I2C1RST BIT(RCC_APB1RSTR_I2C1RST_BIT)
#define RCC_APB1RSTR_UART5RST BIT(RCC_APB1RSTR_UART5RST_BIT)
#define RCC_APB1RSTR_UART4RST BIT(RCC_APB1RSTR_UART4RST_BIT)
#define RCC_APB1RSTR_USART3RST BIT(RCC_APB1RSTR_USART3RST_BIT)
#define RCC_APB1RSTR_USART2RST BIT(RCC_APB1RSTR_USART2RST_BIT)
#define RCC_APB1RSTR_SPI3RST BIT(RCC_APB1RSTR_SPI3RST_BIT)
#define RCC_APB1RSTR_SPI2RST BIT(RCC_APB1RSTR_SPI2RST_BIT)
#define RCC_APB1RSTR_WWDRST BIT(RCC_APB1RSTR_WWDRST_BIT)
#define RCC_APB1RSTR_TIM14RST BIT(RCC_APB1RSTR_TIM14RST_BIT)
#define RCC_APB1RSTR_TIM13RST BIT(RCC_APB1RSTR_TIM13RST_BIT)
#define RCC_APB1RSTR_TIM12RST BIT(RCC_APB1RSTR_TIM12RST_BIT)
#define RCC_APB1RSTR_TIM7RST BIT(RCC_APB1RSTR_TIM7RST_BIT)
#define RCC_APB1RSTR_TIM6RST BIT(RCC_APB1RSTR_TIM6RST_BIT)
#define RCC_APB1RSTR_TIM5RST BIT(RCC_APB1RSTR_TIM5RST_BIT)
#define RCC_APB1RSTR_TIM4RST BIT(RCC_APB1RSTR_TIM4RST_BIT)
#define RCC_APB1RSTR_TIM3RST BIT(RCC_APB1RSTR_TIM3RST_BIT)
#define RCC_APB1RSTR_TIM2RST BIT(RCC_APB1RSTR_TIM2RST_BIT)
/* AHB peripheral clock enable register */
#define RCC_AHBENR_SDIOEN_BIT 10
#define RCC_AHBENR_FSMCEN_BIT 8
#define RCC_AHBENR_CRCEN_BIT 7
#define RCC_AHBENR_FLITFEN_BIT 4
#define RCC_AHBENR_SRAMEN_BIT 2
#define RCC_AHBENR_DMA2EN_BIT 1
#define RCC_AHBENR_DMA1EN_BIT 0
#define RCC_AHBENR_SDIOEN BIT(RCC_AHBENR_SDIOEN_BIT)
#define RCC_AHBENR_FSMCEN BIT(RCC_AHBENR_FSMCEN_BIT)
#define RCC_AHBENR_CRCEN BIT(RCC_AHBENR_CRCEN_BIT)
#define RCC_AHBENR_FLITFEN BIT(RCC_AHBENR_FLITFEN_BIT)
#define RCC_AHBENR_SRAMEN BIT(RCC_AHBENR_SRAMEN_BIT)
#define RCC_AHBENR_DMA2EN BIT(RCC_AHBENR_DMA2EN_BIT)
#define RCC_AHBENR_DMA1EN BIT(RCC_AHBENR_DMA1EN_BIT)
/* APB2 peripheral clock enable register */
#define RCC_APB2ENR_TIM11EN_BIT 21
#define RCC_APB2ENR_TIM10EN_BIT 20
#define RCC_APB2ENR_TIM9EN_BIT 19
#define RCC_APB2ENR_ADC3EN_BIT 15
#define RCC_APB2ENR_USART1EN_BIT 14
#define RCC_APB2ENR_TIM8EN_BIT 13
#define RCC_APB2ENR_SPI1EN_BIT 12
#define RCC_APB2ENR_TIM1EN_BIT 11
#define RCC_APB2ENR_ADC2EN_BIT 10
#define RCC_APB2ENR_ADC1EN_BIT 9
#define RCC_APB2ENR_IOPGEN_BIT 8
#define RCC_APB2ENR_IOPFEN_BIT 7
#define RCC_APB2ENR_IOPEEN_BIT 6
#define RCC_APB2ENR_IOPDEN_BIT 5
#define RCC_APB2ENR_IOPCEN_BIT 4
#define RCC_APB2ENR_IOPBEN_BIT 3
#define RCC_APB2ENR_IOPAEN_BIT 2
#define RCC_APB2ENR_AFIOEN_BIT 0
#define RCC_APB2ENR_TIM11EN BIT(RCC_APB2ENR_TIM11EN_BIT)
#define RCC_APB2ENR_TIM10EN BIT(RCC_APB2ENR_TIM10EN_BIT)
#define RCC_APB2ENR_TIM9EN BIT(RCC_APB2ENR_TIM9EN_BIT)
#define RCC_APB2ENR_ADC3EN BIT(RCC_APB2ENR_ADC3EN_BIT)
#define RCC_APB2ENR_USART1EN BIT(RCC_APB2ENR_USART1EN_BIT)
#define RCC_APB2ENR_TIM8EN BIT(RCC_APB2ENR_TIM8EN_BIT)
#define RCC_APB2ENR_SPI1EN BIT(RCC_APB2ENR_SPI1EN_BIT)
#define RCC_APB2ENR_TIM1EN BIT(RCC_APB2ENR_TIM1EN_BIT)
#define RCC_APB2ENR_ADC2EN BIT(RCC_APB2ENR_ADC2EN_BIT)
#define RCC_APB2ENR_ADC1EN BIT(RCC_APB2ENR_ADC1EN_BIT)
#define RCC_APB2ENR_IOPGEN BIT(RCC_APB2ENR_IOPGEN_BIT)
#define RCC_APB2ENR_IOPFEN BIT(RCC_APB2ENR_IOPFEN_BIT)
#define RCC_APB2ENR_IOPEEN BIT(RCC_APB2ENR_IOPEEN_BIT)
#define RCC_APB2ENR_IOPDEN BIT(RCC_APB2ENR_IOPDEN_BIT)
#define RCC_APB2ENR_IOPCEN BIT(RCC_APB2ENR_IOPCEN_BIT)
#define RCC_APB2ENR_IOPBEN BIT(RCC_APB2ENR_IOPBEN_BIT)
#define RCC_APB2ENR_IOPAEN BIT(RCC_APB2ENR_IOPAEN_BIT)
#define RCC_APB2ENR_AFIOEN BIT(RCC_APB2ENR_AFIOEN_BIT)
/* APB1 peripheral clock enable register */
#define RCC_APB1ENR_DACEN_BIT 29
#define RCC_APB1ENR_PWREN_BIT 28
#define RCC_APB1ENR_BKPEN_BIT 27
#define RCC_APB1ENR_CANEN_BIT 25
#define RCC_APB1ENR_USBEN_BIT 23
#define RCC_APB1ENR_I2C2EN_BIT 22
#define RCC_APB1ENR_I2C1EN_BIT 21
#define RCC_APB1ENR_UART5EN_BIT 20
#define RCC_APB1ENR_UART4EN_BIT 19
#define RCC_APB1ENR_USART3EN_BIT 18
#define RCC_APB1ENR_USART2EN_BIT 17
#define RCC_APB1ENR_SPI3EN_BIT 15
#define RCC_APB1ENR_SPI2EN_BIT 14
#define RCC_APB1ENR_WWDEN_BIT 11
#define RCC_APB1ENR_TIM14EN_BIT 8
#define RCC_APB1ENR_TIM13EN_BIT 7
#define RCC_APB1ENR_TIM12EN_BIT 6
#define RCC_APB1ENR_TIM7EN_BIT 5
#define RCC_APB1ENR_TIM6EN_BIT 4
#define RCC_APB1ENR_TIM5EN_BIT 3
#define RCC_APB1ENR_TIM4EN_BIT 2
#define RCC_APB1ENR_TIM3EN_BIT 1
#define RCC_APB1ENR_TIM2EN_BIT 0
#define RCC_APB1ENR_DACEN BIT(RCC_APB1ENR_DACEN_BIT)
#define RCC_APB1ENR_PWREN BIT(RCC_APB1ENR_PWREN_BIT)
#define RCC_APB1ENR_BKPEN BIT(RCC_APB1ENR_BKPEN_BIT)
#define RCC_APB1ENR_CANEN BIT(RCC_APB1ENR_CANEN_BIT)
#define RCC_APB1ENR_USBEN BIT(RCC_APB1ENR_USBEN_BIT)
#define RCC_APB1ENR_I2C2EN BIT(RCC_APB1ENR_I2C2EN_BIT)
#define RCC_APB1ENR_I2C1EN BIT(RCC_APB1ENR_I2C1EN_BIT)
#define RCC_APB1ENR_UART5EN BIT(RCC_APB1ENR_UART5EN_BIT)
#define RCC_APB1ENR_UART4EN BIT(RCC_APB1ENR_UART4EN_BIT)
#define RCC_APB1ENR_USART3EN BIT(RCC_APB1ENR_USART3EN_BIT)
#define RCC_APB1ENR_USART2EN BIT(RCC_APB1ENR_USART2EN_BIT)
#define RCC_APB1ENR_SPI3EN BIT(RCC_APB1ENR_SPI3EN_BIT)
#define RCC_APB1ENR_SPI2EN BIT(RCC_APB1ENR_SPI2EN_BIT)
#define RCC_APB1ENR_WWDEN BIT(RCC_APB1ENR_WWDEN_BIT)
#define RCC_APB1ENR_TIM14EN BIT(RCC_APB1ENR_TIM14EN_BIT)
#define RCC_APB1ENR_TIM13EN BIT(RCC_APB1ENR_TIM13EN_BIT)
#define RCC_APB1ENR_TIM12EN BIT(RCC_APB1ENR_TIM12EN_BIT)
#define RCC_APB1ENR_TIM7EN BIT(RCC_APB1ENR_TIM7EN_BIT)
#define RCC_APB1ENR_TIM6EN BIT(RCC_APB1ENR_TIM6EN_BIT)
#define RCC_APB1ENR_TIM5EN BIT(RCC_APB1ENR_TIM5EN_BIT)
#define RCC_APB1ENR_TIM4EN BIT(RCC_APB1ENR_TIM4EN_BIT)
#define RCC_APB1ENR_TIM3EN BIT(RCC_APB1ENR_TIM3EN_BIT)
#define RCC_APB1ENR_TIM2EN BIT(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 BIT(RCC_BDCR_BDRST_BIT)
#define RCC_BDCR_RTCEN BIT(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 BIT(RCC_BDCR_LSEBYP_BIT)
#define RCC_BDCR_LSERDY BIT(RCC_BDCR_LSERDY_BIT)
#define RCC_BDCR_LSEON BIT(RCC_BDCR_LSEON_BIT)
/* Control/status register */
#define RCC_CSR_LPWRRSTF_BIT 31
#define RCC_CSR_WWDGRSTF_BIT 30
#define RCC_CSR_IWDGRSTF_BIT 29
#define RCC_CSR_SFTRSTF_BIT 28
#define RCC_CSR_PORRSTF_BIT 27
#define RCC_CSR_PINRSTF_BIT 26
#define RCC_CSR_RMVF_BIT 24
#define RCC_CSR_LSIRDY_BIT 1
#define RCC_CSR_LSION_BIT 0
#define RCC_CSR_LPWRRSTF BIT(RCC_CSR_LPWRRSTF_BIT)
#define RCC_CSR_WWDGRSTF BIT(RCC_CSR_WWDGRSTF_BIT)
#define RCC_CSR_IWDGRSTF BIT(RCC_CSR_IWDGRSTF_BIT)
#define RCC_CSR_SFTRSTF BIT(RCC_CSR_SFTRSTF_BIT)
#define RCC_CSR_PORRSTF BIT(RCC_CSR_PORRSTF_BIT)
#define RCC_CSR_PINRSTF BIT(RCC_CSR_PINRSTF_BIT)
#define RCC_CSR_RMVF BIT(RCC_CSR_RMVF_BIT)
#define RCC_CSR_LSIRDY BIT(RCC_CSR_LSIRDY_BIT)
#define RCC_CSR_LSION BIT(RCC_CSR_LSION_BIT)
/*
* Convenience routines
*/
/**
* SYSCLK sources
* @see rcc_clk_init()
*/
typedef enum rcc_sysclk_src {
RCC_CLKSRC_HSI = 0x0,
RCC_CLKSRC_HSE = 0x1,
RCC_CLKSRC_PLL = 0x2,
} rcc_sysclk_src;
/**
* PLL entry clock source
* @see rcc_clk_init()
*/
typedef enum rcc_pllsrc {
RCC_PLLSRC_HSE = (0x1 << 16),
RCC_PLLSRC_HSI_DIV_2 = (0x0 << 16)
} rcc_pllsrc;
/**
* PLL multipliers
* @see rcc_clk_init()
*/
typedef enum rcc_pll_multiplier {
RCC_PLLMUL_2 = (0x0 << 18),
RCC_PLLMUL_3 = (0x1 << 18),
RCC_PLLMUL_4 = (0x2 << 18),
RCC_PLLMUL_5 = (0x3 << 18),
RCC_PLLMUL_6 = (0x4 << 18),
RCC_PLLMUL_7 = (0x5 << 18),
RCC_PLLMUL_8 = (0x6 << 18),
RCC_PLLMUL_9 = (0x7 << 18),
RCC_PLLMUL_10 = (0x8 << 18),
RCC_PLLMUL_11 = (0x9 << 18),
RCC_PLLMUL_12 = (0xA << 18),
RCC_PLLMUL_13 = (0xB << 18),
RCC_PLLMUL_14 = (0xC << 18),
RCC_PLLMUL_15 = (0xD << 18),
RCC_PLLMUL_16 = (0xE << 18),
} rcc_pll_multiplier;
/**
* @brief Identifies bus and clock line for a peripheral.
*
* Also generally useful as a unique identifier for that peripheral
* (or its corresponding device struct).
*/
typedef enum rcc_clk_id {
RCC_GPIOA,
RCC_GPIOB,
RCC_GPIOC,
RCC_GPIOD,
RCC_AFIO,
RCC_ADC1,
RCC_ADC2,
RCC_ADC3,
RCC_USART1,
RCC_USART2,
RCC_USART3,
RCC_TIMER1,
RCC_TIMER2,
RCC_TIMER3,
RCC_TIMER4,
RCC_SPI1,
RCC_SPI2,
RCC_DMA1,
RCC_PWR,
RCC_BKP,
RCC_I2C1,
RCC_I2C2,
RCC_CRC,
RCC_FLITF,
RCC_SRAM,
#if defined(STM32_HIGH_DENSITY) || defined(STM32_XL_DENSITY)
RCC_GPIOE,
RCC_GPIOF,
RCC_GPIOG,
RCC_UART4,
RCC_UART5,
RCC_TIMER5,
RCC_TIMER6,
RCC_TIMER7,
RCC_TIMER8,
RCC_FSMC,
RCC_DAC,
RCC_DMA2,
RCC_SDIO,
RCC_SPI3,
#endif
#ifdef STM32_XL_DENSITY
RCC_TIMER9,
RCC_TIMER10,
RCC_TIMER11,
RCC_TIMER12,
RCC_TIMER13,
RCC_TIMER14,
#endif
} rcc_clk_id;
void rcc_clk_init(rcc_sysclk_src sysclk_src,
rcc_pllsrc pll_src,
rcc_pll_multiplier pll_mul);
void rcc_clk_enable(rcc_clk_id device);
void rcc_reset_dev(rcc_clk_id device);
typedef enum rcc_clk_domain {
RCC_APB1,
RCC_APB2,
RCC_AHB
} rcc_clk_domain;
rcc_clk_domain rcc_dev_clk(rcc_clk_id device);
uint32 rcc_dev_clk_speed(rcc_clk_id id);
uint32 rcc_dev_timer_clk_speed(rcc_clk_id id);
/**
* Prescaler identifiers
* @see rcc_set_prescaler()
*/
typedef enum rcc_prescaler {
RCC_PRESCALER_AHB,
RCC_PRESCALER_APB1,
RCC_PRESCALER_APB2,
RCC_PRESCALER_USB,
RCC_PRESCALER_ADC
} rcc_prescaler;
/**
* ADC prescaler dividers
* @see rcc_set_prescaler()
*/
typedef enum rcc_adc_divider {
RCC_ADCPRE_PCLK_DIV_2 = 0x0 << 14,
RCC_ADCPRE_PCLK_DIV_4 = 0x1 << 14,
RCC_ADCPRE_PCLK_DIV_6 = 0x2 << 14,
RCC_ADCPRE_PCLK_DIV_8 = 0x3 << 14,
} rcc_adc_divider;
/**
* APB1 prescaler dividers
* @see rcc_set_prescaler()
*/
typedef enum rcc_apb1_divider {
RCC_APB1_HCLK_DIV_1 = 0x0 << 8,
RCC_APB1_HCLK_DIV_2 = 0x4 << 8,
RCC_APB1_HCLK_DIV_4 = 0x5 << 8,
RCC_APB1_HCLK_DIV_8 = 0x6 << 8,
RCC_APB1_HCLK_DIV_16 = 0x7 << 8,
} rcc_apb1_divider;
/**
* APB2 prescaler dividers
* @see rcc_set_prescaler()
*/
typedef enum rcc_apb2_divider {
RCC_APB2_HCLK_DIV_1 = 0x0 << 11,
RCC_APB2_HCLK_DIV_2 = 0x4 << 11,
RCC_APB2_HCLK_DIV_4 = 0x5 << 11,
RCC_APB2_HCLK_DIV_8 = 0x6 << 11,
RCC_APB2_HCLK_DIV_16 = 0x7 << 11,
} rcc_apb2_divider;
/**
* AHB prescaler dividers
* @see rcc_set_prescaler()
*/
typedef enum rcc_ahb_divider {
RCC_AHB_SYSCLK_DIV_1 = 0x0 << 4,
RCC_AHB_SYSCLK_DIV_2 = 0x8 << 4,
RCC_AHB_SYSCLK_DIV_4 = 0x9 << 4,
RCC_AHB_SYSCLK_DIV_8 = 0xA << 4,
RCC_AHB_SYSCLK_DIV_16 = 0xB << 4,
RCC_AHB_SYSCLK_DIV_32 = 0xC << 4,
RCC_AHB_SYSCLK_DIV_64 = 0xD << 4,
RCC_AHB_SYSCLK_DIV_128 = 0xD << 4,
RCC_AHB_SYSCLK_DIV_256 = 0xE << 4,
RCC_AHB_SYSCLK_DIV_512 = 0xF << 4,
} rcc_ahb_divider;
void rcc_set_prescaler(rcc_prescaler prescaler, uint32 divider);
#ifdef __cplusplus
} // extern "C"
#endif
#endif

View File

@ -1,707 +0,0 @@
/******************************************************************************
* 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.
*****************************************************************************/
#ifdef STM32F2
/**
* @file rcc.c
* @brief Implements pretty much only the basic clock setup on the
* stm32, clock enable/disable and peripheral reset commands.
*/
#include "libmaple.h"
#include "flash.h"
#include "gpio.h"
#include "rcc.h"
#include "bitband.h"
#define APB1 RCC_APB1
#define APB2 RCC_APB2
#define AHB1 RCC_AHB1
#define AHB2 RCC_AHB2
#define AHB3 RCC_AHB3
struct rcc_dev_info {
const rcc_clk_domain clk_domain;
const uint8 line_num;
};
static uint32 rcc_dev_clk_speed_table[AHB3];
/* Device descriptor table, maps rcc_clk_id onto bus and enable/reset
* register bit numbers. */
static const struct rcc_dev_info rcc_dev_table[] = {
[RCC_GPIOA] = { .clk_domain = AHB1, .line_num = 0 }, //*
[RCC_GPIOB] = { .clk_domain = AHB1, .line_num = 1 }, //*
[RCC_GPIOC] = { .clk_domain = AHB1, .line_num = 2 }, //*
[RCC_GPIOD] = { .clk_domain = AHB1, .line_num = 3 }, //*
// [RCC_AFIO] = { .clk_domain = APB2, .line_num = 0 },
[RCC_ADC1] = { .clk_domain = APB2, .line_num = 8 }, //*
[RCC_ADC2] = { .clk_domain = APB2, .line_num = 9 }, //*
[RCC_ADC3] = { .clk_domain = APB2, .line_num = 10 }, //*
[RCC_USART1] = { .clk_domain = APB2, .line_num = 4 }, //*
[RCC_USART2] = { .clk_domain = APB1, .line_num = 17 }, //unchanged
[RCC_USART3] = { .clk_domain = APB1, .line_num = 18 }, //unchanged
[RCC_TIMER1] = { .clk_domain = APB2, .line_num = 0 }, //*
[RCC_TIMER2] = { .clk_domain = APB1, .line_num = 0 }, //unchanged
[RCC_TIMER3] = { .clk_domain = APB1, .line_num = 1 }, //unchanged
[RCC_TIMER4] = { .clk_domain = APB1, .line_num = 2 }, //unchanged
[RCC_SPI1] = { .clk_domain = APB2, .line_num = 12 }, //unchanged
[RCC_SPI2] = { .clk_domain = APB1, .line_num = 14 }, //unchanged
[RCC_DMA1] = { .clk_domain = AHB1, .line_num = 21 }, //*
[RCC_PWR] = { .clk_domain = APB1, .line_num = 28}, //unchanged
[RCC_BKP] = { .clk_domain = AHB1, .line_num = 18}, //*
[RCC_I2C1] = { .clk_domain = APB1, .line_num = 21 }, //unchanged
[RCC_I2C2] = { .clk_domain = APB1, .line_num = 22 }, //unchanged
[RCC_CRC] = { .clk_domain = AHB1, .line_num = 12}, //*
// [RCC_FLITF] = { .clk_domain = AHB, .line_num = 4},
// [RCC_SRAM] = { .clk_domain = AHB, .line_num = 2},
[RCC_GPIOE] = { .clk_domain = AHB1, .line_num = 4 }, //*
[RCC_GPIOF] = { .clk_domain = AHB1, .line_num = 5 }, //*
[RCC_GPIOG] = { .clk_domain = AHB1, .line_num = 6 }, //*
[RCC_UART4] = { .clk_domain = APB1, .line_num = 19 }, //unchanged
[RCC_UART5] = { .clk_domain = APB1, .line_num = 20 }, //unchanged
[RCC_TIMER5] = { .clk_domain = APB1, .line_num = 3 }, //unchanged
[RCC_TIMER6] = { .clk_domain = APB1, .line_num = 4 }, //unchanged
[RCC_TIMER7] = { .clk_domain = APB1, .line_num = 5 }, //unchanged
[RCC_TIMER8] = { .clk_domain = APB2, .line_num = 1 }, //*
[RCC_FSMC] = { .clk_domain = AHB3, .line_num = 0 }, //*
[RCC_DAC] = { .clk_domain = APB1, .line_num = 29 }, //unchanged
[RCC_DMA2] = { .clk_domain = AHB1, .line_num = 22 }, //*
[RCC_SDIO] = { .clk_domain = APB2, .line_num = 11 }, //*
[RCC_SPI3] = { .clk_domain = APB1, .line_num = 15 }, //unchanged
[RCC_TIMER9] = { .clk_domain = APB2, .line_num = 16 }, //*
[RCC_TIMER10] = { .clk_domain = APB2, .line_num = 17 }, //*
[RCC_TIMER11] = { .clk_domain = APB2, .line_num = 18 }, //*
[RCC_TIMER12] = { .clk_domain = APB1, .line_num = 6 }, //unchanged
[RCC_TIMER13] = { .clk_domain = APB1, .line_num = 7 }, //unchanged
[RCC_TIMER14] = { .clk_domain = APB1, .line_num = 8 }, //unchanged
[RCC_USBFS] = { .clk_domain = AHB2, .line_num = 7 }, //*
[RCC_SYSCFG] = { .clk_domain = APB2, .line_num = 14 }, //*
[RCC_SPI4] = { .clk_domain = APB1, .line_num = 15 },
};
/**
* @brief Initialize the clock control system. Initializes the system
* clock source to use the PLL driven by an external oscillator
* @param sysclk_src system clock source, must be PLL
* @param pll_src pll clock source, must be HSE
* @param pll_mul pll multiplier
*/
#define HSE_STARTUP_TIMEOUT ((uint16)0x0500) /*!< Time out for HSE start up */
#define RCC_CFGR_HPRE_DIV1 ((uint32)0x00000000) /*!< SYSCLK not divided */
#define RCC_CFGR_PPRE1_DIV2 ((uint32)0x00001000) /*!< HCLK divided by 2 */
#define RCC_CFGR_PPRE1_DIV4 ((uint32)0x00001400) /*!< HCLK divided by 4 */
#define RCC_CFGR_PPRE2_DIV1 ((uint32)0x00000000) /*!< HCLK not divided */
#define RCC_CFGR_PPRE2_DIV2 ((uint32)0x00008000) /*!< HCLK divided by 2 */
#define RCC_PLLCFGR_PLLSRC_HSE ((uint32)0x00400000)
/******************* Bits definition for FLASH_ACR register *****************/
//#define FLASH_ACR_LATENCY ((uint32_t)0x00000007)
#define FLASH_ACR_LATENCY_0WS ((uint32)0x00000000)
#define FLASH_ACR_LATENCY_1WS ((uint32)0x00000001)
#define FLASH_ACR_LATENCY_2WS ((uint32)0x00000002)
#define FLASH_ACR_LATENCY_3WS ((uint32)0x00000003)
#define FLASH_ACR_LATENCY_4WS ((uint32)0x00000004)
#define FLASH_ACR_LATENCY_5WS ((uint32)0x00000005)
#define FLASH_ACR_LATENCY_6WS ((uint32)0x00000006)
#define FLASH_ACR_LATENCY_7WS ((uint32)0x00000007)
#define FLASH_ACR_PRFTEN ((uint32)0x00000100)
#define FLASH_ACR_ICEN ((uint32)0x00000200)
#define FLASH_ACR_DCEN ((uint32)0x00000400)
#define FLASH_ACR_ICRST ((uint32)0x00000800)
#define FLASH_ACR_DCRST ((uint32)0x00001000)
#define FLASH_ACR_BYTE0_ADDRESS ((uint32)0x40023C00)
#define FLASH_ACR_BYTE2_ADDRESS ((uint32)0x40023C03)
typedef struct
{
__io uint32 CR; /*!< PWR power control register, Address offset: 0x00 */
__io uint32 CSR; /*!< PWR power control/status register, Address offset: 0x04 */
} PWR_TypeDef;
#define PWR_BASE (0x40007000)
#define PWR ((PWR_TypeDef *) PWR_BASE)
#define PWR_CR_VOS ((uint16)0x4000) /*!< Regulator voltage scaling output selection */
typedef struct
{
__io uint32 ACR; /*!< FLASH access control register, Address offset: 0x00 */
__io uint32 KEYR; /*!< FLASH key register, Address offset: 0x04 */
__io uint32 OPTKEYR; /*!< FLASH option key register, Address offset: 0x08 */
__io uint32 SR; /*!< FLASH status register, Address offset: 0x0C */
__io uint32 CR; /*!< FLASH control register, Address offset: 0x10 */
__io uint32 OPTCR; /*!< FLASH option control register, Address offset: 0x14 */
} FLASH_TypeDef;
#define FLASH_R_BASE (0x40023C00)
#define FLASH ((FLASH_TypeDef *) FLASH_R_BASE)
#define RESET 0
typedef uint32 uint32_t;
void InitMCO1()
{
rcc_reg_map *RCC = RCC_BASE;
// Turn MCO1 Master Clock Output mode
RCC->CFGR &= RCC_CFGR_MCO1_RESET_MASK;
RCC->CFGR |= RCC_CFGR_MCO1Source_HSE | RCC_CFGR_MCO1Div_1;
// PA8 Output the Master Clock MCO1
gpio_set_af_mode(GPIOA, 8, 0);
gpio_set_mode(GPIOA, 8, GPIO_MODE_AF | GPIO_OTYPE_PP | GPIO_OSPEED_100MHZ);
}
void SetupClock72MHz()
{
uint32_t SystemCoreClock = 72000000;
/******************************************************************************/
/* PLL (clocked by HSE) used as System clock source */
/******************************************************************************/
/************************* PLL Parameters *************************************/
/* PLL_VCO = (HSE_VALUE or HSI_VALUE / PLL_M) * PLL_N */
int PLL_M = 4;
int PLL_N = 216;
/* SYSCLK = PLL_VCO / PLL_P */
int PLL_P = 6;
/* USB OTG FS, SDIO and RNG Clock = PLL_VCO / PLLQ */
int PLL_Q = 9;
uint32 StartUpCounter = 0, HSEStatus = 0;
rcc_reg_map *RCC = RCC_BASE;
/* Enable HSE */
RCC->CR |= ((uint32_t)RCC_CR_HSEON);
/* Wait till HSE is ready and if Time out is reached exit */
do
{
HSEStatus = RCC->CR & RCC_CR_HSERDY;
StartUpCounter++;
} while((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT));
if ((RCC->CR & RCC_CR_HSERDY) != RESET)
{
HSEStatus = (uint32_t)0x01;
}
else
{
HSEStatus = (uint32_t)0x00;
}
if (HSEStatus == (uint32_t)0x01)
{
/* Select regulator voltage output Scale 2 mode, System frequency up to 144 MHz */
RCC->APB1ENR |= RCC_APB1ENR_PWREN;
PWR->CR &= (uint32_t)~(PWR_CR_VOS);
/* HCLK = SYSCLK / 1*/
RCC->CFGR |= RCC_CFGR_HPRE_DIV1;
/* PCLK2 = HCLK / 1*/
RCC->CFGR |= RCC_CFGR_PPRE2_DIV1;
/* PCLK1 = HCLK / 2*/
RCC->CFGR |= RCC_CFGR_PPRE1_DIV2;
// save bus clock values
rcc_dev_clk_speed_table[RCC_AHB1] = (SystemCoreClock/1);
rcc_dev_clk_speed_table[RCC_APB2] = (SystemCoreClock/1);
rcc_dev_clk_speed_table[RCC_APB1] = (SystemCoreClock/2);
/* Configure the main PLL */
RCC->PLLCFGR = PLL_M | (PLL_N << 6) | (((PLL_P >> 1) -1) << 16) |
(RCC_PLLCFGR_PLLSRC_HSE) | (PLL_Q << 24);
/* Enable the main PLL */
RCC->CR |= RCC_CR_PLLON;
/* Wait till the main PLL is ready */
while((RCC->CR & RCC_CR_PLLRDY) == 0)
{
}
/* Configure Flash prefetch, Instruction cache, Data cache and wait state */
FLASH->ACR = FLASH_ACR_ICEN |FLASH_ACR_DCEN |FLASH_ACR_LATENCY_2WS;
/* Select the main PLL as system clock source */
RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_SW));
RCC->CFGR |= RCC_CFGR_SW_PLL;
/* Wait till the main PLL is used as system clock source */
while ((RCC->CFGR & (uint32_t)RCC_CFGR_SWS ) != RCC_CFGR_SWS_PLL);
{
}
}
else
{ /* If HSE fails to start-up, the application will have wrong clock
configuration. User can add here some code to deal with this error */
}
}
void SetupClock120MHz()
{
uint32_t SystemCoreClock = 120000000;
/******************************************************************************/
/* PLL (clocked by HSE) used as System clock source */
/******************************************************************************/
/************************* PLL Parameters *************************************/
/* PLL_VCO = (HSE_VALUE or HSI_VALUE / PLL_M) * PLL_N */
int PLL_M = 8;
int PLL_N = 240;
/* SYSCLK = PLL_VCO / PLL_P */
int PLL_P = 2;
/* USB OTG FS, SDIO and RNG Clock = PLL_VCO / PLLQ */
int PLL_Q = 5;
uint32 StartUpCounter = 0, HSEStatus = 0;
rcc_reg_map *RCC = RCC_BASE;
/* Enable HSE */
RCC->CR |= ((uint32_t)RCC_CR_HSEON);
/* Wait till HSE is ready and if Time out is reached exit */
do
{
HSEStatus = RCC->CR & RCC_CR_HSERDY;
StartUpCounter++;
} while((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT));
if ((RCC->CR & RCC_CR_HSERDY) != RESET)
{
HSEStatus = (uint32_t)0x01;
}
else
{
HSEStatus = (uint32_t)0x00;
}
if (HSEStatus == (uint32_t)0x01)
{
/* Select regulator voltage output Scale 2 mode, System frequency up to 144 MHz */
RCC->APB1ENR |= RCC_APB1ENR_PWREN;
PWR->CR &= (uint32_t)~(PWR_CR_VOS);
/* HCLK = SYSCLK / 1*/
RCC->CFGR |= RCC_CFGR_HPRE_DIV1;
/* PCLK2 = HCLK / 2*/
RCC->CFGR |= RCC_CFGR_PPRE2_DIV2;
/* PCLK1 = HCLK / 4*/
RCC->CFGR |= RCC_CFGR_PPRE1_DIV4;
// save bus clock values
rcc_dev_clk_speed_table[RCC_AHB1] = (SystemCoreClock/1);
rcc_dev_clk_speed_table[RCC_APB2] = (SystemCoreClock/2);
rcc_dev_clk_speed_table[RCC_APB1] = (SystemCoreClock/4);
/* Configure the main PLL */
RCC->PLLCFGR = PLL_M | (PLL_N << 6) | (((PLL_P >> 1) -1) << 16) |
(RCC_PLLCFGR_PLLSRC_HSE) | (PLL_Q << 24);
/* Enable the main PLL */
RCC->CR |= RCC_CR_PLLON;
/* Wait till the main PLL is ready */
while((RCC->CR & RCC_CR_PLLRDY) == 0)
{
}
/* Configure Flash prefetch, Instruction cache, Data cache and wait state */
FLASH->ACR = FLASH_ACR_ICEN |FLASH_ACR_DCEN |FLASH_ACR_LATENCY_3WS;
/* Select the main PLL as system clock source */
RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_SW));
RCC->CFGR |= RCC_CFGR_SW_PLL;
/* Wait till the main PLL is used as system clock source */
while ((RCC->CFGR & (uint32_t)RCC_CFGR_SWS ) != RCC_CFGR_SWS_PLL);
{
}
}
else
{ /* If HSE fails to start-up, the application will have wrong clock
configuration. User can add here some code to deal with this error */
}
}
void SetupClock168MHz()
{
uint32_t SystemCoreClock = 168000000;
/******************************************************************************/
/* PLL (clocked by HSE) used as System clock source */
/******************************************************************************/
/************************* PLL Parameters *************************************/
/* PLL_VCO = (HSE_VALUE or HSI_VALUE / PLL_M) * PLL_N */
#ifdef ARDUINO_STM32F4_NETDUINO2PLUS
int PLL_M = 25; // The NETDUINO has a 25MHz external oscillator
#else
int PLL_M = 8;
#endif
int PLL_N = 336;
/* SYSCLK = PLL_VCO / PLL_P */
int PLL_P = 2;
/* USB OTG FS, SDIO and RNG Clock = PLL_VCO / PLLQ */
int PLL_Q = 7;
uint32 StartUpCounter = 0, HSEStatus = 0;
rcc_reg_map *RCC = RCC_BASE;
#ifdef ARDUINO_STM32F4_NETDUINO2PLUS
InitMCO1();
#endif
/* Enable HSE */
RCC->CR |= ((uint32_t)RCC_CR_HSEON);
/* Wait till HSE is ready and if Time out is reached exit */
do
{
HSEStatus = RCC->CR & RCC_CR_HSERDY;
StartUpCounter++;
} while((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT));
if ((RCC->CR & RCC_CR_HSERDY) != RESET)
{
HSEStatus = (uint32_t)0x01;
}
else
{
HSEStatus = (uint32_t)0x00;
}
if (HSEStatus == (uint32_t)0x01)
{
/* Select regulator voltage output Scale 1 mode, System frequency up to 168 MHz */
RCC->APB1ENR |= RCC_APB1ENR_PWREN;
PWR->CR |= PWR_CR_VOS;
/* HCLK = SYSCLK / 1*/
RCC->CFGR |= RCC_CFGR_HPRE_DIV1;
/* PCLK2 = HCLK / 2*/
RCC->CFGR |= RCC_CFGR_PPRE2_DIV2;
/* PCLK1 = HCLK / 4*/
RCC->CFGR |= RCC_CFGR_PPRE1_DIV4;
// save bus clock values
rcc_dev_clk_speed_table[RCC_AHB1] = (SystemCoreClock/1);
rcc_dev_clk_speed_table[RCC_APB2] = (SystemCoreClock/2);
rcc_dev_clk_speed_table[RCC_APB1] = (SystemCoreClock/4);
/* Configure the main PLL */
RCC->PLLCFGR = PLL_M | (PLL_N << 6) | (((PLL_P >> 1) -1) << 16) |
(RCC_PLLCFGR_PLLSRC_HSE) | (PLL_Q << 24);
/* Enable the main PLL */
RCC->CR |= RCC_CR_PLLON;
/* Wait till the main PLL is ready */
while((RCC->CR & RCC_CR_PLLRDY) == 0)
{
}
/* Configure Flash prefetch, Instruction cache, Data cache and wait state */
FLASH->ACR = FLASH_ACR_ICEN |FLASH_ACR_DCEN |FLASH_ACR_LATENCY_5WS;
/* Select the main PLL as system clock source */
RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_SW));
RCC->CFGR |= RCC_CFGR_SW_PLL;
/* Wait till the main PLL is used as system clock source */
while ((RCC->CFGR & (uint32_t)RCC_CFGR_SWS ) != RCC_CFGR_SWS_PLL);
{
}
}
else
{ /* If HSE fails to start-up, the application will have wrong clock
configuration. User can add here some code to deal with this error */
}
}
void rcc_clk_init(rcc_sysclk_src sysclk_src,
rcc_pllsrc pll_src,
rcc_pll_multiplier pll_mul) {
//SetupClock72MHz();
#if STM32_TICKS_PER_US == 168
SetupClock168MHz();
#endif
#if STM32_TICKS_PER_US == 120
SetupClock120MHz();
#endif
#if STM32_TICKS_PER_US == 72
SetupClock72MHz();
#endif
}
#define PLL_M 8
#define PLL_N 240
/* SYSCLK = PLL_VCO / PLL_P */
#define PLL_P 2
/* USB OTG FS, SDIO and RNG Clock = PLL_VCO / PLLQ */
#define PLL_Q 5
void rcc_clk_init2(rcc_sysclk_src sysclk_src,
rcc_pllsrc pll_src,
rcc_pll_multiplier pll_mul) {
/******************************************************************************/
/* PLL (clocked by HSE) used as System clock source */
/******************************************************************************/
uint32 StartUpCounter = 0, HSEStatus = 0;
rcc_reg_map *pRCC = RCC_BASE;
/* Enable HSE */
pRCC->CR |= RCC_CR_HSEON;
/* Wait till HSE is ready and if Time out is reached exit */
do
{
HSEStatus = pRCC->CR & RCC_CR_HSERDY;
StartUpCounter++;
} while((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT));
if ((pRCC->CR & RCC_CR_HSERDY) != 0)
{
HSEStatus = 0x01;
}
else
{
HSEStatus = 0x00;
}
if (HSEStatus == 0x01)
{
/* HCLK = SYSCLK / 1*/
pRCC->CFGR |= RCC_CFGR_HPRE_DIV1;
/* PCLK2 = HCLK / 2*/
pRCC->CFGR |= RCC_CFGR_PPRE2_DIV2;
/* PCLK1 = HCLK / 4*/
pRCC->CFGR |= RCC_CFGR_PPRE1_DIV4;
/* Configure the main PLL */
pRCC->PLLCFGR = PLL_M | (PLL_N << 6) | (((PLL_P >> 1) -1) << 16) |
(RCC_PLLCFGR_PLLSRC_HSE) | (PLL_Q << 24);
/* Enable the main PLL */
pRCC->CR |= RCC_CR_PLLON;
/* Wait till the main PLL is ready */
while((pRCC->CR & RCC_CR_PLLRDY) == 0)
{
}
/* Configure Flash prefetch, Instruction cache, Data cache and wait state */
((FLASH_TypeDef*)FLASH)->ACR = FLASH_ACR_PRFTEN |FLASH_ACR_ICEN |FLASH_ACR_DCEN |FLASH_ACR_LATENCY_3WS;
/* Select the main PLL as system clock source */
pRCC->CFGR &= ~RCC_CFGR_SW;
pRCC->CFGR |= RCC_CFGR_SW_PLL;
/* Wait till the main PLL is used as system clock source */
while ((pRCC->CFGR & RCC_CFGR_SWS ) != RCC_CFGR_SWS_PLL);
{
}
}
else
{ /* If HSE fails to start-up, the application will have wrong clock
configuration. User can add here some code to deal with this error */
}
#if 0
uint32 cfgr = 0;
uint32 cr;
/* Assume that we're going to clock the chip off the PLL, fed by
* the HSE */
ASSERT(sysclk_src == RCC_CLKSRC_PLL &&
pll_src == RCC_PLLSRC_HSE);
RCC_BASE->CFGR = pll_src | pll_mul;
/* Turn on the HSE */
cr = RCC_BASE->CR;
cr |= RCC_CR_HSEON;
RCC_BASE->CR = cr;
while (!(RCC_BASE->CR & RCC_CR_HSERDY))
;
/* Now the PLL */
cr |= RCC_CR_PLLON;
RCC_BASE->CR = cr;
while (!(RCC_BASE->CR & RCC_CR_PLLRDY))
;
/* Finally, let's switch over to the PLL */
cfgr &= ~RCC_CFGR_SW;
cfgr |= RCC_CFGR_SW_PLL;
RCC_BASE->CFGR = cfgr;
while ((RCC_BASE->CFGR & RCC_CFGR_SWS) != RCC_CFGR_SWS_PLL)
;
#endif
}
/**
* @brief Turn on the clock line on a peripheral
* @param id Clock ID of the peripheral to turn on.
*/
void rcc_clk_enable(rcc_clk_id id) {
static const __io uint32* enable_regs[] = {
[APB1] = &RCC_BASE->APB1ENR,
[APB2] = &RCC_BASE->APB2ENR,
[AHB1] = &RCC_BASE->AHB1ENR,
[AHB2] = &RCC_BASE->AHB2ENR,
[AHB3] = &RCC_BASE->AHB3ENR,
};
rcc_clk_domain clk_domain = rcc_dev_clk(id);
__io uint32* enr = (__io uint32*)enable_regs[clk_domain];
uint8 lnum = rcc_dev_table[id].line_num;
bb_peri_set_bit(enr, lnum, 1);
}
/**
* @brief Turn on the clock line on a peripheral
* @param id Clock ID of the peripheral to turn on.
*/
void rcc_clk_disable(rcc_clk_id id) {
static const __io uint32* enable_regs[] = {
[APB1] = &RCC_BASE->APB1ENR,
[APB2] = &RCC_BASE->APB2ENR,
[AHB1] = &RCC_BASE->AHB1ENR,
[AHB2] = &RCC_BASE->AHB2ENR,
[AHB3] = &RCC_BASE->AHB3ENR,
};
rcc_clk_domain clk_domain = rcc_dev_clk(id);
__io uint32* enr = (__io uint32*)enable_regs[clk_domain];
uint8 lnum = rcc_dev_table[id].line_num;
bb_peri_set_bit(enr, lnum, 0);
}
/**
* @brief Reset a peripheral.
* @param id Clock ID of the peripheral to reset.
*/
void rcc_reset_dev(rcc_clk_id id) {
static const __io uint32* reset_regs[] = {
[APB1] = &RCC_BASE->APB1RSTR,
[APB2] = &RCC_BASE->APB2RSTR,
[AHB1] = &RCC_BASE->AHB1RSTR,
[AHB2] = &RCC_BASE->AHB2RSTR,
[AHB3] = &RCC_BASE->AHB3RSTR,
};
rcc_clk_domain clk_domain = rcc_dev_clk(id);
__io void* addr = (__io void*)reset_regs[clk_domain];
uint8 lnum = rcc_dev_table[id].line_num;
bb_peri_set_bit(addr, lnum, 1);
bb_peri_set_bit(addr, lnum, 0);
}
/**
* @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 Get a peripheral's clock domain speed
* @param id Clock ID of the peripheral whose clock domain speed to return
* @return Clock speed for the given clock ID
*/
uint32 rcc_dev_clk_speed(rcc_clk_id id) {
return rcc_dev_clk_speed_table[rcc_dev_clk(id)];
}
/**
* @brief Get a peripheral's timer clock domain speed
* @param id Clock ID of the peripheral whose clock domain speed to return
* @return Clock speed for the given clock ID
*/
uint32 rcc_dev_timer_clk_speed(rcc_clk_id id) {
return 2*rcc_dev_clk_speed(id);
}
/**
* @brief Set the divider on a peripheral prescaler
* @param prescaler prescaler to set
* @param divider prescaler divider
*/
void rcc_set_prescaler(rcc_prescaler prescaler, uint32 divider) {
#if 0
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_PRESCALER_ADC] = RCC_CFGR_ADCPRE,
};
uint32 cfgr = RCC_BASE->CFGR;
cfgr &= ~masks[prescaler];
cfgr |= divider;
RCC_BASE->CFGR = cfgr;
#endif
}
#endif

View File

@ -1,642 +0,0 @@
/******************************************************************************
* 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 rcc.h
* @brief reset and clock control definitions and prototypes
*/
#include "libmaple_types.h"
#include "bitband.h"
#ifndef _RCC_H_
#define _RCC_H_
#ifdef __cplusplus
extern "C"{
#endif
/** RCC register map type */
typedef struct
{
__io uint32 CR; /*!< RCC clock control register, Address offset: 0x00 */
__io uint32 PLLCFGR; /*!< RCC PLL configuration register, Address offset: 0x04 */
__io uint32 CFGR; /*!< RCC clock configuration register, Address offset: 0x08 */
__io uint32 CIR; /*!< RCC clock interrupt register, Address offset: 0x0C */
__io uint32 AHB1RSTR; /*!< RCC AHB1 peripheral reset register, Address offset: 0x10 */
__io uint32 AHB2RSTR; /*!< RCC AHB2 peripheral reset register, Address offset: 0x14 */
__io uint32 AHB3RSTR; /*!< RCC AHB3 peripheral reset register, Address offset: 0x18 */
uint32 RESERVED0; /*!< Reserved, 0x1C */
__io uint32 APB1RSTR; /*!< RCC APB1 peripheral reset register, Address offset: 0x20 */
__io uint32 APB2RSTR; /*!< RCC APB2 peripheral reset register, Address offset: 0x24 */
uint32 RESERVED1[2]; /*!< Reserved, 0x28-0x2C */
__io uint32 AHB1ENR; /*!< RCC AHB1 peripheral clock register, Address offset: 0x30 */
__io uint32 AHB2ENR; /*!< RCC AHB2 peripheral clock register, Address offset: 0x34 */
__io uint32 AHB3ENR; /*!< RCC AHB3 peripheral clock register, Address offset: 0x38 */
uint32 RESERVED2; /*!< Reserved, 0x3C */
__io uint32 APB1ENR; /*!< RCC APB1 peripheral clock enable register, Address offset: 0x40 */
__io uint32 APB2ENR; /*!< RCC APB2 peripheral clock enable register, Address offset: 0x44 */
uint32 RESERVED3[2]; /*!< Reserved, 0x48-0x4C */
__io uint32 AHB1LPENR; /*!< RCC AHB1 peripheral clock enable in low power mode register, Address offset: 0x50 */
__io uint32 AHB2LPENR; /*!< RCC AHB2 peripheral clock enable in low power mode register, Address offset: 0x54 */
__io uint32 AHB3LPENR; /*!< RCC AHB3 peripheral clock enable in low power mode register, Address offset: 0x58 */
uint32 RESERVED4; /*!< Reserved, 0x5C */
__io uint32 APB1LPENR; /*!< RCC APB1 peripheral clock enable in low power mode register, Address offset: 0x60 */
__io uint32 APB2LPENR; /*!< RCC APB2 peripheral clock enable in low power mode register, Address offset: 0x64 */
uint32 RESERVED5[2]; /*!< Reserved, 0x68-0x6C */
__io uint32 BDCR; /*!< RCC Backup domain control register, Address offset: 0x70 */
__io uint32 CSR; /*!< RCC clock control & status register, Address offset: 0x74 */
uint32 RESERVED6[2]; /*!< Reserved, 0x78-0x7C */
__io uint32 SSCGR; /*!< RCC spread spectrum clock generation register, Address offset: 0x80 */
__io uint32 PLLI2SCFGR; /*!< RCC PLLI2S configuration register, Address offset: 0x84 */
} rcc_reg_map;
/** RCC register map base pointer */
//#define RCC_BASE ((struct rcc_reg_map*)0x40021000)
#define RCC_BASE ((rcc_reg_map*)0x40023800)
/*
* 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 BIT(RCC_CR_PLLRDY_BIT)
#define RCC_CR_PLLON BIT(RCC_CR_PLLON_BIT)
#define RCC_CR_CSSON BIT(RCC_CR_CSSON_BIT)
#define RCC_CR_HSEBYP BIT(RCC_CR_HSEBYP_BIT)
#define RCC_CR_HSERDY BIT(RCC_CR_HSERDY_BIT)
#define RCC_CR_HSEON BIT(RCC_CR_HSEON_BIT)
#define RCC_CR_HSICAL (0xFF << 8)
#define RCC_CR_HSITRIM (0x1F << 3)
#define RCC_CR_HSIRDY BIT(RCC_CR_HSIRDY_BIT)
#define RCC_CR_HSION BIT(RCC_CR_HSION_BIT)
/* Clock configuration register */
#define RCC_CFGR_USBPRE_BIT 22
#define RCC_CFGR_PLLXTPRE_BIT 17
#define RCC_CFGR_PLLSRC_BIT 16
#define RCC_CFGR_MCO (0x3 << 24)
#define RCC_CFGR_USBPRE BIT(RCC_CFGR_USBPRE_BIT)
#define RCC_CFGR_PLLMUL (0xF << 18)
#define RCC_CFGR_PLLXTPRE BIT(RCC_CFGR_PLLXTPRE_BIT)
#define RCC_CFGR_PLLSRC BIT(RCC_CFGR_PLLSRC_BIT)
#define RCC_CFGR_ADCPRE (0x3 << 14)
#define RCC_CFGR_PPRE2 (0x7 << 11)
#define RCC_CFGR_PPRE1 (0x7 << 8)
#define RCC_CFGR_HPRE (0xF << 4)
#define RCC_CFGR_SWS (0x3 << 2)
#define RCC_CFGR_SWS_PLL (0x2 << 2)
#define RCC_CFGR_SWS_HSE (0x1 << 2)
#define RCC_CFGR_SW 0x3
#define RCC_CFGR_SW_PLL 0x2
#define RCC_CFGR_SW_HSE 0x1
#define RCC_CFGR_MCO1Source_HSI ((uint32_t)0x00000000)
#define RCC_CFGR_MCO1Source_LSE ((uint32_t)0x00200000)
#define RCC_CFGR_MCO1Source_HSE ((uint32_t)0x00400000)
#define RCC_CFGR_MCO1Source_PLLCLK ((uint32_t)0x00600000)
#define RCC_CFGR_MCO1Div_1 ((uint32_t)0x00000000)
#define RCC_CFGR_MCO1Div_2 ((uint32_t)0x04000000)
#define RCC_CFGR_MCO1Div_3 ((uint32_t)0x05000000)
#define RCC_CFGR_MCO1Div_4 ((uint32_t)0x06000000)
#define RCC_CFGR_MCO1Div_5 ((uint32_t)0x07000000)
#define RCC_CFGR_MCO1_RESET_MASK ((uint32_t)0xF89FFFFF)
/* 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 BIT(RCC_CIR_CSSC_BIT)
#define RCC_CIR_PLLRDYC BIT(RCC_CIR_PLLRDYC_BIT)
#define RCC_CIR_HSERDYC BIT(RCC_CIR_HSERDYC_BIT)
#define RCC_CIR_HSIRDYC BIT(RCC_CIR_HSIRDYC_BIT)
#define RCC_CIR_LSERDYC BIT(RCC_CIR_LSERDYC_BIT)
#define RCC_CIR_LSIRDYC BIT(RCC_CIR_LSIRDYC_BIT)
#define RCC_CIR_PLLRDYIE BIT(RCC_CIR_PLLRDYIE_BIT)
#define RCC_CIR_HSERDYIE BIT(RCC_CIR_HSERDYIE_BIT)
#define RCC_CIR_HSIRDYIE BIT(RCC_CIR_HSIRDYIE_BIT)
#define RCC_CIR_LSERDYIE BIT(RCC_CIR_LSERDYIE_BIT)
#define RCC_CIR_LSIRDYIE BIT(RCC_CIR_LSIRDYIE_BIT)
#define RCC_CIR_CSSF BIT(RCC_CIR_CSSF_BIT)
#define RCC_CIR_PLLRDYF BIT(RCC_CIR_PLLRDYF_BIT)
#define RCC_CIR_HSERDYF BIT(RCC_CIR_HSERDYF_BIT)
#define RCC_CIR_HSIRDYF BIT(RCC_CIR_HSIRDYF_BIT)
#define RCC_CIR_LSERDYF BIT(RCC_CIR_LSERDYF_BIT)
#define RCC_CIR_LSIRDYF BIT(RCC_CIR_LSIRDYF_BIT)
/* APB2 peripheral reset register */
#define RCC_APB2RSTR_TIM11RST_BIT 21
#define RCC_APB2RSTR_TIM10RST_BIT 20
#define RCC_APB2RSTR_TIM9RST_BIT 19
#define RCC_APB2RSTR_ADC3RST_BIT 15
#define RCC_APB2RSTR_USART1RST_BIT 14
#define RCC_APB2RSTR_TIM8RST_BIT 13
#define RCC_APB2RSTR_SPI1RST_BIT 12
#define RCC_APB2RSTR_TIM1RST_BIT 11
#define RCC_APB2RSTR_ADC2RST_BIT 10
#define RCC_APB2RSTR_ADC1RST_BIT 9
#define RCC_APB2RSTR_IOPGRST_BIT 8
#define RCC_APB2RSTR_IOPFRST_BIT 7
#define RCC_APB2RSTR_IOPERST_BIT 6
#define RCC_APB2RSTR_IOPDRST_BIT 5
#define RCC_APB2RSTR_IOPCRST_BIT 4
#define RCC_APB2RSTR_IOPBRST_BIT 3
#define RCC_APB2RSTR_IOPARST_BIT 2
#define RCC_APB2RSTR_AFIORST_BIT 0
#define RCC_APB2RSTR_TIM11RST BIT(RCC_APB2RSTR_TIM11RST_BIT)
#define RCC_APB2RSTR_TIM10RST BIT(RCC_APB2RSTR_TIM10RST_BIT)
#define RCC_APB2RSTR_TIM9RST BIT(RCC_APB2RSTR_TIM9RST_BIT)
#define RCC_APB2RSTR_ADC3RST BIT(RCC_APB2RSTR_ADC3RST_BIT)
#define RCC_APB2RSTR_USART1RST BIT(RCC_APB2RSTR_USART1RST_BIT)
#define RCC_APB2RSTR_TIM8RST BIT(RCC_APB2RSTR_TIM8RST_BIT)
#define RCC_APB2RSTR_SPI1RST BIT(RCC_APB2RSTR_SPI1RST_BIT)
#define RCC_APB2RSTR_TIM1RST BIT(RCC_APB2RSTR_TIM1RST_BIT)
#define RCC_APB2RSTR_ADC2RST BIT(RCC_APB2RSTR_ADC2RST_BIT)
#define RCC_APB2RSTR_ADC1RST BIT(RCC_APB2RSTR_ADC1RST_BIT)
#define RCC_APB2RSTR_IOPGRST BIT(RCC_APB2RSTR_IOPGRST_BIT)
#define RCC_APB2RSTR_IOPFRST BIT(RCC_APB2RSTR_IOPFRST_BIT)
#define RCC_APB2RSTR_IOPERST BIT(RCC_APB2RSTR_IOPERST_BIT)
#define RCC_APB2RSTR_IOPDRST BIT(RCC_APB2RSTR_IOPDRST_BIT)
#define RCC_APB2RSTR_IOPCRST BIT(RCC_APB2RSTR_IOPCRST_BIT)
#define RCC_APB2RSTR_IOPBRST BIT(RCC_APB2RSTR_IOPBRST_BIT)
#define RCC_APB2RSTR_IOPARST BIT(RCC_APB2RSTR_IOPARST_BIT)
#define RCC_APB2RSTR_AFIORST BIT(RCC_APB2RSTR_AFIORST_BIT)
/* APB1 peripheral reset register */
#define RCC_APB1RSTR_DACRST_BIT 29
#define RCC_APB1RSTR_PWRRST_BIT 28
#define RCC_APB1RSTR_BKPRST_BIT 27
#define RCC_APB1RSTR_CANRST_BIT 25
#define RCC_APB1RSTR_USBRST_BIT 23
#define RCC_APB1RSTR_I2C2RST_BIT 22
#define RCC_APB1RSTR_I2C1RST_BIT 21
#define RCC_APB1RSTR_UART5RST_BIT 20
#define RCC_APB1RSTR_UART4RST_BIT 19
#define RCC_APB1RSTR_USART3RST_BIT 18
#define RCC_APB1RSTR_USART2RST_BIT 17
#define RCC_APB1RSTR_SPI3RST_BIT 15
#define RCC_APB1RSTR_SPI2RST_BIT 14
#define RCC_APB1RSTR_WWDRST_BIT 11
#define RCC_APB1RSTR_TIM14RST_BIT 8
#define RCC_APB1RSTR_TIM13RST_BIT 7
#define RCC_APB1RSTR_TIM12RST_BIT 6
#define RCC_APB1RSTR_TIM7RST_BIT 5
#define RCC_APB1RSTR_TIM6RST_BIT 4
#define RCC_APB1RSTR_TIM5RST_BIT 3
#define RCC_APB1RSTR_TIM4RST_BIT 2
#define RCC_APB1RSTR_TIM3RST_BIT 1
#define RCC_APB1RSTR_TIM2RST_BIT 0
#define RCC_APB1RSTR_DACRST BIT(RCC_APB1RSTR_DACRST_BIT)
#define RCC_APB1RSTR_PWRRST BIT(RCC_APB1RSTR_PWRRST_BIT)
#define RCC_APB1RSTR_BKPRST BIT(RCC_APB1RSTR_BKPRST_BIT)
#define RCC_APB1RSTR_CANRST BIT(RCC_APB1RSTR_CANRST_BIT)
#define RCC_APB1RSTR_USBRST BIT(RCC_APB1RSTR_USBRST_BIT)
#define RCC_APB1RSTR_I2C2RST BIT(RCC_APB1RSTR_I2C2RST_BIT)
#define RCC_APB1RSTR_I2C1RST BIT(RCC_APB1RSTR_I2C1RST_BIT)
#define RCC_APB1RSTR_UART5RST BIT(RCC_APB1RSTR_UART5RST_BIT)
#define RCC_APB1RSTR_UART4RST BIT(RCC_APB1RSTR_UART4RST_BIT)
#define RCC_APB1RSTR_USART3RST BIT(RCC_APB1RSTR_USART3RST_BIT)
#define RCC_APB1RSTR_USART2RST BIT(RCC_APB1RSTR_USART2RST_BIT)
#define RCC_APB1RSTR_SPI3RST BIT(RCC_APB1RSTR_SPI3RST_BIT)
#define RCC_APB1RSTR_SPI2RST BIT(RCC_APB1RSTR_SPI2RST_BIT)
#define RCC_APB1RSTR_WWDRST BIT(RCC_APB1RSTR_WWDRST_BIT)
#define RCC_APB1RSTR_TIM14RST BIT(RCC_APB1RSTR_TIM14RST_BIT)
#define RCC_APB1RSTR_TIM13RST BIT(RCC_APB1RSTR_TIM13RST_BIT)
#define RCC_APB1RSTR_TIM12RST BIT(RCC_APB1RSTR_TIM12RST_BIT)
#define RCC_APB1RSTR_TIM7RST BIT(RCC_APB1RSTR_TIM7RST_BIT)
#define RCC_APB1RSTR_TIM6RST BIT(RCC_APB1RSTR_TIM6RST_BIT)
#define RCC_APB1RSTR_TIM5RST BIT(RCC_APB1RSTR_TIM5RST_BIT)
#define RCC_APB1RSTR_TIM4RST BIT(RCC_APB1RSTR_TIM4RST_BIT)
#define RCC_APB1RSTR_TIM3RST BIT(RCC_APB1RSTR_TIM3RST_BIT)
#define RCC_APB1RSTR_TIM2RST BIT(RCC_APB1RSTR_TIM2RST_BIT)
/* AHB peripheral clock enable register */
#define RCC_AHBENR_SDIOEN_BIT 10
#define RCC_AHBENR_FSMCEN_BIT 8
#define RCC_AHBENR_CRCEN_BIT 7
#define RCC_AHBENR_FLITFEN_BIT 4
#define RCC_AHBENR_SRAMEN_BIT 2
#define RCC_AHBENR_DMA2EN_BIT 1
#define RCC_AHBENR_DMA1EN_BIT 0
#define RCC_AHBENR_SDIOEN BIT(RCC_AHBENR_SDIOEN_BIT)
#define RCC_AHBENR_FSMCEN BIT(RCC_AHBENR_FSMCEN_BIT)
#define RCC_AHBENR_CRCEN BIT(RCC_AHBENR_CRCEN_BIT)
#define RCC_AHBENR_FLITFEN BIT(RCC_AHBENR_FLITFEN_BIT)
#define RCC_AHBENR_SRAMEN BIT(RCC_AHBENR_SRAMEN_BIT)
#define RCC_AHBENR_DMA2EN BIT(RCC_AHBENR_DMA2EN_BIT)
#define RCC_AHBENR_DMA1EN BIT(RCC_AHBENR_DMA1EN_BIT)
/* APB2 peripheral clock enable register */
#define RCC_APB2ENR_TIM11EN_BIT 21
#define RCC_APB2ENR_TIM10EN_BIT 20
#define RCC_APB2ENR_TIM9EN_BIT 19
#define RCC_APB2ENR_ADC3EN_BIT 15
#define RCC_APB2ENR_USART1EN_BIT 14
#define RCC_APB2ENR_TIM8EN_BIT 13
#define RCC_APB2ENR_SPI1EN_BIT 12
#define RCC_APB2ENR_TIM1EN_BIT 11
#define RCC_APB2ENR_ADC2EN_BIT 10
#define RCC_APB2ENR_ADC1EN_BIT 9
#define RCC_APB2ENR_IOPGEN_BIT 8
#define RCC_APB2ENR_IOPFEN_BIT 7
#define RCC_APB2ENR_IOPEEN_BIT 6
#define RCC_APB2ENR_IOPDEN_BIT 5
#define RCC_APB2ENR_IOPCEN_BIT 4
#define RCC_APB2ENR_IOPBEN_BIT 3
#define RCC_APB2ENR_IOPAEN_BIT 2
#define RCC_APB2ENR_AFIOEN_BIT 0
#define RCC_APB2ENR_TIM11EN BIT(RCC_APB2ENR_TIM11EN_BIT)
#define RCC_APB2ENR_TIM10EN BIT(RCC_APB2ENR_TIM10EN_BIT)
#define RCC_APB2ENR_TIM9EN BIT(RCC_APB2ENR_TIM9EN_BIT)
#define RCC_APB2ENR_ADC3EN BIT(RCC_APB2ENR_ADC3EN_BIT)
#define RCC_APB2ENR_USART1EN BIT(RCC_APB2ENR_USART1EN_BIT)
#define RCC_APB2ENR_TIM8EN BIT(RCC_APB2ENR_TIM8EN_BIT)
#define RCC_APB2ENR_SPI1EN BIT(RCC_APB2ENR_SPI1EN_BIT)
#define RCC_APB2ENR_TIM1EN BIT(RCC_APB2ENR_TIM1EN_BIT)
#define RCC_APB2ENR_ADC2EN BIT(RCC_APB2ENR_ADC2EN_BIT)
#define RCC_APB2ENR_ADC1EN BIT(RCC_APB2ENR_ADC1EN_BIT)
#define RCC_APB2ENR_IOPGEN BIT(RCC_APB2ENR_IOPGEN_BIT)
#define RCC_APB2ENR_IOPFEN BIT(RCC_APB2ENR_IOPFEN_BIT)
#define RCC_APB2ENR_IOPEEN BIT(RCC_APB2ENR_IOPEEN_BIT)
#define RCC_APB2ENR_IOPDEN BIT(RCC_APB2ENR_IOPDEN_BIT)
#define RCC_APB2ENR_IOPCEN BIT(RCC_APB2ENR_IOPCEN_BIT)
#define RCC_APB2ENR_IOPBEN BIT(RCC_APB2ENR_IOPBEN_BIT)
#define RCC_APB2ENR_IOPAEN BIT(RCC_APB2ENR_IOPAEN_BIT)
#define RCC_APB2ENR_AFIOEN BIT(RCC_APB2ENR_AFIOEN_BIT)
/* APB1 peripheral clock enable register */
#define RCC_APB1ENR_DACEN_BIT 29
#define RCC_APB1ENR_PWREN_BIT 28
#define RCC_APB1ENR_BKPEN_BIT 27
#define RCC_APB1ENR_CANEN_BIT 25
#define RCC_APB1ENR_USBEN_BIT 23
#define RCC_APB1ENR_I2C2EN_BIT 22
#define RCC_APB1ENR_I2C1EN_BIT 21
#define RCC_APB1ENR_UART5EN_BIT 20
#define RCC_APB1ENR_UART4EN_BIT 19
#define RCC_APB1ENR_USART3EN_BIT 18
#define RCC_APB1ENR_USART2EN_BIT 17
#define RCC_APB1ENR_SPI3EN_BIT 15
#define RCC_APB1ENR_SPI2EN_BIT 14
#define RCC_APB1ENR_WWDEN_BIT 11
#define RCC_APB1ENR_TIM14EN_BIT 8
#define RCC_APB1ENR_TIM13EN_BIT 7
#define RCC_APB1ENR_TIM12EN_BIT 6
#define RCC_APB1ENR_TIM7EN_BIT 5
#define RCC_APB1ENR_TIM6EN_BIT 4
#define RCC_APB1ENR_TIM5EN_BIT 3
#define RCC_APB1ENR_TIM4EN_BIT 2
#define RCC_APB1ENR_TIM3EN_BIT 1
#define RCC_APB1ENR_TIM2EN_BIT 0
#define RCC_APB1ENR_DACEN BIT(RCC_APB1ENR_DACEN_BIT)
#define RCC_APB1ENR_PWREN BIT(RCC_APB1ENR_PWREN_BIT)
#define RCC_APB1ENR_BKPEN BIT(RCC_APB1ENR_BKPEN_BIT)
#define RCC_APB1ENR_CANEN BIT(RCC_APB1ENR_CANEN_BIT)
#define RCC_APB1ENR_USBEN BIT(RCC_APB1ENR_USBEN_BIT)
#define RCC_APB1ENR_I2C2EN BIT(RCC_APB1ENR_I2C2EN_BIT)
#define RCC_APB1ENR_I2C1EN BIT(RCC_APB1ENR_I2C1EN_BIT)
#define RCC_APB1ENR_UART5EN BIT(RCC_APB1ENR_UART5EN_BIT)
#define RCC_APB1ENR_UART4EN BIT(RCC_APB1ENR_UART4EN_BIT)
#define RCC_APB1ENR_USART3EN BIT(RCC_APB1ENR_USART3EN_BIT)
#define RCC_APB1ENR_USART2EN BIT(RCC_APB1ENR_USART2EN_BIT)
#define RCC_APB1ENR_SPI3EN BIT(RCC_APB1ENR_SPI3EN_BIT)
#define RCC_APB1ENR_SPI2EN BIT(RCC_APB1ENR_SPI2EN_BIT)
#define RCC_APB1ENR_WWDEN BIT(RCC_APB1ENR_WWDEN_BIT)
#define RCC_APB1ENR_TIM14EN BIT(RCC_APB1ENR_TIM14EN_BIT)
#define RCC_APB1ENR_TIM13EN BIT(RCC_APB1ENR_TIM13EN_BIT)
#define RCC_APB1ENR_TIM12EN BIT(RCC_APB1ENR_TIM12EN_BIT)
#define RCC_APB1ENR_TIM7EN BIT(RCC_APB1ENR_TIM7EN_BIT)
#define RCC_APB1ENR_TIM6EN BIT(RCC_APB1ENR_TIM6EN_BIT)
#define RCC_APB1ENR_TIM5EN BIT(RCC_APB1ENR_TIM5EN_BIT)
#define RCC_APB1ENR_TIM4EN BIT(RCC_APB1ENR_TIM4EN_BIT)
#define RCC_APB1ENR_TIM3EN BIT(RCC_APB1ENR_TIM3EN_BIT)
#define RCC_APB1ENR_TIM2EN BIT(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 BIT(RCC_BDCR_BDRST_BIT)
#define RCC_BDCR_RTCEN BIT(RCC_BDCR_RTC_BIT)
#define RCC_BDCR_RTCSEL (0x3 << 8)
#define RCC_BDCR_RTCSEL_NONE (0x0 << 8)
#define RCC_BDCR_RTCSEL_LSE (0x1 << 8)
#define RCC_BDCR_RTCSEL_LSI (0x2 << 8)
#define RCC_BDCR_RTCSEL_HSE (0x3 << 8)
#define RCC_BDCR_LSEBYP BIT(RCC_BDCR_LSEBYP_BIT)
#define RCC_BDCR_LSERDY BIT(RCC_BDCR_LSERDY_BIT)
#define RCC_BDCR_LSEON BIT(RCC_BDCR_LSEON_BIT)
/* Control/status register */
#define RCC_CSR_LPWRRSTF_BIT 31
#define RCC_CSR_WWDGRSTF_BIT 30
#define RCC_CSR_IWDGRSTF_BIT 29
#define RCC_CSR_SFTRSTF_BIT 28
#define RCC_CSR_PORRSTF_BIT 27
#define RCC_CSR_PINRSTF_BIT 26
#define RCC_CSR_RMVF_BIT 24
#define RCC_CSR_LSIRDY_BIT 1
#define RCC_CSR_LSION_BIT 0
#define RCC_CSR_LPWRRSTF BIT(RCC_CSR_LPWRRSTF_BIT)
#define RCC_CSR_WWDGRSTF BIT(RCC_CSR_WWDGRSTF_BIT)
#define RCC_CSR_IWDGRSTF BIT(RCC_CSR_IWDGRSTF_BIT)
#define RCC_CSR_SFTRSTF BIT(RCC_CSR_SFTRSTF_BIT)
#define RCC_CSR_PORRSTF BIT(RCC_CSR_PORRSTF_BIT)
#define RCC_CSR_PINRSTF BIT(RCC_CSR_PINRSTF_BIT)
#define RCC_CSR_RMVF BIT(RCC_CSR_RMVF_BIT)
#define RCC_CSR_LSIRDY BIT(RCC_CSR_LSIRDY_BIT)
#define RCC_CSR_LSION BIT(RCC_CSR_LSION_BIT)
/*
* Convenience routines
*/
/**
* SYSCLK sources
* @see rcc_clk_init()
*/
typedef enum rcc_sysclk_src {
RCC_CLKSRC_HSI = 0x0,
RCC_CLKSRC_HSE = 0x1,
RCC_CLKSRC_PLL = 0x2,
} rcc_sysclk_src;
/**
* PLL entry clock source
* @see rcc_clk_init()
*/
typedef enum rcc_pllsrc {
RCC_PLLSRC_HSE = (0x1 << 16),
RCC_PLLSRC_HSI_DIV_2 = (0x0 << 16)
} rcc_pllsrc;
/**
* PLL multipliers
* @see rcc_clk_init()
*/
typedef enum rcc_pll_multiplier {
RCC_PLLMUL_2 = (0x0 << 18),
RCC_PLLMUL_3 = (0x1 << 18),
RCC_PLLMUL_4 = (0x2 << 18),
RCC_PLLMUL_5 = (0x3 << 18),
RCC_PLLMUL_6 = (0x4 << 18),
RCC_PLLMUL_7 = (0x5 << 18),
RCC_PLLMUL_8 = (0x6 << 18),
RCC_PLLMUL_9 = (0x7 << 18),
RCC_PLLMUL_10 = (0x8 << 18),
RCC_PLLMUL_11 = (0x9 << 18),
RCC_PLLMUL_12 = (0xA << 18),
RCC_PLLMUL_13 = (0xB << 18),
RCC_PLLMUL_14 = (0xC << 18),
RCC_PLLMUL_15 = (0xD << 18),
RCC_PLLMUL_16 = (0xE << 18),
} rcc_pll_multiplier;
/**
* @brief Identifies bus and clock line for a peripheral.
*
* Also generally useful as a unique identifier for that peripheral
* (or its corresponding device struct).
*/
typedef enum rcc_clk_id {
RCC_GPIOA,
RCC_GPIOB,
RCC_GPIOC,
RCC_GPIOD,
// RCC_AFIO,
RCC_ADC1,
RCC_ADC2,
RCC_ADC3,
RCC_USART1,
RCC_USART2,
RCC_USART3,
RCC_TIMER1,
RCC_TIMER2,
RCC_TIMER3,
RCC_TIMER4,
RCC_SPI1,
RCC_SPI2,
RCC_DMA1,
RCC_PWR,
RCC_BKP,
RCC_I2C1,
RCC_I2C2,
RCC_CRC,
// RCC_FLITF,
// RCC_SRAM,
RCC_GPIOE,
RCC_GPIOF,
RCC_GPIOG,
RCC_UART4,
RCC_UART5,
RCC_TIMER5,
RCC_TIMER6,
RCC_TIMER7,
RCC_TIMER8,
RCC_FSMC,
RCC_DAC,
RCC_DMA2,
RCC_SDIO,
RCC_SPI3,
RCC_TIMER9,
RCC_TIMER10,
RCC_TIMER11,
RCC_TIMER12,
RCC_TIMER13,
RCC_TIMER14,
RCC_USBFS,
RCC_SYSCFG,
RCC_SPI4
} rcc_clk_id;
void rcc_clk_init(rcc_sysclk_src sysclk_src,
rcc_pllsrc pll_src,
rcc_pll_multiplier pll_mul);
void rcc_clk_disable(rcc_clk_id device);
void rcc_clk_enable(rcc_clk_id device);
void rcc_reset_dev(rcc_clk_id device);
void SetupClock72MHz();
void SetupClock120MHz();
void SetupClock168MHz();
typedef enum rcc_clk_domain {
RCC_APB1,
RCC_APB2,
RCC_AHB1,
RCC_AHB2,
RCC_AHB3
} rcc_clk_domain;
rcc_clk_domain rcc_dev_clk(rcc_clk_id device);
uint32 rcc_dev_clk_speed(rcc_clk_id id);
uint32 rcc_dev_timer_clk_speed(rcc_clk_id id);
/**
* Prescaler identifiers
* @see rcc_set_prescaler()
*/
typedef enum rcc_prescaler {
RCC_PRESCALER_AHB,
RCC_PRESCALER_APB1,
RCC_PRESCALER_APB2,
RCC_PRESCALER_USB,
RCC_PRESCALER_ADC
} rcc_prescaler;
/**
* ADC prescaler dividers
* @see rcc_set_prescaler()
*/
typedef enum rcc_adc_divider {
RCC_ADCPRE_PCLK_DIV_2 = 0x0 << 14,
RCC_ADCPRE_PCLK_DIV_4 = 0x1 << 14,
RCC_ADCPRE_PCLK_DIV_6 = 0x2 << 14,
RCC_ADCPRE_PCLK_DIV_8 = 0x3 << 14,
} rcc_adc_divider;
/**
* APB1 prescaler dividers
* @see rcc_set_prescaler()
*/
typedef enum rcc_apb1_divider {
RCC_APB1_HCLK_DIV_1 = 0x0 << 8,
RCC_APB1_HCLK_DIV_2 = 0x4 << 8,
RCC_APB1_HCLK_DIV_4 = 0x5 << 8,
RCC_APB1_HCLK_DIV_8 = 0x6 << 8,
RCC_APB1_HCLK_DIV_16 = 0x7 << 8,
} rcc_apb1_divider;
/**
* APB2 prescaler dividers
* @see rcc_set_prescaler()
*/
typedef enum rcc_apb2_divider {
RCC_APB2_HCLK_DIV_1 = 0x0 << 11,
RCC_APB2_HCLK_DIV_2 = 0x4 << 11,
RCC_APB2_HCLK_DIV_4 = 0x5 << 11,
RCC_APB2_HCLK_DIV_8 = 0x6 << 11,
RCC_APB2_HCLK_DIV_16 = 0x7 << 11,
} rcc_apb2_divider;
/**
* AHB prescaler dividers
* @see rcc_set_prescaler()
*/
typedef enum rcc_ahb_divider {
RCC_AHB_SYSCLK_DIV_1 = 0x0 << 4,
RCC_AHB_SYSCLK_DIV_2 = 0x8 << 4,
RCC_AHB_SYSCLK_DIV_4 = 0x9 << 4,
RCC_AHB_SYSCLK_DIV_8 = 0xA << 4,
RCC_AHB_SYSCLK_DIV_16 = 0xB << 4,
RCC_AHB_SYSCLK_DIV_32 = 0xC << 4,
RCC_AHB_SYSCLK_DIV_64 = 0xD << 4,
RCC_AHB_SYSCLK_DIV_128 = 0xD << 4,
RCC_AHB_SYSCLK_DIV_256 = 0xE << 4,
RCC_AHB_SYSCLK_DIV_512 = 0xF << 4,
} rcc_ahb_divider;
void rcc_set_prescaler(rcc_prescaler prescaler, uint32 divider);
/**
* @brief Start the low speed internal oscillatior
*/
static inline void rcc_start_lsi(void) {
*bb_perip(&RCC_BASE->CSR, RCC_CSR_LSION_BIT) = 1;
while (*bb_perip(&RCC_BASE->CSR, RCC_CSR_LSIRDY_BIT) == 0);
}
/* FIXME [0.0.13] Just have data point to an rcc_pll_multiplier! */
/**
* @brief Start the low speed external oscillatior
*/
static inline void rcc_start_lse(void) {
bb_peri_set_bit(&RCC_BASE->BDCR, RCC_BDCR_LSEBYP_BIT, 0);
bb_peri_set_bit(&RCC_BASE->BDCR, RCC_BDCR_LSEON_BIT, 1);
while (bb_peri_get_bit(&RCC_BASE->BDCR, RCC_BDCR_LSERDY_BIT ) == 0);
}
/*
* Deprecated bits.
*/
static inline void rcc_start_hse(void) { // Added to support RTClock
// *bb_perip(&RCC_BASE->CR, RCC_CR_HSEON_BIT) = 1;
while (bb_peri_get_bit(&RCC_BASE->CR, RCC_CR_HSERDY_BIT) == 0);
}
#ifdef __cplusplus
} // extern "C"
#endif
#endif

View File

@ -11,8 +11,8 @@ USB_OTG_CORE_HANDLE USB_OTG_dev;
void setupUSB (void) {
#define USB_DISC_DEV GPIOD
#define USB_DISC_PIN 11
#define USB_DISC_DEV GPIOA
#define USB_DISC_PIN 12
gpio_set_mode(USB_DISC_DEV, USB_DISC_PIN, GPIO_OUTPUT_OD); // ala42
#ifdef USB_DISC_OD

View File

@ -48,7 +48,7 @@
* @brief Stores STM32-specific information related to a given Maple pin.
* @see PIN_MAP
*/
#ifdef BOARD_black_f4
#ifdef BOARD_generic_f407v
// restructure members to build consecutive pairs
typedef struct stm32_pin_info {
gpio_dev *gpio_device; /**< Maple pin's GPIO device */

View File

@ -121,7 +121,7 @@ PB0,PB1,PB2,PB3,PB4,PB5,PB6,PB7,PB8,PB9,PB10,PB11,PB12,PB13,PB14,PB15,
PC0,PC1,PC2,PC3,PC4,PC5,PC6,PC7,PC8,PC9,PC10,PC11,PC12,PC13,PC14,PC15,
PD0,PD1,PD2,PD3,PD4,PD5,PD6,PD7,PD8,PD9,PD10,PD11,PD12,PD13,PD14,PD15,
PE0,PE1,PE2,PE3,PE4,PE5,PE6,PE7,PE8,PE9,PE10,PE11,PE12,PE13,PE14,PE15,
#if 0
#if 0 // not available on LQFP100 package
PF0,PF1,PF2,PF3,PF4,PF5,PF6,PF7,PF8,PF9,PF10,PF11,PF12,PF13,PF14,PF15,
PG0,PG1,PG2,PG3,PG4,PG5,PG6,PG7,PG8,PG9,PG10,PG11,PG12,PG13,PG14,PG15
#endif

View File

@ -25,14 +25,14 @@
*****************************************************************************/
/**
* @file black_f4.cpp
* @file generic_f407v.cpp
* @author ala42
* @brief black_f4 board file.
* @brief generic_f407v board file.
*/
#ifdef BOARD_black_f4
#ifdef BOARD_generic_f407v
#include "black_f4.h"
#include "generic_f407v.h"
//#include "fsmc.h"
#include "gpio.h"

View File

@ -0,0 +1,130 @@
/******************************************************************************
* 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 generic_f407v.h
* @author Marti Bolivar <mbolivar@leaflabs.com>
* @brief Private include file for Maple Native in boards.h
*
* See maple.h for more information on these definitions.
*/
#ifndef _BOARD_GENERIC_F407V_H_
#define _BOARD_GENERIC_F407V_H_
#define Port2Pin(port, bit) ((port-'A')*16+bit)
#define CYCLES_PER_MICROSECOND 168
#undef STM32_PCLK1
#undef STM32_PCLK2
#define STM32_PCLK1 (CYCLES_PER_MICROSECOND*1000000/4)
#define STM32_PCLK2 (CYCLES_PER_MICROSECOND*1000000/2)
#define SYSTICK_RELOAD_VAL (CYCLES_PER_MICROSECOND*1000-1)
#define BOARD_USB_DM_PIN PA11
#define BOARD_USB_DP_PIN PA12
#define BOARD_LED_PIN PA6 //Port2Pin('A', 6)
#define BOARD_LED2_PIN PA7 //Port2Pin('A', 7)
#define BOARD_BUTTON1_PIN PA0 //Port2Pin('A', 0)
#define BOARD_BUTTON2_PIN PE4 //Port2Pin('E', 4)
#define BOARD_BUTTON3_PIN PE3 //Port2Pin('E', 3)
#define BOARD_NR_USARTS 5
#define BOARD_USART1_TX_PIN PA9 //Port2Pin('A', 9)
#define BOARD_USART1_RX_PIN PA10 //Port2Pin('A',10)
#define BOARD_USART2_TX_PIN PA2 //Port2Pin('A', 2)
#define BOARD_USART2_RX_PIN PA3 //Port2Pin('A', 3)
#define BOARD_USART3_TX_PIN PB10 //Port2Pin('B',10)
#define BOARD_USART3_RX_PIN PB11 //Port2Pin('B',11)
#define BOARD_UART4_TX_PIN PA0 //Port2Pin('A', 0)
#define BOARD_UART4_RX_PIN PA1 //Port2Pin('A', 1)
#define BOARD_UART5_TX_PIN PC12 //Port2Pin('C',12)
#define BOARD_UART5_RX_PIN PD2 //Port2Pin('D', 2)
#define BOARD_NR_SPI 3
#define BOARD_SPI1_NSS_PIN PA4 //Port2Pin('A', 4)
#define BOARD_SPI1_SCK_PIN PA5 //Port2Pin('A', 5)
#define BOARD_SPI1_MISO_PIN PA6 //Port2Pin('A', 6)
#define BOARD_SPI1_MOSI_PIN PA7 //Port2Pin('A', 7)
#define BOARD_SPI1A_NSS_PIN PA15 //Port2Pin('A',15)
#define BOARD_SPI1A_SCK_PIN PB3 //Port2Pin('B', 3)
#define BOARD_SPI1A_MISO_PIN PB4 //Port2Pin('B', 4)
#define BOARD_SPI1A_MOSI_PIN PB5 //Port2Pin('B', 5)
#define BOARD_SPI2_NSS_PIN PB12 //Port2Pin('B',12)
#define BOARD_SPI2_SCK_PIN PB13 //Port2Pin('B',13)
#define BOARD_SPI2_MISO_PIN PB14 //Port2Pin('B',14)
#define BOARD_SPI2_MOSI_PIN PB15 //Port2Pin('B',15)
#define BOARD_SPI2A_NSS_PIN PB9 //Port2Pin('B', 9)
#define BOARD_SPI2A_SCK_PIN PB10 //Port2Pin('B',10)
#define BOARD_SPI2A_MISO_PIN PC2 //Port2Pin('C', 2)
#define BOARD_SPI2A_MOSI_PIN pc3 //Port2Pin('C', 3)
#define BOARD_SPI3_NSS_PIN PA15 //Port2Pin('A',15)
#define BOARD_SPI3_SCK_PIN PB3 //Port2Pin('B', 3)
#define BOARD_SPI3_MISO_PIN PB4 //Port2Pin('B', 4)
#define BOARD_SPI3_MOSI_PIN PB5 //Port2Pin('B', 5)
/* overlap with the SDIO interface for SD card
#define BOARD_SPI3A_NSS_PIN Port2Pin('A', 4)
#define BOARD_SPI3A_SCK_PIN Port2Pin('C',10)
#define BOARD_SPI3A_MISO_PIN Port2Pin('C',11)
#define BOARD_SPI3A_MOSI_PIN Port2Pin('C',12)
*/
#define BOARD_SDIO_D0 PC8 //Port2Pin('C', 8)
#define BOARD_SDIO_D1 PC9 //Port2Pin('C', 9)
#define BOARD_SDIO_D2 PC10 //Port2Pin('C',10)
#define BOARD_SDIO_D3 PC11 //Port2Pin('C',11)
#define BOARD_SDIO_CK PC12 //Port2Pin('C',12)
#define BOARD_SDIO_CMD PD2 //Port2Pin('D', 2)
#define BOARD_NR_GPIO_PINS 80
#define BOARD_NR_PWM_PINS 22
#define BOARD_NR_ADC_PINS 16
#define BOARD_NR_USED_PINS 22
#define BOARD_JTMS_SWDIO_PIN PA13 //Port2Pin('A',13)
#define BOARD_JTCK_SWCLK_PIN PA14 //Port2Pin('A',14)
#define BOARD_JTDI_PIN PA15 //Port2Pin('A',15)
#define BOARD_JTDO_PIN PB3 //Port2Pin('B', 3)
#define BOARD_NJTRST_PIN PB4 //Port2Pin('B', 4)
enum {
PA0,PA1,PA2,PA3,PA4,PA5,PA6,PA7,PA8,PA9,PA10,PA11,PA12,PA13,PA14,PA15,
PB0,PB1,PB2,PB3,PB4,PB5,PB6,PB7,PB8,PB9,PB10,PB11,PB12,PB13,PB14,PB15,
PC0,PC1,PC2,PC3,PC4,PC5,PC6,PC7,PC8,PC9,PC10,PC11,PC12,PC13,PC14,PC15,
PD0,PD1,PD2,PD3,PD4,PD5,PD6,PD7,PD8,PD9,PD10,PD11,PD12,PD13,PD14,PD15,
PE0,PE1,PE2,PE3,PE4,PE5,PE6,PE7,PE8,PE9,PE10,PE11,PE12,PE13,PE14,PE15,
#if 0 // not available on LQFP100 package
PF0,PF1,PF2,PF3,PF4,PF5,PF6,PF7,PF8,PF9,PF10,PF11,PF12,PF13,PF14,PF15,
PG0,PG1,PG2,PG3,PG4,PG5,PG6,PG7,PG8,PG9,PG10,PG11,PG12,PG13,PG14,PG15
#endif
};
#endif