diff --git a/boards/pygamer/CHANGELOG.md b/boards/pygamer/CHANGELOG.md index 744d7ef96af..f345a913c3c 100644 --- a/boards/pygamer/CHANGELOG.md +++ b/boards/pygamer/CHANGELOG.md @@ -1,5 +1,6 @@ # Unreleased +- remove neopixel support and examples (currently unreliable) - update HAL v0.14 -> v0.17 and other dependencies, fix examples - update path of Cargo config diff --git a/boards/pygamer/Cargo.toml b/boards/pygamer/Cargo.toml index 27c0b16dee1..223545ea9cd 100644 --- a/boards/pygamer/Cargo.toml +++ b/boards/pygamer/Cargo.toml @@ -17,7 +17,6 @@ exclude = ["assets"] [dependencies] cortex-m = {version = "0.7", features = ["critical-section-single-core"]} st7735-lcd = "0.8.1" -ws2812-timer-delay = "0.3" [dependencies.cortex-m-rt] version = "0.7" @@ -46,7 +45,6 @@ embedded-graphics = "0.7.1" embedded-hal-02 = {package = "embedded-hal", version = "0.2", features = ["unproven"]} embedded-hal-bus = "0.2.0" smart-leds = "0.3" -ws2812-spi = { version = "0.4.0", features = ["mosi_idle_high"] } lis3dh = "0.1.0" cortex-m-rtic = "1.0" tinybmp = "0.3.1" @@ -78,10 +76,6 @@ opt-level = "s" [package.metadata] chip = "ATSAMD51J19A" -[[example]] -name = "usb_serial" -required-features = ["usb"] - [[example]] name = "usb_poll" required-features = ["usb"] @@ -90,10 +84,6 @@ required-features = ["usb"] name = "sd_card" required-features = ["sd-card"] -[[example]] -name = "neopixel_easing" -required-features = ["math"] - [[example]] name = "pwm_tc4" required-features = ["math"] diff --git a/boards/pygamer/examples/neopixel_adc_battery.rs b/boards/pygamer/examples/neopixel_adc_battery.rs deleted file mode 100644 index af2f003af50..00000000000 --- a/boards/pygamer/examples/neopixel_adc_battery.rs +++ /dev/null @@ -1,83 +0,0 @@ -//! Display battery percentage on the neopixels. -//! -//! Note leds may appear white during debug. Either build for release or add -//! opt-level = 2 to profile.dev in Cargo.toml - -#![no_std] -#![no_main] - -use bsp::{entry, hal, pac, Pins}; -#[cfg(not(feature = "panic_led"))] -use panic_halt as _; -use pygamer as bsp; - -use hal::adc::Adc; -use hal::pac::gclk::pchctrl::GENSELECT_A::GCLK11; -use hal::prelude::*; -use hal::{clock::GenericClockController, delay::Delay}; -use pac::{CorePeripherals, Peripherals}; -use smart_leds::{brightness, hsv::RGB8, SmartLedsWrite}; - -#[entry] -fn main() -> ! { - let mut peripherals = Peripherals::take().unwrap(); - let core = CorePeripherals::take().unwrap(); - let mut clocks = GenericClockController::with_internal_32kosc( - peripherals.GCLK, - &mut peripherals.MCLK, - &mut peripherals.OSC32KCTRL, - &mut peripherals.OSCCTRL, - &mut peripherals.NVMCTRL, - ); - let pins = Pins::new(peripherals.PORT).split(); - - let mut adc0 = Adc::adc0(peripherals.ADC0, &mut peripherals.MCLK, &mut clocks, GCLK11); - let mut battery = pins.battery.init(); - - let mut neopixel = pins - .neopixel - .init(&mut clocks, peripherals.TC4, &mut peripherals.MCLK); - - let mut delay = Delay::new(core.SYST, &mut clocks); - - //todo put this on a .. 10minute, 30min, update timer - loop { - let battery_data = battery.read(&mut adc0); - - let mut colors = [ - RGB8::default(), - RGB8::default(), - RGB8::default(), - RGB8::default(), - RGB8::default(), - ]; - - if battery_data < 3.6 { - colors[0] = RGB8::from((255, 0, 0)); - } else if (battery_data >= 3.6) && (battery_data < 3.8) { - colors[0] = RGB8::from((255, 0, 0)); - colors[1] = RGB8::from((255, 0, 0)); - } else if (battery_data >= 3.8) && (battery_data < 3.9) { - colors[0] = RGB8::from((255, 255, 0)); - colors[1] = RGB8::from((255, 255, 0)); - colors[2] = RGB8::from((255, 255, 0)); - } else if (battery_data >= 3.9) && (battery_data < 4.0) { - colors[0] = RGB8::from((0, 255, 0)); - colors[1] = RGB8::from((0, 255, 0)); - colors[2] = RGB8::from((0, 255, 0)); - colors[3] = RGB8::from((0, 255, 0)); - } else { - colors[0] = RGB8::from((0, 255, 0)); - colors[1] = RGB8::from((0, 255, 0)); - colors[2] = RGB8::from((0, 255, 0)); - colors[3] = RGB8::from((0, 255, 0)); - colors[4] = RGB8::from((0, 255, 0)); - }; - - neopixel - .write(brightness(colors.iter().cloned(), 1)) - .unwrap(); - - delay.delay_ms(10u8); - } -} diff --git a/boards/pygamer/examples/neopixel_adc_light.rs b/boards/pygamer/examples/neopixel_adc_light.rs deleted file mode 100644 index b76fdaf31f7..00000000000 --- a/boards/pygamer/examples/neopixel_adc_light.rs +++ /dev/null @@ -1,90 +0,0 @@ -//! Display light sensor reading on the neopixels. -//! -//! Note leds may appear white during debug. Either build for release or add -//! opt-level = 2 to profile.dev in Cargo.toml - -#![no_std] -#![no_main] - -use bsp::{entry, hal, pac, LightSensor, Pins}; -#[cfg(not(feature = "panic_led"))] -use panic_halt as _; -use pygamer as bsp; - -use embedded_hal_02::adc::OneShot; -use hal::adc::Adc; -use hal::clock::GenericClockController; -use hal::delay::Delay; -use hal::ehal::delay::DelayNs; -use hal::time::Hertz; -use hal::timer::TimerCounter; -use hal::timer_traits::InterruptDrivenTimer; -use pac::gclk::pchctrl::GENSELECT_A::GCLK11; -use pac::{CorePeripherals, Peripherals}; -use smart_leds::hsv::{hsv2rgb, Hsv, RGB8}; -use smart_leds::SmartLedsWrite; -use ws2812_timer_delay as ws2812; - -#[entry] -fn main() -> ! { - let mut peripherals = Peripherals::take().unwrap(); - let core = CorePeripherals::take().unwrap(); - let mut clocks = GenericClockController::with_internal_32kosc( - peripherals.GCLK, - &mut peripherals.MCLK, - &mut peripherals.OSC32KCTRL, - &mut peripherals.OSCCTRL, - &mut peripherals.NVMCTRL, - ); - let pins = Pins::new(peripherals.PORT); - - let mut adc1 = Adc::adc1(peripherals.ADC1, &mut peripherals.MCLK, &mut clocks, GCLK11); - let mut light: LightSensor = pins.light.into(); - - let gclk0 = clocks.gclk0(); - let tc2_3 = clocks.tc2_tc3(&gclk0).unwrap(); - let mut timer = TimerCounter::tc3_(&tc2_3, peripherals.TC3, &mut peripherals.MCLK); - timer.start(Hertz::MHz(3).into_duration()); - - let neopixel_pin = pins.neopixel.into_push_pull_output(); - let mut neopixel = ws2812::Ws2812::new(timer, neopixel_pin); - - let mut delay = Delay::new(core.SYST, &mut clocks); - - const NUM_LEDS: usize = 5; - let mut j: u8 = 0; - - loop { - let light_data: u16 = adc1.read(&mut light).unwrap(); - - let pos: usize = if light_data < 100 { - 0 - } else if (light_data >= 147) && (light_data < 1048) { - 1 - } else if (light_data >= 1048) && (light_data < 3048) { - 2 - } else if (light_data >= 3048) && (light_data < 3948) { - 3 - } else { - 4 - }; - - //finally paint the one led wherever the position is - let _ = neopixel.write((0..NUM_LEDS).map(|i| { - if i == pos { - hsv2rgb(Hsv { - hue: j, - sat: 255, - val: 32, - }) - } else { - RGB8::default() - } - })); - - //incremement the hue easing - j = j.wrapping_add(1); - - delay.delay_ms(10); - } -} diff --git a/boards/pygamer/examples/neopixel_button.rs b/boards/pygamer/examples/neopixel_button.rs deleted file mode 100644 index 6e9a50f1118..00000000000 --- a/boards/pygamer/examples/neopixel_button.rs +++ /dev/null @@ -1,106 +0,0 @@ -//! Joystick y controls the color of a neopixel while Joystick x moves it -//! left and right around the center neopixel -//! Select and Start control a second neopixel left and right while it is -//! automatically rotating through the color wheel -//! When they overlap, joystick takes precedence -//! -//! Note leds may appear white during debug. Either build for release or add -//! opt-level = 2 to profile.dev in Cargo.toml - -#![no_std] -#![no_main] - -use bsp::{entry, hal, pac, Keys, Pins}; -#[cfg(not(feature = "panic_led"))] -use panic_halt as _; -use pygamer as bsp; - -use bsp::util::map_from; -use hal::adc::Adc; -use hal::prelude::*; -use hal::{clock::GenericClockController, delay::Delay}; -use pac::gclk::pchctrl::GENSELECT_A::GCLK11; -use pac::{CorePeripherals, Peripherals}; -use smart_leds::hsv::{hsv2rgb, Hsv, RGB8}; -use smart_leds::SmartLedsWrite; - -#[entry] -fn main() -> ! { - let mut peripherals = Peripherals::take().unwrap(); - let core_peripherals = CorePeripherals::take().unwrap(); - - let mut clocks = GenericClockController::with_internal_32kosc( - peripherals.GCLK, - &mut peripherals.MCLK, - &mut peripherals.OSC32KCTRL, - &mut peripherals.OSCCTRL, - &mut peripherals.NVMCTRL, - ); - - let mut delay = Delay::new(core_peripherals.SYST, &mut clocks); - let pins = Pins::new(peripherals.PORT).split(); - - let mut buttons = pins.buttons.init(); - - let mut adc1 = Adc::adc1(peripherals.ADC1, &mut peripherals.MCLK, &mut clocks, GCLK11); - let mut joystick = pins.joystick.init(); - - let mut neopixel = pins - .neopixel - .init(&mut clocks, peripherals.TC4, &mut peripherals.MCLK); - - const NUM_LEDS: usize = 5; - let mut pos_button: usize = 2; - let mut color_button: u8 = 0; - loop { - let (x, y) = joystick.read(&mut adc1); - - // map up/down to control rainbow color 0-255 - let color_joy = map_from(y as i16, (0, 4095), (0, 255)) as u8; - - // map left/right to neopixel position 0-4 - // joystick is not quite linear, rests at second pixel - // shifting up by 500 seems to help - let pos_joy = map_from(x as i16 + 500, (0, 4595), (0, 4)) as usize; - - for event in buttons.events() { - match event { - Keys::SelectDown => { - if pos_button > 0 { - pos_button -= 1; - } - } - Keys::StartDown => { - if pos_button < 4 { - pos_button += 1; - } - } - _ => {} - } - } - - //finally paint the two leds at position, accel priority - let _ = neopixel.write((0..NUM_LEDS).map(|i| { - if i == pos_joy { - hsv2rgb(Hsv { - hue: color_joy, - sat: 255, - val: 32, - }) - } else if i == pos_button { - hsv2rgb(Hsv { - hue: color_button, - sat: 255, - val: 32, - }) - } else { - RGB8::default() - } - })); - - //incremement the hue easing - color_button = color_button.wrapping_add(1); - - delay.delay_ms(5u8); - } -} diff --git a/boards/pygamer/examples/neopixel_easing.rs b/boards/pygamer/examples/neopixel_easing.rs deleted file mode 100644 index 9ac19087ce2..00000000000 --- a/boards/pygamer/examples/neopixel_easing.rs +++ /dev/null @@ -1,89 +0,0 @@ -//! Randomly choose and led and color to breath in and out -//! -//! Note leds may appear white during debug. Either build for release or add -//! opt-level = 2 to profile.dev in Cargo.toml - -#![no_std] -#![no_main] - -use bsp::{entry, hal, pac, Pins}; -#[cfg(not(feature = "panic_led"))] -use panic_halt as _; -use pygamer as bsp; - -use core::f32::consts::FRAC_PI_2; -use hal::clock::GenericClockController; -use hal::delay::Delay; -use hal::prelude::*; -use hal::trng::Trng; -use micromath::F32Ext; -use pac::{CorePeripherals, Peripherals}; -use smart_leds::hsv::{hsv2rgb, Hsv, RGB8}; -use smart_leds::SmartLedsWrite; - -#[entry] -fn main() -> ! { - let mut peripherals = Peripherals::take().unwrap(); - let core = CorePeripherals::take().unwrap(); - let mut clocks = GenericClockController::with_internal_32kosc( - peripherals.GCLK, - &mut peripherals.MCLK, - &mut peripherals.OSC32KCTRL, - &mut peripherals.OSCCTRL, - &mut peripherals.NVMCTRL, - ); - - let pins = Pins::new(peripherals.PORT).split(); - - let mut neopixel = pins - .neopixel - .init(&mut clocks, peripherals.TC4, &mut peripherals.MCLK); - let mut delay = Delay::new(core.SYST, &mut clocks); - - let trng = Trng::new(&mut peripherals.MCLK, peripherals.TRNG); - - const NUM_LEDS: usize = 5; - - loop { - let rand = trng.random_u8(); - let pos: usize = rand.wrapping_rem(5) as usize; //random led - - //slowly enable led - for j in 0..255u8 { - let _ = neopixel.write((0..NUM_LEDS).map(|i| { - if i == pos { - hsv2rgb(Hsv { - hue: rand, - sat: 255, - val: sine_ease_in(j as f32, 0.0, 32.0, 255.0) as u8, - }) - } else { - RGB8::default() - } - })); - delay.delay_ms(5u8); - } - - //slowly disable led - note the reverse .rev() - for j in (0..255u8).rev() { - let _ = neopixel.write((0..NUM_LEDS).map(|i| { - if i == pos { - hsv2rgb(Hsv { - hue: rand, - sat: 255, - val: sine_ease_in(j as f32, 0.0, 32.0, 255.0) as u8, - }) - } else { - RGB8::default() - } - })); - delay.delay_ms(5u8); - } - } -} - -#[inline] -// current step, where oputput starts, where output ends, last step -fn sine_ease_in(t: f32, b: f32, c: f32, d: f32) -> f32 { - -c * (t / d * FRAC_PI_2).cos() + c + b -} diff --git a/boards/pygamer/examples/neopixel_rainbow_spi.rs b/boards/pygamer/examples/neopixel_rainbow_spi.rs deleted file mode 100644 index 0ff8aaf9b53..00000000000 --- a/boards/pygamer/examples/neopixel_rainbow_spi.rs +++ /dev/null @@ -1,83 +0,0 @@ -//! Rotate all neopixel leds through a rainbow. Uses a luckily placed set of SPI -//! pins as a timer source. -//! -//! Note leds may appear white during debug. Either build for release or add -//! opt-level = 2 to profile.dev in Cargo.toml - -#![no_std] -#![no_main] - -use bsp::{entry, hal, pac, Pins}; -#[cfg(not(feature = "panic_led"))] -use panic_halt as _; -use pygamer as bsp; - -use hal::prelude::*; -use hal::sercom::spi; -use hal::{clock::GenericClockController, delay::Delay}; -use pac::{CorePeripherals, Peripherals}; -use smart_leds::hsv::{hsv2rgb, Hsv}; -use smart_leds::SmartLedsWrite; -use ws2812_spi as ws2812; - -#[entry] -fn main() -> ! { - let mut peripherals = Peripherals::take().unwrap(); - let core = CorePeripherals::take().unwrap(); - let mut clocks = GenericClockController::with_internal_32kosc( - peripherals.GCLK, - &mut peripherals.MCLK, - &mut peripherals.OSC32KCTRL, - &mut peripherals.OSCCTRL, - &mut peripherals.NVMCTRL, - ); - let pins = Pins::new(peripherals.PORT); - let mclk = &mut peripherals.MCLK; - let gclk = clocks.gclk0(); - let clock = &clocks.sercom2_core(&gclk).unwrap(); - let sercom2 = peripherals.SERCOM2; - let pads = spi::Pads::default() - .data_in(pins.sda) - .data_out(pins.neopixel) - .sclk(pins.scl); - let spi = spi::Config::new(mclk, sercom2, pads, clock.freq()) - .baud(3.MHz()) - .enable(); - let mut neopixel = ws2812::Ws2812::new(spi); - let mut delay = Delay::new(core.SYST, &mut clocks); - loop { - for j in 0..255u8 { - let colors = [ - // split the color changes across all 5 leds evenly, 255/5=51 - // and have them safely wrap over when they go above 255 - hsv2rgb(Hsv { - hue: j, - sat: 255, - val: 32, - }), - hsv2rgb(Hsv { - hue: j.wrapping_add(51), - sat: 255, - val: 32, - }), - hsv2rgb(Hsv { - hue: j.wrapping_add(102), - sat: 255, - val: 32, - }), - hsv2rgb(Hsv { - hue: j.wrapping_add(153), - sat: 255, - val: 32, - }), - hsv2rgb(Hsv { - hue: j.wrapping_add(204), - sat: 255, - val: 32, - }), - ]; - neopixel.write(colors.iter().cloned()).unwrap(); - delay.delay_ms(5u8); - } - } -} diff --git a/boards/pygamer/examples/neopixel_rainbow_timer.rs b/boards/pygamer/examples/neopixel_rainbow_timer.rs deleted file mode 100644 index aa676f0f43d..00000000000 --- a/boards/pygamer/examples/neopixel_rainbow_timer.rs +++ /dev/null @@ -1,79 +0,0 @@ -//! Rotate all neopixel leds through a rainbow. Uses a Timer as a timer source. -//! -//! Note leds may appear white during debug. Either build for release or add -//! opt-level = 2 to profile.dev in Cargo.toml -//! -//! Note: This is jittery these days and probably not a good choice until -//! debugged - -#![no_std] -#![no_main] - -use bsp::{entry, hal, Pins}; -#[cfg(not(feature = "panic_led"))] -use panic_halt as _; -use pygamer as bsp; - -use hal::pac::Peripherals; -use hal::prelude::*; -use hal::{clock::GenericClockController, nb, timer::TimerCounter}; -use smart_leds::hsv::{hsv2rgb, Hsv}; -use smart_leds::SmartLedsWrite; - -#[entry] -fn main() -> ! { - let mut peripherals = Peripherals::take().unwrap(); - let mut clocks = GenericClockController::with_internal_32kosc( - peripherals.GCLK, - &mut peripherals.MCLK, - &mut peripherals.OSC32KCTRL, - &mut peripherals.OSCCTRL, - &mut peripherals.NVMCTRL, - ); - let pins = Pins::new(peripherals.PORT).split(); - - let mut neopixel = pins - .neopixel - .init(&mut clocks, peripherals.TC4, &mut peripherals.MCLK); - - let gclk0 = clocks.gclk0(); - let timer_clock = clocks.tc2_tc3(&gclk0).unwrap(); - let mut timer = TimerCounter::tc3_(&timer_clock, peripherals.TC3, &mut peripherals.MCLK); - InterruptDrivenTimer::start(&mut timer, 5.millis()); - - loop { - for j in 0..255u8 { - let colors = [ - // stagger the color changes across all 5 leds evenly, 255/5=51 - // and have them safely wrap over when they go above 255 - hsv2rgb(Hsv { - hue: j, - sat: 255, - val: 32, - }), - hsv2rgb(Hsv { - hue: j.wrapping_add(51), - sat: 255, - val: 32, - }), - hsv2rgb(Hsv { - hue: j.wrapping_add(102), - sat: 255, - val: 32, - }), - hsv2rgb(Hsv { - hue: j.wrapping_add(153), - sat: 255, - val: 32, - }), - hsv2rgb(Hsv { - hue: j.wrapping_add(204), - sat: 255, - val: 32, - }), - ]; - neopixel.write(colors.iter().cloned()).unwrap(); - nb::block!(InterruptDrivenTimer::wait(&mut timer)).unwrap(); - } - } -} diff --git a/boards/pygamer/examples/neopixel_tilt.rs b/boards/pygamer/examples/neopixel_tilt.rs deleted file mode 100644 index f8358a57167..00000000000 --- a/boards/pygamer/examples/neopixel_tilt.rs +++ /dev/null @@ -1,134 +0,0 @@ -//! LIS3DH accelerometer example. Move the neopixel led by tilting left and -//! right. -//! -//! Note leds may appear white during debug. Either build for release or add -//! opt-level = 2 to profile.dev in Cargo.toml - -#![no_std] -#![no_main] - -use bsp::{entry, hal, i2c_master, pac, Pins}; -#[cfg(not(feature = "panic_led"))] -use panic_halt as _; -use pygamer as bsp; - -// use hal::prelude::*; -use hal::ehal::delay::DelayNs; - -use hal::time::Hertz; -use hal::{clock::GenericClockController, delay::Delay}; -use lis3dh::{accelerometer::Accelerometer, Lis3dh}; -use pac::{CorePeripherals, Peripherals}; -use smart_leds::hsv::{hsv2rgb, Hsv, RGB8}; -use smart_leds::SmartLedsWrite; - -#[entry] -fn main() -> ! { - let mut peripherals = Peripherals::take().unwrap(); - let core_peripherals = CorePeripherals::take().unwrap(); - - let mut clocks = GenericClockController::with_internal_32kosc( - peripherals.GCLK, - &mut peripherals.MCLK, - &mut peripherals.OSC32KCTRL, - &mut peripherals.OSCCTRL, - &mut peripherals.NVMCTRL, - ); - - let mut delay = Delay::new(core_peripherals.SYST, &mut clocks); - let pins = Pins::new(peripherals.PORT).split(); - - let mut neopixel = pins - .neopixel - .init(&mut clocks, peripherals.TC4, &mut peripherals.MCLK); - - let i2c = i2c_master( - &mut clocks, - Hertz::kHz(400), - peripherals.SERCOM2, - &mut peripherals.MCLK, - pins.i2c.sda, - pins.i2c.scl, - ); - - let mut lis3dh = Lis3dh::new(i2c, 0x19).unwrap(); - lis3dh.set_range(lis3dh::Range::G2).unwrap(); - lis3dh.set_datarate(lis3dh::DataRate::Hz_100).unwrap(); - - let mut state = TiltState::new(); - - loop { - let lis = lis3dh.acceleration().unwrap(); - - let (pos, j) = state.update(lis.x); - - // iterate through neopixels and paint the one led - let _ = neopixel.write((0..5).map(|i| { - if i == pos { - hsv2rgb(Hsv { - hue: j, - sat: 255, - val: 32, - }) - } else { - RGB8::default() - } - })); - - //don't update faster than the accell is reading - delay.delay_ms(10); - } -} - -pub struct TiltState { - pos: usize, - tilt: i16, - j: u8, -} - -impl TiltState { - // start at the middle pixel - const fn new() -> TiltState { - TiltState { - pos: 2, - tilt: 0, - j: 0, - } - } - - fn update(&mut self, value: i16) -> (usize, u8) { - //what about like.. momentum, more angle or longer its been at angle stops - // slower like.. steps larger so it gets easier. also on a bigger number - // tilt? - - // naive solution.. threshold tilt - // better.. delay filter? - - // actually 2 thresholds, first you have to be tilted enough (gt / lt 1000) to - // be counted - if value > 1000 { - self.tilt += 1; - } else if value < -1000 { - self.tilt -= 1; - } - - // then we need threshold amount of counted tilts to inc/dec position - if self.tilt.abs() > 20 { - //todo clamp is nightly - if self.tilt.is_negative() { - if self.pos > 0 { - self.pos -= 1; - } - } else { - if self.pos < 4 { - self.pos += 1; - } - } - self.tilt = 0; - } - - //incremement the hue easing - self.j = self.j.wrapping_add(1); - (self.pos, self.j) - } -} diff --git a/boards/pygamer/examples/usb_serial.rs b/boards/pygamer/examples/usb_serial.rs deleted file mode 100644 index 56ebbb51526..00000000000 --- a/boards/pygamer/examples/usb_serial.rs +++ /dev/null @@ -1,136 +0,0 @@ -//! Makes the pygamer appear as a USB serial port. The color of the -//! neopixel LED can be changed by sending bytes to the serial port. -//! -//! Sending the characters R, G, and O set the LED red, green, and off -//! respectively. For example: -//! $> sudo stty -F /dev/ttyACM0 115200 raw -echo -//! $> sudo bash -c "echo 'R' > /dev/ttyACM0" -//! $> sudo bash -c "echo 'G' > /dev/ttyACM0" -//! $> sudo bash -c "echo 'O' > /dev/ttyACM0" -//! -//! Note leds may appear white during debug. Either build for release or add -//! opt-level = 2 to profile.dev in Cargo.toml - -#![no_std] -#![no_main] - -use bsp::{entry, hal, pac, Pins}; -#[cfg(not(feature = "panic_led"))] -use panic_halt as _; -use pygamer as bsp; - -use cortex_m::interrupt::free as disable_interrupts; -use cortex_m::peripheral::NVIC; -use hal::clock::GenericClockController; -use hal::usb::UsbBus; -use pac::{interrupt, CorePeripherals, Peripherals}; -use smart_leds::{colors, hsv::RGB8, SmartLedsWrite}; -use usb_device::bus::UsbBusAllocator; -use usb_device::prelude::*; -use usbd_serial::{SerialPort, USB_CLASS_CDC}; - -#[entry] -fn main() -> ! { - let mut peripherals = Peripherals::take().unwrap(); - let mut core = CorePeripherals::take().unwrap(); - let mut clocks = GenericClockController::with_internal_32kosc( - peripherals.GCLK, - &mut peripherals.MCLK, - &mut peripherals.OSC32KCTRL, - &mut peripherals.OSCCTRL, - &mut peripherals.NVMCTRL, - ); - let pins = Pins::new(peripherals.PORT).split(); - - let mut neopixel = pins - .neopixel - .init(&mut clocks, peripherals.TC4, &mut peripherals.MCLK); - - let _ = neopixel.write((0..5).map(|_| RGB8::default())); - - let bus_allocator = unsafe { - USB_ALLOCATOR = Some( - pins.usb - .init(peripherals.USB, &mut clocks, &mut peripherals.MCLK), - ); - USB_ALLOCATOR.as_ref().unwrap() - }; - - unsafe { - USB_SERIAL = Some(SerialPort::new(&bus_allocator)); - USB_BUS = Some( - UsbDeviceBuilder::new(&bus_allocator, UsbVidPid(0x16c0, 0x27dd)) - .strings(&[StringDescriptors::new(LangID::EN) - .manufacturer("Fake company") - .product("Serial port") - .serial_number("TEST")]) - .expect("Failed to set strings") - .device_class(USB_CLASS_CDC) - .build(), - ); - } - - unsafe { - core.NVIC.set_priority(interrupt::USB_OTHER, 1); - core.NVIC.set_priority(interrupt::USB_TRCPT0, 1); - core.NVIC.set_priority(interrupt::USB_TRCPT1, 1); - NVIC::unmask(interrupt::USB_OTHER); - NVIC::unmask(interrupt::USB_TRCPT0); - NVIC::unmask(interrupt::USB_TRCPT1); - } - - loop { - let pending = disable_interrupts(|_| unsafe { - let pending = PENDING_COLOR; - PENDING_COLOR = None; - pending - }); - if let Some(color) = pending { - let _ = neopixel.write((0..5).map(|_| color)); - } - } -} - -static mut USB_ALLOCATOR: Option> = None; -static mut USB_BUS: Option> = None; -static mut USB_SERIAL: Option> = None; -static mut PENDING_COLOR: Option = None; - -fn poll_usb() { - unsafe { - USB_BUS.as_mut().map(|usb_dev| { - USB_SERIAL.as_mut().map(|serial| { - usb_dev.poll(&mut [serial]); - - let mut buf = [0u8; 64]; - - if let Ok(count) = serial.read(&mut buf) { - let last = buf[count - 1] as char; - let color = match last { - 'R' => colors::RED, - 'G' => colors::GREEN, - 'O' => colors::ORANGE, - _ => RGB8::default(), - }; - - PENDING_COLOR = Some(color); - }; - }); - }); - }; -} - -#[interrupt] -fn USB_OTHER() { - poll_usb(); -} - -#[interrupt] -fn USB_TRCPT0() { - poll_usb(); -} - -#[interrupt] -fn USB_TRCPT1() { - poll_usb(); -} diff --git a/boards/pygamer/src/pins.rs b/boards/pygamer/src/pins.rs index 2ec26010095..6054a6408c6 100644 --- a/boards/pygamer/src/pins.rs +++ b/boards/pygamer/src/pins.rs @@ -2,7 +2,7 @@ use super::{hal, pac}; -use pac::{MCLK, QSPI, TC4}; +use pac::{MCLK, QSPI}; use hal::prelude::*; @@ -13,12 +13,9 @@ use hal::qspi; use hal::sercom::uart::{self, BaudMode, Oversampling}; use hal::sercom::{i2c, spi, IoSet1, Sercom1, Sercom4, UndocIoSet1}; use hal::time::Hertz; -use hal::timer::TimerCounter; -use hal::timer_traits::InterruptDrivenTimer; use hal::typelevel::NoneT; use st7735_lcd::{Orientation, ST7735}; -use ws2812_timer_delay as ws2812; #[cfg(feature = "usb")] use hal::usb::usb_device::bus::UsbBusAllocator; @@ -634,23 +631,6 @@ pub struct Neopixel { pub neopixel: NeopixelReset, } -impl Neopixel { - /// Convenience for setting up the onboard neopixels - pub fn init( - self, - clocks: &mut GenericClockController, - timer4: TC4, - mclk: &mut MCLK, - ) -> ws2812::Ws2812, NeopixelPin> { - let gclk0 = clocks.gclk0(); - let timer_clock = clocks.tc4_tc5(&gclk0).unwrap(); - let mut timer = TimerCounter::tc4_(&timer_clock, timer4, mclk); - InterruptDrivenTimer::start(&mut timer, Hertz::MHz(3).into_duration()); - - ws2812::Ws2812::new(timer, self.neopixel.into()) - } -} - /// SPI pins pub struct SPI { pub mosi: SpiMosiReset,