rtic heartbeat
This commit is contained in:
parent
eb0bda3300
commit
910010ba22
|
@ -7,8 +7,10 @@ license = "MIT OR Apache-2.0"
|
||||||
[dependencies]
|
[dependencies]
|
||||||
cortex-m = {version = "0.7"}
|
cortex-m = {version = "0.7"}
|
||||||
cortex-m-rt = "0.7"
|
cortex-m-rt = "0.7"
|
||||||
|
cortex-m-rtic = "1.1.4"
|
||||||
embedded-hal = { version = "0.2.5", features = ["unproven"] }
|
embedded-hal = { version = "0.2.5", features = ["unproven"] }
|
||||||
embedded-alloc = "0.5.1"
|
embedded-alloc = "0.5.1"
|
||||||
|
rp2040-monotonic = "1.3.0"
|
||||||
|
|
||||||
defmt = "0.3"
|
defmt = "0.3"
|
||||||
defmt-rtt = "0.4"
|
defmt-rtt = "0.4"
|
||||||
|
|
455
src/main.rs
455
src/main.rs
|
@ -1,208 +1,271 @@
|
||||||
#![no_std]
|
#![no_std]
|
||||||
#![no_main]
|
#![no_main]
|
||||||
|
|
||||||
extern crate alloc;
|
#[rtic::app(
|
||||||
use alloc::format;
|
device = rp_pico::hal::pac,
|
||||||
use core::fmt::Write;
|
dispatchers = [TIMER_IRQ_1]
|
||||||
use cortex_m::delay::Delay;
|
)]
|
||||||
use defmt_rtt as _;
|
mod app {
|
||||||
use embedded_alloc::Heap;
|
extern crate alloc;
|
||||||
use embedded_hal::{digital::v2::OutputPin, spi::MODE_0};
|
use alloc::format;
|
||||||
use hd44780::{bus::FourBitBus, HD44780};
|
use core::fmt::Write;
|
||||||
use panic_probe as _;
|
use cortex_m::delay::Delay;
|
||||||
|
use defmt_rtt as _;
|
||||||
|
use embedded_alloc::Heap;
|
||||||
|
use embedded_hal::{
|
||||||
|
digital::v2::{OutputPin, ToggleableOutputPin},
|
||||||
|
spi::MODE_0,
|
||||||
|
};
|
||||||
|
use hd44780::{bus::FourBitBus, HD44780};
|
||||||
|
use panic_probe as _;
|
||||||
|
|
||||||
use rp_pico::{
|
use rp2040_monotonic::{fugit::Duration, Rp2040Monotonic};
|
||||||
entry,
|
|
||||||
hal::{
|
use rp_pico::{
|
||||||
clocks::{init_clocks_and_plls, Clock},
|
hal::{
|
||||||
fugit::RateExtU32,
|
clocks::{init_clocks_and_plls, Clock},
|
||||||
gpio::{
|
fugit::RateExtU32,
|
||||||
self,
|
gpio::{
|
||||||
bank0::{
|
self,
|
||||||
Gpio0, Gpio1, Gpio14, Gpio16, Gpio17, Gpio18, Gpio19, Gpio2, Gpio20, Gpio21,
|
bank0::{
|
||||||
Gpio25, Gpio3, Gpio4, Gpio5,
|
Gpio0, Gpio1, Gpio14, Gpio16, Gpio17, Gpio18, Gpio19, Gpio2, Gpio20, Gpio21,
|
||||||
|
Gpio25, Gpio3, Gpio4, Gpio5,
|
||||||
|
},
|
||||||
|
FunctionSio, FunctionSpi, FunctionUart, Pin, PullDown, SioOutput,
|
||||||
},
|
},
|
||||||
FunctionSio, FunctionSpi, FunctionUart, Pin, PullDown, SioOutput,
|
sio::Sio,
|
||||||
|
spi::{self, Spi},
|
||||||
|
uart::{self, UartConfig, UartPeripheral},
|
||||||
|
watchdog::Watchdog,
|
||||||
},
|
},
|
||||||
pac,
|
pac::{SPI0, UART0},
|
||||||
sio::Sio,
|
Pins,
|
||||||
spi::{self, Spi},
|
|
||||||
uart::{self, UartConfig, UartPeripheral},
|
|
||||||
watchdog::Watchdog,
|
|
||||||
},
|
|
||||||
pac::{SPI0, UART0},
|
|
||||||
Pins,
|
|
||||||
};
|
|
||||||
|
|
||||||
use hd44780_driver as hd44780;
|
|
||||||
use max31855::{Max31855, Unit};
|
|
||||||
|
|
||||||
#[global_allocator]
|
|
||||||
static HEAP: Heap = Heap::empty();
|
|
||||||
|
|
||||||
fn write_lcd<T: hd44780_driver::bus::DataBus>(
|
|
||||||
lcd: &mut hd44780::HD44780<T>,
|
|
||||||
delay: &mut Delay,
|
|
||||||
string: &str,
|
|
||||||
) {
|
|
||||||
lcd.reset(delay).unwrap();
|
|
||||||
lcd.clear(delay).unwrap();
|
|
||||||
lcd.write_str(string, delay).unwrap();
|
|
||||||
}
|
|
||||||
|
|
||||||
type Uart = UartPeripheral<
|
|
||||||
uart::Enabled,
|
|
||||||
UART0,
|
|
||||||
(
|
|
||||||
Pin<Gpio0, FunctionUart, PullDown>,
|
|
||||||
Pin<Gpio1, FunctionUart, PullDown>,
|
|
||||||
),
|
|
||||||
>;
|
|
||||||
|
|
||||||
type Led = Pin<Gpio25, FunctionSio<SioOutput>, PullDown>;
|
|
||||||
|
|
||||||
type ExternalLed = Pin<Gpio14, FunctionSio<SioOutput>, PullDown>;
|
|
||||||
|
|
||||||
type ThermocoupleSpi = Spi<
|
|
||||||
spi::Enabled,
|
|
||||||
SPI0,
|
|
||||||
(
|
|
||||||
Pin<Gpio3, FunctionSpi, PullDown>,
|
|
||||||
Pin<Gpio4, FunctionSpi, PullDown>,
|
|
||||||
Pin<Gpio2, FunctionSpi, PullDown>,
|
|
||||||
),
|
|
||||||
>;
|
|
||||||
|
|
||||||
type Lcd = HD44780<
|
|
||||||
FourBitBus<
|
|
||||||
Pin<Gpio16, FunctionSio<SioOutput>, PullDown>,
|
|
||||||
Pin<Gpio17, FunctionSio<SioOutput>, PullDown>,
|
|
||||||
Pin<Gpio18, FunctionSio<SioOutput>, PullDown>,
|
|
||||||
Pin<Gpio19, FunctionSio<SioOutput>, PullDown>,
|
|
||||||
Pin<Gpio20, FunctionSio<SioOutput>, PullDown>,
|
|
||||||
Pin<Gpio21, FunctionSio<SioOutput>, PullDown>,
|
|
||||||
>,
|
|
||||||
>;
|
|
||||||
|
|
||||||
struct Thermocouple {
|
|
||||||
cs: Pin<Gpio5, FunctionSio<SioOutput>, PullDown>,
|
|
||||||
spi: ThermocoupleSpi,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Thermocouple {
|
|
||||||
fn read_temp(
|
|
||||||
&mut self,
|
|
||||||
) -> Result<f32, max31855::Error<core::convert::Infallible, core::convert::Infallible>> {
|
|
||||||
self.spi.read_thermocouple(&mut self.cs, Unit::Celsius)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[entry]
|
|
||||||
fn main() -> ! {
|
|
||||||
let mut pac = pac::Peripherals::take().unwrap();
|
|
||||||
let core = pac::CorePeripherals::take().unwrap();
|
|
||||||
let mut watchdog = Watchdog::new(pac.WATCHDOG);
|
|
||||||
let sio = Sio::new(pac.SIO);
|
|
||||||
|
|
||||||
// External high-speed crystal on the pico board is 12Mhz
|
|
||||||
let external_xtal_freq_hz = 12_000_000u32;
|
|
||||||
let clocks = init_clocks_and_plls(
|
|
||||||
external_xtal_freq_hz,
|
|
||||||
pac.XOSC,
|
|
||||||
pac.CLOCKS,
|
|
||||||
pac.PLL_SYS,
|
|
||||||
pac.PLL_USB,
|
|
||||||
&mut pac.RESETS,
|
|
||||||
&mut watchdog,
|
|
||||||
)
|
|
||||||
.ok()
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
//initalize the heap
|
|
||||||
{
|
|
||||||
use core::mem::MaybeUninit;
|
|
||||||
const HEAP_SIZE: usize = 1024;
|
|
||||||
static mut HEAP_MEM: [MaybeUninit<u8>; HEAP_SIZE] = [MaybeUninit::uninit(); HEAP_SIZE];
|
|
||||||
unsafe { HEAP.init(HEAP_MEM.as_ptr() as usize, HEAP_SIZE) }
|
|
||||||
}
|
|
||||||
|
|
||||||
let mut delay = cortex_m::delay::Delay::new(core.SYST, clocks.system_clock.freq().to_Hz());
|
|
||||||
|
|
||||||
let pins = Pins::new(
|
|
||||||
pac.IO_BANK0,
|
|
||||||
pac.PADS_BANK0,
|
|
||||||
sio.gpio_bank0,
|
|
||||||
&mut pac.RESETS,
|
|
||||||
);
|
|
||||||
|
|
||||||
let mut uart: Uart = UartPeripheral::new(
|
|
||||||
pac.UART0,
|
|
||||||
(pins.gpio0.into_function(), pins.gpio1.into_function()),
|
|
||||||
&mut pac.RESETS,
|
|
||||||
)
|
|
||||||
.enable(
|
|
||||||
UartConfig::new(
|
|
||||||
9600u32.Hz(),
|
|
||||||
rp_pico::hal::uart::DataBits::Eight,
|
|
||||||
None,
|
|
||||||
rp_pico::hal::uart::StopBits::One,
|
|
||||||
),
|
|
||||||
clocks.peripheral_clock.freq(),
|
|
||||||
)
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
defmt::info!("Program start");
|
|
||||||
writeln!(uart, "Program start\r",).unwrap();
|
|
||||||
|
|
||||||
let mut led_pin: Led = pins.led.into_push_pull_output();
|
|
||||||
let mut external_led_pin: ExternalLed = pins.gpio14.into_push_pull_output();
|
|
||||||
|
|
||||||
//cs
|
|
||||||
let thermometer_spi_device = pac.SPI0;
|
|
||||||
let mut thermocouple = Thermocouple {
|
|
||||||
cs: pins
|
|
||||||
.gpio5
|
|
||||||
.into_push_pull_output_in_state(gpio::PinState::Low),
|
|
||||||
|
|
||||||
spi: Spi::<_, _, _, 8>::new(
|
|
||||||
thermometer_spi_device,
|
|
||||||
(
|
|
||||||
//mosi
|
|
||||||
pins.gpio3.into_function::<gpio::FunctionSpi>(),
|
|
||||||
//miso/do
|
|
||||||
pins.gpio4.into_function::<gpio::FunctionSpi>(),
|
|
||||||
//clk
|
|
||||||
pins.gpio2.into_function::<gpio::FunctionSpi>(),
|
|
||||||
),
|
|
||||||
)
|
|
||||||
.init(&mut pac.RESETS, 125_000_000u32.Hz(), 4u32.MHz(), MODE_0),
|
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut lcd: Lcd = hd44780::HD44780::new_4bit(
|
use hd44780_driver as hd44780;
|
||||||
pins.gpio16.into_push_pull_output(), //rs
|
use max31855::{Max31855, Unit};
|
||||||
pins.gpio17.into_push_pull_output(), //enable
|
|
||||||
pins.gpio18.into_push_pull_output(), //d4
|
|
||||||
pins.gpio19.into_push_pull_output(), //d5
|
|
||||||
pins.gpio20.into_push_pull_output(), //d6
|
|
||||||
pins.gpio21.into_push_pull_output(), //d6
|
|
||||||
&mut delay,
|
|
||||||
)
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
write_lcd(&mut lcd, &mut delay, "Starting");
|
#[global_allocator]
|
||||||
loop {
|
static HEAP: Heap = Heap::empty();
|
||||||
led_pin.set_high().unwrap();
|
|
||||||
external_led_pin.set_low().unwrap();
|
const MONO_NUM: u32 = 1;
|
||||||
delay.delay_ms(500);
|
const MONO_DENOM: u32 = 1000000;
|
||||||
led_pin.set_low().unwrap();
|
const ONE_SEC_TICKS: u64 = 1000000;
|
||||||
external_led_pin.set_high().unwrap();
|
|
||||||
delay.delay_ms(500);
|
type Uart = UartPeripheral<
|
||||||
match thermocouple.read_temp() {
|
uart::Enabled,
|
||||||
Ok(v) => {
|
UART0,
|
||||||
writeln!(uart, "Current: {} \r", v).unwrap();
|
(
|
||||||
write_lcd(&mut lcd, &mut delay, &format!("{:02.2} C", v))
|
Pin<Gpio0, FunctionUart, PullDown>,
|
||||||
}
|
Pin<Gpio1, FunctionUart, PullDown>,
|
||||||
Err(e) => defmt::error!("error reading temp {}", defmt::Debug2Format(&e)),
|
),
|
||||||
|
>;
|
||||||
|
|
||||||
|
type Led = Pin<Gpio25, FunctionSio<SioOutput>, PullDown>;
|
||||||
|
|
||||||
|
type ExternalLed = Pin<Gpio14, FunctionSio<SioOutput>, PullDown>;
|
||||||
|
|
||||||
|
type ThermocoupleSpi = Spi<
|
||||||
|
spi::Enabled,
|
||||||
|
SPI0,
|
||||||
|
(
|
||||||
|
Pin<Gpio3, FunctionSpi, PullDown>,
|
||||||
|
Pin<Gpio4, FunctionSpi, PullDown>,
|
||||||
|
Pin<Gpio2, FunctionSpi, PullDown>,
|
||||||
|
),
|
||||||
|
>;
|
||||||
|
|
||||||
|
type Lcd = HD44780<
|
||||||
|
FourBitBus<
|
||||||
|
Pin<Gpio16, FunctionSio<SioOutput>, PullDown>,
|
||||||
|
Pin<Gpio17, FunctionSio<SioOutput>, PullDown>,
|
||||||
|
Pin<Gpio18, FunctionSio<SioOutput>, PullDown>,
|
||||||
|
Pin<Gpio19, FunctionSio<SioOutput>, PullDown>,
|
||||||
|
Pin<Gpio20, FunctionSio<SioOutput>, PullDown>,
|
||||||
|
Pin<Gpio21, FunctionSio<SioOutput>, PullDown>,
|
||||||
|
>,
|
||||||
|
>;
|
||||||
|
|
||||||
|
#[monotonic(binds = TIMER_IRQ_0, default = true)]
|
||||||
|
type Rp2040Mono = Rp2040Monotonic;
|
||||||
|
|
||||||
|
struct Thermocouple {
|
||||||
|
cs: Pin<Gpio5, FunctionSio<SioOutput>, PullDown>,
|
||||||
|
spi: ThermocoupleSpi,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Thermocouple {
|
||||||
|
fn read_temp(
|
||||||
|
&mut self,
|
||||||
|
) -> Result<f32, max31855::Error<core::convert::Infallible, core::convert::Infallible>>
|
||||||
|
{
|
||||||
|
self.spi.read_thermocouple(&mut self.cs, Unit::Celsius)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn write_lcd(lcd: &mut Lcd, delay: &mut Delay, string: &str) {
|
||||||
|
lcd.reset(delay).unwrap();
|
||||||
|
lcd.clear(delay).unwrap();
|
||||||
|
lcd.write_str(string, delay).unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
|
#[shared]
|
||||||
|
struct Shared {
|
||||||
|
delay: Delay,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[local]
|
||||||
|
struct Local {
|
||||||
|
led: Led,
|
||||||
|
thermocouple: Thermocouple,
|
||||||
|
lcd: Lcd,
|
||||||
|
external_led: ExternalLed,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[init]
|
||||||
|
fn init(mut ctx: init::Context) -> (Shared, Local, init::Monotonics) {
|
||||||
|
let mut watchdog = Watchdog::new(ctx.device.WATCHDOG);
|
||||||
|
let sio = Sio::new(ctx.device.SIO);
|
||||||
|
|
||||||
|
// External high-speed crystal on the pico board is 12Mhz
|
||||||
|
let external_xtal_freq_hz = 12_000_000u32;
|
||||||
|
let clocks = init_clocks_and_plls(
|
||||||
|
external_xtal_freq_hz,
|
||||||
|
ctx.device.XOSC,
|
||||||
|
ctx.device.CLOCKS,
|
||||||
|
ctx.device.PLL_SYS,
|
||||||
|
ctx.device.PLL_USB,
|
||||||
|
&mut ctx.device.RESETS,
|
||||||
|
&mut watchdog,
|
||||||
|
)
|
||||||
|
.ok()
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
//initalize the heap
|
||||||
|
{
|
||||||
|
use core::mem::MaybeUninit;
|
||||||
|
const HEAP_SIZE: usize = 1024;
|
||||||
|
static mut HEAP_MEM: [MaybeUninit<u8>; HEAP_SIZE] = [MaybeUninit::uninit(); HEAP_SIZE];
|
||||||
|
unsafe { HEAP.init(HEAP_MEM.as_ptr() as usize, HEAP_SIZE) }
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut delay =
|
||||||
|
cortex_m::delay::Delay::new(ctx.core.SYST, clocks.system_clock.freq().to_Hz());
|
||||||
|
|
||||||
|
let pins = Pins::new(
|
||||||
|
ctx.device.IO_BANK0,
|
||||||
|
ctx.device.PADS_BANK0,
|
||||||
|
sio.gpio_bank0,
|
||||||
|
&mut ctx.device.RESETS,
|
||||||
|
);
|
||||||
|
|
||||||
|
let mut uart: Uart = UartPeripheral::new(
|
||||||
|
ctx.device.UART0,
|
||||||
|
(pins.gpio0.into_function(), pins.gpio1.into_function()),
|
||||||
|
&mut ctx.device.RESETS,
|
||||||
|
)
|
||||||
|
.enable(
|
||||||
|
UartConfig::new(
|
||||||
|
9600u32.Hz(),
|
||||||
|
rp_pico::hal::uart::DataBits::Eight,
|
||||||
|
None,
|
||||||
|
rp_pico::hal::uart::StopBits::One,
|
||||||
|
),
|
||||||
|
clocks.peripheral_clock.freq(),
|
||||||
|
)
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
defmt::info!("Program start");
|
||||||
|
writeln!(uart, "Program start\r",).unwrap();
|
||||||
|
|
||||||
|
let mut led_pin: Led = pins.led.into_push_pull_output();
|
||||||
|
let mut external_led_pin: ExternalLed = pins.gpio14.into_push_pull_output();
|
||||||
|
|
||||||
|
//cs
|
||||||
|
let thermometer_spi_device = ctx.device.SPI0;
|
||||||
|
let thermocouple = Thermocouple {
|
||||||
|
cs: pins
|
||||||
|
.gpio5
|
||||||
|
.into_push_pull_output_in_state(gpio::PinState::Low),
|
||||||
|
|
||||||
|
spi: Spi::<_, _, _, 8>::new(
|
||||||
|
thermometer_spi_device,
|
||||||
|
(
|
||||||
|
//mosi
|
||||||
|
pins.gpio3.into_function::<gpio::FunctionSpi>(),
|
||||||
|
//miso/do
|
||||||
|
pins.gpio4.into_function::<gpio::FunctionSpi>(),
|
||||||
|
//clk
|
||||||
|
pins.gpio2.into_function::<gpio::FunctionSpi>(),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
.init(
|
||||||
|
&mut ctx.device.RESETS,
|
||||||
|
125_000_000u32.Hz(),
|
||||||
|
4u32.MHz(),
|
||||||
|
MODE_0,
|
||||||
|
),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let mut lcd: Lcd = hd44780::HD44780::new_4bit(
|
||||||
|
pins.gpio16.into_push_pull_output(), //rs
|
||||||
|
pins.gpio17.into_push_pull_output(), //enable
|
||||||
|
pins.gpio18.into_push_pull_output(), //d4
|
||||||
|
pins.gpio19.into_push_pull_output(), //d5
|
||||||
|
pins.gpio20.into_push_pull_output(), //d6
|
||||||
|
pins.gpio21.into_push_pull_output(), //d6
|
||||||
|
&mut delay,
|
||||||
|
)
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
let mono = Rp2040Mono::new(ctx.device.TIMER);
|
||||||
|
|
||||||
|
write_lcd(&mut lcd, &mut delay, "Starting");
|
||||||
|
|
||||||
|
(
|
||||||
|
Shared { delay },
|
||||||
|
Local {
|
||||||
|
led: led_pin,
|
||||||
|
thermocouple,
|
||||||
|
lcd,
|
||||||
|
external_led: external_led_pin,
|
||||||
|
},
|
||||||
|
init::Monotonics(mono),
|
||||||
|
)
|
||||||
|
|
||||||
|
// loop {
|
||||||
|
// led_pin.set_high().unwrap();
|
||||||
|
// external_led_pin.set_low().unwrap();
|
||||||
|
// delay.delay_ms(500);
|
||||||
|
// led_pin.set_low().unwrap();
|
||||||
|
// external_led_pin.set_high().unwrap();
|
||||||
|
// delay.delay_ms(500);
|
||||||
|
// match thermocouple.read_temp() {
|
||||||
|
// Ok(v) => {
|
||||||
|
// writeln!(uart, "Current: {} \r", v).unwrap();
|
||||||
|
// write_lcd(&mut lcd, &mut delay, &format!("{:02.2} C", v))
|
||||||
|
// }
|
||||||
|
// Err(e) => defmt::error!("error reading temp {}", defmt::Debug2Format(&e)),
|
||||||
|
// };
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
#[task(local = [led])]
|
||||||
|
fn heartbeat(ctx: heartbeat::Context) {
|
||||||
|
// Flicker the built-in LED
|
||||||
|
ctx.local.led.toggle().unwrap();
|
||||||
|
|
||||||
|
// Re-spawn this task after 1 second
|
||||||
|
let one_second = Duration::<u64, MONO_NUM, MONO_DENOM>::from_ticks(ONE_SEC_TICKS);
|
||||||
|
heartbeat::spawn_after(one_second).unwrap();
|
||||||
|
}
|
||||||
|
#[task(local = [external_led])]
|
||||||
|
fn second_heartbeat(ctx: second_heartbeat::Context) {
|
||||||
|
// Flicker the built-in LED
|
||||||
|
ctx.local.external_led.toggle().unwrap();
|
||||||
|
|
||||||
|
// Re-spawn this task after 1 second
|
||||||
|
let one_and_one_half_second =
|
||||||
|
Duration::<u64, MONO_NUM, MONO_DENOM>::from_ticks((ONE_SEC_TICKS as f32 * 1.5) as u64);
|
||||||
|
heartbeat::spawn_after(one_and_one_half_second).unwrap();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue