//! Blinks the LED on a Pico board //! //! This will blink an LED attached to GP25, which is the pin the Pico uses for the on-board LED. #![no_std] #![no_main] use defmt_rtt as _; use panic_probe as _; mod flipdot; #[rtic::app(device = rp_pico::hal::pac, peripherals = true, dispatchers = [XIP_IRQ])] mod app { use embedded_hal::digital::v2::OutputPin; use rp_pico::hal; use rp_pico::hal::*; use rp_pico::XOSC_CRYSTAL_FREQ; // USB Device support use usb_device::{class_prelude::*, prelude::*}; // USB Communications Class Device support use usbd_serial::SerialPort; use rp2040_monotonic::fugit::ExtU64; use rp2040_monotonic::*; use crate::flipdot::write_display; #[monotonic(binds = TIMER_IRQ_0, default = true)] type Monotonic = Rp2040Monotonic; #[shared] struct Shared { serial: SerialPort<'static, hal::usb::UsbBus>, usb_dev: usb_device::device::UsbDevice<'static, hal::usb::UsbBus>, } #[local] struct Local { led_pin: hal::gpio::Pin, row_data_pin: hal::gpio::Pin, row_clock_pin: hal::gpio::Pin, col_data_pin: hal::gpio::Pin, col_clock_pin: hal::gpio::Pin, white_pin: hal::gpio::Pin, black_pin: hal::gpio::Pin, strobe_pin: hal::gpio::Pin, delay: cortex_m::delay::Delay, pattern: bool, } #[init(local = [usb_bus: Option> = None])] fn init(c: init::Context) -> (Shared, Local, init::Monotonics) { let mut resets = c.device.RESETS; let mut watchdog = hal::watchdog::Watchdog::new(c.device.WATCHDOG); // Configure the clocks - The default is to generate a 125 MHz system clock let clocks = hal::clocks::init_clocks_and_plls( XOSC_CRYSTAL_FREQ, c.device.XOSC, c.device.CLOCKS, c.device.PLL_SYS, c.device.PLL_USB, &mut resets, &mut watchdog, ) .ok() .unwrap(); let mut delay = cortex_m::delay::Delay::new(c.core.SYST, clocks.system_clock.freq().to_Hz()); let usb_bus: &'static _ = c.local .usb_bus .insert(UsbBusAllocator::new(hal::usb::UsbBus::new( c.device.USBCTRL_REGS, c.device.USBCTRL_DPRAM, clocks.usb_clock, true, &mut resets, ))); let serial = SerialPort::new(usb_bus); let usb_dev = UsbDeviceBuilder::new(usb_bus, UsbVidPid(0x16c0, 0x27dd)) .manufacturer("Fake company") .product("Serial port") .serial_number("TEST") .device_class(2) // from: https://www.usb.org/defined-class-codes .build(); let sio = hal::Sio::new(c.device.SIO); let pins = rp_pico::Pins::new( c.device.IO_BANK0, c.device.PADS_BANK0, sio.gpio_bank0, &mut resets, ); let mut led_pin = pins.led.into_push_pull_output(); led_pin.set_low().unwrap(); let row_data_pin = pins.gpio4.into_push_pull_output(); let row_clock_pin = pins.gpio5.into_push_pull_output(); let col_data_pin = pins.gpio2.into_push_pull_output(); let col_clock_pin = pins.gpio3.into_push_pull_output(); let white_pin = pins.gpio6.into_push_pull_output(); let black_pin = pins.gpio7.into_push_pull_output(); let strobe_pin = pins.gpio8.into_push_pull_output(); let pattern = false; update_display::spawn_after(1.secs()).unwrap(); ( Shared { serial, usb_dev }, Local { led_pin, row_data_pin, row_clock_pin, col_data_pin, col_clock_pin, white_pin, black_pin, strobe_pin, delay, pattern, }, init::Monotonics(Rp2040Monotonic::new(c.device.TIMER)), ) } #[task(local = [pattern, led_pin, row_data_pin, row_clock_pin, col_data_pin, col_clock_pin, white_pin, black_pin, strobe_pin, delay])] fn update_display(cx: update_display::Context) { let pattern = if *cx.local.pattern { [ 0b1010_1010_1010_1010_1010, 0b0101_0101_0101_0101_0101, 0b1010_1010_1010_1010_1010, 0b0101_0101_0101_0101_0101, 0b1010_1010_1010_1010_1010, 0b0101_0100_0000_0101_0101, 0b1010_1010_1111_0010_1010, 0b0101_0100_0001_0101_0101, 0b1010_1010_0001_0010_1010, 0b0101_0100_1001_0101_0101, 0b1010_1010_0000_0010_1010, 0b0101_0101_0101_0101_0101, 0b1010_1010_1010_1010_1010, 0b0101_0101_0101_0101_0101, 0b1010_1010_1010_1010_1010, 0b0101_0101_0101_0101_0101, ] } else { [ 0b0101_0101_0101_0101_0101, 0b1010_1010_1010_1010_1010, 0b0101_0101_0101_0101_0101, 0b1010_1010_1010_1010_1010, 0b0101_0101_0101_0101_0101, 0b1010_1010_0000_0010_1010, 0b0101_0100_1111_0101_0101, 0b1010_1010_0001_0010_1010, 0b0101_0100_0001_0101_0101, 0b1010_1010_1001_0010_1010, 0b0101_0100_0000_0101_0101, 0b1010_1010_1010_1010_1010, 0b0101_0101_0101_0101_0101, 0b1010_1010_1010_1010_1010, 0b0101_0101_0101_0101_0101, 0b1010_1010_1010_1010_1010, ] }; if *cx.local.pattern { cx.local.led_pin.set_high().unwrap(); } else { cx.local.led_pin.set_low().unwrap(); } *cx.local.pattern = !*cx.local.pattern; write_display( &pattern, cx.local.col_clock_pin, cx.local.col_data_pin, cx.local.row_clock_pin, cx.local.row_data_pin, cx.local.strobe_pin, cx.local.white_pin, cx.local.black_pin, cx.local.delay, ); update_display::spawn_after(1.secs()).unwrap(); } }