rtic heartbeat
This commit is contained in:
		
							parent
							
								
									eb0bda3300
								
							
						
					
					
						commit
						910010ba22
					
				
					 2 changed files with 261 additions and 196 deletions
				
			
		| 
						 | 
				
			
			@ -7,8 +7,10 @@ license = "MIT OR Apache-2.0"
 | 
			
		|||
[dependencies]
 | 
			
		||||
cortex-m = {version = "0.7"}
 | 
			
		||||
cortex-m-rt = "0.7"
 | 
			
		||||
cortex-m-rtic = "1.1.4"
 | 
			
		||||
embedded-hal = { version = "0.2.5", features = ["unproven"] }
 | 
			
		||||
embedded-alloc = "0.5.1"
 | 
			
		||||
rp2040-monotonic = "1.3.0"
 | 
			
		||||
 | 
			
		||||
defmt = "0.3"
 | 
			
		||||
defmt-rtt = "0.4"
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										155
									
								
								src/main.rs
									
										
									
									
									
								
							
							
						
						
									
										155
									
								
								src/main.rs
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -1,18 +1,27 @@
 | 
			
		|||
#![no_std]
 | 
			
		||||
#![no_main]
 | 
			
		||||
 | 
			
		||||
#[rtic::app(
 | 
			
		||||
    device = rp_pico::hal::pac,
 | 
			
		||||
    dispatchers = [TIMER_IRQ_1]
 | 
			
		||||
    )]
 | 
			
		||||
mod app {
 | 
			
		||||
    extern crate alloc;
 | 
			
		||||
    use alloc::format;
 | 
			
		||||
    use core::fmt::Write;
 | 
			
		||||
    use cortex_m::delay::Delay;
 | 
			
		||||
    use defmt_rtt as _;
 | 
			
		||||
    use embedded_alloc::Heap;
 | 
			
		||||
use embedded_hal::{digital::v2::OutputPin, spi::MODE_0};
 | 
			
		||||
    use embedded_hal::{
 | 
			
		||||
        digital::v2::{OutputPin, ToggleableOutputPin},
 | 
			
		||||
        spi::MODE_0,
 | 
			
		||||
    };
 | 
			
		||||
    use hd44780::{bus::FourBitBus, HD44780};
 | 
			
		||||
    use panic_probe as _;
 | 
			
		||||
 | 
			
		||||
    use rp2040_monotonic::{fugit::Duration, Rp2040Monotonic};
 | 
			
		||||
 | 
			
		||||
    use rp_pico::{
 | 
			
		||||
    entry,
 | 
			
		||||
        hal::{
 | 
			
		||||
            clocks::{init_clocks_and_plls, Clock},
 | 
			
		||||
            fugit::RateExtU32,
 | 
			
		||||
| 
						 | 
				
			
			@ -24,7 +33,6 @@ use rp_pico::{
 | 
			
		|||
                },
 | 
			
		||||
                FunctionSio, FunctionSpi, FunctionUart, Pin, PullDown, SioOutput,
 | 
			
		||||
            },
 | 
			
		||||
        pac,
 | 
			
		||||
            sio::Sio,
 | 
			
		||||
            spi::{self, Spi},
 | 
			
		||||
            uart::{self, UartConfig, UartPeripheral},
 | 
			
		||||
| 
						 | 
				
			
			@ -40,15 +48,9 @@ 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();
 | 
			
		||||
}
 | 
			
		||||
    const MONO_NUM: u32 = 1;
 | 
			
		||||
    const MONO_DENOM: u32 = 1000000;
 | 
			
		||||
    const ONE_SEC_TICKS: u64 = 1000000;
 | 
			
		||||
 | 
			
		||||
    type Uart = UartPeripheral<
 | 
			
		||||
        uart::Enabled,
 | 
			
		||||
| 
						 | 
				
			
			@ -84,6 +86,9 @@ type Lcd = HD44780<
 | 
			
		|||
        >,
 | 
			
		||||
    >;
 | 
			
		||||
 | 
			
		||||
    #[monotonic(binds = TIMER_IRQ_0, default = true)]
 | 
			
		||||
    type Rp2040Mono = Rp2040Monotonic;
 | 
			
		||||
 | 
			
		||||
    struct Thermocouple {
 | 
			
		||||
        cs: Pin<Gpio5, FunctionSio<SioOutput>, PullDown>,
 | 
			
		||||
        spi: ThermocoupleSpi,
 | 
			
		||||
| 
						 | 
				
			
			@ -92,27 +97,45 @@ struct Thermocouple {
 | 
			
		|||
    impl Thermocouple {
 | 
			
		||||
        fn read_temp(
 | 
			
		||||
            &mut self,
 | 
			
		||||
    ) -> Result<f32, max31855::Error<core::convert::Infallible, core::convert::Infallible>> {
 | 
			
		||||
        ) -> 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);
 | 
			
		||||
    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,
 | 
			
		||||
        pac.XOSC,
 | 
			
		||||
        pac.CLOCKS,
 | 
			
		||||
        pac.PLL_SYS,
 | 
			
		||||
        pac.PLL_USB,
 | 
			
		||||
        &mut pac.RESETS,
 | 
			
		||||
            ctx.device.XOSC,
 | 
			
		||||
            ctx.device.CLOCKS,
 | 
			
		||||
            ctx.device.PLL_SYS,
 | 
			
		||||
            ctx.device.PLL_USB,
 | 
			
		||||
            &mut ctx.device.RESETS,
 | 
			
		||||
            &mut watchdog,
 | 
			
		||||
        )
 | 
			
		||||
        .ok()
 | 
			
		||||
| 
						 | 
				
			
			@ -126,19 +149,20 @@ fn main() -> ! {
 | 
			
		|||
            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 mut delay =
 | 
			
		||||
            cortex_m::delay::Delay::new(ctx.core.SYST, clocks.system_clock.freq().to_Hz());
 | 
			
		||||
 | 
			
		||||
        let pins = Pins::new(
 | 
			
		||||
        pac.IO_BANK0,
 | 
			
		||||
        pac.PADS_BANK0,
 | 
			
		||||
            ctx.device.IO_BANK0,
 | 
			
		||||
            ctx.device.PADS_BANK0,
 | 
			
		||||
            sio.gpio_bank0,
 | 
			
		||||
        &mut pac.RESETS,
 | 
			
		||||
            &mut ctx.device.RESETS,
 | 
			
		||||
        );
 | 
			
		||||
 | 
			
		||||
        let mut uart: Uart = UartPeripheral::new(
 | 
			
		||||
        pac.UART0,
 | 
			
		||||
            ctx.device.UART0,
 | 
			
		||||
            (pins.gpio0.into_function(), pins.gpio1.into_function()),
 | 
			
		||||
        &mut pac.RESETS,
 | 
			
		||||
            &mut ctx.device.RESETS,
 | 
			
		||||
        )
 | 
			
		||||
        .enable(
 | 
			
		||||
            UartConfig::new(
 | 
			
		||||
| 
						 | 
				
			
			@ -158,8 +182,8 @@ fn main() -> ! {
 | 
			
		|||
        let mut external_led_pin: ExternalLed = pins.gpio14.into_push_pull_output();
 | 
			
		||||
 | 
			
		||||
        //cs
 | 
			
		||||
    let thermometer_spi_device = pac.SPI0;
 | 
			
		||||
    let mut thermocouple = Thermocouple {
 | 
			
		||||
        let thermometer_spi_device = ctx.device.SPI0;
 | 
			
		||||
        let thermocouple = Thermocouple {
 | 
			
		||||
            cs: pins
 | 
			
		||||
                .gpio5
 | 
			
		||||
                .into_push_pull_output_in_state(gpio::PinState::Low),
 | 
			
		||||
| 
						 | 
				
			
			@ -175,7 +199,12 @@ fn main() -> ! {
 | 
			
		|||
                    pins.gpio2.into_function::<gpio::FunctionSpi>(),
 | 
			
		||||
                ),
 | 
			
		||||
            )
 | 
			
		||||
        .init(&mut pac.RESETS, 125_000_000u32.Hz(), 4u32.MHz(), MODE_0),
 | 
			
		||||
            .init(
 | 
			
		||||
                &mut ctx.device.RESETS,
 | 
			
		||||
                125_000_000u32.Hz(),
 | 
			
		||||
                4u32.MHz(),
 | 
			
		||||
                MODE_0,
 | 
			
		||||
            ),
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        let mut lcd: Lcd = hd44780::HD44780::new_4bit(
 | 
			
		||||
| 
						 | 
				
			
			@ -189,20 +218,54 @@ fn main() -> ! {
 | 
			
		|||
        )
 | 
			
		||||
        .unwrap();
 | 
			
		||||
 | 
			
		||||
        let mono = Rp2040Mono::new(ctx.device.TIMER);
 | 
			
		||||
 | 
			
		||||
        write_lcd(&mut lcd, &mut delay, "Starting");
 | 
			
		||||
    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))
 | 
			
		||||
 | 
			
		||||
        (
 | 
			
		||||
            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)),
 | 
			
		||||
        //     };
 | 
			
		||||
        // }
 | 
			
		||||
    }
 | 
			
		||||
            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…
	
	Add table
		Add a link
		
	
		Reference in a new issue