Prove of concept for working MCDU firmware, 9th row doesn't get addressed yet and has some USB issue for receiving stuff

Signed-off-by: fly <merspieler@alwaysdata.net>
This commit is contained in:
fly 2024-12-02 01:04:54 +01:00
parent 4a5f63c854
commit 3183f2af4e
2 changed files with 155 additions and 79 deletions

View file

@ -16,31 +16,29 @@ use usbd_human_interface_device::{
// Generated using Waratah
#[rustfmt::skip]
pub const CUSTOM_DESCRIPTOR: &[u8] = &[
0x05, 0x01, // UsagePage(Generic Desktop[0x0001])
0x09, 0x04, // UsageId(Joystick[0x0004])
0xA1, 0x01, // Collection(Application)
0x85, 0x01, // ReportId(1)
0x05, 0x09, // UsagePage(Button[0x0009])
0x19, 0x01, // UsageIdMin(Button 1[0x0001])
0x29, 0x40, // UsageIdMax(Button 64[0x0040])
0x15, 0x00, // LogicalMinimum(0)
0x25, 0x01, // LogicalMaximum(1)
0x95, 0x40, // ReportCount(64)
0x75, 0x01, // ReportSize(1)
0x81, 0x02, // Input(Data, Variable, Absolute, NoWrap, Linear, PreferredState, NoNullPosition, BitField)
0x19, 0x01, // UsageIdMin(Button 1[0x0001])
0x29, 0x20, // UsageIdMax(Button 32[0x0020])
0x95, 0x20, // ReportCount(32)
0x81, 0x02, // Input(Data, Variable, Absolute, NoWrap, Linear, PreferredState, NoNullPosition, BitField)
0x05, 0x0E, // UsagePage(Haptics[0x000E])
0x09, 0x21, // UsageId(Manual Trigger[0x0021])
0x25, 0x7F, // LogicalMaximum(127)
0x95, 0x01, // ReportCount(1)
0x75, 0x07, // ReportSize(7)
0x91, 0x02, // Output(Data, Variable, Absolute, NoWrap, Linear, PreferredState, NoNullPosition, NonVolatile, BitField)
0x75, 0x01, // ReportSize(1)
0x91, 0x03, // Output(Constant, Variable, Absolute, NoWrap, Linear, PreferredState, NoNullPosition, NonVolatile, BitField)
0xC0, // EndCollection()
0x05, 0x01, // UsagePage(Generic Desktop[0x0001])
0x09, 0x04, // UsageId(Joystick[0x0004])
0xA1, 0x01, // Collection(Application)
0x85, 0x01, // ReportId(1)
0x05, 0x09, // UsagePage(Button[0x0009])
0x19, 0x01, // UsageIdMin(Button 1[0x0001])
0x29, 0x40, // UsageIdMax(Button 64[0x0040])
0x15, 0x00, // LogicalMinimum(0)
0x25, 0x01, // LogicalMaximum(1)
0x95, 0x40, // ReportCount(64)
0x75, 0x01, // ReportSize(1)
0x81, 0x02, // Input(Data, Variable, Absolute, NoWrap, Linear, PreferredState, NoNullPosition, BitField)
0x19, 0x01, // UsageIdMin(Button 1[0x0001])
0x29, 0x20, // UsageIdMax(Button 32[0x0020])
0x95, 0x20, // ReportCount(32)
0x81, 0x02, // Input(Data, Variable, Absolute, NoWrap, Linear, PreferredState, NoNullPosition, BitField)
0x05, 0x0E, // UsagePage(Haptics[0x000E])
0x09, 0x21, // UsageId(Manual Trigger[0x0021])
0x26, 0xFF, 0x00, // LogicalMaximum(255)
0x95, 0x01, // ReportCount(1)
0x75, 0x08, // ReportSize(8)
0x91, 0x02, // Output(Data, Variable, Absolute, NoWrap, Linear, PreferredState, NoNullPosition, NonVolatile, BitField)
0xC0, // EndCollection()
];
#[derive(Clone, Copy, Debug, Eq, PartialEq, Default, PackedStruct)]

View file

@ -30,7 +30,7 @@ use crate::device::{CustomConfig, CustomInputReport};
macro_rules! define_output_states {
($bit:literal, $pin:ident, $output:ident, $io_pins:ident) => {
if $output.leds & $bit == $bit {
if $output.leds >= $bit {
$io_pins.$pin.set_high();
}
else {
@ -47,28 +47,29 @@ struct MyPins {
pb6: Pin<'B', 6, Output<PushPull>>,
pb7: Pin<'B', 7, Output<PushPull>>,
pb15: Pin<'B', 15, Output<PushPull>>,
pc0: Pin<'C', 0, Output<PushPull>>,
pc1: Pin<'C', 1, Output<PushPull>>,
pc2: Pin<'C', 2, Output<PushPull>>,
pc3: Pin<'C', 3, Output<PushPull>>,
pc9: Pin<'C', 9, Output<PushPull>>,
pc6: Pin<'C', 6, Output<PushPull>>,
pc7: Pin<'C', 7, Output<PushPull>>,
pc8: Pin<'C', 8, Output<PushPull>>,
pc10: Pin<'C', 10, Output<PushPull>>,
pc11: Pin<'C', 11, Output<PushPull>>,
pc15: Pin<'C', 15, Output<PushPull>>,
// Input read row
pa0: Pin<'A', 0, Input<PullDown>>,
pa1: Pin<'A', 1, Input<PullDown>>,
pa2: Pin<'A', 2, Input<PullDown>>,
pa8: Pin<'A', 8, Input<PullDown>>,
pb4: Pin<'B', 4, Input<PullDown>>,
pb5: Pin<'B', 5, Input<PullDown>>,
pa8: Pin<'A', 8, Input<PullDown>>,
pb12: Pin<'B', 12, Input<PullDown>>,
pb13: Pin<'B', 13, Input<PullDown>>,
pb14: Pin<'B', 14, Input<PullDown>>,
pc6: Pin<'C', 6, Input<PullDown>>,
pc7: Pin<'C', 7, Input<PullDown>>,
pc8: Pin<'C', 8, Input<PullDown>>,
pc10: Pin<'C', 10, Input<PullDown>>,
pc11: Pin<'C', 11, Input<PullDown>>,
pc15: Pin<'C', 15, Input<PullDown>>,
pc0: Pin<'C', 0, Input<PullDown>>,
pc1: Pin<'C', 1, Input<PullDown>>,
pc2: Pin<'C', 2, Input<PullDown>>,
pc3: Pin<'C', 3, Input<PullDown>>,
pc9: Pin<'C', 9, Input<PullDown>>,
pd2: Pin<'D', 2, Input<PullDown>>,
// Outputs
pa9: Pin<'A', 9, Output<PushPull>>,
@ -93,6 +94,7 @@ fn main() -> ! {
let mut gpioa = p.GPIOA.split();
let mut gpiob = p.GPIOB.split();
let mut gpioc = p.GPIOC.split();
let mut gpiod = p.GPIOD.split();
// configure clock
let clocks = rcc
@ -152,28 +154,29 @@ fn main() -> ! {
pb6: gpiob.pb6.into_push_pull_output(&mut gpiob.crl),
pb7: gpiob.pb7.into_push_pull_output(&mut gpiob.crl),
pb15: gpiob.pb15.into_push_pull_output(&mut gpiob.crh),
pc0: gpioc.pc0.into_push_pull_output(&mut gpioc.crl),
pc1: gpioc.pc1.into_push_pull_output(&mut gpioc.crl),
pc2: gpioc.pc2.into_push_pull_output(&mut gpioc.crl),
pc3: gpioc.pc3.into_push_pull_output(&mut gpioc.crl),
pc9: gpioc.pc9.into_push_pull_output(&mut gpioc.crh),
pc6: gpioc.pc6.into_push_pull_output(&mut gpioc.crl),
pc7: gpioc.pc7.into_push_pull_output(&mut gpioc.crl),
pc8: gpioc.pc8.into_push_pull_output(&mut gpioc.crh),
pc10: gpioc.pc10.into_push_pull_output(&mut gpioc.crh),
pc11: gpioc.pc11.into_push_pull_output(&mut gpioc.crh),
pc15: gpioc.pc15.into_push_pull_output(&mut gpioc.crh),
// Inputs Row Read
pa0: gpioa.pa0.into_pull_down_input(&mut gpioa.crl),
pa1: gpioa.pa1.into_pull_down_input(&mut gpioa.crl),
pa2: gpioa.pa2.into_pull_down_input(&mut gpioa.crl),
pa8: gpioa.pa8.into_pull_down_input(&mut gpioa.crh),
pb4: pb4.into_pull_down_input(&mut gpiob.crl),
pb5: gpiob.pb5.into_pull_down_input(&mut gpiob.crl),
pa8: gpioa.pa8.into_pull_down_input(&mut gpioa.crh),
pb12: gpiob.pb12.into_pull_down_input(&mut gpiob.crh),
pb13: gpiob.pb13.into_pull_down_input(&mut gpiob.crh),
pb14: gpiob.pb14.into_pull_down_input(&mut gpiob.crh),
pc6: gpioc.pc6.into_pull_down_input(&mut gpioc.crl),
pc7: gpioc.pc7.into_pull_down_input(&mut gpioc.crl),
pc8: gpioc.pc8.into_pull_down_input(&mut gpioc.crh),
pc10: gpioc.pc10.into_pull_down_input(&mut gpioc.crh),
pc11: gpioc.pc11.into_pull_down_input(&mut gpioc.crh),
pc15: gpioc.pc15.into_pull_down_input(&mut gpioc.crh),
pc0: gpioc.pc0.into_pull_down_input(&mut gpioc.crl),
pc1: gpioc.pc1.into_pull_down_input(&mut gpioc.crl),
pc2: gpioc.pc2.into_pull_down_input(&mut gpioc.crl),
pc3: gpioc.pc3.into_pull_down_input(&mut gpioc.crl),
pc9: gpioc.pc9.into_pull_down_input(&mut gpioc.crh),
pd2: gpiod.pd2.into_pull_down_input(&mut gpiod.crl),
// Outputs
pa9: gpioa.pa9.into_push_pull_output(&mut gpioa.crh), // FM
@ -189,10 +192,109 @@ fn main() -> ! {
let mut timer = Timer::syst(cp.SYST, &clocks).counter_hz();
timer.start(1.kHz()).unwrap();
// ====================== Setup other vars ==========
let mut lsk_col_select: u32 = 0;
let mut col_select: u32 = 0;
// stores the values of the keyboard matrix we can not read out right now
let mut buttons1: u64 = 0;
let mut buttons2: u32 = 0;
// ====================== Main loop =================
loop {
block!(timer.wait()).unwrap();
let report = get_report(&mut io_pins);
// LSK Matirx
let mut lsk_buttons_read: u32 = 0;
if io_pins.pc0.is_high() { lsk_buttons_read += 0x1; }
if io_pins.pc1.is_high() { lsk_buttons_read += 0x2; }
if io_pins.pc2.is_high() { lsk_buttons_read += 0x4; }
if io_pins.pd2.is_high() { lsk_buttons_read += 0x40; }
if io_pins.pb4.is_high() { lsk_buttons_read += 0x80; }
if io_pins.pb5.is_high() { lsk_buttons_read += 0x100; }
buttons2 = buttons2 & (0xFFFFFFFF - (0x1CF << (lsk_col_select * 3)));
buttons2 += lsk_buttons_read << (lsk_col_select * 3);
// Main Matrix
let mut buttons_read: u64 = 0;
if io_pins.pc3.is_high() { buttons_read += 0x1; }
if io_pins.pa0.is_high() { buttons_read += 0x2; }
if io_pins.pa1.is_high() { buttons_read += 0x4; }
if io_pins.pa2.is_high() { buttons_read += 0x8; }
if io_pins.pb12.is_high() { buttons_read += 0x10; }
if io_pins.pb13.is_high() { buttons_read += 0x20; }
if io_pins.pb14.is_high() { buttons_read += 0x40; }
if io_pins.pc9.is_high() { buttons_read += 0x80; }
// if io_pins.pa8.is_high() { buttons_read += 0x100; }
buttons1 = buttons1 & (0xFFFFFFFFFFFFFFFF - (0xFF << (col_select * 8)));
buttons1 += buttons_read << (col_select * 8);
let report = CustomInputReport {
report_id: 1,
buttons1,
buttons2,
};
// Pull the next LSK column high for next time coming through in the main loop ~1ms
if lsk_col_select <= 0 {
io_pins.pc15.set_high();
io_pins.pa5.set_low();
io_pins.pb6.set_high();
io_pins.pb7.set_low();
}
else if lsk_col_select == 1 {
io_pins.pc15.set_low();
io_pins.pa5.set_high();
io_pins.pb6.set_low();
io_pins.pb7.set_high();
}
// Pull the next main column high for next time coming through in the main loop ~1ms
if col_select <= 0 {
io_pins.pb15.set_high();
io_pins.pc10.set_low();
}
else if col_select == 1 {
io_pins.pc6.set_high();
io_pins.pb15.set_low();
}
else if col_select == 2 {
io_pins.pc7.set_high();
io_pins.pc6.set_low();
}
else if col_select == 3 {
io_pins.pc8.set_high();
io_pins.pc7.set_low();
}
else if col_select == 4 {
io_pins.pa4.set_high();
io_pins.pc8.set_low();
}
else if col_select == 5 {
io_pins.pc11.set_high();
io_pins.pa4.set_low();
}
else if col_select == 6 {
io_pins.pa15.set_high();
io_pins.pc11.set_low();
}
else if col_select == 7 {
io_pins.pc10.set_high();
io_pins.pa15.set_low();
}
lsk_col_select += 1;
if lsk_col_select >= 2 {
lsk_col_select = 0;
}
col_select += 1;
if col_select >= 8 {
col_select = 0;
}
match consumer.device().write_report(&report) {
Err(UsbHidError::WouldBlock) => {}
Err(UsbHidError::UsbError(usb_device::UsbError::BufferOverflow)) => {
@ -208,7 +310,10 @@ fn main() -> ! {
if usb_dev.poll(&mut [&mut consumer]) {
match consumer.device().read_report() {
Err(UsbHidError::WouldBlock) => {}
Err(UsbHidError::WouldBlock) => {
// TODO somehow always gets stuck here
io_pins.pa10.set_high();
}
Ok(output) => {
// LED outputs
define_output_states!(0x1, pa9, output, io_pins); // FM
@ -227,30 +332,3 @@ fn main() -> ! {
}
}
// Returns a CustomInputReport from the inputs given
fn get_report(pins: &mut MyPins) -> CustomInputReport {
// TODO keyboard matrix
let mut buttons1: u64 = 0;
let mut buttons2: u32 = 0;
// Buttons
// if pins.pb0.is_high() {
// buttons += 0x01;
// }
// if pins.pc1.is_high() {
// buttons1 += 0x02;
// }
// if pins.pc3.is_high() {
// buttons += 0x04;
// }
if pins.pc15.is_high() {
buttons1 += 0x08;
}
CustomInputReport {
report_id: 1,
buttons1,
buttons2,
}
}