1use proc_macro2::TokenStream;
2use quote::{format_ident, quote};
3
4use crate::{cfg::GenericProperty, generate_for_each_macro, number};
5
6#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, serde::Deserialize, serde::Serialize)]
8pub(crate) enum RmtChannelCapability {
9 Rx,
10 Tx,
11 RxTx,
12}
13
14#[derive(Debug, Clone, PartialEq, Eq, Hash, serde::Serialize, serde::Deserialize)]
15pub(crate) struct RmtChannelConfig(
16 Vec<RmtChannelCapability>,
18);
19
20impl GenericProperty for RmtChannelConfig {
25 fn macros(&self) -> Option<TokenStream> {
26 let channel_cfgs = self
27 .0
28 .iter()
29 .enumerate()
30 .map(|(num, _)| {
31 let num = number(num);
32 quote! {
33 #num
34 }
35 })
36 .collect::<Vec<_>>();
37
38 let make_channel_cfgs = |filter: fn(RmtChannelCapability) -> bool| {
39 self.0
40 .iter()
41 .enumerate()
42 .filter(|&(_, &cap)| filter(cap))
43 .enumerate()
44 .map(|(idx, (num, _))| {
45 let num = number(num);
46 let idx = number(idx);
47 quote! {
48 #num, #idx
49 }
50 })
51 .collect::<Vec<_>>()
52 };
53
54 let tx_channel_cfgs = make_channel_cfgs(|cap| {
55 matches!(cap, RmtChannelCapability::Tx | RmtChannelCapability::RxTx)
56 });
57 let rx_channel_cfgs = make_channel_cfgs(|cap| {
58 matches!(cap, RmtChannelCapability::Rx | RmtChannelCapability::RxTx)
59 });
60
61 let for_each = generate_for_each_macro(
62 "rmt_channel",
63 &[
64 ("all", &channel_cfgs),
65 ("tx", &tx_channel_cfgs),
66 ("rx", &rx_channel_cfgs),
67 ],
68 );
69
70 Some(quote! {
71 #for_each
93 })
94 }
95}
96
97#[derive(Debug, Clone, PartialEq, Eq, Hash, serde::Serialize, serde::Deserialize)]
98pub(crate) struct RmtClockSourcesConfig {
99 supported: Vec<String>,
100 default: String,
101}
102
103impl GenericProperty for RmtClockSourcesConfig {
104 fn cfgs(&self) -> Option<Vec<String>> {
105 let mut cfgs = Vec::new();
106
107 for value in &self.supported {
108 cfgs.push(format!("rmt_supports_{}_clock", value.to_lowercase()));
109 }
110
111 Some(cfgs)
112 }
113
114 fn macros(&self) -> Option<TokenStream> {
115 let clock_sources = self
116 .supported
117 .iter()
118 .enumerate()
119 .filter(|(_, name)| *name != "None")
120 .map(|(bits, name)| {
121 let src_name = format_ident!("{}", name);
122 let bits = number(bits);
123 quote! {
124 #src_name, #bits
125 }
126 })
127 .collect::<Vec<_>>();
128
129 let default = format_ident!("{}", self.default);
130 let default_clock_source = [quote!( #default )];
131
132 let branches: &[(&str, &[TokenStream])] = if self.supported.len() <= 2 {
133 &[
134 ("all", &clock_sources),
135 ("default", &default_clock_source),
136 ("is_boolean", &[]),
137 ]
138 } else {
139 &[("all", &clock_sources), ("default", &default_clock_source)]
140 };
141
142 Some(generate_for_each_macro("rmt_clock_source", branches))
143 }
144}