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

@ -34,12 +34,10 @@ pub const CUSTOM_DESCRIPTOR: &[u8] = &[
0x81, 0x02, // Input(Data, Variable, Absolute, NoWrap, Linear, PreferredState, NoNullPosition, BitField) 0x81, 0x02, // Input(Data, Variable, Absolute, NoWrap, Linear, PreferredState, NoNullPosition, BitField)
0x05, 0x0E, // UsagePage(Haptics[0x000E]) 0x05, 0x0E, // UsagePage(Haptics[0x000E])
0x09, 0x21, // UsageId(Manual Trigger[0x0021]) 0x09, 0x21, // UsageId(Manual Trigger[0x0021])
0x25, 0x7F, // LogicalMaximum(127) 0x26, 0xFF, 0x00, // LogicalMaximum(255)
0x95, 0x01, // ReportCount(1) 0x95, 0x01, // ReportCount(1)
0x75, 0x07, // ReportSize(7) 0x75, 0x08, // ReportSize(8)
0x91, 0x02, // Output(Data, Variable, Absolute, NoWrap, Linear, PreferredState, NoNullPosition, NonVolatile, BitField) 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() 0xC0, // EndCollection()
]; ];

View file

@ -30,7 +30,7 @@ use crate::device::{CustomConfig, CustomInputReport};
macro_rules! define_output_states { macro_rules! define_output_states {
($bit:literal, $pin:ident, $output:ident, $io_pins:ident) => { ($bit:literal, $pin:ident, $output:ident, $io_pins:ident) => {
if $output.leds & $bit == $bit { if $output.leds >= $bit {
$io_pins.$pin.set_high(); $io_pins.$pin.set_high();
} }
else { else {
@ -47,28 +47,29 @@ struct MyPins {
pb6: Pin<'B', 6, Output<PushPull>>, pb6: Pin<'B', 6, Output<PushPull>>,
pb7: Pin<'B', 7, Output<PushPull>>, pb7: Pin<'B', 7, Output<PushPull>>,
pb15: Pin<'B', 15, Output<PushPull>>, pb15: Pin<'B', 15, Output<PushPull>>,
pc0: Pin<'C', 0, Output<PushPull>>, pc6: Pin<'C', 6, Output<PushPull>>,
pc1: Pin<'C', 1, Output<PushPull>>, pc7: Pin<'C', 7, Output<PushPull>>,
pc2: Pin<'C', 2, Output<PushPull>>, pc8: Pin<'C', 8, Output<PushPull>>,
pc3: Pin<'C', 3, Output<PushPull>>, pc10: Pin<'C', 10, Output<PushPull>>,
pc9: Pin<'C', 9, Output<PushPull>>, pc11: Pin<'C', 11, Output<PushPull>>,
pc15: Pin<'C', 15, Output<PushPull>>,
// Input read row // Input read row
pa0: Pin<'A', 0, Input<PullDown>>, pa0: Pin<'A', 0, Input<PullDown>>,
pa1: Pin<'A', 1, Input<PullDown>>, pa1: Pin<'A', 1, Input<PullDown>>,
pa2: Pin<'A', 2, Input<PullDown>>, pa2: Pin<'A', 2, Input<PullDown>>,
pa8: Pin<'A', 8, Input<PullDown>>,
pb4: Pin<'B', 4, Input<PullDown>>, pb4: Pin<'B', 4, Input<PullDown>>,
pb5: Pin<'B', 5, Input<PullDown>>, pb5: Pin<'B', 5, Input<PullDown>>,
pa8: Pin<'A', 8, Input<PullDown>>,
pb12: Pin<'B', 12, Input<PullDown>>, pb12: Pin<'B', 12, Input<PullDown>>,
pb13: Pin<'B', 13, Input<PullDown>>, pb13: Pin<'B', 13, Input<PullDown>>,
pb14: Pin<'B', 14, Input<PullDown>>, pb14: Pin<'B', 14, Input<PullDown>>,
pc6: Pin<'C', 6, Input<PullDown>>, pc0: Pin<'C', 0, Input<PullDown>>,
pc7: Pin<'C', 7, Input<PullDown>>, pc1: Pin<'C', 1, Input<PullDown>>,
pc8: Pin<'C', 8, Input<PullDown>>, pc2: Pin<'C', 2, Input<PullDown>>,
pc10: Pin<'C', 10, Input<PullDown>>, pc3: Pin<'C', 3, Input<PullDown>>,
pc11: Pin<'C', 11, Input<PullDown>>, pc9: Pin<'C', 9, Input<PullDown>>,
pc15: Pin<'C', 15, Input<PullDown>>, pd2: Pin<'D', 2, Input<PullDown>>,
// Outputs // Outputs
pa9: Pin<'A', 9, Output<PushPull>>, pa9: Pin<'A', 9, Output<PushPull>>,
@ -93,6 +94,7 @@ fn main() -> ! {
let mut gpioa = p.GPIOA.split(); let mut gpioa = p.GPIOA.split();
let mut gpiob = p.GPIOB.split(); let mut gpiob = p.GPIOB.split();
let mut gpioc = p.GPIOC.split(); let mut gpioc = p.GPIOC.split();
let mut gpiod = p.GPIOD.split();
// configure clock // configure clock
let clocks = rcc let clocks = rcc
@ -152,28 +154,29 @@ fn main() -> ! {
pb6: gpiob.pb6.into_push_pull_output(&mut gpiob.crl), pb6: gpiob.pb6.into_push_pull_output(&mut gpiob.crl),
pb7: gpiob.pb7.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), pb15: gpiob.pb15.into_push_pull_output(&mut gpiob.crh),
pc0: gpioc.pc0.into_push_pull_output(&mut gpioc.crl), pc6: gpioc.pc6.into_push_pull_output(&mut gpioc.crl),
pc1: gpioc.pc1.into_push_pull_output(&mut gpioc.crl), pc7: gpioc.pc7.into_push_pull_output(&mut gpioc.crl),
pc2: gpioc.pc2.into_push_pull_output(&mut gpioc.crl), pc8: gpioc.pc8.into_push_pull_output(&mut gpioc.crh),
pc3: gpioc.pc3.into_push_pull_output(&mut gpioc.crl), pc10: gpioc.pc10.into_push_pull_output(&mut gpioc.crh),
pc9: gpioc.pc9.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 // Inputs Row Read
pa0: gpioa.pa0.into_pull_down_input(&mut gpioa.crl), pa0: gpioa.pa0.into_pull_down_input(&mut gpioa.crl),
pa1: gpioa.pa1.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), 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), pb4: pb4.into_pull_down_input(&mut gpiob.crl),
pb5: gpiob.pb5.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), pb12: gpiob.pb12.into_pull_down_input(&mut gpiob.crh),
pb13: gpiob.pb13.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), pb14: gpiob.pb14.into_pull_down_input(&mut gpiob.crh),
pc6: gpioc.pc6.into_pull_down_input(&mut gpioc.crl), pc0: gpioc.pc0.into_pull_down_input(&mut gpioc.crl),
pc7: gpioc.pc7.into_pull_down_input(&mut gpioc.crl), pc1: gpioc.pc1.into_pull_down_input(&mut gpioc.crl),
pc8: gpioc.pc8.into_pull_down_input(&mut gpioc.crh), pc2: gpioc.pc2.into_pull_down_input(&mut gpioc.crl),
pc10: gpioc.pc10.into_pull_down_input(&mut gpioc.crh), pc3: gpioc.pc3.into_pull_down_input(&mut gpioc.crl),
pc11: gpioc.pc11.into_pull_down_input(&mut gpioc.crh), pc9: gpioc.pc9.into_pull_down_input(&mut gpioc.crh),
pc15: gpioc.pc15.into_pull_down_input(&mut gpioc.crh), pd2: gpiod.pd2.into_pull_down_input(&mut gpiod.crl),
// Outputs // Outputs
pa9: gpioa.pa9.into_push_pull_output(&mut gpioa.crh), // FM 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(); let mut timer = Timer::syst(cp.SYST, &clocks).counter_hz();
timer.start(1.kHz()).unwrap(); 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 ================= // ====================== Main loop =================
loop { loop {
block!(timer.wait()).unwrap(); 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) { match consumer.device().write_report(&report) {
Err(UsbHidError::WouldBlock) => {} Err(UsbHidError::WouldBlock) => {}
Err(UsbHidError::UsbError(usb_device::UsbError::BufferOverflow)) => { Err(UsbHidError::UsbError(usb_device::UsbError::BufferOverflow)) => {
@ -208,7 +310,10 @@ fn main() -> ! {
if usb_dev.poll(&mut [&mut consumer]) { if usb_dev.poll(&mut [&mut consumer]) {
match consumer.device().read_report() { match consumer.device().read_report() {
Err(UsbHidError::WouldBlock) => {} Err(UsbHidError::WouldBlock) => {
// TODO somehow always gets stuck here
io_pins.pa10.set_high();
}
Ok(output) => { Ok(output) => {
// LED outputs // LED outputs
define_output_states!(0x1, pa9, output, io_pins); // FM 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,
}
}