2024-02-27 22:55:50 +00:00
|
|
|
//! Blinks an LED
|
|
|
|
|
//!
|
|
|
|
|
//! This assumes that a LED is connected to pc13 as is the case on the blue pill board.
|
|
|
|
|
//!
|
|
|
|
|
//! Note: Without additional hardware, PC13 should not be used to drive an LED, see page 5.1.2 of
|
|
|
|
|
//! the reference manual for an explanation. This is not an issue on the blue pill.
|
|
|
|
|
|
2024-03-08 16:59:02 +00:00
|
|
|
// #![deny(unsafe_code)]
|
2024-02-27 22:55:50 +00:00
|
|
|
#![no_std]
|
|
|
|
|
#![no_main]
|
|
|
|
|
|
2024-03-08 16:59:02 +00:00
|
|
|
// use cortex_m::singleton;
|
2024-02-27 22:55:50 +00:00
|
|
|
use panic_halt as _;
|
2024-03-08 16:59:02 +00:00
|
|
|
use stm32f1xx_hal::{dma, gpio, pac, prelude::*, rcc, serial, timer};
|
|
|
|
|
use systick_monotonic::Systick;
|
2024-02-27 22:55:50 +00:00
|
|
|
|
2024-03-03 15:49:38 +00:00
|
|
|
mod i2c_reg_slave;
|
|
|
|
|
mod i2c_slave;
|
|
|
|
|
|
2024-03-08 16:59:02 +00:00
|
|
|
// static mut BUFFER: Option<&mut [u8; 256]> = None;
|
2024-02-28 13:02:02 +00:00
|
|
|
|
2024-03-08 16:59:02 +00:00
|
|
|
#[rtic::app(device = stm32f1::stm32f103, peripherals = true)]
|
|
|
|
|
mod app {
|
|
|
|
|
use super::*;
|
|
|
|
|
|
|
|
|
|
// A monotonic timer to enable scheduling in RTIC
|
|
|
|
|
#[monotonic(binds = SysTick, default = true)]
|
|
|
|
|
type MyMono = Systick<100>; // 100 Hz / 10 ms granularity
|
|
|
|
|
|
|
|
|
|
#[shared]
|
|
|
|
|
struct Shared {}
|
|
|
|
|
|
|
|
|
|
#[local]
|
|
|
|
|
struct Local {
|
|
|
|
|
tx: dma::TxDma<serial::Tx<pac::USART1>, dma::dma1::C4>,
|
|
|
|
|
delay: timer::Delay<pac::TIM1, 1_000_000>,
|
|
|
|
|
led: gpio::Pin<'C', 13, gpio::Output>,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[init]
|
|
|
|
|
fn init(cx: init::Context) -> (Shared, Local, init::Monotonics) {
|
|
|
|
|
// Take ownership over the raw flash and rcc devices and convert them into the corresponding
|
|
|
|
|
// HAL structs
|
|
|
|
|
let mut flash = cx.device.FLASH.constrain();
|
|
|
|
|
let rcc = cx.device.RCC.constrain();
|
|
|
|
|
|
|
|
|
|
// Freeze the configuration of all the clocks in the system and store the frozen frequencies in
|
|
|
|
|
// `clocks`
|
|
|
|
|
let clocks = rcc.cfgr.freeze_with_config(
|
|
|
|
|
rcc::Config {
|
|
|
|
|
// HSE frequency
|
|
|
|
|
hse: Some(8_000_000),
|
|
|
|
|
// PLLMUL represented by an integer -2
|
|
|
|
|
pllmul: Some(9 - 2),
|
|
|
|
|
// PCLK1 freq must be 36 MHz or less
|
|
|
|
|
ppre1: stm32f1xx_hal::rcc::PPre::Div2,
|
|
|
|
|
// ADCCLK freq must be 14 MHz or less
|
|
|
|
|
adcpre: pac::rcc::cfgr::ADCPRE_A::Div6,
|
|
|
|
|
..Default::default()
|
|
|
|
|
},
|
|
|
|
|
&mut flash.acr,
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
// Initialize the monotonic
|
|
|
|
|
let mono = Systick::new(cx.core.SYST, clocks.sysclk().to_Hz());
|
|
|
|
|
|
|
|
|
|
// Acquire the peripherals
|
|
|
|
|
let mut gpioa = cx.device.GPIOA.split();
|
|
|
|
|
let mut gpioc = cx.device.GPIOC.split();
|
|
|
|
|
|
|
|
|
|
let mut afio = cx.device.AFIO.constrain();
|
|
|
|
|
let dma1 = cx.device.DMA1.split();
|
|
|
|
|
|
|
|
|
|
// USART1
|
|
|
|
|
let tx = gpioa.pa9.into_alternate_push_pull(&mut gpioa.crh);
|
|
|
|
|
let rx = gpioa.pa10; //.into_pull_up_input(&mut gpioa.crh);
|
|
|
|
|
|
|
|
|
|
let serial = serial::Serial::new(
|
|
|
|
|
cx.device.USART1,
|
|
|
|
|
(tx, rx),
|
|
|
|
|
&mut afio.mapr,
|
|
|
|
|
serial::Config {
|
|
|
|
|
baudrate: 250_000.bps(),
|
|
|
|
|
..Default::default()
|
|
|
|
|
},
|
|
|
|
|
&clocks,
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
// unsafe {
|
|
|
|
|
// BUFFER = Some(singleton!(: [u8; 256] = [0b01010101; 256]).unwrap());
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
|
|
(
|
|
|
|
|
Shared {},
|
|
|
|
|
Local {
|
|
|
|
|
tx: serial.tx.with_dma(dma1.4),
|
|
|
|
|
|
|
|
|
|
// Configure timer
|
|
|
|
|
delay: cx.device.TIM1.delay_us(&clocks),
|
|
|
|
|
|
|
|
|
|
// Configure gpio C pin 13 as a push-pull output. The `crh` register is passed to the function
|
|
|
|
|
// in order to configure the port. For pins 0-7, crl should be passed instead.
|
|
|
|
|
led: gpioc.pc13.into_push_pull_output(&mut gpioc.crh),
|
|
|
|
|
},
|
|
|
|
|
init::Monotonics(mono),
|
|
|
|
|
)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[idle(local = [tx, delay, led])]
|
|
|
|
|
fn idle(cx: idle::Context) -> ! {
|
|
|
|
|
// Wait for the timer to trigger an update and change the state of the LED
|
|
|
|
|
loop {
|
|
|
|
|
// let xfer = cx.shared.tx.lock(|tx| tx.write(BUFFER.unwrap()));
|
2024-03-01 15:18:26 +00:00
|
|
|
|
2024-03-08 16:59:02 +00:00
|
|
|
cx.local.delay.delay(1u32.secs());
|
|
|
|
|
cx.local.led.set_high();
|
|
|
|
|
|
|
|
|
|
cx.local.delay.delay(1u32.secs());
|
|
|
|
|
cx.local.led.set_low();
|
|
|
|
|
|
|
|
|
|
// xfer.wait();
|
|
|
|
|
}
|
2024-02-27 22:55:50 +00:00
|
|
|
}
|
|
|
|
|
}
|