From f2846d9152b120dba24374e62022ecfbb43a26d6 Mon Sep 17 00:00:00 2001 From: Daniel Schaefer Date: Tue, 19 Sep 2023 10:29:15 +0800 Subject: [PATCH 1/7] Add QT Py Module Signed-off-by: Daniel Schaefer --- .github/workflows/firmware.yml | 10 ++ Cargo.lock | 52 +++++++- Cargo.toml | 7 ++ fl16-inputmodules/Cargo.toml | 1 + fl16-inputmodules/src/lib.rs | 2 +- qtpy/Cargo.toml | 38 ++++++ qtpy/Makefile.toml | 12 ++ qtpy/README.md | 17 +++ qtpy/src/main.rs | 215 +++++++++++++++++++++++++++++++++ 9 files changed, 349 insertions(+), 5 deletions(-) create mode 100644 qtpy/Cargo.toml create mode 100644 qtpy/Makefile.toml create mode 100644 qtpy/README.md create mode 100644 qtpy/src/main.rs diff --git a/.github/workflows/firmware.yml b/.github/workflows/firmware.yml index 0ef133cf..9d6cd755 100644 --- a/.github/workflows/firmware.yml +++ b/.github/workflows/firmware.yml @@ -32,13 +32,18 @@ jobs: - run: cargo install cargo-make - run: cargo install flip-link + # Debug version - run: cargo make --cwd b1display - run: cargo make --cwd c1minimal + - run: cargo make --cwd ledmatrix + - run: cargo make --cwd qtpy + # Release version - run: cargo make --cwd ledmatrix build-release - run: cargo make --cwd ledmatrix build-release-10k - run: cargo make --cwd ledmatrix build-release-evt - run: cargo make --cwd b1display build-release - run: cargo make --cwd c1minimal build-release + - run: cargo make --cwd qtpy build-release - name: Convert to UF2 format run: | @@ -46,6 +51,7 @@ jobs: sudo apt-get install -y libudev-dev cargo make --cwd b1display uf2 cargo make --cwd c1minimal uf2 + cargo make --cwd qtpy uf2 cargo make --cwd ledmatrix build-release-10k-uf2 cargo make --cwd ledmatrix build-release-evt-uf2 cargo make --cwd ledmatrix uf2 @@ -55,6 +61,7 @@ jobs: sudo apt-get update sudo apt-get install -y llvm cargo make --cwd b1display bin + cargo make --cwd qtpy bin cargo make --cwd c1minimal bin cargo make --cwd ledmatrix bin @@ -99,6 +106,7 @@ jobs: sudo apt-get update sudo apt-get install -y libudev-dev cargo make clippy --cwd b1display + cargo make clippy --cwd qtpy cargo make clippy --cwd c1minimal cargo make clippy --cwd ledmatrix @@ -110,6 +118,7 @@ jobs: run: | cargo pkgid -p fl16-inputmodules | cut -d "#" -f2 >> versions.tmp cargo pkgid -p b1display | cut -d "#" -f2 >> versions.tmp + cargo pkgid -p qtpy | cut -d "#" -f2 >> versions.tmp cargo pkgid -p c1minimal | cut -d "#" -f2 >> versions.tmp cargo pkgid -p ledmatrix | cut -d "#" -f2 >> versions.tmp uniq -c versions.tmp | [ $(wc -l) -eq 1 ] @@ -127,4 +136,5 @@ jobs: cargo fmt -p b1display -- --check cargo fmt -p c1minimal -- --check cargo fmt -p ledmatrix -- --check + cargo fmt -p qtpy -- --check cargo fmt -p fl16-inputmodules -- --check diff --git a/Cargo.lock b/Cargo.lock index 00663417..f943a7b9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -23,6 +23,18 @@ dependencies = [ "mach", ] +[[package]] +name = "adafruit-qt-py-rp2040" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e36e061b89c1354cab7a96173730928d67e9970ad509cd295af724abb30920b6" +dependencies = [ + "cortex-m", + "cortex-m-rt", + "rp2040-boot2 0.2.1", + "rp2040-hal", +] + [[package]] name = "addr2line" version = "0.19.0" @@ -208,7 +220,7 @@ dependencies = [ "fl16-inputmodules", "fugit", "heapless", - "rp2040-boot2", + "rp2040-boot2 0.3.0", "rp2040-hal", "rp2040-panic-usb-boot", "st7306", @@ -316,7 +328,7 @@ dependencies = [ "fl16-inputmodules", "fugit", "heapless", - "rp2040-boot2", + "rp2040-boot2 0.3.0", "rp2040-hal", "rp2040-panic-usb-boot", "smart-leds", @@ -789,7 +801,7 @@ dependencies = [ "num", "num-derive", "num-traits", - "rp2040-boot2", + "rp2040-boot2 0.3.0", "rp2040-hal", "rp2040-panic-usb-boot", "smart-leds", @@ -1114,7 +1126,7 @@ dependencies = [ "fugit", "heapless", "is31fl3741", - "rp2040-boot2", + "rp2040-boot2 0.3.0", "rp2040-hal", "rp2040-panic-usb-boot", "usb-device", @@ -1615,6 +1627,29 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "qtpy" +version = "0.1.7" +dependencies = [ + "adafruit-qt-py-rp2040", + "cortex-m", + "cortex-m-rt", + "defmt", + "defmt-rtt", + "embedded-hal", + "fl16-inputmodules", + "fugit", + "heapless", + "rp2040-boot2 0.3.0", + "rp2040-hal", + "rp2040-panic-usb-boot", + "smart-leds", + "usb-device", + "usbd-hid", + "usbd-serial", + "ws2812-pio", +] + [[package]] name = "quote" version = "1.0.28" @@ -1832,6 +1867,15 @@ dependencies = [ "bytemuck", ] +[[package]] +name = "rp2040-boot2" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c773ec49b836077aa144b58dc7654a243e1eecdb6cf0d25361ae7c7600fabd8" +dependencies = [ + "crc-any", +] + [[package]] name = "rp2040-boot2" version = "0.3.0" diff --git a/Cargo.toml b/Cargo.toml index e86f3e3b..35a23d12 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -10,6 +10,7 @@ members = [ "ledmatrix", "fl16-inputmodules", "inputmodule-control", + "qtpy", ] # Don't build all of them by default. # Because that'll lead to all features enabled in `fl16-inputmodules` and it @@ -63,6 +64,12 @@ incremental = true # To allow single-stepping through code use 0. Will cause timing issues, though opt-level = 3 +[profile.dev.package.qtpy] +codegen-units = 1 +incremental = true +# To allow single-stepping through code use 0. Will cause timing issues, though +opt-level = 3 + # Faster and smaller code but much slower to compile. # Increase in rebuild time from <1s to 20s [profile.release] diff --git a/fl16-inputmodules/Cargo.toml b/fl16-inputmodules/Cargo.toml index 9c28fd13..c4e7dc9c 100644 --- a/fl16-inputmodules/Cargo.toml +++ b/fl16-inputmodules/Cargo.toml @@ -47,3 +47,4 @@ default = [] ledmatrix = ["is31fl3741"] b1display = ["st7306", "embedded-graphics", "tinybmp"] c1minimal = ["smart-leds", "ws2812-pio"] +qtpy = ["c1minimal"] diff --git a/fl16-inputmodules/src/lib.rs b/fl16-inputmodules/src/lib.rs index e7fa8370..598154a6 100644 --- a/fl16-inputmodules/src/lib.rs +++ b/fl16-inputmodules/src/lib.rs @@ -27,7 +27,7 @@ pub mod graphics; #[cfg(feature = "b1display")] pub mod lcd_hal; -#[cfg(feature = "c1minimal")] +#[cfg(all(feature = "c1minimal", not(feature = "qtpy")))] pub mod minimal_hal; pub mod control; diff --git a/qtpy/Cargo.toml b/qtpy/Cargo.toml new file mode 100644 index 00000000..15e9bac8 --- /dev/null +++ b/qtpy/Cargo.toml @@ -0,0 +1,38 @@ +[package] +edition = "2021" +name = "qtpy" +version = "0.1.7" + +[dependencies] +cortex-m.workspace = true +cortex-m-rt.workspace = true +embedded-hal.workspace = true + +defmt.workspace = true +defmt-rtt.workspace = true + +#panic-probe.workspace = true +rp2040-panic-usb-boot.workspace = true + +# Not using an external BSP, we've got the Framework Laptop 16 BSPs locally in this crate +rp2040-hal.workspace = true +rp2040-boot2.workspace = true + +# USB Serial +usb-device.workspace = true +heapless.workspace = true +usbd-serial.workspace = true +usbd-hid.workspace = true +fugit.workspace = true + +# C1 Minimal +smart-leds.workspace = true +ws2812-pio.workspace = true + +# QT Py +adafruit-qt-py-rp2040 = "0.6.0" + +[dependencies.fl16-inputmodules] +path = "../fl16-inputmodules" +# Same feature as c1minimal +features = [ "c1minimal", "qtpy" ] diff --git a/qtpy/Makefile.toml b/qtpy/Makefile.toml new file mode 100644 index 00000000..54d98f28 --- /dev/null +++ b/qtpy/Makefile.toml @@ -0,0 +1,12 @@ +extend = "../Makefile.toml" + +[tasks.uf2] +command = "elf2uf2-rs" +args = ["../target/thumbv6m-none-eabi/release/qtpy", "../target/thumbv6m-none-eabi/release/qtpy.uf2"] +dependencies = ["build-release"] +install_crate = "elf2uf2-rs" + +[tasks.bin] +command = "llvm-objcopy" +args = ["-Obinary", "../target/thumbv6m-none-eabi/release/qtpy", "../target/thumbv6m-none-eabi/release/qtpy.bin"] +dependencies = ["build-release"] diff --git a/qtpy/README.md b/qtpy/README.md new file mode 100644 index 00000000..415d5531 --- /dev/null +++ b/qtpy/README.md @@ -0,0 +1,17 @@ +## QT PY RP2040 + +Easy to get started with, without having a Framework module. +Has GPIO and WS2812/Neopixel compatible RGB LED. + +When booting up this LED is lit in green color. +Its color and brightness can be controlled via the commands: + +```sh +> ./ledmatrix_control.py --brightness 255 +> ./ledmatrix_control.py --get-brightness +Current brightness: 255 + +> ./ledmatrix_control.py --set-color yellow +> ./ledmatrix_control.py --get-color +Current color: RGB:(255, 255, 0) +``` diff --git a/qtpy/src/main.rs b/qtpy/src/main.rs new file mode 100644 index 00000000..c4c615c2 --- /dev/null +++ b/qtpy/src/main.rs @@ -0,0 +1,215 @@ +//! C1 Minimal Input Module +//! +//! Neopixel/WS2812 compatible RGB LED is connected to GPIO12. +//! This pin doesn't support SPI TX. +//! It does support UART TX, but that output would have to be inverted. +//! So instead we use PIO to drive the LED. +#![no_std] +#![no_main] +#![allow(clippy::needless_range_loop)] + +use bsp::entry; +use cortex_m::delay::Delay; +use defmt_rtt as _; + +use rp2040_hal::gpio::bank0::Gpio12; +use rp2040_hal::pio::PIOExt; +//#[cfg(debug_assertions)] +//use panic_probe as _; +use rp2040_panic_usb_boot as _; + +// Provide an alias for our BSP so we can switch targets quickly. +// Uncomment the BSP you included in Cargo.toml, the rest of the code does not need to change. +use adafruit_qt_py_rp2040 as bsp; +//use rp_pico as bsp; + +use bsp::hal::{ + clocks::{init_clocks_and_plls, Clock}, + gpio::PinState, + pac, + sio::Sio, + usb, + watchdog::Watchdog, + Timer, +}; + +// USB Device support +use usb_device::{class_prelude::*, prelude::*}; + +// USB Communications Class Device support +use usbd_serial::{SerialPort, USB_CLASS_CDC}; + +// Used to demonstrate writing formatted strings +// use core::fmt::Write; +// use heapless::String; + +// RGB LED +use smart_leds::{colors, SmartLedsWrite, RGB8}; +pub type Ws2812<'a> = ws2812_pio::Ws2812< + crate::pac::PIO0, + rp2040_hal::pio::SM0, + rp2040_hal::timer::CountDown<'a>, + Gpio12, +>; + +use fl16_inputmodules::control::*; +use fl16_inputmodules::serialnum::{device_release, get_serialnum}; + +// TODO: Need to adjust +// FRA - Framwork +// 000 - C1 Minimal Input Module (No assigned value) +// AM - Atemitech +// 00 - Default Configuration +// 00000000 - Device Identifier +const DEFAULT_SERIAL: &str = "FRA000AM0000000000"; + +#[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); + + let clocks = init_clocks_and_plls( + bsp::XOSC_CRYSTAL_FREQ, + pac.XOSC, + pac.CLOCKS, + pac.PLL_SYS, + pac.PLL_USB, + &mut pac.RESETS, + &mut watchdog, + ) + .ok() + .unwrap(); + + let mut delay = cortex_m::delay::Delay::new(core.SYST, clocks.system_clock.freq().to_Hz()); + + let pins = bsp::Pins::new( + pac.IO_BANK0, + pac.PADS_BANK0, + sio.gpio_bank0, + &mut pac.RESETS, + ); + + // Set up the USB driver + let usb_bus = UsbBusAllocator::new(usb::UsbBus::new( + pac.USBCTRL_REGS, + pac.USBCTRL_DPRAM, + clocks.usb_clock, + true, + &mut pac.RESETS, + )); + + // Set up the USB Communications Class Device driver + let mut serial = SerialPort::new(&usb_bus); + + let serialnum = if let Some(serialnum) = get_serialnum() { + serialnum.serialnum + } else { + DEFAULT_SERIAL + }; + + // TODO: Choose other ID + let mut usb_dev = UsbDeviceBuilder::new(&usb_bus, UsbVidPid(0x32ac, 0xFFFF)) + .manufacturer("Adafruit") + .product("QT PY") + .serial_number(serialnum) + .max_power(500) + .device_release(device_release()) + .device_class(USB_CLASS_CDC) + .build(); + + let mut state = C1MinimalState { + sleeping: SimpleSleepState::Awake, + color: colors::GREEN, + brightness: 10, + }; + + let timer = Timer::new(pac.TIMER, &mut pac.RESETS); + let mut prev_timer = timer.get_counter().ticks(); + + pins.neopixel_power + .into_push_pull_output_in_state(PinState::High); + let (mut pio, sm0, _, _, _) = pac.PIO0.split(&mut pac.RESETS); + let mut ws2812: Ws2812 = ws2812_pio::Ws2812::new( + pins.neopixel_data.into_mode(), + &mut pio, + sm0, + clocks.peripheral_clock.freq(), + timer.count_down(), + ); + + ws2812 + .write(smart_leds::brightness( + [state.color].iter().cloned(), + state.brightness, + )) + .unwrap(); + + loop { + // Handle period LED updates. Don't do it too often or USB will get stuck + if timer.get_counter().ticks() > prev_timer + 20_000 { + // TODO: Can do animations here + prev_timer = timer.get_counter().ticks(); + } + + // Check for new data + if usb_dev.poll(&mut [&mut serial]) { + let mut buf = [0u8; 64]; + match serial.read(&mut buf) { + Err(_e) => { + // Do nothing + } + Ok(0) => { + // Do nothing + } + Ok(count) => { + if let Some(command) = parse_command(count, &buf) { + if let Command::Sleep(go_sleeping) = command { + handle_sleep(go_sleeping, &mut state, &mut delay, &mut ws2812); + } else if let SimpleSleepState::Awake = state.sleeping { + // While sleeping no command is handled, except waking up + if let Some(response) = + handle_command(&command, &mut state, &mut ws2812) + { + let _ = serial.write(&response); + }; + } + } + } + } + } + } +} + +fn handle_sleep( + go_sleeping: bool, + state: &mut C1MinimalState, + _delay: &mut Delay, + ws2812: &mut impl SmartLedsWrite, +) { + match (state.sleeping.clone(), go_sleeping) { + (SimpleSleepState::Awake, false) => (), + (SimpleSleepState::Awake, true) => { + state.sleeping = SimpleSleepState::Sleeping; + + // Turn off LED + ws2812.write([colors::BLACK].iter().cloned()).unwrap(); + + // TODO: Set up SLEEP# pin as interrupt and wfi + //cortex_m::asm::wfi(); + } + (SimpleSleepState::Sleeping, true) => (), + (SimpleSleepState::Sleeping, false) => { + state.sleeping = SimpleSleepState::Awake; + + // Turn LED back on + ws2812 + .write(smart_leds::brightness( + [state.color].iter().cloned(), + state.brightness, + )) + .unwrap(); + } + } +} From c729796400d3ff2985347f86aa3b7a4d1e62064c Mon Sep 17 00:00:00 2001 From: Moon Sungjoon Date: Fri, 22 Sep 2023 02:55:48 +0900 Subject: [PATCH 2/7] Update is31fl3741 dependency to crates release v0.2.2 --- Cargo.lock | 5 +++-- Cargo.toml | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index f943a7b9..c99c30a9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1033,8 +1033,9 @@ dependencies = [ [[package]] name = "is31fl3741" -version = "0.2.1" -source = "git+https://github.com/FrameworkComputer/is31fl3741-rs?branch=sw-enablement#fb88ad1baf28aa2a61bc85ff5db83c6e2b661ed5" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "954e34e51c5456ad555979abfdf34ee0574fdfdde2d2499404800cb51929eceb" dependencies = [ "embedded-graphics-core", "embedded-hal", diff --git a/Cargo.toml b/Cargo.toml index 35a23d12..d4d5c401 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -37,7 +37,7 @@ usbd-serial = "0.1.1" usbd-hid = "0.6.1" fugit = "0.3.7" # LED Matrix -is31fl3741 = { git = "https://github.com/FrameworkComputer/is31fl3741-rs", branch = "sw-enablement" } +is31fl3741 = "0.2.2" # B1 Display st7306 = { git = "https://github.com/FrameworkComputer/st7306-rs", branch = "update-deps" } embedded-graphics = "0.8" From 7c1936385c72e27f521e43ae380f517a66591641 Mon Sep 17 00:00:00 2001 From: Moon Sungjoon Date: Fri, 22 Sep 2023 03:17:05 +0900 Subject: [PATCH 3/7] ledmatrix_control: Fix function prototypes Some function prototypes were missing the `dev` parameter, and some of the `send_command` function calls were also missing the `dev` parameter. Releated PR: https://github.com/FrameworkComputer/inputmodule-rs/pull/56 --- ledmatrix_control.py | 64 ++++++++++++++++++++++---------------------- 1 file changed, 32 insertions(+), 32 deletions(-) diff --git a/ledmatrix_control.py b/ledmatrix_control.py index e347ba37..f43e19c4 100755 --- a/ledmatrix_control.py +++ b/ledmatrix_control.py @@ -614,12 +614,12 @@ def commit_cols(s): send_serial(s, command) -def get_color(): +def get_color(dev): res = send_command(dev, CommandVals.SetColor, with_response=True) return (int(res[0]), int(res[1]), int(res[2])) -def set_color(color): +def set_color(dev, color): rgb = None if color == 'white': rgb = [0xFF, 0xFF, 0xFF] @@ -825,7 +825,7 @@ def game_over(dev): time.sleep(0.75) -def pong_embedded(): +def pong_embedded(dev): # Start game send_command(dev, CommandVals.StartGame, [Game.Pong]) @@ -849,14 +849,14 @@ def pong_embedded(): send_command(dev, CommandVals.GameControl, [key_arg]) -def game_of_life_embedded(arg): +def game_of_life_embedded(dev, arg): # Start game # TODO: Add a way to stop it print("Game", int(arg)) send_command(dev, CommandVals.StartGame, [Game.GameOfLife, int(arg)]) -def snake_embedded(): +def snake_embedded(dev): # Start game send_command(dev, CommandVals.StartGame, [Game.Snake]) @@ -938,7 +938,7 @@ def snake(dev): render_matrix(dev, matrix) -def wpm_demo(): +def wpm_demo(dev): """Capture keypresses and calculate the WPM of the last 10 seconds TODO: I'm not sure my calculation is right.""" from getkey import getkey, keys @@ -1363,81 +1363,81 @@ def gui(devices): #sg.popup_error_with_traceback(f'An error happened. Here is the info:', e) -def display_string(disp_str): +def display_string(dev, disp_str): b = [ord(x) for x in disp_str] - send_command(CommandVals.SetText, [len(disp_str)] + b) + send_command(dev, CommandVals.SetText, [len(disp_str)] + b) -def display_on_cmd(on): - send_command(CommandVals.DisplayOn, [on]) +def display_on_cmd(dev, on): + send_command(dev, CommandVals.DisplayOn, [on]) -def invert_screen_cmd(invert): - send_command(CommandVals.InvertScreen, [invert]) +def invert_screen_cmd(dev, invert): + send_command(dev, CommandVals.InvertScreen, [invert]) -def screen_saver_cmd(on): - send_command(CommandVals.ScreenSaver, [on]) +def screen_saver_cmd(dev, on): + send_command(dev, CommandVals.ScreenSaver, [on]) -def set_fps_cmd(mode): - res = send_command(CommandVals.SetFps, with_response=True) +def set_fps_cmd(dev, mode): + res = send_command(dev, CommandVals.SetFps, with_response=True) current_fps = res[0] if mode == 'quarter': fps = current_fps & ~LOW_FPS_MASK fps |= 0b000 - send_command(CommandVals.SetFps, [fps]) + send_command(dev, CommandVals.SetFps, [fps]) set_power_mode_cmd('low') elif mode == 'half': fps = current_fps & ~LOW_FPS_MASK fps |= 0b001 - send_command(CommandVals.SetFps, [fps]) + send_command(dev, CommandVals.SetFps, [fps]) set_power_mode_cmd('low') elif mode == 'one': fps = current_fps & ~LOW_FPS_MASK fps |= 0b010 - send_command(CommandVals.SetFps, [fps]) + send_command(dev, CommandVals.SetFps, [fps]) set_power_mode_cmd('low') elif mode == 'two': fps = current_fps & ~LOW_FPS_MASK fps |= 0b011 - send_command(CommandVals.SetFps, [fps]) + send_command(dev, CommandVals.SetFps, [fps]) set_power_mode_cmd('low') elif mode == 'four': fps = current_fps & ~LOW_FPS_MASK fps |= 0b100 - send_command(CommandVals.SetFps, [fps]) + send_command(dev, CommandVals.SetFps, [fps]) set_power_mode_cmd('low') elif mode == 'eight': fps = current_fps & ~LOW_FPS_MASK fps |= 0b101 - send_command(CommandVals.SetFps, [fps]) + send_command(dev, CommandVals.SetFps, [fps]) set_power_mode_cmd('low') elif mode == 'sixteen': fps = current_fps & ~HIGH_FPS_MASK fps |= 0b00000000 - send_command(CommandVals.SetFps, [fps]) + send_command(dev, CommandVals.SetFps, [fps]) set_power_mode_cmd('high') elif mode == 'thirtytwo': fps = current_fps & ~HIGH_FPS_MASK fps |= 0b00010000 - send_command(CommandVals.SetFps, [fps]) + send_command(dev, CommandVals.SetFps, [fps]) set_power_mode_cmd('high') -def set_power_mode_cmd(mode): +def set_power_mode_cmd(dev, mode): if mode == 'low': - send_command(CommandVals.SetPowerMode, [0]) + send_command(dev, CommandVals.SetPowerMode, [0]) elif mode == 'high': - send_command(CommandVals.SetPowerMode, [1]) + send_command(dev, CommandVals.SetPowerMode, [1]) else: print("Unsupported power mode") sys.exit(1) -def get_power_mode_cmd(): - res = send_command(CommandVals.SetPowerMode, with_response=True) +def get_power_mode_cmd(dev): + res = send_command(dev, CommandVals.SetPowerMode, with_response=True) current_mode = int(res[0]) if current_mode == 0: print(f"Current Power Mode: Low Power") @@ -1445,10 +1445,10 @@ def get_power_mode_cmd(): print(f"Current Power Mode: High Power") -def get_fps_cmd(): - res = send_command(CommandVals.SetFps, with_response=True) +def get_fps_cmd(dev): + res = send_command(dev, CommandVals.SetFps, with_response=True) current_fps = res[0] - res = send_command(CommandVals.SetPowerMode, with_response=True) + res = send_command(dev, CommandVals.SetPowerMode, with_response=True) current_mode = int(res[0]) if current_mode == 0: From 0aaf49a94dc225828a5424e8dded5cba21a90e43 Mon Sep 17 00:00:00 2001 From: Moon Sungjoon Date: Fri, 22 Sep 2023 03:28:52 +0900 Subject: [PATCH 4/7] qtpy: Change USB PID to 0x01AF --- qtpy/src/main.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/qtpy/src/main.rs b/qtpy/src/main.rs index c4c615c2..4f868371 100644 --- a/qtpy/src/main.rs +++ b/qtpy/src/main.rs @@ -109,8 +109,7 @@ fn main() -> ! { DEFAULT_SERIAL }; - // TODO: Choose other ID - let mut usb_dev = UsbDeviceBuilder::new(&usb_bus, UsbVidPid(0x32ac, 0xFFFF)) + let mut usb_dev = UsbDeviceBuilder::new(&usb_bus, UsbVidPid(0x32ac, 0x01AF)) .manufacturer("Adafruit") .product("QT PY") .serial_number(serialnum) From 43f3317d311adaf9ea6f16d3bbf87c13dcb0cbaf Mon Sep 17 00:00:00 2001 From: Moon Sungjoon Date: Fri, 22 Sep 2023 03:30:26 +0900 Subject: [PATCH 5/7] ledmatrix_control: Add USB PID for QT PY support --- ledmatrix_control.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/ledmatrix_control.py b/ledmatrix_control.py index f43e19c4..11be1a1d 100755 --- a/ledmatrix_control.py +++ b/ledmatrix_control.py @@ -20,7 +20,8 @@ FWK_MAGIC = [0x32, 0xAC] FWK_VID = 0x32AC LED_MATRIX_PID = 0x20 -INPUTMODULE_PIDS = [LED_MATRIX_PID] +QTPY_PID = 0x01AF +INPUTMODULE_PIDS = [LED_MATRIX_PID, QTPY_PID] class CommandVals(IntEnum): From 529ec08827f52f12e4ad9c806794a16d632d2982 Mon Sep 17 00:00:00 2001 From: Daniel Schaefer Date: Sun, 8 Oct 2023 18:01:07 +0800 Subject: [PATCH 6/7] qtpy: Clean up And change PID to 0x001F Signed-off-by: Daniel Schaefer --- README.md | 3 ++- ledmatrix_control.py | 2 +- qtpy/README.md | 5 +++-- qtpy/src/main.rs | 27 ++++++--------------------- 4 files changed, 12 insertions(+), 25 deletions(-) diff --git a/README.md b/README.md index 10c51fd6..8eb911a4 100644 --- a/README.md +++ b/README.md @@ -11,8 +11,9 @@ See pages of the individual modules for details about how they work and how they're controlled. - [LED Matrix](ledmatrix/README.md) -- [2nd Display](b1display/README.md) - [Minimal C1 Input Module](c1minimal/README.md) +- [2nd Display](b1display/README.md) +- [QT PY RP2040](qtpy/README.md) ## Generic Features diff --git a/ledmatrix_control.py b/ledmatrix_control.py index 11be1a1d..464ced5a 100755 --- a/ledmatrix_control.py +++ b/ledmatrix_control.py @@ -20,7 +20,7 @@ FWK_MAGIC = [0x32, 0xAC] FWK_VID = 0x32AC LED_MATRIX_PID = 0x20 -QTPY_PID = 0x01AF +QTPY_PID = 0x001F INPUTMODULE_PIDS = [LED_MATRIX_PID, QTPY_PID] diff --git a/qtpy/README.md b/qtpy/README.md index 415d5531..526807c6 100644 --- a/qtpy/README.md +++ b/qtpy/README.md @@ -1,7 +1,8 @@ ## QT PY RP2040 -Easy to get started with, without having a Framework module. -Has GPIO and WS2812/Neopixel compatible RGB LED. +**NOT** an official Framework module. +Just reference firmware that's easy to get started with, without having a +Framework module. Has GPIO and WS2812/Neopixel compatible RGB LED. When booting up this LED is lit in green color. Its color and brightness can be controlled via the commands: diff --git a/qtpy/src/main.rs b/qtpy/src/main.rs index 4f868371..1ba7cd1a 100644 --- a/qtpy/src/main.rs +++ b/qtpy/src/main.rs @@ -1,4 +1,4 @@ -//! C1 Minimal Input Module +//! QT PY RP2040 with Framework 16 Input Module Firmware //! //! Neopixel/WS2812 compatible RGB LED is connected to GPIO12. //! This pin doesn't support SPI TX. @@ -53,15 +53,10 @@ pub type Ws2812<'a> = ws2812_pio::Ws2812< >; use fl16_inputmodules::control::*; -use fl16_inputmodules::serialnum::{device_release, get_serialnum}; +use fl16_inputmodules::serialnum::device_release; -// TODO: Need to adjust -// FRA - Framwork -// 000 - C1 Minimal Input Module (No assigned value) -// AM - Atemitech -// 00 - Default Configuration -// 00000000 - Device Identifier -const DEFAULT_SERIAL: &str = "FRA000AM0000000000"; +const FRAMEWORK_VID: u16 = 0x32AC; +const COMMUNITY_PID: u16 = 0x001F; #[entry] fn main() -> ! { @@ -103,16 +98,9 @@ fn main() -> ! { // Set up the USB Communications Class Device driver let mut serial = SerialPort::new(&usb_bus); - let serialnum = if let Some(serialnum) = get_serialnum() { - serialnum.serialnum - } else { - DEFAULT_SERIAL - }; - - let mut usb_dev = UsbDeviceBuilder::new(&usb_bus, UsbVidPid(0x32ac, 0x01AF)) + let mut usb_dev = UsbDeviceBuilder::new(&usb_bus, UsbVidPid(FRAMEWORK_VID, COMMUNITY_PID)) .manufacturer("Adafruit") - .product("QT PY") - .serial_number(serialnum) + .product("QT PY - Framework 16 Inputmodule FW") .max_power(500) .device_release(device_release()) .device_class(USB_CLASS_CDC) @@ -194,9 +182,6 @@ fn handle_sleep( // Turn off LED ws2812.write([colors::BLACK].iter().cloned()).unwrap(); - - // TODO: Set up SLEEP# pin as interrupt and wfi - //cortex_m::asm::wfi(); } (SimpleSleepState::Sleeping, true) => (), (SimpleSleepState::Sleeping, false) => { From ed382ddf8a819a6fdeb97cdf64874c2e5a196981 Mon Sep 17 00:00:00 2001 From: Daniel Schaefer Date: Mon, 9 Oct 2023 11:28:54 -0700 Subject: [PATCH 7/7] Bump is31fl3741 to v0.3.0 Signed-off-by: Daniel Schaefer --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index d4d5c401..a8e11c48 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -37,7 +37,7 @@ usbd-serial = "0.1.1" usbd-hid = "0.6.1" fugit = "0.3.7" # LED Matrix -is31fl3741 = "0.2.2" +is31fl3741 = "0.3.0" # B1 Display st7306 = { git = "https://github.com/FrameworkComputer/st7306-rs", branch = "update-deps" } embedded-graphics = "0.8"