Keyboard matrix implementation for PedestalBox
Signed-off-by: fly <merspieler@alwaysdata.net>
This commit is contained in:
parent
4a301af6ae
commit
af5db5d657
3 changed files with 171 additions and 92 deletions
|
@ -54,6 +54,10 @@ logicalValueRange = [0, 65535]
|
|||
usageRange = ['Button', 'Button 1', 'Button 32']
|
||||
logicalValueRange = [0, 1]
|
||||
|
||||
[[applicationCollection.inputReport.variableItem]]
|
||||
usageRange = ['Button', 'Button 1', 'Button 32']
|
||||
logicalValueRange = [0, 1]
|
||||
|
||||
[[applicationCollection.outputReport]]
|
||||
|
||||
[[applicationCollection.outputReport.variableItem]]
|
||||
|
|
|
@ -43,11 +43,15 @@ pub const CUSTOM_DESCRIPTOR: &[u8] = &[
|
|||
0x19, 0x01, // UsageIdMin(Button 1[0x0001])
|
||||
0x29, 0x20, // UsageIdMax(Button 32[0x0020])
|
||||
0x25, 0x01, // LogicalMaximum(1)
|
||||
0x95, 0x10, // ReportCount(16)
|
||||
0x95, 0x20, // ReportCount(32)
|
||||
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])
|
||||
0x81, 0x02, // Input(Data, Variable, Absolute, NoWrap, Linear, PreferredState, NoNullPosition, BitField)
|
||||
0x05, 0x0E, // UsagePage(Haptics[0x000E])
|
||||
0x09, 0x21, // UsageId(Manual Trigger[0x0021])
|
||||
0x09, 0x21, // UsageId(Manual Trigger[0x0021])
|
||||
0x27, 0x80, 0xBB, 0x00, 0x00, // LogicalMaximum(48,000)
|
||||
0x95, 0x02, // ReportCount(2)
|
||||
0x75, 0x10, // ReportSize(16)
|
||||
|
@ -62,7 +66,7 @@ pub const CUSTOM_DESCRIPTOR: &[u8] = &[
|
|||
];
|
||||
|
||||
#[derive(Clone, Copy, Debug, Eq, PartialEq, Default, PackedStruct)]
|
||||
#[packed_struct(endian = "lsb", size_bytes = "27")] // MUST be <= 64 else we get problem cause InBytes64 or OutBytes64
|
||||
#[packed_struct(endian = "lsb", size_bytes = "31")] // MUST be <= 64 else we get problem cause InBytes64 or OutBytes64
|
||||
pub struct CustomInputReport {
|
||||
#[packed_field]
|
||||
pub report_id: u8,
|
||||
|
@ -70,6 +74,8 @@ pub struct CustomInputReport {
|
|||
pub axis: [u16; 11],
|
||||
#[packed_field]
|
||||
pub buttons: u32,
|
||||
#[packed_field]
|
||||
pub ecam_buttons: u32,
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug, Eq, PartialEq, Default, PackedStruct)]
|
||||
|
|
|
@ -131,7 +131,20 @@ struct MyPins {
|
|||
pe9: Pin<'E', 9, Output<PushPull>>, // ECAM LEDs Row 3
|
||||
pe13: Pin<'E', 13, Output<PushPull>>, // ECAM LEDs Row 2
|
||||
|
||||
// TODO ECAM matrix pins
|
||||
// ECAM matrix read row
|
||||
pe12: Pin<'E', 12, Input<PullDown>>, // ECAM Keys Row 1
|
||||
pe15: Pin<'E', 15, Input<PullDown>>, // ECAM Keys Row 2
|
||||
pe11: Pin<'E', 11, Input<PullDown>>, // ECAM Keys Row 3
|
||||
pe7: Pin<'E', 7, Input<PullDown>>, // ECAM Keys Row 4
|
||||
|
||||
// ECAM matrix column select
|
||||
pd11: Pin<'D', 11, Output<PushPull>>, // ECAM Keys Column 1
|
||||
pd12: Pin<'D', 12, Output<PushPull>>, // ECAM Keys Column 2
|
||||
pe8: Pin<'E', 8, Output<PushPull>>, // ECAM Keys Column 3
|
||||
pb2: Pin<'B', 2, Output<PushPull>>, // ECAM Keys Column 4
|
||||
pe10: Pin<'E', 10, Output<PushPull>>, // ECAM Keys Column 5
|
||||
pe14: Pin<'E', 14, Output<PushPull>>, // ECAM Keys Column 6
|
||||
|
||||
}
|
||||
|
||||
#[derive(Pod)]
|
||||
|
@ -295,6 +308,21 @@ fn main() -> ! {
|
|||
pe4: gpioe.pe4.into_push_pull_output(&mut gpioe.crl),
|
||||
pe9: gpioe.pe9.into_push_pull_output(&mut gpioe.crh),
|
||||
pe13: gpioe.pe13.into_push_pull_output(&mut gpioe.crh),
|
||||
|
||||
// ECAM matrix read row
|
||||
pe12: gpioe.pe12.into_pull_down_input(&mut gpioe.crh),
|
||||
pe15: gpioe.pe15.into_pull_down_input(&mut gpioe.crh),
|
||||
pe11: gpioe.pe11.into_pull_down_input(&mut gpioe.crh),
|
||||
pe7: gpioe.pe7.into_pull_down_input(&mut gpioe.crl),
|
||||
|
||||
|
||||
// ECAM matrix column select
|
||||
pd11: gpiod.pd11.into_push_pull_output(&mut gpiod.crh),
|
||||
pd12: gpiod.pd12.into_push_pull_output(&mut gpiod.crh),
|
||||
pe8: gpioe.pe8.into_push_pull_output(&mut gpioe.crh),
|
||||
pb2: gpiob.pb2.into_push_pull_output(&mut gpiob.crl),
|
||||
pe10: gpioe.pe10.into_push_pull_output(&mut gpioe.crh),
|
||||
pe14: gpioe.pe14.into_push_pull_output(&mut gpioe.crh),
|
||||
};
|
||||
|
||||
// ====================== PWM setup =================
|
||||
|
@ -311,10 +339,127 @@ fn main() -> ! {
|
|||
let mut timer = Timer::syst(cp.SYST, &clocks).counter_hz();
|
||||
timer.start(1.kHz()).unwrap();
|
||||
|
||||
// ====================== Setup other vars ==========
|
||||
let mut ecam_col_select: u8 = 0;
|
||||
let mut ecam_buttons: u32 = 0; // stores the values of the keyboard matrix we can not read out right now
|
||||
|
||||
// ====================== Main loop =================
|
||||
loop {
|
||||
block!(timer.wait()).unwrap();
|
||||
let report = get_report(&mut io_pins, &mut adc1, &cal);
|
||||
// Generate report
|
||||
// Read axis
|
||||
let mut values: [u16; 11] = [0; 11];
|
||||
values[0] = adc1.read(&mut io_pins.pa2).unwrap();
|
||||
values[1] = adc1.read(&mut io_pins.pa3).unwrap();
|
||||
values[2] = adc1.read(&mut io_pins.pa5).unwrap();
|
||||
values[3] = adc1.read(&mut io_pins.pa6).unwrap();
|
||||
values[4] = adc1.read(&mut io_pins.pa7).unwrap();
|
||||
values[5] = adc1.read(&mut io_pins.pb0).unwrap();
|
||||
values[6] = adc1.read(&mut io_pins.pb1).unwrap();
|
||||
values[7] = adc1.read(&mut io_pins.pc0).unwrap();
|
||||
values[8] = adc1.read(&mut io_pins.pc1).unwrap();
|
||||
values[9] = adc1.read(&mut io_pins.pc2).unwrap();
|
||||
values[10] = adc1.read(&mut io_pins.pc3).unwrap();
|
||||
|
||||
// Apply calibration to axis data
|
||||
let mut values_norm: [u16; 11] = [0; 11];
|
||||
let mut i = 0;
|
||||
loop {
|
||||
if values[i] < cal.data[i].min {
|
||||
values_norm[i] = 0;
|
||||
}
|
||||
else if values[i] > cal.data[i].max {
|
||||
values_norm[i] = CalibrationData::ADC_MAX;
|
||||
}
|
||||
else {
|
||||
values_norm[i] = ((values[i] - cal.data[i].min) as f32 * cal.data[i].factor) as u16;
|
||||
}
|
||||
i += 1;
|
||||
if i == values_norm.len() {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Buttons
|
||||
let mut buttons: u32 = 0;
|
||||
if io_pins.pa0.is_high() { buttons += 0x1; }
|
||||
if io_pins.pa1.is_high() { buttons += 0x2; }
|
||||
if io_pins.pa4.is_high() { buttons += 0x4; }
|
||||
if io_pins.pa8.is_high() { buttons += 0x8; }
|
||||
if io_pins.pa9.is_high() { buttons += 0x10; }
|
||||
if io_pins.pa10.is_high() { buttons += 0x20; }
|
||||
if io_pins.pb4.is_high() { buttons += 0x40; }
|
||||
if io_pins.pb5.is_high() { buttons += 0x80; }
|
||||
if io_pins.pb8.is_high() { buttons += 0x100; }
|
||||
if io_pins.pb9.is_high() { buttons += 0x200; }
|
||||
if io_pins.pc4.is_high() { buttons += 0x400; }
|
||||
if io_pins.pc5.is_high() { buttons += 0x800; }
|
||||
if io_pins.pc6.is_high() { buttons += 0x1000; }
|
||||
if io_pins.pc9.is_high() { buttons += 0x0200; }
|
||||
if io_pins.pc13.is_high() { buttons += 0x4000; }
|
||||
if io_pins.pc14.is_high() { buttons += 0x8000; }
|
||||
if io_pins.pc15.is_high() { buttons += 0x10000; }
|
||||
if io_pins.pd1.is_high() { buttons += 0x20000; }
|
||||
if io_pins.pd3.is_high() { buttons += 0x40000; }
|
||||
if io_pins.pd4.is_high() { buttons += 0x80000; }
|
||||
if io_pins.pd5.is_high() { buttons += 0x100000; }
|
||||
if io_pins.pd6.is_high() { buttons += 0x200000; }
|
||||
if io_pins.pd7.is_high() { buttons += 0x400000; }
|
||||
if io_pins.pd13.is_high() { buttons += 0x800000; }
|
||||
if io_pins.pd14.is_high() { buttons += 0x1000000; }
|
||||
if io_pins.pd15.is_high() { buttons += 0x2000000; }
|
||||
if io_pins.pe0.is_high() { buttons += 0x4000000; }
|
||||
if io_pins.pe5.is_high() { buttons += 0x8000000; }
|
||||
if io_pins.pe6.is_high() { buttons += 0x10000000; }
|
||||
|
||||
// ECAM Keyboard matrix
|
||||
let mut ecam_buttons_read: u32 = 0;
|
||||
|
||||
if io_pins.pe12.is_high() { ecam_buttons_read += 0x1; }
|
||||
if io_pins.pe15.is_high() { ecam_buttons_read += 0x2; }
|
||||
if io_pins.pe11.is_high() { ecam_buttons_read += 0x4; }
|
||||
if io_pins.pe7.is_high() { ecam_buttons_read += 0x8; }
|
||||
|
||||
ecam_buttons = ecam_buttons & (0xFFFFFFFF - (0xF << (ecam_col_select * 4)));
|
||||
ecam_buttons += ecam_buttons_read << (ecam_col_select * 4);
|
||||
|
||||
// Pull the next column high for next time coming through in the main loop ~1ms
|
||||
if ecam_col_select == 0 {
|
||||
io_pins.pd11.set_high();
|
||||
io_pins.pe14.set_low();
|
||||
}
|
||||
else if ecam_col_select == 1 {
|
||||
io_pins.pd12.set_high();
|
||||
io_pins.pd11.set_low();
|
||||
}
|
||||
else if ecam_col_select == 2 {
|
||||
io_pins.pe8.set_high();
|
||||
io_pins.pd12.set_low();
|
||||
}
|
||||
else if ecam_col_select == 3 {
|
||||
io_pins.pb2.set_high();
|
||||
io_pins.pe8.set_low();
|
||||
}
|
||||
else if ecam_col_select == 4 {
|
||||
io_pins.pe10.set_high();
|
||||
io_pins.pb2.set_low();
|
||||
}
|
||||
else if ecam_col_select == 5 {
|
||||
io_pins.pe14.set_high();
|
||||
io_pins.pe10.set_low();
|
||||
}
|
||||
|
||||
ecam_col_select += 1;
|
||||
if ecam_col_select >= 6 {
|
||||
ecam_col_select = 0
|
||||
}
|
||||
|
||||
let report = CustomInputReport {
|
||||
report_id: 1,
|
||||
axis: values_norm,
|
||||
buttons,
|
||||
ecam_buttons,
|
||||
};
|
||||
match consumer.device().write_report(&report) {
|
||||
Err(UsbHidError::WouldBlock) => {}
|
||||
Err(UsbHidError::UsbError(usb_device::UsbError::BufferOverflow)) => {
|
||||
|
@ -446,82 +591,6 @@ fn calculate_factor(min: u16, max: u16) -> f32 {
|
|||
return CalibrationData::ADC_MAX as f32 / (CalibrationData::ADC_MAX - min - (CalibrationData::ADC_MAX - max)) as f32;
|
||||
}
|
||||
|
||||
// Returns a CustomInputReport from the inputs given
|
||||
fn get_report(pins: &mut MyPins, adc1: &mut adc::Adc<pac::ADC1>, cal: &Calibration) -> CustomInputReport {
|
||||
// Read axis
|
||||
let mut values: [u16; 11] = [0; 11];
|
||||
values[0] = adc1.read(&mut pins.pa2).unwrap();
|
||||
values[1] = adc1.read(&mut pins.pa3).unwrap();
|
||||
values[2] = adc1.read(&mut pins.pa5).unwrap();
|
||||
values[3] = adc1.read(&mut pins.pa6).unwrap();
|
||||
values[4] = adc1.read(&mut pins.pa7).unwrap();
|
||||
values[5] = adc1.read(&mut pins.pb0).unwrap();
|
||||
values[6] = adc1.read(&mut pins.pb1).unwrap();
|
||||
values[7] = adc1.read(&mut pins.pc0).unwrap();
|
||||
values[8] = adc1.read(&mut pins.pc1).unwrap();
|
||||
values[9] = adc1.read(&mut pins.pc2).unwrap();
|
||||
values[10] = adc1.read(&mut pins.pc3).unwrap();
|
||||
|
||||
// Apply calibration to axis data
|
||||
let mut values_norm: [u16; 11] = [0; 11];
|
||||
let mut i = 0;
|
||||
loop {
|
||||
if values[i] < cal.data[i].min {
|
||||
values_norm[i] = 0;
|
||||
}
|
||||
else if values[i] > cal.data[i].max {
|
||||
values_norm[i] = CalibrationData::ADC_MAX;
|
||||
}
|
||||
else {
|
||||
values_norm[i] = ((values[i] - cal.data[i].min) as f32 * cal.data[i].factor) as u16;
|
||||
}
|
||||
i += 1;
|
||||
if i == values_norm.len() {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Buttons
|
||||
let mut buttons: u32 = 0;
|
||||
if pins.pa0.is_high() { buttons += 0x1; }
|
||||
if pins.pa1.is_high() { buttons += 0x2; }
|
||||
if pins.pa4.is_high() { buttons += 0x4; }
|
||||
if pins.pa8.is_high() { buttons += 0x8; }
|
||||
if pins.pa9.is_high() { buttons += 0x10; }
|
||||
if pins.pa10.is_high() { buttons += 0x20; }
|
||||
if pins.pb4.is_high() { buttons += 0x40; }
|
||||
if pins.pb5.is_high() { buttons += 0x80; }
|
||||
if pins.pb8.is_high() { buttons += 0x100; }
|
||||
if pins.pb9.is_high() { buttons += 0x200; }
|
||||
if pins.pc4.is_high() { buttons += 0x400; }
|
||||
if pins.pc5.is_high() { buttons += 0x800; }
|
||||
if pins.pc6.is_high() { buttons += 0x1000; }
|
||||
if pins.pc9.is_high() { buttons += 0x0200; }
|
||||
if pins.pc13.is_high() { buttons += 0x4000; }
|
||||
if pins.pc14.is_high() { buttons += 0x8000; }
|
||||
if pins.pc15.is_high() { buttons += 0x10000; }
|
||||
if pins.pd1.is_high() { buttons += 0x20000; }
|
||||
if pins.pd3.is_high() { buttons += 0x40000; }
|
||||
if pins.pd4.is_high() { buttons += 0x80000; }
|
||||
if pins.pd5.is_high() { buttons += 0x100000; }
|
||||
if pins.pd6.is_high() { buttons += 0x200000; }
|
||||
if pins.pd7.is_high() { buttons += 0x400000; }
|
||||
if pins.pd13.is_high() { buttons += 0x800000; }
|
||||
if pins.pd14.is_high() { buttons += 0x1000000; }
|
||||
if pins.pd15.is_high() { buttons += 0x2000000; }
|
||||
if pins.pe0.is_high() { buttons += 0x4000000; }
|
||||
if pins.pe5.is_high() { buttons += 0x8000000; }
|
||||
if pins.pe6.is_high() { buttons += 0x10000000; }
|
||||
|
||||
// ECAM Keyboard matrix
|
||||
|
||||
CustomInputReport {
|
||||
report_id: 1,
|
||||
axis: values_norm,
|
||||
buttons,
|
||||
}
|
||||
}
|
||||
|
||||
// Save calibration to flash
|
||||
fn save_calibration(flash: &mut FlashWriter, cal: &Calibration) -> bool {
|
||||
let mut data: [u8; 1024] = [0; 1024];
|
||||
|
|
Loading…
Reference in a new issue