diff --git a/.vscode/launch.json b/.vscode/launch.json index 265489d..a755f2e 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -33,8 +33,8 @@ "rttEnabled": true, "options": { "env": { - "DEFMT_LOG": "debug", - "RUST_LOG": "debug" + "DEFMT_LOG": "trace", + "RUST_LOG": "trace" } }, } diff --git a/Cargo.toml b/Cargo.toml index f613672..e016ed6 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -10,6 +10,7 @@ cortex-m-rt = "0.7" cortex-m-rtic = "1.1.4" embedded-hal = { version = "0.2.5", features = ["unproven"] } fugit = "0.3.7" +heapless = "0.7.16" #fusb302b = { version = "0.0.1" } #ili9341 = "0.5.0" #ssd1306 = "0.8.3" @@ -29,6 +30,8 @@ display-interface-spi = "0.4.1" embedded-graphics-core = "0.4.0" # We're using a Pico by default on this template rp-pico = { version = "0.8.0", features = ["rt"] } +mipidsi = "0.7.1" +u8g2-fonts = "0.3.0" # but you can use any BSP. Uncomment this to use the pro_micro_rp2040 BSP instead # sparkfun-pro-micro-rp2040 = "0.6" diff --git a/src/main.rs b/src/main.rs index d65b967..502ad51 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,6 +1,7 @@ #![no_std] #![no_main] +mod types; //mod display; use defmt_rtt as _; @@ -87,18 +88,27 @@ mod app { >, >; + use cortex_m::delay; use defmt::{debug, info}; + use embedded_graphics_core::prelude::Point; use usb_pd::{ - pdo::PowerDataObject, + pdo::{FixedSupply, PowerDataObject}, sink::{Event, Request, Sink}, }; + use embedded_graphics::{ + mono_font::{ascii::FONT_6X10, MonoTextStyle}, + pixelcolor::Rgb565, + prelude::*, + primitives::{Circle, PrimitiveStyle}, + text::{Alignment, Text}, + }; use embedded_hal::digital::v2::{OutputPin, ToggleableOutputPin}; // use embedded_hal::prelude::{ // _embedded_hal_blocking_delay_DelayMs, _embedded_hal_blocking_i2c_Read, // _embedded_hal_blocking_i2c_Write, _embedded_hal_blocking_i2c_WriteRead, // }; - use fugit::{ExtU64, Instant, RateExtU32}; + use fugit::{ExtU64, Instant, RateExtU32, RateExtU64}; use fusb302b::Fusb302b; use rp_pico::hal::{ @@ -112,6 +122,13 @@ mod app { Sio, }; + use display_interface_spi::SPIInterface; + use mipidsi::{options::*, Builder}; + use u8g2_fonts::{ + fonts, + types::{FontColor, HorizontalAlignment, VerticalPosition}, + FontRenderer, + }; //use crate::display; // use usb_pd::sink::{Driver, DriverState}; @@ -125,6 +142,8 @@ mod app { gpio::Pin, gpio::PullDown>, ), i2c0: I2C0Proxy, + pdos: heapless::Vec, + display: crate::types::DisplayType, //fusb302: FUSB302BDev, } @@ -173,17 +192,20 @@ mod app { ); let spi0_pins = ( - // SPI0 TX + // SPI0 TX PIN 21 pins.gpio7.into_function::(), - // SPI0 RX + // SPI0 RX PIN 18 pins.gpio4.into_function::(), - // SPI0 CLK + // SPI0 CLK PIN 20 pins.gpio6.into_function::(), ); - let _dis_cs = pins.gpio5.into_push_pull_output(); - let _dis_dc = pins.gpio9.into_push_pull_output(); - let _dis_rst = pins.gpio10.into_push_pull_output(); + // GPIO 5 PIN 19 + let dis_cs = pins.gpio5.into_push_pull_output(); + // GPIO 9 PIN 23 + let dis_dc = pins.gpio9.into_push_pull_output(); + // GPIO 10 PIN 24 + let dis_rst = pins.gpio10.into_push_pull_output(); let i2c0 = i2c::I2C::i2c0( c.device.I2C0, @@ -211,8 +233,6 @@ mod app { let mut pd = Sink::new(fusb302b::Fusb302b::new(i2c_bus0.acquire_i2c())); - pd.init(); - info!("INIT!"); let mut leds = ( @@ -234,28 +254,90 @@ mod app { let i2c0 = i2c_bus0.acquire_i2c(); let spi0 = spi::Spi::<_, _, _, 8>::new(c.device.SPI0, spi0_pins); - let _spi0 = spi0.init( + let spi0 = spi0.init( &mut resets, clocks.system_clock.freq(), - 10_u32.MHz(), + 10u32.MHz(), embedded_hal::spi::MODE_0, ); - let _delay = cortex_m::delay::Delay::new(c.core.SYST, clocks.system_clock.freq().to_Hz()); + let mut delay = + cortex_m::delay::Delay::new(c.core.SYST, clocks.system_clock.freq().to_Hz()); + let di = SPIInterface::new(spi0, dis_dc, dis_cs); + let mut display = Builder::ili9341_rgb565(di) + .with_display_size(240, 320) + .with_orientation(Orientation::PortraitInverted(true)) + .with_color_order(ColorOrder::Bgr) + .init(&mut delay, Some(dis_rst)) + .unwrap(); + + // Clear the screen + display.clear(Rgb565::BLACK).unwrap(); + // Create a new character style + let style = MonoTextStyle::new(&FONT_6X10, Rgb565::RED); + + Text::with_alignment("Init Complete!", Point::new(0, 8), style, Alignment::Left) + .draw(&mut display) + .unwrap(); + + //let font1 = FontRenderer::new::(); + let font1 = FontRenderer::new::(); + let font2 = FontRenderer::new::(); + let font3 = FontRenderer::new::(); + + font1 + .render_aligned( + format_args!("Init Complete"), + Point::new(0, 140), + VerticalPosition::Baseline, + HorizontalAlignment::Left, + FontColor::Transparent(Rgb565::CSS_BLUE_VIOLET), + &mut display, + ) + .unwrap(); + font2 + .render_aligned( + format_args!("Init Complete"), + Point::new(0, 160), + VerticalPosition::Baseline, + HorizontalAlignment::Left, + FontColor::Transparent(Rgb565::CSS_BLUE_VIOLET), + &mut display, + ) + .unwrap(); + font3 + .render_aligned( + format_args!("Init Complete"), + Point::new(0, 180), + VerticalPosition::Baseline, + HorizontalAlignment::Left, + FontColor::Transparent(Rgb565::CSS_BLUE_VIOLET), + &mut display, + ) + .unwrap(); + pd.init(); + + update_display::spawn_after(ExtU64::millis(100)).unwrap(); info!("INIT COMPLETE!"); + let pdos = heapless::Vec::::new(); + ( - Shared { leds, i2c0 }, + Shared { + leds, + i2c0, + pdos, + display, + }, Local { pdev: pd }, init::Monotonics(Monotonic::new(timer, alarm)), ) } - #[task(local = [pdev], shared = [leds])] + #[task(local = [pdev], shared = [leds, pdos])] fn pd_task(mut c: pd_task::Context) { - //info!("IDLE!"); - //loop { + // Convert from us to ms let now = monotonics::MyMono::now(); let now: Instant = Instant::::from_ticks(now.ticks() / 1000); @@ -265,9 +347,15 @@ mod app { Event::SourceCapabilitiesChanged(caps) => { info!("CAPS CHANGED!"); c.shared.leds.lock(|leds| { - leds.0.toggle().unwrap(); + leds.0.set_high().unwrap(); + }); + + c.shared.pdos.lock(|pdos| { + pdos.clear(); + pdos.extend_from_slice(caps.as_slice()).unwrap(); }); + // Take maximum voltage let (index, supply) = caps .iter() .enumerate() @@ -320,12 +408,51 @@ mod app { }); } } + } else { + c.shared.leds.lock(|leds| { + leds.0.set_low().unwrap(); + }); } //pd_task::spawn().unwrap(); pd_task::spawn_after(50_u64.micros()).unwrap(); } + #[task(shared = [display, pdos])] + fn update_display(mut c: update_display::Context) { + let font = FontRenderer::new::(); + + c.shared.pdos.lock(|pdos| { + for pdo in pdos.iter().enumerate() { + let (i, pdo) = pdo; + match pdo { + PowerDataObject::FixedSupply(supply) => { + c.shared.display.lock(|dis| { + font.render_aligned( + format_args!( + "{}mV {}mA", + supply.voltage() * 50, + supply.max_current() * 10 + ), + Point::new( + 0, + 200 + (i * (font.get_ascent() - font.get_descent()) as usize) + as i32, + ), + VerticalPosition::Baseline, + HorizontalAlignment::Left, + FontColor::Transparent(Rgb565::CSS_MISTY_ROSE), + dis, + ) + .unwrap(); + }); + } + _ => {} + } + } + }); + update_display::spawn_after(1000_u64.millis()).unwrap(); // 1 second + } #[task( shared = [leds, i2c0], local = [tog: bool = false, which: u8 = 0], diff --git a/src/types.rs b/src/types.rs new file mode 100644 index 0000000..2fd6408 --- /dev/null +++ b/src/types.rs @@ -0,0 +1,25 @@ +use display_interface_spi::SPIInterface; +use rp_pico::hal::{self, gpio, spi}; + +pub type SpiType = hal::Spi< + spi::Enabled, + hal::pac::SPI0, + ( + gpio::Pin, + gpio::Pin, + gpio::Pin, + ), + 8, +>; + +pub type SPIInterfaceType = SPIInterface< + SpiType, + gpio::Pin, gpio::PullDown>, + gpio::Pin, gpio::PullDown>, +>; + +pub type DisplayType = mipidsi::Display< + SPIInterfaceType, + mipidsi::models::ILI9341Rgb565, + gpio::Pin, gpio::PullDown>, +>;