From b02fe2bc2e9cb60a388c1da5bfa94fd0eba2545d Mon Sep 17 00:00:00 2001 From: beerpsi Date: Fri, 22 Mar 2024 22:16:40 +0700 Subject: [PATCH] Fix compilation errors + scaffold redboard backend --- Cargo.toml | 1 + src/backends/mod.rs | 1 + src/backends/redboard.rs | 129 +++++++++++++++++++++++++++++++++++++++ src/lib.rs | 7 +-- 4 files changed, 134 insertions(+), 4 deletions(-) create mode 100644 src/backends/redboard.rs diff --git a/Cargo.toml b/Cargo.toml index 80d685f..9413ad9 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -18,6 +18,7 @@ chusan = [] tasoller_v1 = [] tasoller_v2 = [] laverita_v3 = [] +redboard = [] [dependencies] anyhow = "1.0.76" diff --git a/src/backends/mod.rs b/src/backends/mod.rs index c600532..26946d5 100644 --- a/src/backends/mod.rs +++ b/src/backends/mod.rs @@ -1,5 +1,6 @@ pub mod dummy; pub mod laverita_v2; +pub mod redboard; pub mod tasoller_v1; pub mod tasoller_v2; diff --git a/src/backends/redboard.rs b/src/backends/redboard.rs new file mode 100644 index 0000000..e90e07c --- /dev/null +++ b/src/backends/redboard.rs @@ -0,0 +1,129 @@ +//! # RedBoard +//! USB device: 0F0D:0092 +//! USB interface: 0 +//! +//! ## Protocol information +//! - Content length: 9 bytes (72 bits) +//! - Byte 1: Report ID +//! - Byte 2: +//! - 0x01: Service +//! - 0x02: Start (?) +//! - 0x10: Test +//! - Byte 3: +//! - 0x01: IR2 +//! - 0x02: IR3 +//! - 0x04: IR4 +//! - 0x08: IR1 +//! - 0x10: IR5 +//! - 0x20: IR6 +//! - Byte 4: HAT switch, whatever this is +//! - Byte +//! +#[cfg(any(chuni, chusanapp))] +use anyhow::Result; +#[cfg(any(chuni, chusanapp))] +use rusb::{DeviceHandle, UsbContext}; + +use super::ReadType; + +pub const DEVICE_VID: u16 = 0x0F0D; +pub const DEVICE_PID: u16 = 0x0092; +pub const READ_TYPE: ReadType = ReadType::Interrupt; +pub const READ_ENDPOINT: u8 = 0x01; +pub const INPUT_MEMORY_SIZE: usize = 9; +pub const OUTPUT_MEMORY_SIZE: usize = 98; + +#[repr(C, packed)] +struct ControllerReport { + pub report_id: u8, + pub buttons: u16, + pub _hat: u8, + pub axis: u32, + pub vendor_spec: u8, +} + +/// Poll JVS input. +/// +/// The return value is a tuple: +/// - The first value returns the cabinet test/service state, where bit 0 is Test +/// and bit 1 is Service. +/// - The second value returns the IR beams that are currently broken, where bit 0 +/// is the lowest IR beam and bit 5 is the highest IR beam, for a total of 6 beams. +/// +/// Both bit masks are active-high. +#[cfg(any(chuni, amdaemon))] +#[inline(always)] +pub fn jvs_poll(input: &[u8]) -> (u8, u8) { + let buttons = (input[1] as u16) << 8 | (input[2] as u16); + (0, 0) +} + +/// Checks the current state of the coin button (if there is one). +#[cfg(any(chuni, amdaemon))] +#[inline(always)] +pub fn is_coin_button_pressed(_input: &[u8]) -> bool { + false +} + +/// Reads slider pressure information from USB input. +/// +/// There are a total of 32 regions on the touch slider. Each region can return +/// an 8-bit pressure value. The operator menu allows the operator to adjust the +/// pressure level at which a region is considered to be pressed; the factory +/// default value for this setting is 20. +/// +/// You should return an array of 32 unsigned 8-bit integers, starting from top right +/// and going from top to bottom, right to left. +/// +/// ```ignore +/// ^^ Towards screen ^^ +/// ----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+ +/// 30 | 28 | 26 | 24 | 22 | 20 | 18 | 16 | 14 | 12 | 10 | 8 | 6 | 4 | 2 | 0 | +/// ----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+ +/// 31 | 29 | 27 | 25 | 23 | 21 | 19 | 17 | 15 | 13 | 11 | 9 | 7 | 5 | 3 | 1 | +/// ----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+ +/// ``` +#[cfg(any(chuni, chusanapp))] +#[inline(always)] +pub fn read_pressure_data(_input: &[u8]) -> [u8; 32] { + [0u8; 32] +} + +/// Do some one-time initialization to the USB out buffer +/// (e.g. set magic bytes). +#[cfg(any(chuni, chusanapp))] +#[inline(always)] +pub fn init_output_buffer(_output: &mut [u8]) {} + +/// Update the RGB lighting on the slider. A slice `rgb` is provided, alternating +/// between 16 touch pad pixels and 15 divider pixels, going from right to left. +#[cfg(any(chuni, chusanapp))] +#[inline(always)] +pub fn set_slider_leds( + _device: &DeviceHandle, + _output: &mut [u8], + _rgb: &[u8], +) -> Result<()> { + Ok(()) +} + +/// Update the RGB LEDs. +/// +/// Board 0 corresponds to the left LEDs, with 5 * 10 * 3 RGB values for the +/// billboard, followed by 3 RGB values for the air tower. +/// +/// Board 1 corresponds to the right LEDs, with 6 * 10 * 3 RGB values for the +/// billboard, followed by 3 RGB values for the air tower. +/// +/// Note that billboard strips have alternating direction (bottom to top, top +/// to bottom...) +#[cfg(any(chuni, chusanapp))] +#[inline(always)] +pub fn set_led_colors( + _device: &DeviceHandle, + _output: &mut [u8], + _board: u8, + _rgb: &[u8], +) -> Result<()> { + Ok(()) +} diff --git a/src/lib.rs b/src/lib.rs index 112df7f..c1828c9 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -36,6 +36,8 @@ cfg_if::cfg_if! { use crate::backends::tasoller_v2 as con_impl; } else if #[cfg(feature = "laverita_v2")] { use crate::backends::laverita_v2 as con_impl; + } else if #[cfg(feature = "redboard")] { + use crate::backends::redboard as con_impl; } else { use crate::backends::dummy as con_impl; } @@ -326,10 +328,7 @@ pub extern "C" fn chuni_io_led_set_colors(_rgb: *const u8) {} #[cfg(any(chuni, chusanapp))] fn device_init() -> Result<()> { { - let Some(mut global_device) = DEVICE.write() else { - return Ok(()) - }; - + let mut global_device = DEVICE.write(); *global_device = None; }