rmk_config/
communication.rs

1use crate::usb_interrupt_map::get_usb_info;
2use crate::{BleConfig, ChipModel, ChipSeries, KeyboardTomlConfig};
3
4/// Information about USB interface
5#[derive(Clone, Debug, Default)]
6pub struct UsbInfo {
7    pub dm: String,
8    pub dp: String,
9    pub peripheral_name: String,
10    pub interrupt_name: String,
11}
12
13impl UsbInfo {
14    pub fn new(dm: &str, dp: &str, p: &str, i: &str) -> Self {
15        UsbInfo {
16            dm: dm.to_string(),
17            dp: dp.to_string(),
18            peripheral_name: p.to_string(),
19            interrupt_name: i.to_string(),
20        }
21    }
22
23    pub fn new_default(chip: &ChipModel) -> Self {
24        match chip.series {
25            ChipSeries::Stm32 => UsbInfo::new("PA11", "PA12", "USB_OTG_FS", "USB_FS"),
26            ChipSeries::Nrf52 => UsbInfo::new("", "", "USBD", "USBD"),
27            ChipSeries::Rp2040 => UsbInfo::new("", "", "USB", "USBCTRL_IRQ"),
28            _ => UsbInfo::new(
29                "default_dm",
30                "default_dp",
31                "default_usb_peripheral",
32                "default_usb_interrupt",
33            ),
34        }
35    }
36}
37
38/// Communication configuration enum
39#[derive(Clone, Debug, Default)]
40pub enum CommunicationConfig {
41    // USB only
42    Usb(UsbInfo),
43    // BLE only
44    Ble(BleConfig),
45    // Both USB and BLE
46    Both(UsbInfo, BleConfig),
47    #[default]
48    None,
49}
50
51impl CommunicationConfig {
52    pub fn ble_enabled(&self) -> bool {
53        matches!(self, CommunicationConfig::Ble(_) | CommunicationConfig::Both(_, _))
54    }
55
56    pub fn usb_enabled(&self) -> bool {
57        matches!(self, CommunicationConfig::Usb(_) | CommunicationConfig::Both(_, _))
58    }
59
60    pub fn get_ble_config(&self) -> Option<BleConfig> {
61        match self {
62            CommunicationConfig::Ble(ble_config) | CommunicationConfig::Both(_, ble_config) => Some(ble_config.clone()),
63            _ => None,
64        }
65    }
66
67    pub fn get_usb_info(&self) -> Option<UsbInfo> {
68        match self {
69            CommunicationConfig::Usb(usb_info) | CommunicationConfig::Both(usb_info, _) => Some(usb_info.clone()),
70            _ => None,
71        }
72    }
73}
74
75impl KeyboardTomlConfig {
76    pub fn get_communication_config(&self) -> Result<CommunicationConfig, String> {
77        let usb_enabled = self.keyboard.clone().unwrap_or_default().usb_enable.unwrap_or(false);
78        let chip = self.get_chip_model().unwrap();
79        let usb_info = if usb_enabled { get_usb_info(&chip.chip) } else { None };
80        let ble_config = self.ble.clone();
81
82        match (usb_info, ble_config) {
83            (Some(usb_info), None) => Ok(CommunicationConfig::Usb(usb_info)),
84            (Some(usb_info), Some(ble_config)) => {
85                if !ble_config.enabled {
86                    Ok(CommunicationConfig::Usb(usb_info))
87                } else {
88                    Ok(CommunicationConfig::Both(usb_info, ble_config))
89                }
90            }
91            (None, Some(c)) => {
92                if !c.enabled {
93                    Err("You must enable at least one of usb or ble".to_string())
94                } else {
95                    Ok(CommunicationConfig::Ble(c))
96                }
97            }
98            _ => Err("You must enable at least one of usb or ble".to_string()),
99        }
100    }
101}