A RPi Pico powered Lightning Detector
at main 119 lines 3.1 kB view raw
1#![feature(allocator_api)] 2#![allow(unexpected_cfgs)] 3#![no_std] 4#![no_main] 5 6mod allocator; 7mod detector; 8mod errors; 9mod locks; 10mod net; 11#[cfg(not(feature = "defmt"))] 12mod panic_handler; 13mod rpc; 14mod rtc; 15mod state; 16mod updates; 17mod utils; 18mod wifi; 19 20use crate::{allocator::PicoHeap, rtc::GlobalRtc}; 21use cyw43_pio::{DEFAULT_CLOCK_DIVIDER, PioSpi}; 22use embassy_executor::Executor; 23use embassy_rp::{ 24 adc as rp_adc, bind_interrupts, 25 clocks::RoscRng, 26 gpio::{Level, Output}, 27 multicore::{Stack, spawn_core1}, 28 peripherals::PIO0, 29 pio::{InterruptHandler, Pio}, 30 rtc::{self as rp_rtc, Rtc}, 31}; 32use sachy_fmt::*; 33use static_cell::{ConstStaticCell, StaticCell}; 34 35extern crate alloc; 36 37#[cfg(feature = "defmt")] 38use {defmt_rtt as _, panic_probe as _}; 39 40mod constants { 41 include!(concat!(env!("OUT_DIR"), "/constants.rs")); 42} 43 44use constants::HEAP_SIZE; 45 46#[global_allocator] 47static HEAP: PicoHeap<HEAP_SIZE> = PicoHeap::empty(); 48 49bind_interrupts!(struct Irqs { 50 ADC_IRQ_FIFO => rp_adc::InterruptHandler; 51 PIO0_IRQ_0 => InterruptHandler<PIO0>; 52 RTC_IRQ => rp_rtc::InterruptHandler, rtc::GlobalRtcHandler; 53}); 54 55#[unsafe(no_mangle)] 56unsafe extern "Rust" fn __getrandom_v03_custom( 57 dest: *mut u8, 58 len: usize, 59) -> Result<(), getrandom::Error> { 60 let slice = unsafe { 61 // Initialise the buffer with zeros before transmuting it into 62 // a mutable slice 63 core::ptr::write_bytes(dest, 0, len); 64 core::slice::from_raw_parts_mut(dest, len) 65 }; 66 67 RoscRng.fill_bytes(slice); 68 69 Ok(()) 70} 71 72#[cortex_m_rt::entry] 73fn main() -> ! { 74 let p = embassy_rp::init(Default::default()); 75 76 info!("Welcome to Pico Strike!"); 77 info!("Initialising Heap, SIZE: {}", HEAP_SIZE); 78 unwrap!(HEAP.init()); 79 80 info!("Initialising drivers"); 81 let pwm = embassy_strike_driver::drivers::rp::PwmDriver::new(p.PWM_SLICE5, p.PIN_27); 82 let adc = embassy_strike_driver::drivers::rp::AdcDriver::new(p.ADC, p.PIN_26, p.DMA_CH1, Irqs); 83 84 let pwr = Output::new(p.PIN_23, Level::Low); 85 let cs = Output::new(p.PIN_25, Level::High); 86 let mut pio = Pio::new(p.PIO0, Irqs); 87 let spi = PioSpi::new( 88 &mut pio.common, 89 pio.sm0, 90 DEFAULT_CLOCK_DIVIDER, 91 pio.irq0, 92 cs, 93 p.PIN_24, 94 p.PIN_29, 95 p.DMA_CH0, 96 ); 97 98 info!("Initialising RTC"); 99 let rtc = GlobalRtc::init(Rtc::new(p.RTC, Irqs)); 100 101 static CORE1_STACK: ConstStaticCell<Stack<8192>> = ConstStaticCell::new(Stack::new()); 102 103 info!("Initialising executors for multi-core tasks"); 104 spawn_core1(p.CORE1, CORE1_STACK.take(), move || { 105 static EXECUTOR1: StaticCell<Executor> = StaticCell::new(); 106 107 EXECUTOR1.init_with(Executor::new).run(|spawner| { 108 info!("Spawning Detector task on Core 1"); 109 spawner.must_spawn(detector::detector_task(adc, pwm, rtc)); 110 }) 111 }); 112 113 static EXECUTOR0: StaticCell<Executor> = StaticCell::new(); 114 115 EXECUTOR0.init_with(Executor::new).run(|spawner| { 116 info!("Spawning Network tasks on Core 0"); 117 spawner.must_spawn(wifi::main_loop(spawner, rtc, spi, pwr)); 118 }); 119}