Enforce better safety guarentees
* Makes use of Rcc parameters rather than making RCC pointers * Applys CS parameters to GPIO functions that mutate the port non atomically * Cut down on build gating hell a bit
This commit is contained in:
parent
f54423aa9c
commit
7ea2af8a74
|
@ -15,6 +15,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
|
|||
### Changed
|
||||
|
||||
- Optimize delay implemenation (#42) - @david-sawatzke
|
||||
- Enforced more rigorous safety guarentees (#41 - Very breaking change) - @HarkonenBade
|
||||
|
||||
### Fixed
|
||||
|
||||
|
|
|
@ -29,40 +29,41 @@ fn main() -> ! {
|
|||
hal::stm32::Peripherals::take(),
|
||||
cortex_m::peripheral::Peripherals::take(),
|
||||
) {
|
||||
let gpioa = p.GPIOA.split();
|
||||
let rcc = p.RCC.constrain();
|
||||
let clocks = rcc.cfgr.sysclk(8.mhz()).freeze();
|
||||
|
||||
let mut syst = cp.SYST;
|
||||
|
||||
// Set source for SysTick counter, here full operating frequency (== 8MHz)
|
||||
syst.set_clock_source(Core);
|
||||
|
||||
// Set reload value, i.e. timer delay 8 MHz/counts
|
||||
syst.set_reload(8_000_000 - 1);
|
||||
|
||||
// Start SysTick counter
|
||||
syst.enable_counter();
|
||||
|
||||
// Start SysTick interrupt generation
|
||||
syst.enable_interrupt();
|
||||
|
||||
// USART1 at PA9 (TX) and PA10(RX)
|
||||
let tx = gpioa.pa9.into_alternate_af1();
|
||||
let rx = gpioa.pa10.into_alternate_af1();
|
||||
|
||||
// Initialiase UART
|
||||
let (mut tx, _) =
|
||||
hal::serial::Serial::usart1(p.USART1, (tx, rx), 115_200.bps(), clocks).split();
|
||||
|
||||
// Initialise ADC
|
||||
let adc = hal::adc::Adc::new(p.ADC);
|
||||
|
||||
// Output a friendly greeting
|
||||
tx.write_str("\n\rThis ADC example will read various values using the ADC and print them out to the serial terminal\r\n").ok();
|
||||
|
||||
// Move all components under Mutex supervision
|
||||
cortex_m::interrupt::free(move |cs| {
|
||||
let mut flash = p.FLASH;
|
||||
let mut rcc = p.RCC.configure().sysclk(8.mhz()).freeze(&mut flash);
|
||||
|
||||
let gpioa = p.GPIOA.split(&mut rcc);
|
||||
|
||||
let mut syst = cp.SYST;
|
||||
|
||||
// Set source for SysTick counter, here full operating frequency (== 8MHz)
|
||||
syst.set_clock_source(Core);
|
||||
|
||||
// Set reload value, i.e. timer delay 8 MHz/counts
|
||||
syst.set_reload(8_000_000 - 1);
|
||||
|
||||
// Start SysTick counter
|
||||
syst.enable_counter();
|
||||
|
||||
// Start SysTick interrupt generation
|
||||
syst.enable_interrupt();
|
||||
|
||||
// USART1 at PA9 (TX) and PA10(RX)
|
||||
let tx = gpioa.pa9.into_alternate_af1(cs);
|
||||
let rx = gpioa.pa10.into_alternate_af1(cs);
|
||||
|
||||
// Initialiase UART
|
||||
let (mut tx, _) =
|
||||
hal::serial::Serial::usart1(p.USART1, (tx, rx), 115_200.bps(), &mut rcc).split();
|
||||
|
||||
// Initialise ADC
|
||||
let adc = hal::adc::Adc::new(p.ADC, &mut rcc);
|
||||
|
||||
// Output a friendly greeting
|
||||
tx.write_str("\n\rThis ADC example will read various values using the ADC and print them out to the serial terminal\r\n").ok();
|
||||
|
||||
// Move all components under Mutex supervision
|
||||
*SHARED.borrow(cs).borrow_mut() = Some(Shared { adc, tx });
|
||||
});
|
||||
}
|
||||
|
|
|
@ -14,21 +14,26 @@ use cortex_m_rt::entry;
|
|||
#[entry]
|
||||
fn main() -> ! {
|
||||
if let Some(p) = stm32::Peripherals::take() {
|
||||
let gpioa = p.GPIOA.split();
|
||||
cortex_m::interrupt::free(move |cs| {
|
||||
let mut flash = p.FLASH;
|
||||
let mut rcc = p.RCC.configure().sysclk(8.mhz()).freeze(&mut flash);
|
||||
|
||||
/* (Re-)configure PA1 as output */
|
||||
let mut led = gpioa.pa1.into_push_pull_output();
|
||||
let gpioa = p.GPIOA.split(&mut rcc);
|
||||
|
||||
loop {
|
||||
/* Turn PA1 on a million times in a row */
|
||||
for _ in 0..1_000_000 {
|
||||
led.set_high();
|
||||
/* (Re-)configure PA1 as output */
|
||||
let mut led = gpioa.pa1.into_push_pull_output(cs);
|
||||
|
||||
loop {
|
||||
/* Turn PA1 on a million times in a row */
|
||||
for _ in 0..1_000_000 {
|
||||
led.set_high();
|
||||
}
|
||||
/* Then turn PA1 off a million times in a row */
|
||||
for _ in 0..1_000_000 {
|
||||
led.set_low();
|
||||
}
|
||||
}
|
||||
/* Then turn PA1 off a million times in a row */
|
||||
for _ in 0..1_000_000 {
|
||||
led.set_low();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
loop {
|
||||
|
|
|
@ -18,36 +18,35 @@ use cortex_m_rt::entry;
|
|||
#[entry]
|
||||
fn main() -> ! {
|
||||
if let (Some(p), Some(cp)) = (stm32::Peripherals::take(), Peripherals::take()) {
|
||||
let gpioa = p.GPIOA.split();
|
||||
cortex_m::interrupt::free(move |cs| {
|
||||
let mut flash = p.FLASH;
|
||||
let mut rcc = p.RCC.configure().sysclk(8.mhz()).freeze(&mut flash);
|
||||
|
||||
/* (Re-)configure PA1 as output */
|
||||
let mut led = gpioa.pa1.into_push_pull_output();
|
||||
let gpioa = p.GPIOA.split(&mut rcc);
|
||||
|
||||
/* (Re-)configure PA0 as analog in */
|
||||
let mut an_in = gpioa.pa0.into_analog();
|
||||
/* (Re-)configure PA1 as output */
|
||||
let mut led = gpioa.pa1.into_push_pull_output(cs);
|
||||
|
||||
/* Constrain clocking registers */
|
||||
let rcc = p.RCC.constrain();
|
||||
/* (Re-)configure PA0 as analog in */
|
||||
let mut an_in = gpioa.pa0.into_analog(cs);
|
||||
|
||||
/* Configure clock to 8 MHz (i.e. the default) and freeze it */
|
||||
let clocks = rcc.cfgr.sysclk(8.mhz()).freeze();
|
||||
/* Get delay provider */
|
||||
let mut delay = Delay::new(cp.SYST, &rcc);
|
||||
|
||||
/* Get delay provider */
|
||||
let mut delay = Delay::new(cp.SYST, clocks);
|
||||
let mut adc = Adc::new(p.ADC, &mut rcc);
|
||||
|
||||
let mut adc = Adc::new(p.ADC);
|
||||
loop {
|
||||
led.toggle();
|
||||
|
||||
loop {
|
||||
led.toggle();
|
||||
let val: u16 = adc.read(&mut an_in).unwrap();
|
||||
|
||||
let val: u16 = adc.read(&mut an_in).unwrap();
|
||||
/* shift the value right by 3, same as divide by 8, reduces
|
||||
the 0-4095 range into something approximating 1-512 */
|
||||
let time: u16 = (val >> 3) + 1;
|
||||
|
||||
/* shift the value right by 3, same as divide by 8, reduces
|
||||
the 0-4095 range into something approximating 1-512 */
|
||||
let time: u16 = (val >> 3) + 1;
|
||||
|
||||
delay.delay_ms(time);
|
||||
}
|
||||
delay.delay_ms(time);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
loop {
|
||||
|
|
|
@ -16,24 +16,23 @@ use cortex_m_rt::entry;
|
|||
#[entry]
|
||||
fn main() -> ! {
|
||||
if let (Some(p), Some(cp)) = (stm32::Peripherals::take(), Peripherals::take()) {
|
||||
let gpioa = p.GPIOA.split();
|
||||
cortex_m::interrupt::free(move |cs| {
|
||||
let mut flash = p.FLASH;
|
||||
let mut rcc = p.RCC.configure().sysclk(8.mhz()).freeze(&mut flash);
|
||||
|
||||
/* (Re-)configure PA1 as output */
|
||||
let mut led = gpioa.pa1.into_push_pull_output();
|
||||
let gpioa = p.GPIOA.split(&mut rcc);
|
||||
|
||||
/* Constrain clocking registers */
|
||||
let rcc = p.RCC.constrain();
|
||||
/* (Re-)configure PA1 as output */
|
||||
let mut led = gpioa.pa1.into_push_pull_output(cs);
|
||||
|
||||
/* Configure clock to 8 MHz (i.e. the default) and freeze it */
|
||||
let clocks = rcc.cfgr.sysclk(8.mhz()).freeze();
|
||||
/* Get delay provider */
|
||||
let mut delay = Delay::new(cp.SYST, &rcc);
|
||||
|
||||
/* Get delay provider */
|
||||
let mut delay = Delay::new(cp.SYST, clocks);
|
||||
|
||||
loop {
|
||||
led.toggle();
|
||||
delay.delay_ms(1_000_u16);
|
||||
}
|
||||
loop {
|
||||
led.toggle();
|
||||
delay.delay_ms(1_000_u16);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
loop {
|
||||
|
|
|
@ -16,37 +16,36 @@ use cortex_m_rt::entry;
|
|||
#[entry]
|
||||
fn main() -> ! {
|
||||
if let (Some(p), Some(cp)) = (stm32::Peripherals::take(), Peripherals::take()) {
|
||||
let gpioa = p.GPIOA.split();
|
||||
let gpiob = p.GPIOB.split();
|
||||
cortex_m::interrupt::free(move |cs| {
|
||||
let mut flash = p.FLASH;
|
||||
let mut rcc = p.RCC.configure().sysclk(8.mhz()).freeze(&mut flash);
|
||||
|
||||
/* (Re-)configure PA1 as output */
|
||||
let led1 = gpioa.pa1.into_push_pull_output();
|
||||
let gpioa = p.GPIOA.split(&mut rcc);
|
||||
let gpiob = p.GPIOB.split(&mut rcc);
|
||||
|
||||
/* (Re-)configure PB1 as output */
|
||||
let led2 = gpiob.pb1.into_push_pull_output();
|
||||
/* (Re-)configure PA1 as output */
|
||||
let led1 = gpioa.pa1.into_push_pull_output(cs);
|
||||
|
||||
/* Constrain clocking registers */
|
||||
let rcc = p.RCC.constrain();
|
||||
/* (Re-)configure PB1 as output */
|
||||
let led2 = gpiob.pb1.into_push_pull_output(cs);
|
||||
|
||||
/* Configure clock to 8 MHz (i.e. the default) and freeze it */
|
||||
let clocks = rcc.cfgr.sysclk(8.mhz()).freeze();
|
||||
/* Get delay provider */
|
||||
let mut delay = Delay::new(cp.SYST, &rcc);
|
||||
|
||||
/* Get delay provider */
|
||||
let mut delay = Delay::new(cp.SYST, clocks);
|
||||
/* Store them together */
|
||||
let mut leds = [led1.downgrade(), led2.downgrade()];
|
||||
loop {
|
||||
for l in &mut leds {
|
||||
l.set_high();
|
||||
}
|
||||
delay.delay_ms(1_000_u16);
|
||||
|
||||
/* Store them together */
|
||||
let mut leds = [led1.downgrade(), led2.downgrade()];
|
||||
loop {
|
||||
for l in &mut leds {
|
||||
l.set_high();
|
||||
for l in &mut leds {
|
||||
l.set_low();
|
||||
}
|
||||
delay.delay_ms(1_000_u16);
|
||||
}
|
||||
delay.delay_ms(1_000_u16);
|
||||
|
||||
for l in &mut leds {
|
||||
l.set_low();
|
||||
}
|
||||
delay.delay_ms(1_000_u16);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
loop {
|
||||
|
|
|
@ -17,22 +17,21 @@ use nb::block;
|
|||
#[entry]
|
||||
fn main() -> ! {
|
||||
if let Some(p) = stm32::Peripherals::take() {
|
||||
let gpioa = p.GPIOA.split();
|
||||
/* (Re-)configure PA1 as output */
|
||||
let mut led = gpioa.pa1.into_push_pull_output();
|
||||
cortex_m::interrupt::free(move |cs| {
|
||||
let mut flash = p.FLASH;
|
||||
let mut rcc = p.RCC.configure().sysclk(8.mhz()).freeze(&mut flash);
|
||||
|
||||
/* Constrain clocking registers */
|
||||
let rcc = p.RCC.constrain();
|
||||
let gpioa = p.GPIOA.split(&mut rcc);
|
||||
/* (Re-)configure PA1 as output */
|
||||
let mut led = gpioa.pa1.into_push_pull_output(cs);
|
||||
|
||||
/* Configure clock to 8 MHz (i.e. the default) and freeze it */
|
||||
let clocks = rcc.cfgr.sysclk(8.mhz()).freeze();
|
||||
let mut timer = Timer::tim1(p.TIM1, Hertz(1), &mut rcc);
|
||||
|
||||
let mut timer = Timer::tim1(p.TIM1, Hertz(1), clocks);
|
||||
|
||||
loop {
|
||||
led.toggle();
|
||||
block!(timer.wait()).ok();
|
||||
}
|
||||
loop {
|
||||
led.toggle();
|
||||
block!(timer.wait()).ok();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
loop {
|
||||
|
|
|
@ -23,32 +23,34 @@ static GPIO: Mutex<RefCell<Option<gpioa::PA1<Output<PushPull>>>>> = Mutex::new(R
|
|||
#[entry]
|
||||
fn main() -> ! {
|
||||
if let (Some(p), Some(cp)) = (stm32::Peripherals::take(), Peripherals::take()) {
|
||||
let gpioa = p.GPIOA.split();
|
||||
let rcc = p.RCC.constrain();
|
||||
let _ = rcc.cfgr.sysclk(48.mhz()).freeze();
|
||||
let mut syst = cp.SYST;
|
||||
|
||||
/* (Re-)configure PA1 as output */
|
||||
let led = gpioa.pa1.into_push_pull_output();
|
||||
|
||||
cortex_m::interrupt::free(move |cs| {
|
||||
let mut flash = p.FLASH;
|
||||
let mut rcc = p.RCC.configure().sysclk(48.mhz()).freeze(&mut flash);
|
||||
|
||||
let gpioa = p.GPIOA.split(&mut rcc);
|
||||
|
||||
let mut syst = cp.SYST;
|
||||
|
||||
/* (Re-)configure PA1 as output */
|
||||
let led = gpioa.pa1.into_push_pull_output(cs);
|
||||
|
||||
*GPIO.borrow(cs).borrow_mut() = Some(led);
|
||||
|
||||
/* Initialise SysTick counter with a defined value */
|
||||
unsafe { syst.cvr.write(1) };
|
||||
|
||||
/* Set source for SysTick counter, here full operating frequency (== 8MHz) */
|
||||
syst.set_clock_source(Core);
|
||||
|
||||
/* Set reload value, i.e. timer delay 48 MHz/4 Mcounts == 12Hz or 83ms */
|
||||
syst.set_reload(4_000_000 - 1);
|
||||
|
||||
/* Start counter */
|
||||
syst.enable_counter();
|
||||
|
||||
/* Start interrupt generation */
|
||||
syst.enable_interrupt();
|
||||
});
|
||||
|
||||
/* Initialise SysTick counter with a defined value */
|
||||
unsafe { syst.cvr.write(1) };
|
||||
|
||||
/* Set source for SysTick counter, here full operating frequency (== 8MHz) */
|
||||
syst.set_clock_source(Core);
|
||||
|
||||
/* Set reload value, i.e. timer delay 48 MHz/4 Mcounts == 12Hz or 83ms */
|
||||
syst.set_reload(4_000_000 - 1);
|
||||
|
||||
/* Start counter */
|
||||
syst.enable_counter();
|
||||
|
||||
/* Start interrupt generation */
|
||||
syst.enable_interrupt();
|
||||
}
|
||||
|
||||
loop {
|
||||
|
|
|
@ -31,53 +31,53 @@ static INT: Mutex<RefCell<Option<EXTI>>> = Mutex::new(RefCell::new(None));
|
|||
#[entry]
|
||||
fn main() -> ! {
|
||||
if let (Some(p), Some(cp)) = (Peripherals::take(), c_m_Peripherals::take()) {
|
||||
let gpioa = p.GPIOA.split();
|
||||
let gpiob = p.GPIOB.split();
|
||||
let syscfg = p.SYSCFG_COMP;
|
||||
let exti = p.EXTI;
|
||||
|
||||
// Enable clock for SYSCFG
|
||||
let rcc = p.RCC;
|
||||
rcc.apb2enr.modify(|_, w| w.syscfgen().set_bit());
|
||||
|
||||
// Configure PB1 as input (button)
|
||||
let _ = gpiob.pb1.into_pull_down_input();
|
||||
|
||||
// Configure PA1 as output (LED)
|
||||
let mut led = gpioa.pa1.into_push_pull_output();
|
||||
|
||||
// Turn off LED
|
||||
led.set_low();
|
||||
|
||||
// Configure clock to 8 MHz (i.e. the default) and freeze it
|
||||
let clocks = rcc.constrain().cfgr.sysclk(8.mhz()).freeze();
|
||||
|
||||
// Initialise delay provider
|
||||
let delay = Delay::new(cp.SYST, clocks);
|
||||
|
||||
// Enable external interrupt for PB1
|
||||
syscfg
|
||||
.syscfg_exticr1
|
||||
.modify(|_, w| unsafe { w.exti1().bits(1) });
|
||||
|
||||
// Set interrupt request mask for line 1
|
||||
exti.imr.modify(|_, w| w.mr1().set_bit());
|
||||
|
||||
// Set interrupt rising trigger for line 1
|
||||
exti.rtsr.modify(|_, w| w.tr1().set_bit());
|
||||
|
||||
// Move control over LED and DELAY and EXTI into global mutexes
|
||||
cortex_m::interrupt::free(move |cs| {
|
||||
// Enable clock for SYSCFG
|
||||
let rcc = p.RCC;
|
||||
rcc.apb2enr.modify(|_, w| w.syscfgen().set_bit());
|
||||
|
||||
let mut flash = p.FLASH;
|
||||
let mut rcc = rcc.configure().sysclk(8.mhz()).freeze(&mut flash);
|
||||
|
||||
let gpioa = p.GPIOA.split(&mut rcc);
|
||||
let gpiob = p.GPIOB.split(&mut rcc);
|
||||
let syscfg = p.SYSCFG_COMP;
|
||||
let exti = p.EXTI;
|
||||
|
||||
// Configure PB1 as input (button)
|
||||
let _ = gpiob.pb1.into_pull_down_input(cs);
|
||||
|
||||
// Configure PA1 as output (LED)
|
||||
let mut led = gpioa.pa1.into_push_pull_output(cs);
|
||||
|
||||
// Turn off LED
|
||||
led.set_low();
|
||||
|
||||
// Initialise delay provider
|
||||
let delay = Delay::new(cp.SYST, &rcc);
|
||||
|
||||
// Enable external interrupt for PB1
|
||||
syscfg
|
||||
.syscfg_exticr1
|
||||
.modify(|_, w| unsafe { w.exti1().bits(1) });
|
||||
|
||||
// Set interrupt request mask for line 1
|
||||
exti.imr.modify(|_, w| w.mr1().set_bit());
|
||||
|
||||
// Set interrupt rising trigger for line 1
|
||||
exti.rtsr.modify(|_, w| w.tr1().set_bit());
|
||||
|
||||
// Move control over LED and DELAY and EXTI into global mutexes
|
||||
*LED.borrow(cs).borrow_mut() = Some(led);
|
||||
*DELAY.borrow(cs).borrow_mut() = Some(delay);
|
||||
*INT.borrow(cs).borrow_mut() = Some(exti);
|
||||
});
|
||||
|
||||
// Enable EXTI IRQ, set prio 1 and clear any pending IRQs
|
||||
let mut nvic = cp.NVIC;
|
||||
nvic.enable(Interrupt::EXTI0_1);
|
||||
unsafe { nvic.set_priority(Interrupt::EXTI0_1, 1) };
|
||||
cortex_m::peripheral::NVIC::unpend(Interrupt::EXTI0_1);
|
||||
// Enable EXTI IRQ, set prio 1 and clear any pending IRQs
|
||||
let mut nvic = cp.NVIC;
|
||||
nvic.enable(Interrupt::EXTI0_1);
|
||||
unsafe { nvic.set_priority(Interrupt::EXTI0_1, 1) };
|
||||
cortex_m::peripheral::NVIC::unpend(Interrupt::EXTI0_1);
|
||||
});
|
||||
}
|
||||
|
||||
loop {
|
||||
|
|
|
@ -17,21 +17,24 @@ use cortex_m_rt::entry;
|
|||
#[entry]
|
||||
fn main() -> ! {
|
||||
if let Some(p) = stm32::Peripherals::take() {
|
||||
let gpioa = p.GPIOA.split();
|
||||
let rcc = p.RCC.constrain();
|
||||
let clocks = rcc.cfgr.sysclk(48.mhz()).freeze();
|
||||
cortex_m::interrupt::free(move |cs| {
|
||||
let mut flash = p.FLASH;
|
||||
let mut rcc = p.RCC.configure().sysclk(48.mhz()).freeze(&mut flash);
|
||||
|
||||
let tx = gpioa.pa9.into_alternate_af1();
|
||||
let rx = gpioa.pa10.into_alternate_af1();
|
||||
let gpioa = p.GPIOA.split(&mut rcc);
|
||||
|
||||
let serial = Serial::usart1(p.USART1, (tx, rx), 115_200.bps(), clocks);
|
||||
let tx = gpioa.pa9.into_alternate_af1(cs);
|
||||
let rx = gpioa.pa10.into_alternate_af1(cs);
|
||||
|
||||
let (mut tx, mut rx) = serial.split();
|
||||
let serial = Serial::usart1(p.USART1, (tx, rx), 115_200.bps(), &mut rcc);
|
||||
|
||||
loop {
|
||||
let received = block!(rx.read()).unwrap();
|
||||
block!(tx.write(received)).ok();
|
||||
}
|
||||
let (mut tx, mut rx) = serial.split();
|
||||
|
||||
loop {
|
||||
let received = block!(rx.read()).unwrap();
|
||||
block!(tx.write(received)).ok();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
loop {
|
||||
|
|
|
@ -30,34 +30,37 @@ fn main() -> ! {
|
|||
};
|
||||
|
||||
if let Some(p) = stm32::Peripherals::take() {
|
||||
let rcc = p.RCC.constrain();
|
||||
let clocks = rcc.cfgr.freeze();
|
||||
let gpioa = p.GPIOA.split();
|
||||
cortex_m::interrupt::free(move |cs| {
|
||||
let mut flash = p.FLASH;
|
||||
let mut rcc = p.RCC.configure().freeze(&mut flash);
|
||||
|
||||
// Configure pins for SPI
|
||||
let sck = gpioa.pa5.into_alternate_af0();
|
||||
let miso = gpioa.pa6.into_alternate_af0();
|
||||
let mosi = gpioa.pa7.into_alternate_af0();
|
||||
let gpioa = p.GPIOA.split(&mut rcc);
|
||||
|
||||
// Configure SPI with 1MHz rate
|
||||
let mut spi = Spi::spi1(p.SPI1, (sck, miso, mosi), MODE, 1.mhz(), clocks);
|
||||
// Configure pins for SPI
|
||||
let sck = gpioa.pa5.into_alternate_af0(cs);
|
||||
let miso = gpioa.pa6.into_alternate_af0(cs);
|
||||
let mosi = gpioa.pa7.into_alternate_af0(cs);
|
||||
|
||||
let tx = gpioa.pa9.into_alternate_af1();
|
||||
let rx = gpioa.pa10.into_alternate_af1();
|
||||
// Configure SPI with 1MHz rate
|
||||
let mut spi = Spi::spi1(p.SPI1, (sck, miso, mosi), MODE, 1.mhz(), &mut rcc);
|
||||
|
||||
let serial = Serial::usart1(p.USART1, (tx, rx), 115_200.bps(), clocks);
|
||||
let tx = gpioa.pa9.into_alternate_af1(cs);
|
||||
let rx = gpioa.pa10.into_alternate_af1(cs);
|
||||
|
||||
let (mut tx, mut rx) = serial.split();
|
||||
let serial = Serial::usart1(p.USART1, (tx, rx), 115_200.bps(), &mut rcc);
|
||||
|
||||
loop {
|
||||
let serial_received = block!(rx.read()).unwrap();
|
||||
let (mut tx, mut rx) = serial.split();
|
||||
|
||||
block!(spi.send(serial_received)).ok();
|
||||
loop {
|
||||
let serial_received = block!(rx.read()).unwrap();
|
||||
|
||||
let spi_received = block!(spi.read()).unwrap();
|
||||
block!(spi.send(serial_received)).ok();
|
||||
|
||||
block!(tx.write(spi_received)).ok();
|
||||
}
|
||||
let spi_received = block!(spi.read()).unwrap();
|
||||
|
||||
block!(tx.write(spi_received)).ok();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
loop {
|
||||
|
|
|
@ -21,42 +21,45 @@ fn main() -> ! {
|
|||
};
|
||||
|
||||
if let Some(p) = stm32::Peripherals::take() {
|
||||
let rcc = p.RCC.constrain();
|
||||
let clocks = rcc.cfgr.freeze();
|
||||
let gpioa = p.GPIOA.split();
|
||||
cortex_m::interrupt::free(move |cs| {
|
||||
let mut flash = p.FLASH;
|
||||
let mut rcc = p.RCC.configure().freeze(&mut flash);
|
||||
|
||||
// Configure pins for SPI
|
||||
let sck = gpioa.pa5.into_alternate_af0();
|
||||
let miso = gpioa.pa6.into_alternate_af0();
|
||||
let mosi = gpioa.pa7.into_alternate_af0();
|
||||
let gpioa = p.GPIOA.split(&mut rcc);
|
||||
|
||||
// Configure SPI with 100kHz rate
|
||||
let mut spi = Spi::spi1(p.SPI1, (sck, miso, mosi), MODE, 100_000.hz(), clocks);
|
||||
// Configure pins for SPI
|
||||
let sck = gpioa.pa5.into_alternate_af0(cs);
|
||||
let miso = gpioa.pa6.into_alternate_af0(cs);
|
||||
let mosi = gpioa.pa7.into_alternate_af0(cs);
|
||||
|
||||
// Cycle through colors on 16 chained APA102C LEDs
|
||||
loop {
|
||||
for r in 0..255 {
|
||||
let _ = spi.write(&[0, 0, 0, 0]);
|
||||
for _i in 0..16 {
|
||||
let _ = spi.write(&[0b1110_0001, 0, 0, r]);
|
||||
// Configure SPI with 100kHz rate
|
||||
let mut spi = Spi::spi1(p.SPI1, (sck, miso, mosi), MODE, 100_000.hz(), &mut rcc);
|
||||
|
||||
// Cycle through colors on 16 chained APA102C LEDs
|
||||
loop {
|
||||
for r in 0..255 {
|
||||
let _ = spi.write(&[0, 0, 0, 0]);
|
||||
for _i in 0..16 {
|
||||
let _ = spi.write(&[0b1110_0001, 0, 0, r]);
|
||||
}
|
||||
let _ = spi.write(&[0xFF, 0xFF, 0xFF, 0xFF]);
|
||||
}
|
||||
let _ = spi.write(&[0xFF, 0xFF, 0xFF, 0xFF]);
|
||||
}
|
||||
for b in 0..255 {
|
||||
let _ = spi.write(&[0, 0, 0, 0]);
|
||||
for _i in 0..16 {
|
||||
let _ = spi.write(&[0b1110_0001, b, 0, 0]);
|
||||
for b in 0..255 {
|
||||
let _ = spi.write(&[0, 0, 0, 0]);
|
||||
for _i in 0..16 {
|
||||
let _ = spi.write(&[0b1110_0001, b, 0, 0]);
|
||||
}
|
||||
let _ = spi.write(&[0xFF, 0xFF, 0xFF, 0xFF]);
|
||||
}
|
||||
let _ = spi.write(&[0xFF, 0xFF, 0xFF, 0xFF]);
|
||||
}
|
||||
for g in 0..255 {
|
||||
let _ = spi.write(&[0, 0, 0, 0]);
|
||||
for _i in 0..16 {
|
||||
let _ = spi.write(&[0b1110_0001, 0, g, 0]);
|
||||
for g in 0..255 {
|
||||
let _ = spi.write(&[0, 0, 0, 0]);
|
||||
for _i in 0..16 {
|
||||
let _ = spi.write(&[0b1110_0001, 0, g, 0]);
|
||||
}
|
||||
let _ = spi.write(&[0xFF, 0xFF, 0xFF, 0xFF]);
|
||||
}
|
||||
let _ = spi.write(&[0xFF, 0xFF, 0xFF, 0xFF]);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
loop {
|
||||
|
|
|
@ -20,39 +20,42 @@ use cortex_m_rt::entry;
|
|||
#[entry]
|
||||
fn main() -> ! {
|
||||
if let (Some(p), Some(cp)) = (stm32::Peripherals::take(), Peripherals::take()) {
|
||||
let gpioa = p.GPIOA.split();
|
||||
let rcc = p.RCC.constrain();
|
||||
let dbgmcu = p.DBGMCU;
|
||||
cortex_m::interrupt::free(move |cs| {
|
||||
let mut flash = p.FLASH;
|
||||
let mut rcc = p.RCC.configure().sysclk(8.mhz()).freeze(&mut flash);
|
||||
|
||||
// Disable the watchdog when the cpu is stopped under debug
|
||||
dbgmcu.apb1_fz.modify(|_, w| w.dbg_iwdg_stop().set_bit());
|
||||
let gpioa = p.GPIOA.split(&mut rcc);
|
||||
let dbgmcu = p.DBGMCU;
|
||||
|
||||
let mut watchdog = Watchdog::new(p.IWDG);
|
||||
let clocks = rcc.cfgr.sysclk(8.mhz()).freeze();
|
||||
// Disable the watchdog when the cpu is stopped under debug
|
||||
dbgmcu.apb1_fz.modify(|_, w| w.dbg_iwdg_stop().set_bit());
|
||||
|
||||
// Get delay provider
|
||||
let mut delay = Delay::new(cp.SYST, clocks);
|
||||
let mut watchdog = Watchdog::new(p.IWDG);
|
||||
|
||||
let tx = gpioa.pa9.into_alternate_af1();
|
||||
let rx = gpioa.pa10.into_alternate_af1();
|
||||
// Get delay provider
|
||||
let mut delay = Delay::new(cp.SYST, &rcc);
|
||||
|
||||
let serial = Serial::usart1(p.USART1, (tx, rx), 115_200.bps(), clocks);
|
||||
let tx = gpioa.pa9.into_alternate_af1(cs);
|
||||
let rx = gpioa.pa10.into_alternate_af1(cs);
|
||||
|
||||
let (mut tx, _rx) = serial.split();
|
||||
tx.write_str("RESET \r\n").ok();
|
||||
let serial = Serial::usart1(p.USART1, (tx, rx), 115_200.bps(), &mut rcc);
|
||||
|
||||
watchdog.start(Hertz(1));
|
||||
delay.delay_ms(500_u16);
|
||||
watchdog.feed();
|
||||
delay.delay_ms(500_u16);
|
||||
watchdog.feed();
|
||||
delay.delay_ms(500_u16);
|
||||
tx.write_str("This will get printed \r\n").ok();
|
||||
watchdog.feed();
|
||||
let (mut tx, _rx) = serial.split();
|
||||
tx.write_str("RESET \r\n").ok();
|
||||
|
||||
// Now a reset happens while delaying
|
||||
delay.delay_ms(1500_u16);
|
||||
tx.write_str("This won't\r\n").ok();
|
||||
watchdog.start(Hertz(1));
|
||||
delay.delay_ms(500_u16);
|
||||
watchdog.feed();
|
||||
delay.delay_ms(500_u16);
|
||||
watchdog.feed();
|
||||
delay.delay_ms(500_u16);
|
||||
tx.write_str("This will get printed \r\n").ok();
|
||||
watchdog.feed();
|
||||
|
||||
// Now a reset happens while delaying
|
||||
delay.delay_ms(1500_u16);
|
||||
tx.write_str("This won't\r\n").ok();
|
||||
});
|
||||
}
|
||||
|
||||
loop {
|
||||
|
|
69
src/adc.rs
69
src/adc.rs
|
@ -12,52 +12,45 @@
|
|||
//! use crate::hal::prelude::*;
|
||||
//! use crate::hal::adc::Adc;
|
||||
//!
|
||||
//! let mut p = stm32::Peripherals::take().unwrap();
|
||||
//! cortex_m::interrupt::free(|cs| {
|
||||
//! let mut p = stm32::Peripherals::take().unwrap();
|
||||
//! let mut rcc = p.RCC.configure().freeze(&mut p.FLASH);
|
||||
//!
|
||||
//! let mut led = gpioa.pa1.into_push_pull_pull_output();
|
||||
//! let mut an_in = gpioa.pa0.into_analog();
|
||||
//! let gpioa = p.GPIOA.split(&mut rcc);
|
||||
//!
|
||||
//! let rcc = p.RCC.constrain().cfgr.freeze();
|
||||
//! let mut delay = Delay::new(cp.SYST, clocks);
|
||||
//! let mut led = gpioa.pa1.into_push_pull_pull_output(cs);
|
||||
//! let mut an_in = gpioa.pa0.into_analog(cs);
|
||||
//!
|
||||
//! let mut adc = Adc::new(p.ADC);
|
||||
//! let mut delay = Delay::new(cp.SYST, &rcc);
|
||||
//!
|
||||
//! loop {
|
||||
//! let val: u16 = adc.read(&mut an_in).unwrap();
|
||||
//! if val < ((1 << 8) - 1) {
|
||||
//! led.set_low();
|
||||
//! } else {
|
||||
//! led.set_high();
|
||||
//! let mut adc = Adc::new(p.ADC, &mut rcc);
|
||||
//!
|
||||
//! loop {
|
||||
//! let val: u16 = adc.read(&mut an_in).unwrap();
|
||||
//! if val < ((1 << 8) - 1) {
|
||||
//! led.set_low();
|
||||
//! } else {
|
||||
//! led.set_high();
|
||||
//! }
|
||||
//! delay.delay_ms(50_u16);
|
||||
//! }
|
||||
//! delay.delay_ms(50_u16);
|
||||
//! }
|
||||
//! });
|
||||
//! ```
|
||||
|
||||
#[cfg(feature = "device-selected")]
|
||||
const VREFCAL: *const u16 = 0x1FFF_F7BA as *const u16;
|
||||
|
||||
#[cfg(feature = "device-selected")]
|
||||
const VTEMPCAL30: *const u16 = 0x1FFF_F7B8 as *const u16;
|
||||
|
||||
#[cfg(feature = "device-selected")]
|
||||
const VTEMPCAL110: *const u16 = 0x1FFF_F7C2 as *const u16;
|
||||
|
||||
#[cfg(feature = "device-selected")]
|
||||
const VDD_CALIB: u16 = 3300;
|
||||
|
||||
#[cfg(feature = "device-selected")]
|
||||
use core::ptr;
|
||||
|
||||
#[cfg(feature = "device-selected")]
|
||||
use embedded_hal::{
|
||||
adc::{Channel, OneShot},
|
||||
blocking::delay::DelayUs,
|
||||
};
|
||||
|
||||
#[cfg(feature = "device-selected")]
|
||||
use crate::{delay::Delay, gpio::*, stm32};
|
||||
use crate::{delay::Delay, gpio::*, rcc::Rcc, stm32};
|
||||
|
||||
#[cfg(feature = "device-selected")]
|
||||
/// Analog to Digital converter interface
|
||||
pub struct Adc {
|
||||
rb: stm32::ADC,
|
||||
|
@ -89,7 +82,6 @@ pub enum AdcSampleTime {
|
|||
T_239,
|
||||
}
|
||||
|
||||
#[cfg(feature = "device-selected")]
|
||||
impl AdcSampleTime {
|
||||
fn write_bits(self, adc: &mut stm32::ADC) {
|
||||
unsafe {
|
||||
|
@ -137,7 +129,6 @@ pub enum AdcAlign {
|
|||
LeftAsRM,
|
||||
}
|
||||
|
||||
#[cfg(feature = "device-selected")]
|
||||
impl AdcAlign {
|
||||
fn write_bits(self, adc: &mut stm32::ADC) {
|
||||
adc.cfgr1.write(|w| {
|
||||
|
@ -168,7 +159,6 @@ pub enum AdcPrecision {
|
|||
B_6,
|
||||
}
|
||||
|
||||
#[cfg(feature = "device-selected")]
|
||||
impl AdcPrecision {
|
||||
fn write_bits(self, adc: &mut stm32::ADC) {
|
||||
unsafe {
|
||||
|
@ -189,7 +179,6 @@ impl AdcPrecision {
|
|||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "device-selected")]
|
||||
macro_rules! adc_pins {
|
||||
($($pin:ty => $chan:expr),+ $(,)*) => {
|
||||
$(
|
||||
|
@ -202,7 +191,6 @@ macro_rules! adc_pins {
|
|||
};
|
||||
}
|
||||
|
||||
#[cfg(feature = "device-selected")]
|
||||
adc_pins!(
|
||||
gpioa::PA0<Analog> => 0_u8,
|
||||
gpioa::PA1<Analog> => 1_u8,
|
||||
|
@ -239,13 +227,11 @@ pub struct VTemp;
|
|||
/// Internal voltage reference (ADC Channel 17)
|
||||
pub struct VRef;
|
||||
|
||||
#[cfg(feature = "device-selected")]
|
||||
adc_pins!(
|
||||
VTemp => 16_u8,
|
||||
VRef => 17_u8,
|
||||
);
|
||||
|
||||
#[cfg(feature = "device-selected")]
|
||||
impl VTemp {
|
||||
/// Init a new VTemp
|
||||
pub fn new() -> Self {
|
||||
|
@ -319,7 +305,6 @@ impl VTemp {
|
|||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "device-selected")]
|
||||
impl VRef {
|
||||
/// Init a new VRef
|
||||
pub fn new() -> Self {
|
||||
|
@ -421,21 +406,20 @@ impl VBat {
|
|||
#[derive(Copy, Clone, Debug, PartialEq)]
|
||||
pub struct StoredConfig(AdcSampleTime, AdcAlign, AdcPrecision);
|
||||
|
||||
#[cfg(feature = "device-selected")]
|
||||
impl Adc {
|
||||
/// Init a new Adc
|
||||
///
|
||||
/// Sets all configurable parameters to defaults, enables the HSI14 clock
|
||||
/// for the ADC if it is not already enabled and performs a boot time
|
||||
/// calibration. As such this method may take an appreciable time to run.
|
||||
pub fn new(adc: stm32::ADC) -> Self {
|
||||
pub fn new(adc: stm32::ADC, rcc: &mut Rcc) -> Self {
|
||||
let mut s = Self {
|
||||
rb: adc,
|
||||
sample_time: AdcSampleTime::default(),
|
||||
align: AdcAlign::default(),
|
||||
precision: AdcPrecision::default(),
|
||||
};
|
||||
s.select_clock();
|
||||
s.select_clock(rcc);
|
||||
s.calibrate();
|
||||
s
|
||||
}
|
||||
|
@ -527,12 +511,10 @@ impl Adc {
|
|||
while self.rb.cr.read().adcal().bit_is_set() {}
|
||||
}
|
||||
|
||||
fn select_clock(&mut self) {
|
||||
let rcc = unsafe { &*stm32::RCC::ptr() };
|
||||
|
||||
rcc.apb2enr.modify(|_, w| w.adcen().set_bit());
|
||||
rcc.cr2.write(|w| w.hsi14on().set_bit());
|
||||
while rcc.cr2.read().hsi14rdy().bit_is_clear() {}
|
||||
fn select_clock(&mut self, rcc: &mut Rcc) {
|
||||
rcc.regs.apb2enr.modify(|_, w| w.adcen().set_bit());
|
||||
rcc.regs.cr2.write(|w| w.hsi14on().set_bit());
|
||||
while rcc.regs.cr2.read().hsi14rdy().bit_is_clear() {}
|
||||
}
|
||||
|
||||
fn power_up(&mut self) {
|
||||
|
@ -569,7 +551,6 @@ impl Adc {
|
|||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "device-selected")]
|
||||
impl<WORD, PIN> OneShot<Adc, WORD, PIN> for Adc
|
||||
where
|
||||
WORD: From<u16>,
|
||||
|
|
14
src/delay.rs
14
src/delay.rs
|
@ -18,8 +18,8 @@
|
|||
//! let mut p = stm32::Peripherals::take().unwrap();
|
||||
//! let mut cp = cortex_m::Peripherals::take().unwrap();
|
||||
//!
|
||||
//! let clocks = p.RCC.constrain().cfgr.freeze();
|
||||
//! let mut delay = Delay::new(cp.SYST, clocks);
|
||||
//! let mut rcc = p.RCC.configure().freeze(&mut p.FLASH);
|
||||
//! let mut delay = Delay::new(cp.SYST, &rcc);
|
||||
//! loop {
|
||||
//! delay.delay_ms(1_000_u16);
|
||||
//! }
|
||||
|
@ -29,7 +29,8 @@ use cast::{u16, u32};
|
|||
use cortex_m::peripheral::syst::SystClkSource;
|
||||
use cortex_m::peripheral::SYST;
|
||||
|
||||
use crate::rcc::Clocks;
|
||||
use crate::rcc::Rcc;
|
||||
|
||||
use embedded_hal::blocking::delay::{DelayMs, DelayUs};
|
||||
|
||||
/// System timer (SysTick) as a delay provider
|
||||
|
@ -42,14 +43,15 @@ const SYSTICK_RANGE: u32 = 0x0100_0000;
|
|||
|
||||
impl Delay {
|
||||
/// Configures the system timer (SysTick) as a delay provider
|
||||
pub fn new(mut syst: SYST, clocks: Clocks) -> Delay {
|
||||
pub fn new(mut syst: SYST, rcc: &Rcc) -> Delay {
|
||||
syst.set_clock_source(SystClkSource::Core);
|
||||
|
||||
syst.set_reload(SYSTICK_RANGE - 1);
|
||||
syst.clear_current();
|
||||
syst.enable_counter();
|
||||
assert!(clocks.hclk().0 >= 1_000_000);
|
||||
let scale = clocks.hclk().0 / 1_000_000;
|
||||
|
||||
assert!(rcc.clocks.hclk().0 >= 1_000_000);
|
||||
let scale = rcc.clocks.hclk().0 / 1_000_000;
|
||||
|
||||
Delay { scale }
|
||||
// As access to the count register is possible without a reference to the systick, we can
|
||||
|
|
78
src/gpio.rs
78
src/gpio.rs
|
@ -2,13 +2,15 @@
|
|||
|
||||
use core::marker::PhantomData;
|
||||
|
||||
use crate::rcc::Rcc;
|
||||
|
||||
/// Extension trait to split a GPIO peripheral in independent pins and registers
|
||||
pub trait GpioExt {
|
||||
/// The parts to split the GPIO into
|
||||
type Parts;
|
||||
|
||||
/// Splits the GPIO block into independent pins and registers
|
||||
fn split(self) -> Self::Parts;
|
||||
fn split(self, rcc: &mut Rcc) -> Self::Parts;
|
||||
}
|
||||
|
||||
trait GpioRegExt {
|
||||
|
@ -116,7 +118,6 @@ impl<MODE> InputPin for Pin<Input<MODE>> {
|
|||
}
|
||||
}
|
||||
|
||||
#[allow(unused)]
|
||||
macro_rules! gpio_trait {
|
||||
($gpiox:ident) => {
|
||||
impl GpioRegExt for crate::stm32::$gpiox::RegisterBlock {
|
||||
|
@ -143,13 +144,9 @@ macro_rules! gpio_trait {
|
|||
};
|
||||
}
|
||||
|
||||
#[cfg(feature = "device-selected")]
|
||||
gpio_trait!(gpioa);
|
||||
|
||||
#[cfg(feature = "device-selected")]
|
||||
gpio_trait!(gpiof);
|
||||
|
||||
#[allow(unused)]
|
||||
macro_rules! gpio {
|
||||
($GPIOX:ident, $gpiox:ident, $iopxenr:ident, $PXx:ident, [
|
||||
$($PXi:ident: ($pxi:ident, $i:expr, $MODE:ty),)+
|
||||
|
@ -159,9 +156,13 @@ macro_rules! gpio {
|
|||
use core::marker::PhantomData;
|
||||
|
||||
use embedded_hal::digital::{InputPin, OutputPin, StatefulOutputPin, toggleable};
|
||||
use crate::stm32::$GPIOX;
|
||||
use crate::{
|
||||
rcc::Rcc,
|
||||
stm32::$GPIOX
|
||||
};
|
||||
|
||||
use cortex_m::interrupt::CriticalSection;
|
||||
|
||||
use crate::stm32::RCC;
|
||||
use super::{
|
||||
Alternate, Analog, Floating, GpioExt, Input, OpenDrain, Output,
|
||||
PullDown, PullUp, PushPull, AF0, AF1, AF2, AF3, AF4, AF5, AF6, AF7,
|
||||
|
@ -179,10 +180,8 @@ macro_rules! gpio {
|
|||
impl GpioExt for $GPIOX {
|
||||
type Parts = Parts;
|
||||
|
||||
fn split(self) -> Parts {
|
||||
// NOTE(unsafe) This executes only during initialisation
|
||||
let rcc = unsafe { &(*RCC::ptr()) };
|
||||
rcc.ahbenr.modify(|_, w| w.$iopxenr().set_bit());
|
||||
fn split(self, rcc: &mut Rcc) -> Parts {
|
||||
rcc.regs.ahbenr.modify(|_, w| w.$iopxenr().set_bit());
|
||||
|
||||
Parts {
|
||||
$(
|
||||
|
@ -201,8 +200,7 @@ macro_rules! gpio {
|
|||
&(*$GPIOX::ptr()).afrl.modify(|r, w| {
|
||||
w.bits((r.bits() & !(0b1111 << offset2)) | (mode << offset2))
|
||||
});
|
||||
} else
|
||||
{
|
||||
} else {
|
||||
let offset2 = offset2 - 32;
|
||||
&(*$GPIOX::ptr()).afrh.modify(|r, w| {
|
||||
w.bits((r.bits() & !(0b1111 << offset2)) | (mode << offset2))
|
||||
|
@ -223,7 +221,7 @@ macro_rules! gpio {
|
|||
impl<MODE> $PXi<MODE> {
|
||||
/// Configures the pin to operate in AF0 mode
|
||||
pub fn into_alternate_af0(
|
||||
self,
|
||||
self, _cs: &CriticalSection
|
||||
) -> $PXi<Alternate<AF0>> {
|
||||
_set_alternate_mode($i, 0);
|
||||
$PXi { _mode: PhantomData }
|
||||
|
@ -231,7 +229,7 @@ macro_rules! gpio {
|
|||
|
||||
/// Configures the pin to operate in AF1 mode
|
||||
pub fn into_alternate_af1(
|
||||
self,
|
||||
self, _cs: &CriticalSection
|
||||
) -> $PXi<Alternate<AF1>> {
|
||||
_set_alternate_mode($i, 1);
|
||||
$PXi { _mode: PhantomData }
|
||||
|
@ -239,7 +237,7 @@ macro_rules! gpio {
|
|||
|
||||
/// Configures the pin to operate in AF2 mode
|
||||
pub fn into_alternate_af2(
|
||||
self,
|
||||
self, _cs: &CriticalSection
|
||||
) -> $PXi<Alternate<AF2>> {
|
||||
_set_alternate_mode($i, 2);
|
||||
$PXi { _mode: PhantomData }
|
||||
|
@ -247,7 +245,7 @@ macro_rules! gpio {
|
|||
|
||||
/// Configures the pin to operate in AF3 mode
|
||||
pub fn into_alternate_af3(
|
||||
self,
|
||||
self, _cs: &CriticalSection
|
||||
) -> $PXi<Alternate<AF3>> {
|
||||
_set_alternate_mode($i, 3);
|
||||
$PXi { _mode: PhantomData }
|
||||
|
@ -255,7 +253,7 @@ macro_rules! gpio {
|
|||
|
||||
/// Configures the pin to operate in AF4 mode
|
||||
pub fn into_alternate_af4(
|
||||
self,
|
||||
self, _cs: &CriticalSection
|
||||
) -> $PXi<Alternate<AF4>> {
|
||||
_set_alternate_mode($i, 4);
|
||||
$PXi { _mode: PhantomData }
|
||||
|
@ -263,7 +261,7 @@ macro_rules! gpio {
|
|||
|
||||
/// Configures the pin to operate in AF5 mode
|
||||
pub fn into_alternate_af5(
|
||||
self,
|
||||
self, _cs: &CriticalSection
|
||||
) -> $PXi<Alternate<AF5>> {
|
||||
_set_alternate_mode($i, 5);
|
||||
$PXi { _mode: PhantomData }
|
||||
|
@ -271,7 +269,7 @@ macro_rules! gpio {
|
|||
|
||||
/// Configures the pin to operate in AF6 mode
|
||||
pub fn into_alternate_af6(
|
||||
self,
|
||||
self, _cs: &CriticalSection
|
||||
) -> $PXi<Alternate<AF6>> {
|
||||
_set_alternate_mode($i, 6);
|
||||
$PXi { _mode: PhantomData }
|
||||
|
@ -279,7 +277,7 @@ macro_rules! gpio {
|
|||
|
||||
/// Configures the pin to operate in AF7 mode
|
||||
pub fn into_alternate_af7(
|
||||
self,
|
||||
self, _cs: &CriticalSection
|
||||
) -> $PXi<Alternate<AF7>> {
|
||||
_set_alternate_mode($i, 7);
|
||||
$PXi { _mode: PhantomData }
|
||||
|
@ -287,7 +285,7 @@ macro_rules! gpio {
|
|||
|
||||
/// Configures the pin to operate as a floating input pin
|
||||
pub fn into_floating_input(
|
||||
self,
|
||||
self, _cs: &CriticalSection
|
||||
) -> $PXi<Input<Floating>> {
|
||||
let offset = 2 * $i;
|
||||
unsafe {
|
||||
|
@ -303,7 +301,7 @@ macro_rules! gpio {
|
|||
|
||||
/// Configures the pin to operate as a pulled down input pin
|
||||
pub fn into_pull_down_input(
|
||||
self,
|
||||
self, _cs: &CriticalSection
|
||||
) -> $PXi<Input<PullDown>> {
|
||||
let offset = 2 * $i;
|
||||
unsafe {
|
||||
|
@ -319,7 +317,7 @@ macro_rules! gpio {
|
|||
|
||||
/// Configures the pin to operate as a pulled up input pin
|
||||
pub fn into_pull_up_input(
|
||||
self,
|
||||
self, _cs: &CriticalSection
|
||||
) -> $PXi<Input<PullUp>> {
|
||||
let offset = 2 * $i;
|
||||
unsafe {
|
||||
|
@ -335,7 +333,7 @@ macro_rules! gpio {
|
|||
|
||||
/// Configures the pin to operate as an analog pin
|
||||
pub fn into_analog(
|
||||
self,
|
||||
self, _cs: &CriticalSection
|
||||
) -> $PXi<Analog> {
|
||||
let offset = 2 * $i;
|
||||
unsafe {
|
||||
|
@ -351,7 +349,7 @@ macro_rules! gpio {
|
|||
|
||||
/// Configures the pin to operate as an open drain output pin
|
||||
pub fn into_open_drain_output(
|
||||
self,
|
||||
self, _cs: &CriticalSection
|
||||
) -> $PXi<Output<OpenDrain>> {
|
||||
let offset = 2 * $i;
|
||||
unsafe {
|
||||
|
@ -370,10 +368,9 @@ macro_rules! gpio {
|
|||
|
||||
/// Configures the pin to operate as an push pull output pin
|
||||
pub fn into_push_pull_output(
|
||||
self,
|
||||
self, _cs: &CriticalSection
|
||||
) -> $PXi<Output<PushPull>> {
|
||||
let offset = 2 * $i;
|
||||
|
||||
unsafe {
|
||||
&(*$GPIOX::ptr()).pupdr.modify(|r, w| {
|
||||
w.bits((r.bits() & !(0b11 << offset)) | (0b00 << offset))
|
||||
|
@ -391,10 +388,9 @@ macro_rules! gpio {
|
|||
/// Configures the pin to operate as an push pull output pin with quick fall
|
||||
/// and rise times
|
||||
pub fn into_push_pull_output_hs(
|
||||
self,
|
||||
self, _cs: &CriticalSection
|
||||
) -> $PXi<Output<PushPull>> {
|
||||
let offset = 2 * $i;
|
||||
|
||||
unsafe {
|
||||
&(*$GPIOX::ptr()).pupdr.modify(|r, w| {
|
||||
w.bits((r.bits() & !(0b11 << offset)) | (0b00 << offset))
|
||||
|
@ -409,46 +405,46 @@ macro_rules! gpio {
|
|||
w.bits((r.bits() & !(0b11 << offset)) | (0b01 << offset))
|
||||
});
|
||||
}
|
||||
|
||||
$PXi { _mode: PhantomData }
|
||||
}
|
||||
}
|
||||
|
||||
impl $PXi<Output<OpenDrain>> {
|
||||
/// Enables / disables the internal pull up
|
||||
pub fn internal_pull_up(&mut self, on: bool) {
|
||||
pub fn internal_pull_up(&mut self, _cs: &CriticalSection, on: bool) {
|
||||
let offset = 2 * $i;
|
||||
let value = if on { 0b01 } else { 0b00 };
|
||||
unsafe {
|
||||
&(*$GPIOX::ptr()).pupdr.modify(|r, w| {
|
||||
w.bits((r.bits() & !(0b11 << offset)) | (value << offset))
|
||||
})};
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<MODE> $PXi<Alternate<MODE>> {
|
||||
/// Enables / disables the internal pull up
|
||||
pub fn internal_pull_up(self, on: bool) -> Self {
|
||||
pub fn internal_pull_up(self, _cs: &CriticalSection, on: bool) -> Self {
|
||||
let offset = 2 * $i;
|
||||
let value = if on { 0b01 } else { 0b00 };
|
||||
unsafe {
|
||||
&(*$GPIOX::ptr()).pupdr.modify(|r, w| {
|
||||
w.bits((r.bits() & !(0b11 << offset)) | (value << offset))
|
||||
})};
|
||||
|
||||
});
|
||||
}
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
impl<MODE> $PXi<Alternate<MODE>> {
|
||||
/// Turns pin alternate configuration pin into open drain
|
||||
pub fn set_open_drain(self) -> Self {
|
||||
pub fn set_open_drain(self, _cs: &CriticalSection) -> Self {
|
||||
let offset = $i;
|
||||
unsafe {
|
||||
&(*$GPIOX::ptr()).otyper.modify(|r, w| {
|
||||
|