Initial STM32F1 family support with two examples for STM32F103C8 (Blue Pill)

This commit is contained in:
Mariusz Ryndzionek
2021-09-26 17:08:22 +02:00
parent 1650983e46
commit bce909ec1e
14 changed files with 573 additions and 20 deletions

View File

@ -18,6 +18,7 @@ pub enum Pull {
Down,
}
#[cfg(gpio_v2)]
impl From<Pull> for vals::Pupdr {
fn from(pull: Pull) -> Self {
use Pull::*;
@ -36,11 +37,25 @@ impl From<Pull> for vals::Pupdr {
pub enum Speed {
Low,
Medium,
#[cfg(not(syscfg_f0))]
#[cfg(not(any(syscfg_f0, gpio_v1)))]
High,
VeryHigh,
}
#[cfg(gpio_v1)]
impl From<Speed> for vals::Mode {
fn from(speed: Speed) -> Self {
use Speed::*;
match speed {
Low => vals::Mode::OUTPUT2,
Medium => vals::Mode::OUTPUT,
VeryHigh => vals::Mode::OUTPUT50,
}
}
}
#[cfg(gpio_v2)]
impl From<Speed> for vals::Ospeedr {
fn from(speed: Speed) -> Self {
use Speed::*;
@ -68,9 +83,29 @@ impl<'d, T: Pin> Input<'d, T> {
cortex_m::interrupt::free(|_| unsafe {
let r = pin.block();
let n = pin.pin() as usize;
r.pupdr().modify(|w| w.set_pupdr(n, pull.into()));
r.otyper().modify(|w| w.set_ot(n, vals::Ot::PUSHPULL));
r.moder().modify(|w| w.set_moder(n, vals::Moder::INPUT));
#[cfg(gpio_v1)]
{
let crlh = if n < 8 { 0 } else { 1 };
match pull {
Pull::Up => r.bsrr().write(|w| w.set_bs(n, true)),
Pull::Down => r.bsrr().write(|w| w.set_br(n, true)),
Pull::None => {}
}
if pull == Pull::None {
r.cr(crlh)
.modify(|w| w.set_cnf(n % 8, vals::Cnf::OPENDRAIN));
} else {
r.cr(crlh)
.modify(|w| w.set_cnf(n % 8, vals::Cnf::ALTPUSHPULL));
}
r.cr(crlh).modify(|w| w.set_mode(n % 8, vals::Mode::INPUT));
}
#[cfg(gpio_v2)]
{
r.pupdr().modify(|w| w.set_pupdr(n, pull.into()));
r.otyper().modify(|w| w.set_ot(n, vals::Ot::PUSHPULL));
r.moder().modify(|w| w.set_moder(n, vals::Moder::INPUT));
}
});
Self {
@ -85,6 +120,13 @@ impl<'d, T: Pin> Drop for Input<'d, T> {
cortex_m::interrupt::free(|_| unsafe {
let r = self.pin.block();
let n = self.pin.pin() as usize;
#[cfg(gpio_v1)]
{
let crlh = if n < 8 { 0 } else { 1 };
r.cr(crlh)
.modify(|w| w.set_cnf(n % 8, vals::Cnf::OPENDRAIN));
}
#[cfg(gpio_v2)]
r.pupdr().modify(|w| w.set_pupdr(n, vals::Pupdr::FLOATING));
});
}
@ -129,10 +171,19 @@ impl<'d, T: Pin> Output<'d, T> {
cortex_m::interrupt::free(|_| unsafe {
let r = pin.block();
let n = pin.pin() as usize;
r.pupdr().modify(|w| w.set_pupdr(n, vals::Pupdr::FLOATING));
r.otyper().modify(|w| w.set_ot(n, vals::Ot::PUSHPULL));
pin.set_speed(speed);
r.moder().modify(|w| w.set_moder(n, vals::Moder::OUTPUT));
#[cfg(gpio_v1)]
{
let crlh = if n < 8 { 0 } else { 1 };
r.cr(crlh).modify(|w| w.set_cnf(n % 8, vals::Cnf::PUSHPULL));
r.cr(crlh).modify(|w| w.set_mode(n % 8, speed.into()));
}
#[cfg(gpio_v2)]
{
r.pupdr().modify(|w| w.set_pupdr(n, vals::Pupdr::FLOATING));
r.otyper().modify(|w| w.set_ot(n, vals::Ot::PUSHPULL));
pin.set_speed(speed);
r.moder().modify(|w| w.set_moder(n, vals::Moder::OUTPUT));
}
});
Self {
@ -147,8 +198,18 @@ impl<'d, T: Pin> Drop for Output<'d, T> {
cortex_m::interrupt::free(|_| unsafe {
let r = self.pin.block();
let n = self.pin.pin() as usize;
r.pupdr().modify(|w| w.set_pupdr(n, vals::Pupdr::FLOATING));
r.moder().modify(|w| w.set_moder(n, vals::Moder::INPUT));
#[cfg(gpio_v1)]
{
let crlh = if n < 8 { 0 } else { 1 };
r.cr(crlh)
.modify(|w| w.set_cnf(n % 8, vals::Cnf::OPENDRAIN));
r.cr(crlh).modify(|w| w.set_mode(n % 8, vals::Mode::INPUT));
}
#[cfg(gpio_v2)]
{
r.pupdr().modify(|w| w.set_pupdr(n, vals::Pupdr::FLOATING));
r.moder().modify(|w| w.set_moder(n, vals::Moder::INPUT));
}
});
}
}
@ -207,10 +268,25 @@ impl<'d, T: Pin> OutputOpenDrain<'d, T> {
cortex_m::interrupt::free(|_| unsafe {
let r = pin.block();
let n = pin.pin() as usize;
r.pupdr().modify(|w| w.set_pupdr(n, pull.into()));
r.otyper().modify(|w| w.set_ot(n, vals::Ot::OPENDRAIN));
pin.set_speed(speed);
r.moder().modify(|w| w.set_moder(n, vals::Moder::OUTPUT));
#[cfg(gpio_v1)]
{
let crlh = if n < 8 { 0 } else { 1 };
match pull {
Pull::Up => r.bsrr().write(|w| w.set_bs(n, true)),
Pull::Down => r.bsrr().write(|w| w.set_br(n, true)),
Pull::None => {}
}
r.cr(crlh).modify(|w| w.set_mode(n % 8, speed.into()));
r.cr(crlh)
.modify(|w| w.set_cnf(n % 8, vals::Cnf::OPENDRAIN));
}
#[cfg(gpio_v2)]
{
r.pupdr().modify(|w| w.set_pupdr(n, pull.into()));
r.otyper().modify(|w| w.set_ot(n, vals::Ot::OPENDRAIN));
pin.set_speed(speed);
r.moder().modify(|w| w.set_moder(n, vals::Moder::OUTPUT));
}
});
Self {
@ -225,8 +301,18 @@ impl<'d, T: Pin> Drop for OutputOpenDrain<'d, T> {
cortex_m::interrupt::free(|_| unsafe {
let r = self.pin.block();
let n = self.pin.pin() as usize;
r.pupdr().modify(|w| w.set_pupdr(n, vals::Pupdr::FLOATING));
r.moder().modify(|w| w.set_moder(n, vals::Moder::INPUT));
#[cfg(gpio_v1)]
{
let crlh = if n < 8 { 0 } else { 1 };
r.cr(crlh)
.modify(|w| w.set_cnf(n % 8, vals::Cnf::OPENDRAIN));
r.cr(crlh).modify(|w| w.set_mode(n % 8, vals::Mode::INPUT));
}
#[cfg(gpio_v2)]
{
r.pupdr().modify(|w| w.set_pupdr(n, vals::Pupdr::FLOATING));
r.moder().modify(|w| w.set_moder(n, vals::Moder::INPUT));
}
});
}
}
@ -307,6 +393,11 @@ pub(crate) mod sealed {
}
}
#[cfg(gpio_v1)]
unsafe fn set_as_af(&self, _af_num: u8, _af_type: OutputType) {
panic!("F1 alternate GPIO functions not supported yet!");
}
#[cfg(gpio_v2)]
unsafe fn set_as_af(&self, af_num: u8, af_type: OutputType) {
let pin = self._pin() as usize;
let block = self.block();
@ -333,11 +424,23 @@ pub(crate) mod sealed {
unsafe fn set_as_analog(&self) {
let pin = self._pin() as usize;
let block = self.block();
#[cfg(gpio_v1)]
{
let crlh = if pin < 8 { 0 } else { 1 };
block
.cr(crlh)
.modify(|w| w.set_cnf(pin % 8, vals::Cnf::PUSHPULL));
block
.cr(crlh)
.modify(|w| w.set_mode(pin % 8, vals::Mode::INPUT));
}
#[cfg(gpio_v2)]
block
.moder()
.modify(|w| w.set_moder(pin, vals::Moder::ANALOG));
}
#[cfg(gpio_v2)]
unsafe fn set_speed(&self, speed: Speed) {
let pin = self._pin() as usize;
self.block()