use adc::expand_adc_device;
use encoder::expand_encoder_device;
use iqs5xx::expand_iqs5xx_device;
use pmw33xx::expand_pmw33xx_device;
use pmw3610::expand_pmw3610_device;
use proc_macro2::{Ident, TokenStream};
use quote::quote;
use rmk_config::resolved::Hardware;
use rmk_config::resolved::hardware::{
BleConfig, BoardConfig, CommunicationConfig, InputDeviceConfig, UniBodyConfig,
};
pub(crate) mod adc;
pub(crate) mod encoder;
pub(crate) mod iqs5xx;
pub(crate) mod pmw33xx;
pub(crate) mod pmw3610;
pub(crate) struct Initializer {
pub(crate) initializer: TokenStream,
pub(crate) var_name: Ident,
}
pub(crate) fn expand_input_device_config(
hardware: &Hardware,
) -> (TokenStream, Vec<TokenStream>, Vec<TokenStream>) {
let mut initialization = TokenStream::new();
let mut devices = Vec::new();
let mut processors = Vec::new();
let communication = &hardware.communication;
let ble_config = match communication {
CommunicationConfig::Ble(ble_config) | CommunicationConfig::Both(_, ble_config) => {
Some(ble_config.clone())
}
_ => None,
};
let board = &hardware.board;
let chip = &hardware.chip;
let (adc_initializers, adc_processors) = match board {
BoardConfig::UniBody(UniBodyConfig { input_device, .. }) => expand_adc_device(
input_device.clone().joystick.unwrap_or(Vec::new()),
ble_config,
chip.series.clone(),
),
BoardConfig::Split(split_config) => {
let central_ble_config = if split_config.central.battery_adc_pin.is_some() {
if let Some(ref ble_cfg) = ble_config
&& ble_cfg.battery_adc_pin.is_some()
{
let ble_matches = ble_cfg.battery_adc_pin
== split_config.central.battery_adc_pin
&& ble_cfg.adc_divider_measured
== split_config.central.adc_divider_measured
&& ble_cfg.adc_divider_total == split_config.central.adc_divider_total;
if !ble_matches {
eprintln!(
"warning: Battery configuration found in both [ble] and [split.central] sections with different values"
);
eprintln!(
"help: [split.central] configuration will be used. Remove [ble] battery config to avoid confusion."
);
}
}
Some(BleConfig {
enabled: ble_config.as_ref().map(|c| c.enabled).unwrap_or(false),
battery_adc_pin: split_config.central.battery_adc_pin.clone(),
adc_divider_measured: split_config.central.adc_divider_measured,
adc_divider_total: split_config.central.adc_divider_total,
..Default::default()
})
} else {
ble_config
};
expand_adc_device(
split_config
.central
.input_device
.clone()
.unwrap_or(InputDeviceConfig::default())
.joystick
.unwrap_or(Vec::new()),
central_ble_config,
chip.series.clone(),
)
}
};
for initializer in adc_initializers {
initialization.extend(initializer.initializer);
let device_name = initializer.var_name;
devices.push(quote! { #device_name });
}
for initializer in adc_processors {
initialization.extend(initializer.initializer);
let processor_name = initializer.var_name;
processors.push(quote! { #processor_name });
}
let (device_initializer, processor_initializer) = match board {
BoardConfig::UniBody(UniBodyConfig { input_device, .. }) => {
expand_encoder_device(0, input_device.clone().encoder.unwrap_or(Vec::new()), chip)
}
BoardConfig::Split(split_config) => expand_encoder_device(
0,
split_config
.central
.input_device
.clone()
.unwrap_or(InputDeviceConfig::default())
.encoder
.unwrap_or(Vec::new()),
chip,
),
};
for initializer in device_initializer {
initialization.extend(initializer.initializer);
let device_name = initializer.var_name;
devices.push(quote! { #device_name });
}
for initializer in processor_initializer {
initialization.extend(initializer.initializer);
let processor_name = initializer.var_name;
processors.push(quote! { #processor_name });
}
let (pmw3610_device_initializers, pmw3610_processor_initializers) = match board {
BoardConfig::UniBody(UniBodyConfig { input_device, .. }) => {
expand_pmw3610_device(input_device.clone().pmw3610.unwrap_or(Vec::new()), chip)
}
BoardConfig::Split(split_config) => expand_pmw3610_device(
split_config
.central
.input_device
.clone()
.unwrap_or(InputDeviceConfig::default())
.pmw3610
.unwrap_or(Vec::new()),
chip,
),
};
for initializer in pmw3610_device_initializers {
initialization.extend(initializer.initializer);
let device_name = initializer.var_name;
devices.push(quote! { #device_name });
}
for initializer in pmw3610_processor_initializers {
initialization.extend(initializer.initializer);
let processor_name = initializer.var_name;
processors.push(quote! { #processor_name });
}
if let BoardConfig::Split(split_config) = board {
for peripheral in &split_config.peripheral {
let peripheral_pmw3610_config = peripheral
.input_device
.clone()
.unwrap_or(InputDeviceConfig::default())
.pmw3610
.unwrap_or(Vec::new());
let (_, peripheral_pmw3610_processors) =
expand_pmw3610_device(peripheral_pmw3610_config, chip);
for initializer in peripheral_pmw3610_processors {
initialization.extend(initializer.initializer);
let processor_name = initializer.var_name;
processors.push(quote! { #processor_name });
}
}
}
let (pmw33xx_device_initializers, pmw33xx_processor_initializers) = match board {
BoardConfig::UniBody(UniBodyConfig { input_device, .. }) => {
expand_pmw33xx_device(input_device.clone().pmw33xx.unwrap_or(Vec::new()), chip)
}
BoardConfig::Split(split_config) => expand_pmw33xx_device(
split_config
.central
.input_device
.clone()
.unwrap_or(InputDeviceConfig::default())
.pmw33xx
.unwrap_or(Vec::new()),
chip,
),
};
for initializer in pmw33xx_device_initializers {
initialization.extend(initializer.initializer);
let device_name = initializer.var_name;
devices.push(quote! { #device_name });
}
for initializer in pmw33xx_processor_initializers {
initialization.extend(initializer.initializer);
let processor_name = initializer.var_name;
processors.push(quote! { #processor_name });
}
if let BoardConfig::Split(split_config) = board {
for peripheral in &split_config.peripheral {
let peripheral_pmw33xx_config = peripheral
.input_device
.clone()
.unwrap_or(InputDeviceConfig::default())
.pmw33xx
.unwrap_or(Vec::new());
let (_, peripheral_pmw33xx_processors) =
expand_pmw33xx_device(peripheral_pmw33xx_config, chip);
for initializer in peripheral_pmw33xx_processors {
initialization.extend(initializer.initializer);
let processor_name = initializer.var_name;
processors.push(quote! { #processor_name });
}
}
}
let (iqs5xx_device_initializers, iqs5xx_processor_initializers) = match board {
BoardConfig::UniBody(UniBodyConfig { input_device, .. }) => {
expand_iqs5xx_device(input_device.clone().iqs5xx.unwrap_or(Vec::new()), chip)
}
BoardConfig::Split(split_config) => expand_iqs5xx_device(
split_config
.central
.input_device
.clone()
.unwrap_or(InputDeviceConfig::default())
.iqs5xx
.unwrap_or(Vec::new()),
chip,
),
};
for initializer in iqs5xx_device_initializers {
initialization.extend(initializer.initializer);
let device_name = initializer.var_name;
devices.push(quote! { #device_name });
}
for initializer in iqs5xx_processor_initializers {
initialization.extend(initializer.initializer);
let processor_name = initializer.var_name;
processors.push(quote! { #processor_name });
}
if let BoardConfig::Split(split_config) = board {
for peripheral in &split_config.peripheral {
let peripheral_iqs5xx_config = peripheral
.input_device
.clone()
.unwrap_or(InputDeviceConfig::default())
.iqs5xx
.unwrap_or(Vec::new());
let (_, peripheral_iqs5xx_processors) =
expand_iqs5xx_device(peripheral_iqs5xx_config, chip);
for initializer in peripheral_iqs5xx_processors {
initialization.extend(initializer.initializer);
let processor_name = initializer.var_name;
processors.push(quote! { #processor_name });
}
}
}
(initialization, devices, processors)
}