renamed target from "black" to generic f407v + removed unused files
This commit is contained in:
parent
065f58684d
commit
5c9dc5ebfc
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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]);
|
||||
}
|
|
@ -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
|
||||
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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 = ®s->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
|
|
@ -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
|
||||
|
|
@ -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
|
|
@ -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
|
||||
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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
|
|
@ -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"
|
|
@ -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
|
Loading…
Reference in New Issue