mirror of
https://github.com/esp-rs/esp-hal.git
synced 2025-09-27 12:20:56 +00:00
Move GPIO pin properties to metadata (#3656)
* Reorganize esp-metadata * Move GPIO properties to metadata * Fix AF enum variants, remove need for paste for them
This commit is contained in:
parent
4be232dea4
commit
b98631570f
@ -779,8 +779,8 @@ macro_rules! gpio {
|
||||
$(
|
||||
($gpionum:literal, [$($type:tt),*]
|
||||
$(
|
||||
( $( $af_input_num:literal => $af_input_signal:ident )* )
|
||||
( $( $af_output_num:literal => $af_output_signal:ident )* )
|
||||
( $( $af_input_num:ident => $af_input_signal:ident )* )
|
||||
( $( $af_output_num:ident => $af_output_signal:ident )* )
|
||||
)?
|
||||
)
|
||||
)+
|
||||
@ -834,7 +834,7 @@ macro_rules! gpio {
|
||||
$(
|
||||
$(
|
||||
(
|
||||
$crate::gpio::AlternateFunction::[< _ $af_output_num >],
|
||||
$crate::gpio::AlternateFunction::$af_output_num,
|
||||
$crate::gpio::OutputSignal::$af_output_signal
|
||||
),
|
||||
)*
|
||||
@ -847,7 +847,7 @@ macro_rules! gpio {
|
||||
$(
|
||||
$(
|
||||
(
|
||||
$crate::gpio::AlternateFunction::[< _ $af_input_num >],
|
||||
$crate::gpio::AlternateFunction::$af_input_num,
|
||||
$crate::gpio::InputSignal::$af_input_signal
|
||||
),
|
||||
)*
|
||||
|
@ -25,7 +25,7 @@ macro_rules! peripherals {
|
||||
),* $(,)?
|
||||
],
|
||||
pins: [
|
||||
$( ( $pin:literal, $($pin_tokens:tt)* ) )*
|
||||
$( $pin:literal, )*
|
||||
]
|
||||
) => {
|
||||
paste::paste! {
|
||||
@ -109,10 +109,6 @@ macro_rules! peripherals {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$crate::gpio! {
|
||||
$( ($pin, $($pin_tokens)* ) )*
|
||||
}
|
||||
}
|
||||
|
||||
$(
|
||||
|
@ -83,41 +83,43 @@ crate::peripherals! {
|
||||
DMA_I2S1 <= I2S1,
|
||||
],
|
||||
pins: [
|
||||
(0, [Input, Output, Analog, RtcIo, Touch] (5 => EMAC_TX_CLK) (1 => CLK_OUT1))
|
||||
(1, [Input, Output] (5 => EMAC_RXD2) (0 => U0TXD 1 => CLK_OUT3))
|
||||
(2, [Input, Output, Analog, RtcIo, Touch] (1 => HSPIWP 3 => HS2_DATA0 4 => SD_DATA0) (3 => HS2_DATA0 4 => SD_DATA0))
|
||||
(3, [Input, Output] (0 => U0RXD) (1 => CLK_OUT2))
|
||||
(4, [Input, Output, Analog, RtcIo, Touch] (1 => HSPIHD 3 => HS2_DATA1 4 => SD_DATA1 5 => EMAC_TX_ER) (3 => HS2_DATA1 4 => SD_DATA1))
|
||||
(5, [Input, Output] (1 => VSPICS0 3 => HS1_DATA6 5 => EMAC_RX_CLK) (3 => HS1_DATA6))
|
||||
(6, [Input, Output] (4 => U1CTS) (0 => SD_CLK 1 => SPICLK 3 => HS1_CLK))
|
||||
(7, [Input, Output] (0 => SD_DATA0 1 => SPIQ 3 => HS1_DATA0) (0 => SD_DATA0 1 => SPIQ 3 => HS1_DATA0 4 => U2RTS))
|
||||
(8, [Input, Output] (0 => SD_DATA1 1 => SPID 3 => HS1_DATA1 4 => U2CTS) (0 => SD_DATA1 1 => SPID 3 => HS1_DATA1))
|
||||
(9, [Input, Output] (0 => SD_DATA2 1 => SPIHD 3 => HS1_DATA2 4 => U1RXD) (0 => SD_DATA2 1 => SPIHD 3 => HS1_DATA2))
|
||||
(10, [Input, Output] ( 0 => SD_DATA3 1 => SPIWP 3 => HS1_DATA3) (0 => SD_DATA3 1 => SPIWP 3 => HS1_DATA3 4 => U1TXD))
|
||||
(11, [Input, Output] ( 1 => SPICS0) (0 => SD_CMD 1 => SPICS0 3 => HS1_CMD 4 => U1RTS))
|
||||
(12, [Input, Output, Analog, RtcIo, Touch] (0 => MTDI 1 => HSPIQ 3 => HS2_DATA2 4 => SD_DATA2) (1 => HSPIQ 3 => HS2_DATA2 4 => SD_DATA2 5 => EMAC_TXD3))
|
||||
(13, [Input, Output, Analog, RtcIo, Touch] (0 => MTCK 1 => HSPID 3 => HS2_DATA3 4 => SD_DATA3) (1 => HSPID 3 => HS2_DATA3 4 => SD_DATA3 5 => EMAC_RX_ER))
|
||||
(14, [Input, Output, Analog, RtcIo, Touch] (0 => MTMS 1 => HSPICLK) (1 => HSPICLK 3 => HS2_CLK 4 => SD_CLK 5 => EMAC_TXD2))
|
||||
(15, [Input, Output, Analog, RtcIo, Touch] (1 => HSPICS0 5 => EMAC_RXD3) (0 => MTDO 1 => HSPICS0 3 => HS2_CMD 4 => SD_CMD))
|
||||
(16, [Input, Output] (3 => HS1_DATA4 4 => U2RXD) (3 => HS1_DATA4 5 => EMAC_CLK_OUT))
|
||||
(17, [Input, Output] (3 => HS1_DATA5) (3 => HS1_DATA5 4 => U2TXD 5 => EMAC_CLK_180))
|
||||
(18, [Input, Output] (1 => VSPICLK 3 => HS1_DATA7) (1 => VSPICLK 3 => HS1_DATA7))
|
||||
(19, [Input, Output] (1 => VSPIQ 3 => U0CTS) (1 => VSPIQ 5 => EMAC_TXD0))
|
||||
(20, [Input, Output])
|
||||
(21, [Input, Output] (1 => VSPIHD) (1 => VSPIHD 5 => EMAC_TX_EN))
|
||||
(22, [Input, Output] (1 => VSPIWP) (1 => VSPIWP 3 => U0RTS 5 => EMAC_TXD1))
|
||||
(23, [Input, Output] (1 => VSPID) (1 => VSPID 3 => HS1_STROBE))
|
||||
(24, [Input, Output])
|
||||
(25, [Input, Output, Analog, RtcIo] (5 => EMAC_RXD0) ())
|
||||
(26, [Input, Output, Analog, RtcIo] (5 => EMAC_RXD1) ())
|
||||
(27, [Input, Output, Analog, RtcIo, Touch] (5 => EMAC_RX_DV) ())
|
||||
(32, [Input, Output, Analog, RtcIo, Touch])
|
||||
(33, [Input, Output, Analog, RtcIo, Touch])
|
||||
(34, [Input, Analog, RtcIoInput])
|
||||
(35, [Input, Analog, RtcIoInput])
|
||||
(36, [Input, Analog, RtcIoInput])
|
||||
(37, [Input, Analog, RtcIoInput])
|
||||
(38, [Input, Analog, RtcIoInput])
|
||||
(39, [Input, Analog, RtcIoInput])
|
||||
0,
|
||||
1,
|
||||
2,
|
||||
3,
|
||||
4,
|
||||
5,
|
||||
6,
|
||||
7,
|
||||
8,
|
||||
9,
|
||||
10,
|
||||
11,
|
||||
12,
|
||||
13,
|
||||
14,
|
||||
15,
|
||||
16,
|
||||
17,
|
||||
18,
|
||||
19,
|
||||
20,
|
||||
21,
|
||||
22,
|
||||
23,
|
||||
24,
|
||||
25,
|
||||
26,
|
||||
27,
|
||||
32,
|
||||
33,
|
||||
34,
|
||||
35,
|
||||
36,
|
||||
37,
|
||||
38,
|
||||
39,
|
||||
]
|
||||
}
|
||||
|
||||
include!(concat!(env!("OUT_DIR"), "/_generated_gpio.rs"));
|
||||
|
@ -65,19 +65,21 @@ crate::peripherals! {
|
||||
DMA_CH0 <= virtual,
|
||||
],
|
||||
pins: [
|
||||
(0, [Input, Output, Analog, RtcIo])
|
||||
(1, [Input, Output, Analog, RtcIo])
|
||||
(2, [Input, Output, Analog, RtcIo] (2 => FSPIQ) (2 => FSPIQ))
|
||||
(3, [Input, Output, Analog, RtcIo])
|
||||
(4, [Input, Output, Analog, RtcIo] (2 => FSPIHD) (2 => FSPIHD))
|
||||
(5, [Input, Output, Analog, RtcIo] (2 => FSPIWP) (2 => FSPIWP))
|
||||
(6, [Input, Output] (2 => FSPICLK) (2 => FSPICLK_MUX))
|
||||
(7, [Input, Output] (2 => FSPID) (2 => FSPID))
|
||||
(8, [Input, Output])
|
||||
(9, [Input, Output])
|
||||
(10, [Input, Output] (2 => FSPICS0) (2 => FSPICS0))
|
||||
(18, [Input, Output])
|
||||
(19, [Input, Output])
|
||||
(20, [Input, Output] (0 => U0RXD) ())
|
||||
0,
|
||||
1,
|
||||
2,
|
||||
3,
|
||||
4,
|
||||
5,
|
||||
6,
|
||||
7,
|
||||
8,
|
||||
9,
|
||||
10,
|
||||
18,
|
||||
19,
|
||||
20,
|
||||
]
|
||||
}
|
||||
|
||||
include!(concat!(env!("OUT_DIR"), "/_generated_gpio.rs"));
|
||||
|
@ -75,27 +75,29 @@ crate::peripherals! {
|
||||
DMA_CH2 <= virtual,
|
||||
],
|
||||
pins: [
|
||||
(0, [Input, Output, Analog, RtcIo])
|
||||
(1, [Input, Output, Analog, RtcIo])
|
||||
(2, [Input, Output, Analog, RtcIo] (2 => FSPIQ) (2 => FSPIQ))
|
||||
(3, [Input, Output, Analog, RtcIo])
|
||||
(4, [Input, Output, Analog, RtcIo] (2 => FSPIHD) (0 => USB_JTAG_TMS 2 => FSPIHD))
|
||||
(5, [Input, Output, Analog, RtcIo] (2 => FSPIWP) (0 => USB_JTAG_TDI 2 => FSPIWP))
|
||||
(6, [Input, Output] (2 => FSPICLK) (0 => USB_JTAG_TCK 2 => FSPICLK_MUX))
|
||||
(7, [Input, Output] (2 => FSPID) (0 => USB_JTAG_TDO 2 => FSPID))
|
||||
(8, [Input, Output])
|
||||
(9, [Input, Output])
|
||||
(10, [Input, Output] (2 => FSPICS0) (2 => FSPICS0))
|
||||
(11, [Input, Output])
|
||||
(12, [Input, Output] (0 => SPIHD) (0 => SPIHD))
|
||||
(13, [Input, Output] (0 => SPIWP) (0 => SPIWP))
|
||||
(14, [Input, Output] () (0 => SPICS0))
|
||||
(15, [Input, Output] () (0 => SPICLK_MUX))
|
||||
(16, [Input, Output] (0 => SPID) (0 => SPID))
|
||||
(17, [Input, Output] (0 => SPIQ) (0 => SPIQ))
|
||||
(18, [Input, Output])
|
||||
(19, [Input, Output])
|
||||
(20, [Input, Output] (0 => U0RXD) ())
|
||||
(21, [Input, Output] () (0 => U0TXD))
|
||||
0,
|
||||
1,
|
||||
2,
|
||||
3,
|
||||
4,
|
||||
5,
|
||||
6,
|
||||
7,
|
||||
8,
|
||||
9,
|
||||
10,
|
||||
11,
|
||||
12,
|
||||
13,
|
||||
14,
|
||||
15,
|
||||
16,
|
||||
17,
|
||||
18,
|
||||
19,
|
||||
20,
|
||||
21,
|
||||
]
|
||||
}
|
||||
|
||||
include!(concat!(env!("OUT_DIR"), "/_generated_gpio.rs"));
|
||||
|
@ -111,36 +111,38 @@ crate::peripherals! {
|
||||
DMA_CH2 <= virtual,
|
||||
],
|
||||
pins: [
|
||||
(0, [Input, Output, Analog, RtcIo])
|
||||
(1, [Input, Output, Analog, RtcIo])
|
||||
(2, [Input, Output, Analog, RtcIo] (2 => FSPIQ) (2 => FSPIQ))
|
||||
(3, [Input, Output, Analog, RtcIo])
|
||||
(4, [Input, Output, Analog, RtcIo] (2 => FSPIHD) (0 => USB_JTAG_TMS 2 => FSPIHD))
|
||||
(5, [Input, Output, Analog, RtcIo] (2 => FSPIWP) (0 => USB_JTAG_TDI 2 => FSPIWP))
|
||||
(6, [Input, Output, Analog, RtcIo] (2 => FSPICLK) (0 => USB_JTAG_TCK 2 => FSPICLK_MUX))
|
||||
(7, [Input, Output, Analog, RtcIo] (2 => FSPID) (0 => USB_JTAG_TDO 2 => FSPID))
|
||||
(8, [Input, Output])
|
||||
(9, [Input, Output])
|
||||
(10, [Input, Output])
|
||||
(11, [Input, Output])
|
||||
(12, [Input, Output])
|
||||
(13, [Input, Output])
|
||||
(14, [Input, Output])
|
||||
(15, [Input, Output])
|
||||
(16, [Input, Output] (0 => U0RXD) (2 => FSPICS0))
|
||||
(17, [Input, Output] () (0 => U0TXD 2 => FSPICS1))
|
||||
(18, [Input, Output] () (2 => FSPICS2)) // 0 => SDIO_CMD but there are no signals since it's a fixed pin
|
||||
(19, [Input, Output] () (2 => FSPICS3)) // 0 => SDIO_CLK but there are no signals since it's a fixed pin
|
||||
(20, [Input, Output] () (2 => FSPICS4)) // 0 => SDIO_DATA0 but there are no signals since it's a fixed pin
|
||||
(21, [Input, Output] () (2 => FSPICS5)) // 0 => SDIO_DATA1 but there are no signals since it's a fixed pin
|
||||
(22, [Input, Output] () ()) // 0 => SDIO_DATA2 but there are no signals since it's a fixed pin
|
||||
(23, [Input, Output] () ()) // 0 => SDIO_DATA3 but there are no signals since it's a fixed pin
|
||||
(24, [Input, Output] () (0 => SPICS0))
|
||||
(25, [Input, Output] (0 => SPIQ) (0 => SPIQ))
|
||||
(26, [Input, Output] (0 => SPIWP) (0 => SPIWP))
|
||||
(27, [Input, Output])
|
||||
(28, [Input, Output] (0 => SPIHD) (0 => SPIHD))
|
||||
(29, [Input, Output] () (0 => SPICLK_MUX))
|
||||
(30, [Input, Output] (0 => SPID) (0 => SPID))
|
||||
0,
|
||||
1,
|
||||
2,
|
||||
3,
|
||||
4,
|
||||
5,
|
||||
6,
|
||||
7,
|
||||
8,
|
||||
9,
|
||||
10,
|
||||
11,
|
||||
12,
|
||||
13,
|
||||
14,
|
||||
15,
|
||||
16,
|
||||
17,
|
||||
18,
|
||||
19,
|
||||
20,
|
||||
21,
|
||||
22,
|
||||
23,
|
||||
24,
|
||||
25,
|
||||
26,
|
||||
27,
|
||||
28,
|
||||
29,
|
||||
30,
|
||||
]
|
||||
}
|
||||
|
||||
include!(concat!(env!("OUT_DIR"), "/_generated_gpio.rs"));
|
||||
|
@ -99,33 +99,35 @@ crate::peripherals! {
|
||||
DMA_CH2 <= virtual,
|
||||
],
|
||||
pins: [
|
||||
(0, [Input, Output, Analog] (2 => FSPIQ) (2 => FSPIQ))
|
||||
(1, [Input, Output, Analog] (2 => FSPICS0) (2 => FSPICS0))
|
||||
(2, [Input, Output, Analog] (2 => FSPIWP) (2 => FSPIWP))
|
||||
(3, [Input, Output, Analog] (2 => FSPIHD) (2 => FSPIHD))
|
||||
(4, [Input, Output, Analog] (2 => FSPICLK) (2 => FSPICLK_MUX))
|
||||
(5, [Input, Output, Analog] (2 => FSPID) (2 => FSPID))
|
||||
(6, [Input, Output])
|
||||
(7, [Input, Output])
|
||||
(8, [Input, Output])
|
||||
(9, [Input, Output])
|
||||
(10, [Input, Output])
|
||||
(11, [Input, Output])
|
||||
(12, [Input, Output])
|
||||
(13, [Input, Output])
|
||||
(14, [Input, Output])
|
||||
(15, [Input, Output] () (0 => SPICS0))
|
||||
(16, [Input, Output] (0 => SPIQ) (0 => SPIQ))
|
||||
(17, [Input, Output] (0 => SPIWP) (0 => SPIWP))
|
||||
(18, [Input, Output] (0 => SPIHD) (0 => SPIHD))
|
||||
(19, [Input, Output] () (0 => SPICLK))
|
||||
(20, [Input, Output] (0 => SPID) (0 => SPID))
|
||||
(21, [Input, Output])
|
||||
(22, [Input, Output])
|
||||
(23, [Input, Output] () (2 => FSPICS1))
|
||||
(24, [Input, Output] () (2 => FSPICS2))
|
||||
(25, [Input, Output] () (2 => FSPICS3))
|
||||
(26, [Input, Output] () (2 => FSPICS4))
|
||||
(27, [Input, Output] () (2 => FSPICS5))
|
||||
0,
|
||||
1,
|
||||
2,
|
||||
3,
|
||||
4,
|
||||
5,
|
||||
6,
|
||||
7,
|
||||
8,
|
||||
9,
|
||||
10,
|
||||
11,
|
||||
12,
|
||||
13,
|
||||
14,
|
||||
15,
|
||||
16,
|
||||
17,
|
||||
18,
|
||||
19,
|
||||
20,
|
||||
21,
|
||||
22,
|
||||
23,
|
||||
24,
|
||||
25,
|
||||
26,
|
||||
27,
|
||||
]
|
||||
}
|
||||
|
||||
include!(concat!(env!("OUT_DIR"), "/_generated_gpio.rs"));
|
||||
|
@ -83,49 +83,50 @@ crate::peripherals! {
|
||||
DMA_COPY <= COPY_DMA,
|
||||
],
|
||||
pins: [
|
||||
(0, [Input, Output, Analog, RtcIo])
|
||||
(1, [Input, Output, Analog, RtcIo])
|
||||
(2, [Input, Output, Analog, RtcIo])
|
||||
(3, [Input, Output, Analog, RtcIo])
|
||||
(4, [Input, Output, Analog, RtcIo])
|
||||
(5, [Input, Output, Analog, RtcIo])
|
||||
(6, [Input, Output, Analog, RtcIo])
|
||||
(7, [Input, Output, Analog, RtcIo])
|
||||
(8, [Input, Output, Analog, RtcIo] ( ) ( 3 => SUBSPICS1 ))
|
||||
(9, [Input, Output, Analog, RtcIo] ( 3 => SUBSPIHD 4 => FSPIHD ) ( 3 => SUBSPIHD 4 => FSPIHD ))
|
||||
(10, [Input, Output, Analog, RtcIo] (2 => FSPIIO4 4 => FSPICS0) (2 => FSPIIO4 3 => SUBSPICS0 4 => FSPICS0))
|
||||
(11, [Input, Output, Analog, RtcIo] (2 => FSPIIO5 3 => SUBSPID 4 => FSPID ) (2 => FSPIIO5 3 => SUBSPID 4 => FSPID ))
|
||||
(12, [Input, Output, Analog, RtcIo] (2 => FSPIIO6 4 => FSPICLK) (2 => FSPIIO6 3 => SUBSPICLK 4 => FSPICLK))
|
||||
(13, [Input, Output, Analog, RtcIo] (2 => FSPIIO7 3 => SUBSPIQ 4 => FSPIQ ) (2 => FSPIIO7 3 => SUBSPIQ 4 => FSPIQ ))
|
||||
(14, [Input, Output, Analog, RtcIo] ( 3 => SUBSPIWP 4 => FSPIWP ) (2 => FSPIDQS 3 => SUBSPIWP 4 => FSPIWP ))
|
||||
(15, [Input, Output, Analog, RtcIo] ( ) (2 => U0RTS))
|
||||
(16, [Input, Output, Analog, RtcIo] (2 => U0CTS) ( ))
|
||||
(17, [Input, Output, Analog, RtcIo] ( ) (2 => U1TXD))
|
||||
(18, [Input, Output, Analog, RtcIo] (2 => U1RXD) ( ))
|
||||
(19, [Input, Output, Analog, RtcIo] ( ) (2 => U1RTS))
|
||||
(20, [Input, Output, Analog, RtcIo] (2 => U1CTS) ( ))
|
||||
(21, [Input, Output, Analog, RtcIo])
|
||||
|
||||
(26, [Input, Output])
|
||||
(27, [Input, Output])
|
||||
(28, [Input, Output])
|
||||
(29, [Input, Output])
|
||||
(30, [Input, Output])
|
||||
(31, [Input, Output])
|
||||
(32, [Input, Output])
|
||||
(33, [Input, Output] (2 => FSPIHD 3 => SUBSPIHD ) (2 => FSPIHD 3 => SUBSPIHD ))
|
||||
(34, [Input, Output] (2 => FSPICS0 ) (2 => FSPICS0 3 => SUBSPICS0 ))
|
||||
(35, [Input, Output] (2 => FSPID 3 => SUBSPID ) (2 => FSPID 3 => SUBSPID ))
|
||||
(36, [Input, Output] (2 => FSPICLK ) (2 => FSPICLK 3 => SUBSPICLK ))
|
||||
(37, [Input, Output] (2 => FSPIQ 3 => SUBSPIQ 4 => SPIDQS) (2 => FSPIQ 3 => SUBSPIQ 4 => SPIDQS))
|
||||
(38, [Input, Output] (2 => FSPIWP 3 => SUBSPIWP ) (2 => FSPIWP 3 => SUBSPIWP ))
|
||||
(39, [Input, Output] ( ) ( 3 => SUBSPICS1 ))
|
||||
(40, [Input, Output])
|
||||
(41, [Input, Output])
|
||||
(42, [Input, Output])
|
||||
(43, [Input, Output])
|
||||
(44, [Input, Output])
|
||||
(45, [Input, Output])
|
||||
(46, [Input, Output])
|
||||
0,
|
||||
1,
|
||||
2,
|
||||
3,
|
||||
4,
|
||||
5,
|
||||
6,
|
||||
7,
|
||||
8,
|
||||
9,
|
||||
10,
|
||||
11,
|
||||
12,
|
||||
13,
|
||||
14,
|
||||
15,
|
||||
16,
|
||||
17,
|
||||
18,
|
||||
19,
|
||||
20,
|
||||
21,
|
||||
26,
|
||||
27,
|
||||
28,
|
||||
29,
|
||||
30,
|
||||
31,
|
||||
32,
|
||||
33,
|
||||
34,
|
||||
35,
|
||||
36,
|
||||
37,
|
||||
38,
|
||||
39,
|
||||
40,
|
||||
41,
|
||||
42,
|
||||
43,
|
||||
44,
|
||||
45,
|
||||
46,
|
||||
]
|
||||
}
|
||||
|
||||
include!(concat!(env!("OUT_DIR"), "/_generated_gpio.rs"));
|
||||
|
@ -90,50 +90,52 @@ crate::peripherals! {
|
||||
DMA_CH4 <= virtual,
|
||||
],
|
||||
pins: [
|
||||
(0, [Input, Output, Analog, RtcIo])
|
||||
(1, [Input, Output, Analog, RtcIo])
|
||||
(2, [Input, Output, Analog, RtcIo])
|
||||
(3, [Input, Output, Analog, RtcIo])
|
||||
(4, [Input, Output, Analog, RtcIo])
|
||||
(5, [Input, Output, Analog, RtcIo])
|
||||
(6, [Input, Output, Analog, RtcIo])
|
||||
(7, [Input, Output, Analog, RtcIo])
|
||||
(8, [Input, Output, Analog, RtcIo] () (3 => SUBSPICS1))
|
||||
(9, [Input, Output, Analog, RtcIo] (3 => SUBSPIHD 4 => FSPIHD) (3 => SUBSPIHD 4 => FSPIHD))
|
||||
(10, [Input, Output, Analog, RtcIo] (2 => FSPIIO4 4 => FSPICS0) (2 => FSPIIO4 3 => SUBSPICS0 4 => FSPICS0))
|
||||
(11, [Input, Output, Analog, RtcIo] (2 => FSPIIO5 3 => SUBSPID 4 => FSPID) (2 => FSPIIO5 3 => SUBSPID 4 => FSPID))
|
||||
(12, [Input, Output, Analog, RtcIo] (2 => FSPIIO6 4 => FSPICLK) (2 => FSPIIO6 3=> SUBSPICLK 4 => FSPICLK))
|
||||
(13, [Input, Output, Analog, RtcIo] (2 => FSPIIO7 3 => SUBSPIQ 4 => FSPIQ) (2 => FSPIIO7 3 => SUBSPIQ 4 => FSPIQ))
|
||||
(14, [Input, Output, Analog, RtcIo] (3 => SUBSPIWP 4 => FSPIWP) (2 => FSPIDQS 3 => SUBSPIWP 4 => FSPIWP))
|
||||
(15, [Input, Output, Analog, RtcIo] () (2 => U0RTS))
|
||||
(16, [Input, Output, Analog, RtcIo] (2 => U0CTS) ())
|
||||
(17, [Input, Output, Analog, RtcIo] () (2 => U1TXD))
|
||||
(18, [Input, Output, Analog, RtcIo] (2 => U1RXD) ())
|
||||
(19, [Input, Output, Analog, RtcIo] () (2 => U1RTS))
|
||||
(20, [Input, Output, Analog, RtcIo] (2 => U1CTS) ())
|
||||
(21, [Input, Output, Analog, RtcIo])
|
||||
(26, [Input, Output])
|
||||
(27, [Input, Output])
|
||||
(28, [Input, Output])
|
||||
(29, [Input, Output])
|
||||
(30, [Input, Output])
|
||||
(31, [Input, Output])
|
||||
(32, [Input, Output])
|
||||
(33, [Input, Output] (2 => FSPIHD 3 => SUBSPIHD) (2 => FSPIHD 3 => SUBSPIHD))
|
||||
(34, [Input, Output] (2 => FSPICS0) (2 => FSPICS0 3 => SUBSPICS0))
|
||||
(35, [Input, Output] (2 => FSPID 3 => SUBSPID) (2 => FSPID 3 => SUBSPID))
|
||||
(36, [Input, Output] (2 => FSPICLK) (2 => FSPICLK 3 => SUBSPICLK))
|
||||
(37, [Input, Output] (2 => FSPIQ 3 => SUBSPIQ 4 => SPIDQS) (2 => FSPIQ 3=> SUBSPIQ 4 => SPIDQS))
|
||||
(38, [Input, Output] (2 => FSPIWP 3 => SUBSPIWP) (3 => FSPIWP 3 => SUBSPIWP))
|
||||
(39, [Input, Output] () (4 => SUBSPICS1))
|
||||
(40, [Input, Output])
|
||||
(41, [Input, Output])
|
||||
(42, [Input, Output])
|
||||
(43, [Input, Output])
|
||||
(44, [Input, Output])
|
||||
(45, [Input, Output])
|
||||
(46, [Input, Output])
|
||||
(47, [Input, Output])
|
||||
(48, [Input, Output])
|
||||
0,
|
||||
1,
|
||||
2,
|
||||
3,
|
||||
4,
|
||||
5,
|
||||
6,
|
||||
7,
|
||||
8,
|
||||
9,
|
||||
10,
|
||||
11,
|
||||
12,
|
||||
13,
|
||||
14,
|
||||
15,
|
||||
16,
|
||||
17,
|
||||
18,
|
||||
19,
|
||||
20,
|
||||
21,
|
||||
26,
|
||||
27,
|
||||
28,
|
||||
29,
|
||||
30,
|
||||
31,
|
||||
32,
|
||||
33,
|
||||
34,
|
||||
35,
|
||||
36,
|
||||
37,
|
||||
38,
|
||||
39,
|
||||
40,
|
||||
41,
|
||||
42,
|
||||
43,
|
||||
44,
|
||||
45,
|
||||
46,
|
||||
47,
|
||||
48,
|
||||
]
|
||||
}
|
||||
|
||||
include!(concat!(env!("OUT_DIR"), "/_generated_gpio.rs"));
|
||||
|
@ -104,6 +104,46 @@ instances = [
|
||||
[device.gpio]
|
||||
support_status = "supported"
|
||||
has_bank_1 = true
|
||||
instances = [
|
||||
{ name = "gpio", pins = [
|
||||
{ pin = 0, kind = ["input", "output", "analog", "rtc", "touch"], af_input = { 5 = "EMAC_TX_CLK" }, af_output = { 1 = "CLK_OUT1" } },
|
||||
{ pin = 1, kind = ["input", "output"], af_input = { 5 = "EMAC_RXD2" }, af_output = { 0 = "U0TXD", 1 = "CLK_OUT3" } },
|
||||
{ pin = 2, kind = ["input", "output", "analog", "rtc", "touch"], af_input = { 1 = "HSPIWP", 3 = "HS2_DATA0", 4 = "SD_DATA0" }, af_output = { 3 = "HS2_DATA0", 4 = "SD_DATA0" } },
|
||||
{ pin = 3, kind = ["input", "output"], af_input = { 0 = "U0RXD" }, af_output = { 1 = "CLK_OUT2" } },
|
||||
{ pin = 4, kind = ["input", "output", "analog", "rtc", "touch"], af_input = { 1 = "HSPIHD", 3 = "HS2_DATA1", 4 = "SD_DATA1", 5 = "EMAC_TX_ER" }, af_output = { 3 = "HS2_DATA1", 4 = "SD_DATA1" } },
|
||||
{ pin = 5, kind = ["input", "output"], af_input = { 1 = "VSPICS0", 3 = "HS1_DATA6", 5 = "EMAC_RX_CLK" }, af_output = { 3 = "HS1_DATA6" } },
|
||||
{ pin = 6, kind = ["input", "output"], af_input = { 4 = "U1CTS" }, af_output = { 0 = "SD_CLK", 1 = "SPICLK", 3 = "HS1_CLK" } },
|
||||
{ pin = 7, kind = ["input", "output"], af_input = { 0 = "SD_DATA0", 1 = "SPIQ", 3 = "HS1_DATA0" }, af_output = { 0 = "SD_DATA0", 1 = "SPIQ", 3 = "HS1_DATA0", 4 = "U2RTS"} },
|
||||
{ pin = 8, kind = ["input", "output"], af_input = { 0 = "SD_DATA1", 1 = "SPID", 3 = "HS1_DATA1" }, af_output = { 0 = "SD_DATA1", 1 = "SPID", 3 = "HS1_DATA1"} },
|
||||
{ pin = 9, kind = ["input", "output"], af_input = { 0 = "SD_DATA2", 1 = "SPIHD", 3 = "HS1_DATA2", 4 = "U1RXD" }, af_output = { 0 = "SD_DATA2", 1 = "SPIHD", 3 = "HS1_DATA2" } },
|
||||
{ pin = 10, kind = ["input", "output"], af_input = { 0 = "SD_DATA3", 1 = "SPIWP", 3 = "HS1_DATA3" }, af_output = { 0 = "SD_DATA3", 1 = "SPIWP", 3 = "HS1_DATA3", 4 = "U1TXD" } },
|
||||
{ pin = 11, kind = ["input", "output"], af_input = { 1 = "SPICS0" }, af_output = { 0 = "SD_CMD", 1 = "SPICS0", 3 = "HS1_CMD", 4 = "U1RTS" } },
|
||||
{ pin = 12, kind = ["input", "output", "analog", "rtc", "touch"], af_input = { 0 = "MTDI", 1 = "HSPIQ", 3 = "HS2_DATA2", 4 = "SD_DATA2" }, af_output = { 1 = "HSPIQ", 3 = "HS2_DATA2", 4 = "SD_DATA2", 5 = "EMAC_TXD3" } },
|
||||
{ pin = 13, kind = ["input", "output", "analog", "rtc", "touch"], af_input = { 0 = "MTCK", 1 = "HSPID", 3 = "HS2_DATA3", 4 = "SD_DATA3" }, af_output = { 1 = "HSPID", 3 = "HS2_DATA3", 4 = "SD_DATA3", 5 = "EMAC_RX_ER" } },
|
||||
{ pin = 14, kind = ["input", "output", "analog", "rtc", "touch"], af_input = { 0 = "MTMS", 1 = "HSPICLK" }, af_output = { 1 = "HSPICLK", 3 = "HS2_CLK", 4 = "SD_CLK", 5 = "EMAC_TXD2" } },
|
||||
{ pin = 15, kind = ["input", "output", "analog", "rtc", "touch"], af_input = { 1 = "HSPICS0", 5 = "EMAC_RXD3" }, af_output = { 0 = "MTDO", 1 = "HSPICS0", 3 = "HS2_CMD", 4 = "SD_CMD" } },
|
||||
{ pin = 16, kind = ["input", "output"], af_input = { 3 = "HS1_DATA4", 4 = "U2RXD" }, af_output = { 3 = "HS1_DATA4", 5 = "EMAC_CLK_OUT" } },
|
||||
{ pin = 17, kind = ["input", "output"], af_input = { 3 = "HS1_DATA5" }, af_output = { 3 = "HS1_DATA5", 4 = "U2TXD", 5 = "EMAC_CLK_180" } },
|
||||
{ pin = 18, kind = ["input", "output"], af_input = { 1 = "VSPICLK", 3 = "HS1_DATA7" }, af_output = { 1 = "VSPICLK", 3 = "HS1_DATA7" } },
|
||||
{ pin = 19, kind = ["input", "output"], af_input = { 1 = "VSPIQ", 3 = "U0CTS" }, af_output = { 1 = "VSPIQ", 5 = "EMAC_TXD0" } },
|
||||
{ pin = 20, kind = ["input", "output"] },
|
||||
{ pin = 21, kind = ["input", "output"], af_input = { 1 = "VSPIHD" }, af_output = { 1 = "VSPIHD", 5 = "EMAC_TX_EN" } },
|
||||
{ pin = 22, kind = ["input", "output"], af_input = { 1 = "VSPIWP" }, af_output = { 1 = "VSPIWP", 3 = "U0RTS", 5 = "EMAC_TXD1" } },
|
||||
{ pin = 23, kind = ["input", "output"], af_input = { 1 = "VSPID" }, af_output = { 1 = "VSPID", 3 = "HS1_STROBE" } },
|
||||
{ pin = 24, kind = ["input", "output"] },
|
||||
{ pin = 25, kind = ["input", "output", "analog", "rtc"], af_input = { 5 = "EMAC_RXD0" } },
|
||||
{ pin = 26, kind = ["input", "output", "analog", "rtc"], af_input = { 5 = "EMAC_RXD1" } },
|
||||
{ pin = 27, kind = ["input", "output", "analog", "rtc", "touch"], af_input = { 5 = "EMAC_RX_DV" } },
|
||||
{ pin = 32, kind = ["input", "output", "analog", "rtc", "touch"] },
|
||||
{ pin = 33, kind = ["input", "output", "analog", "rtc", "touch"] },
|
||||
{ pin = 34, kind = ["input", "analog", "rtc"] },
|
||||
{ pin = 35, kind = ["input", "analog", "rtc"] },
|
||||
{ pin = 36, kind = ["input", "analog", "rtc"] },
|
||||
{ pin = 37, kind = ["input", "analog", "rtc"] },
|
||||
{ pin = 38, kind = ["input", "analog", "rtc"] },
|
||||
{ pin = 39, kind = ["input", "analog", "rtc"] },
|
||||
] },
|
||||
]
|
||||
|
||||
[device.i2c_master]
|
||||
support_status = "supported"
|
||||
|
@ -72,6 +72,24 @@ instances = [
|
||||
|
||||
[device.gpio]
|
||||
support_status = "supported"
|
||||
instances = [
|
||||
{ name = "gpio", pins = [
|
||||
{ pin = 0, kind = ["input", "output", "analog", "rtc"] },
|
||||
{ pin = 1, kind = ["input", "output", "analog", "rtc"] },
|
||||
{ pin = 2, kind = ["input", "output", "analog", "rtc"], af_input = { 2 = "FSPIQ" }, af_output = { 2 = "FSPIQ" } },
|
||||
{ pin = 3, kind = ["input", "output", "analog", "rtc"] },
|
||||
{ pin = 4, kind = ["input", "output", "analog", "rtc"], af_input = { 2 = "FSPIHD" }, af_output = { 2 = "FSPIHD" } },
|
||||
{ pin = 5, kind = ["input", "output", "analog", "rtc"], af_input = { 2 = "FSPIWP" }, af_output = { 2 = "FSPIWP" } },
|
||||
{ pin = 6, kind = ["input", "output"], af_input = { 2 = "FSPICLK" }, af_output = { 2 = "FSPICLK_MUX" } },
|
||||
{ pin = 7, kind = ["input", "output"], af_input = { 2 = "FSPID" }, af_output = { 2 = "FSPID" } },
|
||||
{ pin = 8, kind = ["input", "output"] },
|
||||
{ pin = 9, kind = ["input", "output"] },
|
||||
{ pin = 10, kind = ["input", "output"], af_input = { 2 = "FSPICS0" }, af_output = { 2 = "FSPICS0" } },
|
||||
{ pin = 18, kind = ["input", "output"] },
|
||||
{ pin = 19, kind = ["input", "output"] },
|
||||
{ pin = 20, kind = ["input", "output"], af_input = { 0 = "U0RXD" } },
|
||||
] },
|
||||
]
|
||||
|
||||
[device.i2c_master]
|
||||
support_status = "supported"
|
||||
|
@ -87,6 +87,32 @@ instances = [
|
||||
|
||||
[device.gpio]
|
||||
support_status = "supported"
|
||||
instances = [
|
||||
{ name = "gpio", pins = [
|
||||
{ pin = 0, kind = ["input", "output", "analog", "rtc"] },
|
||||
{ pin = 1, kind = ["input", "output", "analog", "rtc"] },
|
||||
{ pin = 2, kind = ["input", "output", "analog", "rtc"], af_input = { 2 = "FSPIQ" }, af_output = { 2 = "FSPIQ" } },
|
||||
{ pin = 3, kind = ["input", "output", "analog", "rtc"] },
|
||||
{ pin = 4, kind = ["input", "output", "analog", "rtc"], af_input = { 2 = "FSPIHD" }, af_output = { 0 = "USB_JTAG_TMS", 2 = "FSPIHD" } },
|
||||
{ pin = 5, kind = ["input", "output", "analog", "rtc"], af_input = { 2 = "FSPIWP" }, af_output = { 0 = "USB_JTAG_TDI", 2 = "FSPIWP" } },
|
||||
{ pin = 6, kind = ["input", "output"], af_input = { 2 = "FSPICLK" }, af_output = { 0 = "USB_JTAG_TCK", 2 = "FSPICLK_MUX" } },
|
||||
{ pin = 7, kind = ["input", "output"], af_input = { 2 = "FSPID" }, af_output = { 0 = "USB_JTAG_TDO", 2 = "FSPID" } },
|
||||
{ pin = 8, kind = ["input", "output"] },
|
||||
{ pin = 9, kind = ["input", "output"] },
|
||||
{ pin = 10, kind = ["input", "output"], af_input = { 2 = "FSPICS0" }, af_output = { 2 = "FSPICS0" } },
|
||||
{ pin = 11, kind = ["input", "output"] },
|
||||
{ pin = 12, kind = ["input", "output"], af_input = { 0 = "SPIHD" }, af_output = { 0 = "SPIHD" } },
|
||||
{ pin = 13, kind = ["input", "output"], af_input = { 0 = "SPIWP" }, af_output = { 0 = "SPIWP" } },
|
||||
{ pin = 14, kind = ["input", "output"], af_output = { 0 = "SPICS0" } },
|
||||
{ pin = 15, kind = ["input", "output"], af_output = { 0 = "SPICLK_MUX" } },
|
||||
{ pin = 16, kind = ["input", "output"], af_input = { 0 = "SPID" }, af_output = { 0 = "SPID" } },
|
||||
{ pin = 17, kind = ["input", "output"], af_input = { 0 = "SPIQ" }, af_output = { 0 = "SPIQ" } },
|
||||
{ pin = 18, kind = ["input", "output"] },
|
||||
{ pin = 19, kind = ["input", "output"] },
|
||||
{ pin = 20, kind = ["input", "output"], af_input = { 0 = "U0RXD" } },
|
||||
{ pin = 21, kind = ["input", "output"], af_output = { 0 = "U0TXD" } },
|
||||
] },
|
||||
]
|
||||
|
||||
[device.i2c_master]
|
||||
support_status = "supported"
|
||||
|
@ -115,6 +115,41 @@ instances = [
|
||||
|
||||
[device.gpio]
|
||||
support_status = "supported"
|
||||
instances = [
|
||||
{ name = "gpio", pins = [
|
||||
{ pin = 0, kind = ["input", "output", "analog", "rtc"] },
|
||||
{ pin = 1, kind = ["input", "output", "analog", "rtc"] },
|
||||
{ pin = 2, kind = ["input", "output", "analog", "rtc"], af_input = { 2 = "FSPIQ" }, af_output = { 2 = "FSPIQ" } },
|
||||
{ pin = 3, kind = ["input", "output", "analog", "rtc"] },
|
||||
{ pin = 4, kind = ["input", "output", "analog", "rtc"], af_input = { 2 = "FSPIHD" }, af_output = { 0 = "USB_JTAG_TMS", 2 = "FSPIHD" } },
|
||||
{ pin = 5, kind = ["input", "output", "analog", "rtc"], af_input = { 2 = "FSPIWP" }, af_output = { 0 = "USB_JTAG_TDI", 2 = "FSPIWP" } },
|
||||
{ pin = 6, kind = ["input", "output"], af_input = { 2 = "FSPICLK" }, af_output = { 0 = "USB_JTAG_TCK", 2 = "FSPICLK_MUX" } },
|
||||
{ pin = 7, kind = ["input", "output"], af_input = { 2 = "FSPID" }, af_output = { 0 = "USB_JTAG_TDO", 2 = "FSPID" } },
|
||||
{ pin = 8, kind = ["input", "output"] },
|
||||
{ pin = 9, kind = ["input", "output"] },
|
||||
{ pin = 10, kind = ["input", "output"] },
|
||||
{ pin = 11, kind = ["input", "output"] },
|
||||
{ pin = 12, kind = ["input", "output"] },
|
||||
{ pin = 13, kind = ["input", "output"] },
|
||||
{ pin = 14, kind = ["input", "output"] },
|
||||
{ pin = 15, kind = ["input", "output"] },
|
||||
{ pin = 16, kind = ["input", "output"], af_input = { 0 = "U0RXD" }, af_output = { 2 = "FSPICS0" } },
|
||||
{ pin = 17, kind = ["input", "output"], af_output = { 0 = "U0TXD", 2 = "FSPICS1" } },
|
||||
{ pin = 18, kind = ["input", "output"], af_output = { 2 = "FSPICS2" } },
|
||||
{ pin = 19, kind = ["input", "output"], af_output = { 2 = "FSPICS3" } },
|
||||
{ pin = 20, kind = ["input", "output"], af_output = { 2 = "FSPICS4" } },
|
||||
{ pin = 21, kind = ["input", "output"], af_output = { 2 = "FSPICS5" } },
|
||||
{ pin = 22, kind = ["input", "output"] },
|
||||
{ pin = 23, kind = ["input", "output"] },
|
||||
{ pin = 24, kind = ["input", "output"], af_output = { 0 = "SPICS0" } },
|
||||
{ pin = 25, kind = ["input", "output"], af_input = { 0 = "SPIQ" }, af_output = { 0 = "SPIQ" } },
|
||||
{ pin = 26, kind = ["input", "output"], af_input = { 0 = "SPIWP" }, af_output = { 0 = "SPIWP" } },
|
||||
{ pin = 27, kind = ["input", "output"] },
|
||||
{ pin = 28, kind = ["input", "output"], af_input = { 0 = "SPIHD" }, af_output = { 0 = "SPIHD" } },
|
||||
{ pin = 29, kind = ["input", "output"], af_output = { 0 = "SPICLK_MUX" } },
|
||||
{ pin = 30, kind = ["input", "output"], af_input = { 0 = "SPID" }, af_output = { 0 = "SPID" } },
|
||||
] },
|
||||
]
|
||||
|
||||
[device.i2c_master]
|
||||
support_status = "supported"
|
||||
|
@ -98,6 +98,38 @@ instances = [
|
||||
|
||||
[device.gpio]
|
||||
support_status = "supported"
|
||||
instances = [
|
||||
{ name = "gpio", pins = [
|
||||
{ pin = 0, kind = ["input", "output", "analog"], af_input = { 2 = "FSPIQ" }, af_output = { 2 = "FSPIQ" } },
|
||||
{ pin = 1, kind = ["input", "output", "analog"], af_input = { 2 = "FSPICS0" }, af_output = { 2 = "FSPICS0" } },
|
||||
{ pin = 2, kind = ["input", "output", "analog"], af_input = { 2 = "FSPIWP" }, af_output = { 2 = "FSPIWP" } },
|
||||
{ pin = 3, kind = ["input", "output", "analog"], af_input = { 2 = "FSPIHD" }, af_output = { 2 = "FSPIHD" } },
|
||||
{ pin = 4, kind = ["input", "output", "analog"], af_input = { 2 = "FSPICLK" }, af_output = { 2 = "FSPICLK_MUX" } },
|
||||
{ pin = 5, kind = ["input", "output", "analog"], af_input = { 2 = "FSPID" }, af_output = { 2 = "FSPID" } },
|
||||
{ pin = 6, kind = ["input", "output"] },
|
||||
{ pin = 7, kind = ["input", "output"] },
|
||||
{ pin = 8, kind = ["input", "output"] },
|
||||
{ pin = 9, kind = ["input", "output"] },
|
||||
{ pin = 10, kind = ["input", "output"] },
|
||||
{ pin = 11, kind = ["input", "output"] },
|
||||
{ pin = 12, kind = ["input", "output"] },
|
||||
{ pin = 13, kind = ["input", "output"] },
|
||||
{ pin = 14, kind = ["input", "output"] },
|
||||
{ pin = 15, kind = ["input", "output"], af_output = { 0 = "SPICS0" } },
|
||||
{ pin = 16, kind = ["input", "output"], af_input = { 0 = "SPIQ" }, af_output = { 0 = "SPIQ" } },
|
||||
{ pin = 17, kind = ["input", "output"], af_input = { 0 = "SPIWP" }, af_output = { 0 = "SPIWP" } },
|
||||
{ pin = 18, kind = ["input", "output"], af_input = { 0 = "SPIHD" }, af_output = { 0 = "SPIHD" } },
|
||||
{ pin = 19, kind = ["input", "output"], af_output = { 0 = "SPICLK" } },
|
||||
{ pin = 20, kind = ["input", "output"], af_input = { 0 = "SPID" }, af_output = { 0 = "SPID" } },
|
||||
{ pin = 21, kind = ["input", "output"] },
|
||||
{ pin = 22, kind = ["input", "output"] },
|
||||
{ pin = 23, kind = ["input", "output"], af_output = { 2 = "FSPICS1" } },
|
||||
{ pin = 24, kind = ["input", "output"], af_output = { 2 = "FSPICS2" } },
|
||||
{ pin = 25, kind = ["input", "output"], af_output = { 2 = "FSPICS3" } },
|
||||
{ pin = 26, kind = ["input", "output"], af_output = { 2 = "FSPICS4" } },
|
||||
{ pin = 27, kind = ["input", "output"], af_output = { 2 = "FSPICS5" } },
|
||||
] },
|
||||
]
|
||||
|
||||
[device.i2c_master]
|
||||
support_status = "supported"
|
||||
|
@ -104,7 +104,54 @@ instances = [
|
||||
[device.gpio]
|
||||
support_status = "supported"
|
||||
has_bank_1 = true
|
||||
instances = [
|
||||
{ name = "gpio", pins = [
|
||||
{ pin = 0, kind = ["input", "output", "analog", "rtc"] },
|
||||
{ pin = 1, kind = ["input", "output", "analog", "rtc"] },
|
||||
{ pin = 2, kind = ["input", "output", "analog", "rtc"] },
|
||||
{ pin = 3, kind = ["input", "output", "analog", "rtc"] },
|
||||
{ pin = 4, kind = ["input", "output", "analog", "rtc"] },
|
||||
{ pin = 5, kind = ["input", "output", "analog", "rtc"] },
|
||||
{ pin = 6, kind = ["input", "output", "analog", "rtc"] },
|
||||
{ pin = 7, kind = ["input", "output", "analog", "rtc"] },
|
||||
{ pin = 8, kind = ["input", "output", "analog", "rtc"], af_output = { 3 = "SUBSPICS1" } },
|
||||
{ pin = 9, kind = ["input", "output", "analog", "rtc"], af_input = { 3 = "SUBSPIHD", 4 = "FSPIHD" }, af_output = { 3 = "SUBSPIHD", 4 = "FSPIHD" } },
|
||||
{ pin = 10, kind = ["input", "output", "analog", "rtc"], af_input = { 2 = "FSPIIO4", 4 = "FSPICS0" }, af_output = { 2 = "FSPIIO4", 3 = "SUBSPICS0", 4 = "FSPICS0" } },
|
||||
{ pin = 11, kind = ["input", "output", "analog", "rtc"], af_input = { 2 = "FSPIIO5", 3 = "SUBSPID", 4 = "FSPID" }, af_output = { 2 = "FSPIIO5", 3 = "SUBSPID", 4 = "FSPID" } },
|
||||
{ pin = 12, kind = ["input", "output", "analog", "rtc"], af_input = { 2 = "FSPIIO6", 4 = "FSPICLK" }, af_output = { 2 = "FSPIIO6", 3 = "SUBSPICLK", 4 = "FSPICLK" } },
|
||||
{ pin = 13, kind = ["input", "output", "analog", "rtc"], af_input = { 2 = "FSPIIO7", 3 = "SUBSPIQ", 4 = "FSPIQ" }, af_output = { 2 = "FSPIIO7", 3 = "SUBSPIQ", 4 = "FSPIQ" } },
|
||||
{ pin = 14, kind = ["input", "output", "analog", "rtc"], af_input = { 3 = "SUBSPIWP", 4 = "FSPIWP" }, af_output = { 2 = "FSPIDQS", 3 = "SUBSPIWP", 4 = "FSPIWP" } },
|
||||
{ pin = 15, kind = ["input", "output", "analog", "rtc"], af_output = { 2 = "U0RTS" } },
|
||||
{ pin = 16, kind = ["input", "output", "analog", "rtc"], af_input = { 2 = "U0CTS" } },
|
||||
{ pin = 17, kind = ["input", "output", "analog", "rtc"], af_output = { 2 = "U1TXD" } },
|
||||
{ pin = 18, kind = ["input", "output", "analog", "rtc"], af_input = { 2 = "U1RXD" } },
|
||||
{ pin = 19, kind = ["input", "output", "analog", "rtc"], af_output = { 2 = "U1RTS" } },
|
||||
{ pin = 20, kind = ["input", "output", "analog", "rtc"], af_input = { 2 = "U1CTS" } },
|
||||
{ pin = 21, kind = ["input", "output", "analog", "rtc"] },
|
||||
|
||||
{ pin = 26, kind = ["input", "output"] },
|
||||
{ pin = 27, kind = ["input", "output"] },
|
||||
{ pin = 28, kind = ["input", "output"] },
|
||||
{ pin = 29, kind = ["input", "output"] },
|
||||
{ pin = 30, kind = ["input", "output"] },
|
||||
{ pin = 31, kind = ["input", "output"] },
|
||||
{ pin = 32, kind = ["input", "output"] },
|
||||
{ pin = 33, kind = ["input", "output"], af_input = { 2 = "FSPIHD", 3 = "SUBSPIHD" }, af_output = { 2 = "FSPIHD", 3 = "SUBSPIHD" } },
|
||||
{ pin = 34, kind = ["input", "output"], af_input = { 2 = "FSPICS0" }, af_output = { 2 = "FSPICS0", 3 = "SUBSPICS0" } },
|
||||
{ pin = 35, kind = ["input", "output"], af_input = { 2 = "FSPID", 3 = "SUBSPID" }, af_output = { 2 = "FSPID", 3 = "SUBSPID" } },
|
||||
{ pin = 36, kind = ["input", "output"], af_input = { 2 = "FSPICLK" }, af_output = { 2 = "FSPICLK", 3 = "SUBSPICLK" } },
|
||||
{ pin = 37, kind = ["input", "output"], af_input = { 2 = "FSPIQ", 3 = "SUBSPIQ", 4 = "SPIDQS" }, af_output = { 2 = "FSPIQ", 3 = "SUBSPIQ", 4 = "SPIDQS" } },
|
||||
{ pin = 38, kind = ["input", "output"], af_input = { 2 = "FSPIWP", 3 = "SUBSPIWP" }, af_output = { 2 = "FSPIWP", 3 = "SUBSPIWP" } },
|
||||
{ pin = 39, kind = ["input", "output"], af_output = { 3 = "SUBSPICS1" } },
|
||||
{ pin = 40, kind = ["input", "output"] },
|
||||
{ pin = 41, kind = ["input", "output"] },
|
||||
{ pin = 42, kind = ["input", "output"] },
|
||||
{ pin = 43, kind = ["input", "output"] },
|
||||
{ pin = 44, kind = ["input", "output"] },
|
||||
{ pin = 45, kind = ["input", "output"] },
|
||||
{ pin = 46, kind = ["input", "output"] },
|
||||
] },
|
||||
]
|
||||
[device.i2c_master]
|
||||
support_status = "supported"
|
||||
instances = [{ name = "i2c0" }, { name = "i2c1" }]
|
||||
|
@ -112,6 +112,56 @@ instances = [
|
||||
[device.gpio]
|
||||
support_status = "supported"
|
||||
has_bank_1 = true
|
||||
instances = [
|
||||
{ name = "gpio", pins = [
|
||||
{ pin = 0, kind = ["input", "output", "analog", "rtc"] },
|
||||
{ pin = 1, kind = ["input", "output", "analog", "rtc"] },
|
||||
{ pin = 2, kind = ["input", "output", "analog", "rtc"] },
|
||||
{ pin = 3, kind = ["input", "output", "analog", "rtc"] },
|
||||
{ pin = 4, kind = ["input", "output", "analog", "rtc"] },
|
||||
{ pin = 5, kind = ["input", "output", "analog", "rtc"] },
|
||||
{ pin = 6, kind = ["input", "output", "analog", "rtc"] },
|
||||
{ pin = 7, kind = ["input", "output", "analog", "rtc"] },
|
||||
{ pin = 8, kind = ["input", "output", "analog", "rtc"], af_output = { 3 = "SUBSPICS1" } },
|
||||
{ pin = 9, kind = ["input", "output", "analog", "rtc"], af_input = { 3 = "SUBSPIHD", 4 = "FSPIHD" }, af_output = { 3 = "SUBSPIHD", 4 = "FSPIHD" } },
|
||||
{ pin = 10, kind = ["input", "output", "analog", "rtc"], af_input = { 2 = "FSPIIO4", 4 = "FSPICS0" }, af_output = { 2 = "FSPIIO4", 3 = "SUBSPICS0", 4 = "FSPICS0" } },
|
||||
{ pin = 11, kind = ["input", "output", "analog", "rtc"], af_input = { 2 = "FSPIIO5", 3 = "SUBSPID", 4 = "FSPID" }, af_output = { 2 = "FSPIIO5", 3 = "SUBSPID", 4 = "FSPID" } },
|
||||
{ pin = 12, kind = ["input", "output", "analog", "rtc"], af_input = { 2 = "FSPIIO6", 4 = "FSPICLK" }, af_output = { 2 = "FSPIIO6", 3 = "SUBSPICLK", 4 = "FSPICLK" } },
|
||||
{ pin = 13, kind = ["input", "output", "analog", "rtc"], af_input = { 2 = "FSPIIO7", 3 = "SUBSPIQ", 4 = "FSPIQ" }, af_output = { 2 = "FSPIIO7", 3 = "SUBSPIQ", 4 = "FSPIQ" } },
|
||||
{ pin = 14, kind = ["input", "output", "analog", "rtc"], af_input = { 3 = "SUBSPIWP", 4 = "FSPIWP" }, af_output = { 2 = "FSPIDQS", 3 = "SUBSPIWP", 4 = "FSPIWP" } },
|
||||
{ pin = 15, kind = ["input", "output", "analog", "rtc"], af_output = { 2 = "U0RTS" } },
|
||||
{ pin = 16, kind = ["input", "output", "analog", "rtc"], af_input = { 2 = "U0CTS" } },
|
||||
{ pin = 17, kind = ["input", "output", "analog", "rtc"], af_output = { 2 = "U1TXD" } },
|
||||
{ pin = 18, kind = ["input", "output", "analog", "rtc"], af_input = { 2 = "U1RXD" } },
|
||||
{ pin = 19, kind = ["input", "output", "analog", "rtc"], af_output = { 2 = "U1RTS" } },
|
||||
{ pin = 20, kind = ["input", "output", "analog", "rtc"], af_input = { 2 = "U1CTS" } },
|
||||
{ pin = 21, kind = ["input", "output", "analog", "rtc"] },
|
||||
|
||||
{ pin = 26, kind = ["input", "output"] },
|
||||
{ pin = 27, kind = ["input", "output"] },
|
||||
{ pin = 28, kind = ["input", "output"] },
|
||||
{ pin = 29, kind = ["input", "output"] },
|
||||
{ pin = 30, kind = ["input", "output"] },
|
||||
{ pin = 31, kind = ["input", "output"] },
|
||||
{ pin = 32, kind = ["input", "output"] },
|
||||
{ pin = 33, kind = ["input", "output"], af_input = { 2 = "FSPIHD", 3 = "SUBSPIHD" }, af_output = { 2 = "FSPIHD", 3 = "SUBSPIHD" } },
|
||||
{ pin = 34, kind = ["input", "output"], af_input = { 2 = "FSPICS0" }, af_output = { 2 = "FSPICS0", 3 = "SUBSPICS0" } },
|
||||
{ pin = 35, kind = ["input", "output"], af_input = { 2 = "FSPID", 3 = "SUBSPID" }, af_output = { 2 = "FSPID", 3 = "SUBSPID" } },
|
||||
{ pin = 36, kind = ["input", "output"], af_input = { 2 = "FSPICLK" }, af_output = { 2 = "FSPICLK", 3 = "SUBSPICLK" } },
|
||||
{ pin = 37, kind = ["input", "output"], af_input = { 2 = "FSPIQ", 3 = "SUBSPIQ", 4 = "SPIDQS" }, af_output = { 2 = "FSPIQ", 3 = "SUBSPIQ", 4 = "SPIDQS" } },
|
||||
{ pin = 38, kind = ["input", "output"], af_input = { 2 = "FSPIWP", 3 = "SUBSPIWP" }, af_output = { 2 = "FSPIWP", 3 = "SUBSPIWP" } },
|
||||
{ pin = 39, kind = ["input", "output"], af_output = { 3 = "SUBSPICS1" } },
|
||||
{ pin = 40, kind = ["input", "output"] },
|
||||
{ pin = 41, kind = ["input", "output"] },
|
||||
{ pin = 42, kind = ["input", "output"] },
|
||||
{ pin = 43, kind = ["input", "output"] },
|
||||
{ pin = 44, kind = ["input", "output"] },
|
||||
{ pin = 45, kind = ["input", "output"] },
|
||||
{ pin = 46, kind = ["input", "output"] },
|
||||
{ pin = 47, kind = ["input", "output"] },
|
||||
{ pin = 48, kind = ["input", "output"] },
|
||||
] },
|
||||
]
|
||||
|
||||
[device.i2c_master]
|
||||
support_status = "supported"
|
||||
|
577
esp-metadata/src/cfg.rs
Normal file
577
esp-metadata/src/cfg.rs
Normal file
@ -0,0 +1,577 @@
|
||||
/// Represents a value in the driver configuration.
|
||||
pub(crate) enum Value {
|
||||
Unset,
|
||||
/// A numeric value. The generated macro will not include a type suffix
|
||||
/// (i.e. will not be generated as `0u32`).
|
||||
Number(u32),
|
||||
/// A boolean value. If true, the value is included in the cfg symbols.
|
||||
Boolean(bool),
|
||||
}
|
||||
|
||||
impl From<u32> for Value {
|
||||
fn from(value: u32) -> Self {
|
||||
Value::Number(value)
|
||||
}
|
||||
}
|
||||
impl From<Option<u32>> for Value {
|
||||
fn from(value: Option<u32>) -> Self {
|
||||
match value {
|
||||
Some(v) => Value::Number(v),
|
||||
None => Value::Unset,
|
||||
}
|
||||
}
|
||||
}
|
||||
impl From<bool> for Value {
|
||||
fn from(value: bool) -> Self {
|
||||
Value::Boolean(value)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Default, Clone, Copy, serde::Deserialize, serde::Serialize)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub(crate) enum SupportStatus {
|
||||
NotSupported,
|
||||
#[default] // Just the common option to reduce visual noise of "declare only" drivers.
|
||||
Partial,
|
||||
Supported,
|
||||
}
|
||||
|
||||
impl SupportStatus {
|
||||
pub fn icon(self) -> &'static str {
|
||||
match self {
|
||||
SupportStatus::NotSupported => "❌",
|
||||
SupportStatus::Partial => "⚒️",
|
||||
SupportStatus::Supported => "✔️",
|
||||
}
|
||||
}
|
||||
|
||||
pub fn status(self) -> &'static str {
|
||||
match self {
|
||||
SupportStatus::NotSupported => "Not supported",
|
||||
SupportStatus::Partial => "Partial support",
|
||||
SupportStatus::Supported => "Supported",
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// An empty configuration, used when a driver just wants to declare that
|
||||
/// it supports a peripheral, but does not have any configuration options.
|
||||
#[derive(Debug, Default, Clone, serde::Deserialize, serde::Serialize)]
|
||||
pub(crate) struct EmptyInstanceConfig {}
|
||||
|
||||
#[derive(Debug, Clone, serde::Deserialize, serde::Serialize)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub(crate) enum PinCapability {
|
||||
Input,
|
||||
Output,
|
||||
Analog,
|
||||
Rtc,
|
||||
Touch,
|
||||
}
|
||||
|
||||
#[derive(Debug, Default, Clone, serde::Deserialize, serde::Serialize)]
|
||||
pub(crate) struct AfMap {
|
||||
#[serde(rename = "0")]
|
||||
af0: Option<String>,
|
||||
#[serde(rename = "1")]
|
||||
af1: Option<String>,
|
||||
#[serde(rename = "2")]
|
||||
af2: Option<String>,
|
||||
#[serde(rename = "3")]
|
||||
af3: Option<String>,
|
||||
#[serde(rename = "4")]
|
||||
af4: Option<String>,
|
||||
#[serde(rename = "5")]
|
||||
af5: Option<String>,
|
||||
}
|
||||
|
||||
impl AfMap {
|
||||
pub fn get(&self, af: usize) -> Option<&str> {
|
||||
match af {
|
||||
0 => self.af0.as_deref(),
|
||||
1 => self.af1.as_deref(),
|
||||
2 => self.af2.as_deref(),
|
||||
3 => self.af3.as_deref(),
|
||||
4 => self.af4.as_deref(),
|
||||
5 => self.af5.as_deref(),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Default, Clone, serde::Deserialize, serde::Serialize)]
|
||||
pub(crate) struct PinConfig {
|
||||
/// The GPIO pin number.
|
||||
pub pin: usize,
|
||||
pub kind: Vec<PinCapability>,
|
||||
// Pin => InputSignal
|
||||
#[serde(default)]
|
||||
pub af_input: AfMap,
|
||||
// Pin => OutputSignal
|
||||
#[serde(default)]
|
||||
pub af_output: AfMap,
|
||||
}
|
||||
|
||||
#[derive(Debug, Default, Clone, serde::Deserialize, serde::Serialize)]
|
||||
pub(crate) struct GpioInstanceConfig {
|
||||
pub pins: Vec<PinConfig>,
|
||||
}
|
||||
|
||||
/// A peripheral instance for which a driver is implemented.
|
||||
#[derive(Debug, Default, Clone, serde::Deserialize, serde::Serialize)]
|
||||
pub(crate) struct PeriInstance<I = EmptyInstanceConfig> {
|
||||
/// The name of the instance
|
||||
pub name: String,
|
||||
#[serde(flatten)]
|
||||
pub instance_config: I,
|
||||
}
|
||||
|
||||
pub(crate) struct SupportItem {
|
||||
pub name: &'static str,
|
||||
pub config_group: &'static str,
|
||||
pub symbols: &'static [&'static str],
|
||||
}
|
||||
|
||||
/// Define driver configuration structs, and a PeriConfig struct
|
||||
/// that contains all of them.
|
||||
macro_rules! driver_configs {
|
||||
// Creates a single struct
|
||||
(@one
|
||||
$struct:ident $(<$instance_config:ident>)? ($group:ident) {
|
||||
$(
|
||||
$(#[$meta:meta])? $config:ident: $ty:ty,
|
||||
)*
|
||||
}
|
||||
) => {
|
||||
#[derive(Debug, Clone, serde::Deserialize, serde::Serialize)]
|
||||
pub(crate) struct $struct {
|
||||
#[serde(default)]
|
||||
pub support_status: SupportStatus,
|
||||
// The list of peripherals for which this driver is implemented.
|
||||
// If empty, the driver supports a single instance only.
|
||||
#[serde(default)]
|
||||
pub instances: Vec<PeriInstance $(<$instance_config>)?>,
|
||||
$(
|
||||
$(#[$meta])?
|
||||
pub $config: $ty
|
||||
),*
|
||||
}
|
||||
|
||||
impl $struct {
|
||||
fn properties(&self) -> impl Iterator<Item = (&str, Value)> {
|
||||
[$( // for each property, generate a tuple
|
||||
(
|
||||
/* name: */ concat!(stringify!($group), ".", stringify!($config)),
|
||||
/* value: */ Value::from(self.$config),
|
||||
),
|
||||
)*].into_iter()
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// Repeat pattern for multiple structs
|
||||
($(
|
||||
$struct:ident $(<$instance_config:ident>)? {
|
||||
// This name will be emitted as a cfg symbol, to activate a driver.
|
||||
driver: $driver:ident,
|
||||
// Driver name, used in the generated documentation.
|
||||
name: $name:literal,
|
||||
// The list of peripheral symbols that this driver supports. For now this is used to
|
||||
// double-check the configuration.
|
||||
// TODO: remove once the metadata encodes which instances are supported.
|
||||
peripherals: $symbols:expr,
|
||||
properties: $tokens:tt
|
||||
},
|
||||
)+) => {
|
||||
// Implement the config driver and DriverConfig trait for each driver
|
||||
$(
|
||||
driver_configs!(@one $struct $(<$instance_config>)? ($driver) $tokens);
|
||||
)+
|
||||
|
||||
// Generate a single PeriConfig struct that contains all the drivers. Each of the
|
||||
// drivers is optional to support devices that may not have all peripherals.
|
||||
#[derive(Default, Debug, Clone, serde::Deserialize, serde::Serialize)]
|
||||
pub(crate) struct PeriConfig {
|
||||
$(
|
||||
// Each driver is an optional struct.
|
||||
#[serde(default)]
|
||||
pub(crate) $driver: Option<$struct>,
|
||||
)+
|
||||
}
|
||||
|
||||
impl PeriConfig {
|
||||
pub fn drivers() -> &'static [SupportItem] {
|
||||
&[
|
||||
$(
|
||||
SupportItem {
|
||||
name: $name,
|
||||
config_group: stringify!($driver),
|
||||
symbols: $symbols,
|
||||
},
|
||||
)+
|
||||
]
|
||||
}
|
||||
|
||||
/// Returns an iterator over all driver names, that are
|
||||
/// available on the selected device.
|
||||
pub fn driver_names(&self) -> impl Iterator<Item = &str> {
|
||||
[$(
|
||||
self.$driver.as_ref().and_then(|d| {
|
||||
match d.support_status {
|
||||
SupportStatus::NotSupported => None,
|
||||
_ => Some(stringify!($driver)),
|
||||
}
|
||||
}),
|
||||
)*].into_iter().flatten()
|
||||
}
|
||||
|
||||
pub fn driver_instances(&self) -> impl Iterator<Item = String> {
|
||||
// Collect into a vector. This compiles faster than chaining iterators.
|
||||
let mut instances = vec![];
|
||||
$(
|
||||
if let Some(driver) = &self.$driver {
|
||||
instances.extend(driver.instances.iter().map(|i| {
|
||||
format!("{}.{}", stringify!($driver), i.name)
|
||||
}));
|
||||
}
|
||||
)*
|
||||
instances.into_iter()
|
||||
}
|
||||
|
||||
/// Returns an iterator over all properties of all peripherals.
|
||||
pub fn properties(&self) -> impl Iterator<Item = (&str, Value)> {
|
||||
// Collect into a vector. This compiles faster than chaining iterators.
|
||||
let mut properties = vec![];
|
||||
$(
|
||||
if let Some(driver) = &self.$driver {
|
||||
properties.extend(driver.properties());
|
||||
}
|
||||
)*
|
||||
properties.into_iter()
|
||||
}
|
||||
|
||||
/// Returns the support status of a peripheral by its name.
|
||||
pub fn support_status(&self, peripheral: &str) -> Option<SupportStatus> {
|
||||
// Find the driver by name and return its support status.
|
||||
match peripheral {
|
||||
$(stringify!($driver) => self.$driver.as_ref().map(|p| p.support_status),)*
|
||||
_ => None, // If the peripheral is not found, return None.
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
// TODO: sort this similar to how the product portfolio is organized
|
||||
driver_configs![
|
||||
AdcProperties {
|
||||
driver: adc,
|
||||
name: "ADC",
|
||||
peripherals: &[],
|
||||
properties: {}
|
||||
},
|
||||
AesProperties {
|
||||
driver: aes,
|
||||
name: "AES",
|
||||
peripherals: &["aes"],
|
||||
properties: {}
|
||||
},
|
||||
AssistDebugProperties {
|
||||
driver: assist_debug,
|
||||
name: "ASSIST_DEBUG",
|
||||
peripherals: &["assist_debug"],
|
||||
properties: {}
|
||||
},
|
||||
DacProperties {
|
||||
driver: dac,
|
||||
name: "DAC",
|
||||
peripherals: &["dac"],
|
||||
properties: {}
|
||||
},
|
||||
DmaProperties {
|
||||
driver: dma,
|
||||
name: "DMA",
|
||||
peripherals: &["pdma", "gdma"],
|
||||
properties: {}
|
||||
},
|
||||
DsProperties {
|
||||
driver: ds,
|
||||
name: "DS",
|
||||
peripherals: &["ds"],
|
||||
properties: {}
|
||||
},
|
||||
EccProperties {
|
||||
driver: ecc,
|
||||
name: "ECC",
|
||||
peripherals: &["ecc"],
|
||||
properties: {}
|
||||
},
|
||||
EthernetProperties {
|
||||
driver: ethernet,
|
||||
name: "Ethernet",
|
||||
peripherals: &["emac"],
|
||||
properties: {}
|
||||
},
|
||||
EtmProperties {
|
||||
driver: etm,
|
||||
name: "ETM",
|
||||
peripherals: &["etm"],
|
||||
properties: {}
|
||||
},
|
||||
GpioProperties<GpioInstanceConfig> {
|
||||
driver: gpio,
|
||||
name: "GPIO",
|
||||
peripherals: &["gpio"],
|
||||
properties: {
|
||||
#[serde(default)]
|
||||
has_bank_1: bool,
|
||||
}
|
||||
},
|
||||
HmacProperties {
|
||||
driver: hmac,
|
||||
name: "HMAC",
|
||||
peripherals: &["hmac"],
|
||||
properties: {}
|
||||
},
|
||||
I2cMasterProperties {
|
||||
driver: i2c_master,
|
||||
name: "I2C master",
|
||||
peripherals: &["i2c0", "i2c1"],
|
||||
properties: {
|
||||
#[serde(default)]
|
||||
has_fsm_timeouts: bool,
|
||||
#[serde(default)]
|
||||
has_hw_bus_clear: bool,
|
||||
#[serde(default)]
|
||||
has_bus_timeout_enable: bool,
|
||||
#[serde(default)]
|
||||
separate_filter_config_registers: bool,
|
||||
#[serde(default)]
|
||||
can_estimate_nack_reason: bool,
|
||||
#[serde(default)]
|
||||
has_conf_update: bool,
|
||||
#[serde(default)]
|
||||
has_reliable_fsm_reset: bool,
|
||||
#[serde(default)]
|
||||
has_arbitration_en: bool,
|
||||
#[serde(default)]
|
||||
has_tx_fifo_watermark: bool,
|
||||
#[serde(default)]
|
||||
bus_timeout_is_exponential: bool,
|
||||
#[serde(default)]
|
||||
i2c0_data_register_ahb_address: Option<u32>,
|
||||
max_bus_timeout: u32,
|
||||
ll_intr_mask: u32,
|
||||
fifo_size: u32,
|
||||
}
|
||||
},
|
||||
I2cSlaveProperties {
|
||||
driver: i2c_slave,
|
||||
name: "I2C slave",
|
||||
peripherals: &["i2c0", "i2c1"],
|
||||
properties: {}
|
||||
},
|
||||
I2sProperties {
|
||||
driver: i2s,
|
||||
name: "I2S",
|
||||
peripherals: &["i2s0", "i2s1"],
|
||||
properties: {}
|
||||
},
|
||||
InterruptProperties {
|
||||
driver: interrupts,
|
||||
name: "Interrupts",
|
||||
peripherals: &[],
|
||||
properties: {
|
||||
status_registers: u32,
|
||||
}
|
||||
},
|
||||
IoMuxProperties {
|
||||
driver: io_mux,
|
||||
name: "IOMUX",
|
||||
peripherals: &["io_mux"],
|
||||
properties: {}
|
||||
},
|
||||
CameraProperties {
|
||||
driver: camera,
|
||||
name: "Camera interface", // LCD_CAM, ESP32 I2S, S2 SPI
|
||||
peripherals: &[],
|
||||
properties: {}
|
||||
},
|
||||
RgbProperties {
|
||||
driver: rgb_display,
|
||||
name: "RGB display", // LCD_CAM, ESP32 I2S, S2 SPI
|
||||
peripherals: &[],
|
||||
properties: {}
|
||||
},
|
||||
LedcProperties {
|
||||
driver: ledc,
|
||||
name: "LEDC",
|
||||
peripherals: &["ledc"],
|
||||
properties: {}
|
||||
},
|
||||
McpwmProperties {
|
||||
driver: mcpwm,
|
||||
name: "MCPWM",
|
||||
peripherals: &["mcpwm0", "mcpwm1"],
|
||||
properties: {}
|
||||
},
|
||||
ParlIoProperties {
|
||||
driver: parl_io,
|
||||
name: "PARL_IO",
|
||||
peripherals: &["parl_io"],
|
||||
properties: {}
|
||||
},
|
||||
PcntProperties {
|
||||
driver: pcnt,
|
||||
name: "PCNT",
|
||||
peripherals: &["pcnt"],
|
||||
properties: {}
|
||||
},
|
||||
PsramProperties {
|
||||
driver: psram,
|
||||
name: "PSRAM",
|
||||
peripherals: &["psram"],
|
||||
properties: {}
|
||||
},
|
||||
RmtProperties {
|
||||
driver: rmt,
|
||||
name: "RMT",
|
||||
peripherals: &["rmt"],
|
||||
properties: {
|
||||
ram_start: u32,
|
||||
channel_ram_size: u32,
|
||||
}
|
||||
},
|
||||
RngProperties {
|
||||
driver: rng,
|
||||
name: "RNG",
|
||||
peripherals: &["rng"],
|
||||
properties: {}
|
||||
},
|
||||
RsaProperties {
|
||||
driver: rsa,
|
||||
name: "RSA",
|
||||
peripherals: &["rsa"],
|
||||
properties: {}
|
||||
},
|
||||
SdHostProperties {
|
||||
driver: sd_host,
|
||||
name: "SDIO host",
|
||||
peripherals: &["sdhost"],
|
||||
properties: {}
|
||||
},
|
||||
SdSlaveProperties {
|
||||
driver: sd_slave,
|
||||
name: "SDIO slave",
|
||||
peripherals: &["slchost"],
|
||||
properties: {}
|
||||
},
|
||||
SleepProperties {
|
||||
driver: sleep,
|
||||
name: "Light/deep sleep",
|
||||
peripherals: &[],
|
||||
properties: {}
|
||||
},
|
||||
ShaProperties {
|
||||
driver: sha,
|
||||
name: "SHA",
|
||||
peripherals: &["sha"],
|
||||
properties: {}
|
||||
},
|
||||
SpiMasterProperties {
|
||||
driver: spi_master,
|
||||
name: "SPI master",
|
||||
peripherals: &["spi2", "spi3"],
|
||||
properties: {}
|
||||
},
|
||||
SpiSlaveProperties {
|
||||
driver: spi_slave,
|
||||
name: "SPI slave",
|
||||
peripherals: &["spi2", "spi3"],
|
||||
properties: {}
|
||||
},
|
||||
SysTimerProperties {
|
||||
driver: systimer,
|
||||
name: "SYSTIMER",
|
||||
peripherals: &["systimer"],
|
||||
properties: {}
|
||||
},
|
||||
TempProperties {
|
||||
driver: temp_sensor,
|
||||
name: "Temperature sensor",
|
||||
peripherals: &[],
|
||||
properties: {}
|
||||
},
|
||||
TimersProperties {
|
||||
driver: timergroup,
|
||||
name: "Timers",
|
||||
peripherals: &[],
|
||||
properties: {
|
||||
#[serde(default)]
|
||||
timg_has_timer1: bool,
|
||||
}
|
||||
},
|
||||
TouchProperties {
|
||||
driver: touch,
|
||||
name: "Touch",
|
||||
peripherals: &["touch"],
|
||||
properties: {}
|
||||
},
|
||||
TwaiProperties {
|
||||
driver: twai,
|
||||
name: "TWAI",
|
||||
peripherals: &["twai0", "twai1"],
|
||||
properties: {}
|
||||
},
|
||||
UartProperties {
|
||||
driver: uart,
|
||||
name: "UART",
|
||||
peripherals: &["uart0", "uart1", "uart2"],
|
||||
properties: {}
|
||||
},
|
||||
UlpFsmProperties {
|
||||
driver: ulp_fsm,
|
||||
name: "ULP (FSM)",
|
||||
peripherals: &["ulp_supported"],
|
||||
properties: {}
|
||||
},
|
||||
UlpRiscvProperties {
|
||||
driver: ulp_riscv,
|
||||
name: "ULP (RISC-V)",
|
||||
peripherals: &["ulp_riscv_core", "lp_core"],
|
||||
properties: {}
|
||||
},
|
||||
UsbOtgProperties {
|
||||
driver: usb_otg,
|
||||
name: "USB OTG FS",
|
||||
peripherals: &["usb0"],
|
||||
properties: {}
|
||||
},
|
||||
UsbSerialJtagProperties {
|
||||
driver: usb_serial_jtag,
|
||||
name: "USB Serial/JTAG",
|
||||
peripherals: &["usb_device"],
|
||||
properties: {}
|
||||
},
|
||||
WifiProperties {
|
||||
driver: wifi,
|
||||
name: "WIFI",
|
||||
peripherals: &["wifi"],
|
||||
properties: {
|
||||
#[serde(default)]
|
||||
has_wifi6: bool,
|
||||
}
|
||||
},
|
||||
BluetoothProperties {
|
||||
driver: bt,
|
||||
name: "Bluetooth",
|
||||
peripherals: &["bt"],
|
||||
properties: {}
|
||||
},
|
||||
IeeeProperties {
|
||||
driver: ieee802154,
|
||||
name: "IEEE 802.15.4",
|
||||
peripherals: &["ieee802154"],
|
||||
properties: {}
|
||||
},
|
||||
];
|
File diff suppressed because it is too large
Load Diff
@ -1,4 +1,667 @@
|
||||
//! Metadata for Espressif devices, primarily intended for use in build scripts.
|
||||
mod generate_cfg;
|
||||
mod cfg;
|
||||
|
||||
pub use generate_cfg::*;
|
||||
use core::str::FromStr;
|
||||
use std::{collections::HashMap, fmt::Write, path::Path, sync::OnceLock};
|
||||
|
||||
use anyhow::{Result, bail, ensure};
|
||||
use cfg::PeriConfig;
|
||||
use proc_macro2::TokenStream;
|
||||
use strum::IntoEnumIterator;
|
||||
|
||||
use crate::cfg::{SupportItem, SupportStatus, Value};
|
||||
|
||||
macro_rules! include_toml {
|
||||
(Config, $file:expr) => {{
|
||||
static LOADED_TOML: OnceLock<Config> = OnceLock::new();
|
||||
LOADED_TOML.get_or_init(|| {
|
||||
let config: Config = basic_toml::from_str(include_str!($file)).unwrap();
|
||||
|
||||
config.validate().expect("Invalid device configuration");
|
||||
|
||||
config
|
||||
})
|
||||
}};
|
||||
}
|
||||
|
||||
/// Supported device architectures.
|
||||
#[derive(
|
||||
Debug,
|
||||
Clone,
|
||||
Copy,
|
||||
PartialEq,
|
||||
Eq,
|
||||
PartialOrd,
|
||||
Ord,
|
||||
serde::Deserialize,
|
||||
serde::Serialize,
|
||||
strum::Display,
|
||||
strum::EnumIter,
|
||||
strum::EnumString,
|
||||
strum::AsRefStr,
|
||||
)]
|
||||
#[serde(rename_all = "lowercase")]
|
||||
#[strum(serialize_all = "lowercase")]
|
||||
pub enum Arch {
|
||||
/// RISC-V architecture
|
||||
RiscV,
|
||||
/// Xtensa architecture
|
||||
Xtensa,
|
||||
}
|
||||
|
||||
/// Device core count.
|
||||
#[derive(
|
||||
Debug,
|
||||
Clone,
|
||||
Copy,
|
||||
PartialEq,
|
||||
Eq,
|
||||
PartialOrd,
|
||||
Ord,
|
||||
serde::Deserialize,
|
||||
serde::Serialize,
|
||||
strum::Display,
|
||||
strum::EnumIter,
|
||||
strum::EnumString,
|
||||
strum::AsRefStr,
|
||||
)]
|
||||
pub enum Cores {
|
||||
/// Single CPU core
|
||||
#[serde(rename = "single_core")]
|
||||
#[strum(serialize = "single_core")]
|
||||
Single,
|
||||
/// Two or more CPU cores
|
||||
#[serde(rename = "multi_core")]
|
||||
#[strum(serialize = "multi_core")]
|
||||
Multi,
|
||||
}
|
||||
|
||||
/// Supported devices.
|
||||
#[derive(
|
||||
Debug,
|
||||
Clone,
|
||||
Copy,
|
||||
PartialEq,
|
||||
Eq,
|
||||
PartialOrd,
|
||||
Ord,
|
||||
Hash,
|
||||
serde::Deserialize,
|
||||
serde::Serialize,
|
||||
strum::Display,
|
||||
strum::EnumIter,
|
||||
strum::EnumString,
|
||||
strum::AsRefStr,
|
||||
)]
|
||||
#[cfg_attr(feature = "clap", derive(clap::ValueEnum))]
|
||||
#[serde(rename_all = "kebab-case")]
|
||||
#[strum(serialize_all = "kebab-case")]
|
||||
pub enum Chip {
|
||||
/// ESP32
|
||||
Esp32,
|
||||
/// ESP32-C2, ESP8684
|
||||
Esp32c2,
|
||||
/// ESP32-C3, ESP8685
|
||||
Esp32c3,
|
||||
/// ESP32-C6
|
||||
Esp32c6,
|
||||
/// ESP32-H2
|
||||
Esp32h2,
|
||||
/// ESP32-S2
|
||||
Esp32s2,
|
||||
/// ESP32-S3
|
||||
Esp32s3,
|
||||
}
|
||||
|
||||
impl Chip {
|
||||
pub fn from_cargo_feature() -> Result<Self> {
|
||||
let all_chips = Chip::iter().map(|c| c.to_string()).collect::<Vec<_>>();
|
||||
|
||||
let mut chip = None;
|
||||
for c in all_chips.iter() {
|
||||
if std::env::var(format!("CARGO_FEATURE_{}", c.to_uppercase())).is_ok() {
|
||||
if chip.is_some() {
|
||||
bail!(
|
||||
"Expected exactly one of the following features to be enabled: {}",
|
||||
all_chips.join(", ")
|
||||
);
|
||||
}
|
||||
chip = Some(c);
|
||||
}
|
||||
}
|
||||
|
||||
let Some(chip) = chip else {
|
||||
bail!(
|
||||
"Expected exactly one of the following features to be enabled: {}",
|
||||
all_chips.join(", ")
|
||||
);
|
||||
};
|
||||
|
||||
Ok(Self::from_str(chip.as_str()).unwrap())
|
||||
}
|
||||
|
||||
pub fn target(&self) -> &'static str {
|
||||
use Chip::*;
|
||||
|
||||
match self {
|
||||
Esp32 => "xtensa-esp32-none-elf",
|
||||
Esp32c2 | Esp32c3 => "riscv32imc-unknown-none-elf",
|
||||
Esp32c6 | Esp32h2 => "riscv32imac-unknown-none-elf",
|
||||
Esp32s2 => "xtensa-esp32s2-none-elf",
|
||||
Esp32s3 => "xtensa-esp32s3-none-elf",
|
||||
}
|
||||
}
|
||||
|
||||
pub fn has_lp_core(&self) -> bool {
|
||||
use Chip::*;
|
||||
|
||||
matches!(self, Esp32c6 | Esp32s2 | Esp32s3)
|
||||
}
|
||||
|
||||
pub fn lp_target(&self) -> Result<&'static str> {
|
||||
use Chip::*;
|
||||
|
||||
match self {
|
||||
Esp32c6 => Ok("riscv32imac-unknown-none-elf"),
|
||||
Esp32s2 | Esp32s3 => Ok("riscv32imc-unknown-none-elf"),
|
||||
_ => bail!("Chip does not contain an LP core: '{}'", self),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn pretty_name(&self) -> &str {
|
||||
match self {
|
||||
Chip::Esp32 => "ESP32",
|
||||
Chip::Esp32c2 => "ESP32-C2",
|
||||
Chip::Esp32c3 => "ESP32-C3",
|
||||
Chip::Esp32c6 => "ESP32-C6",
|
||||
Chip::Esp32h2 => "ESP32-H2",
|
||||
Chip::Esp32s2 => "ESP32-S2",
|
||||
Chip::Esp32s3 => "ESP32-S3",
|
||||
}
|
||||
}
|
||||
|
||||
pub fn is_xtensa(&self) -> bool {
|
||||
matches!(self, Chip::Esp32 | Chip::Esp32s2 | Chip::Esp32s3)
|
||||
}
|
||||
|
||||
pub fn is_riscv(&self) -> bool {
|
||||
!self.is_xtensa()
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, serde::Deserialize, serde::Serialize)]
|
||||
pub struct MemoryRegion {
|
||||
name: String,
|
||||
start: u32,
|
||||
end: u32,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, serde::Deserialize, serde::Serialize)]
|
||||
struct Device {
|
||||
name: String,
|
||||
arch: Arch,
|
||||
cores: usize,
|
||||
trm: String,
|
||||
|
||||
peripherals: Vec<String>,
|
||||
// For now, this is only used to double-check the configuration.
|
||||
virtual_peripherals: Vec<String>,
|
||||
symbols: Vec<String>,
|
||||
memory: Vec<MemoryRegion>,
|
||||
|
||||
// Peripheral driver configuration:
|
||||
#[serde(flatten)]
|
||||
peri_config: PeriConfig,
|
||||
}
|
||||
|
||||
// Output a Display-able value as a TokenStream, intended to generate numbers
|
||||
// without the type suffix.
|
||||
fn number(n: impl std::fmt::Display) -> TokenStream {
|
||||
TokenStream::from_str(&format!("{n}")).unwrap()
|
||||
}
|
||||
|
||||
/// Device configuration file format.
|
||||
#[derive(Debug, Clone, serde::Deserialize, serde::Serialize)]
|
||||
pub struct Config {
|
||||
device: Device,
|
||||
#[serde(skip)]
|
||||
all_symbols: OnceLock<Vec<String>>,
|
||||
}
|
||||
|
||||
impl Config {
|
||||
/// The configuration for the specified chip.
|
||||
pub fn for_chip(chip: &Chip) -> &Self {
|
||||
match chip {
|
||||
Chip::Esp32 => include_toml!(Config, "../devices/esp32.toml"),
|
||||
Chip::Esp32c2 => include_toml!(Config, "../devices/esp32c2.toml"),
|
||||
Chip::Esp32c3 => include_toml!(Config, "../devices/esp32c3.toml"),
|
||||
Chip::Esp32c6 => include_toml!(Config, "../devices/esp32c6.toml"),
|
||||
Chip::Esp32h2 => include_toml!(Config, "../devices/esp32h2.toml"),
|
||||
Chip::Esp32s2 => include_toml!(Config, "../devices/esp32s2.toml"),
|
||||
Chip::Esp32s3 => include_toml!(Config, "../devices/esp32s3.toml"),
|
||||
}
|
||||
}
|
||||
|
||||
/// Create an empty configuration
|
||||
pub fn empty() -> Self {
|
||||
Self {
|
||||
device: Device {
|
||||
name: "".to_owned(),
|
||||
arch: Arch::RiscV,
|
||||
cores: 1,
|
||||
trm: "".to_owned(),
|
||||
peripherals: Vec::new(),
|
||||
virtual_peripherals: Vec::new(),
|
||||
symbols: Vec::new(),
|
||||
memory: Vec::new(),
|
||||
peri_config: PeriConfig::default(),
|
||||
},
|
||||
all_symbols: OnceLock::new(),
|
||||
}
|
||||
}
|
||||
|
||||
fn validate(&self) -> Result<()> {
|
||||
for instance in self.device.peri_config.driver_instances() {
|
||||
let (driver, peri) = instance.split_once('.').unwrap();
|
||||
ensure!(
|
||||
self.device.peripherals.iter().any(|p| p == peri)
|
||||
|| self.device.virtual_peripherals.iter().any(|p| p == peri),
|
||||
"Driver {driver} marks an implementation for '{peri}' but this peripheral is not defined for '{}'",
|
||||
self.device.name
|
||||
);
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// The name of the device.
|
||||
pub fn name(&self) -> String {
|
||||
self.device.name.clone()
|
||||
}
|
||||
|
||||
/// The CPU architecture of the device.
|
||||
pub fn arch(&self) -> Arch {
|
||||
self.device.arch
|
||||
}
|
||||
|
||||
/// The core count of the device.
|
||||
pub fn cores(&self) -> Cores {
|
||||
if self.device.cores > 1 {
|
||||
Cores::Multi
|
||||
} else {
|
||||
Cores::Single
|
||||
}
|
||||
}
|
||||
|
||||
/// The peripherals of the device.
|
||||
pub fn peripherals(&self) -> &[String] {
|
||||
&self.device.peripherals
|
||||
}
|
||||
|
||||
/// User-defined symbols for the device.
|
||||
pub fn symbols(&self) -> &[String] {
|
||||
&self.device.symbols
|
||||
}
|
||||
|
||||
/// Memory regions.
|
||||
///
|
||||
/// Will be available as env-variables `REGION-<NAME>-START` /
|
||||
/// `REGION-<NAME>-END`
|
||||
pub fn memory(&self) -> &[MemoryRegion] {
|
||||
&self.device.memory
|
||||
}
|
||||
|
||||
/// All configuration values for the device.
|
||||
pub fn all(&self) -> &[String] {
|
||||
self.all_symbols.get_or_init(|| {
|
||||
let mut all = vec![
|
||||
self.device.name.clone(),
|
||||
self.device.arch.to_string(),
|
||||
match self.cores() {
|
||||
Cores::Single => String::from("single_core"),
|
||||
Cores::Multi => String::from("multi_core"),
|
||||
},
|
||||
];
|
||||
all.extend(
|
||||
self.device
|
||||
.peripherals
|
||||
.iter()
|
||||
.map(|p| format!("soc_has_{p}")),
|
||||
);
|
||||
all.extend_from_slice(&self.device.symbols);
|
||||
all.extend(
|
||||
self.device
|
||||
.peri_config
|
||||
.driver_names()
|
||||
.map(|name| name.to_string()),
|
||||
);
|
||||
all.extend(self.device.peri_config.driver_instances());
|
||||
|
||||
all.extend(self.device.peri_config.properties().filter_map(
|
||||
|(name, value)| match value {
|
||||
Value::Boolean(true) => Some(name.to_string()),
|
||||
Value::Number(value) => Some(format!("{name}=\"{value}\"")),
|
||||
_ => None,
|
||||
},
|
||||
));
|
||||
all
|
||||
})
|
||||
}
|
||||
|
||||
/// Does the configuration contain `item`?
|
||||
pub fn contains(&self, item: &str) -> bool {
|
||||
self.all().iter().any(|i| i == item)
|
||||
}
|
||||
|
||||
/// Define all symbols for a given configuration.
|
||||
pub fn define_symbols(&self) {
|
||||
define_all_possible_symbols();
|
||||
// Define all necessary configuration symbols for the configured device:
|
||||
for symbol in self.all() {
|
||||
println!("cargo:rustc-cfg={}", symbol.replace('.', "_"));
|
||||
}
|
||||
|
||||
// Define env-vars for all memory regions
|
||||
for memory in self.memory() {
|
||||
println!("cargo:rustc-cfg=has_{}_region", memory.name.to_lowercase());
|
||||
}
|
||||
}
|
||||
|
||||
pub fn generate_metadata(&self) {
|
||||
let out_dir = std::env::var_os("OUT_DIR").unwrap();
|
||||
let out_dir = Path::new(&out_dir);
|
||||
|
||||
self.generate_properties(out_dir, "_generated.rs");
|
||||
self.generate_gpios(out_dir, "_generated_gpio.rs");
|
||||
}
|
||||
|
||||
fn generate_properties(&self, out_dir: &Path, file_name: &str) {
|
||||
let out_file = out_dir.join(file_name).to_string_lossy().to_string();
|
||||
|
||||
let mut g = TokenStream::new();
|
||||
|
||||
let chip_name = self.name();
|
||||
// Public API, can't use a private macro:
|
||||
g.extend(quote::quote! {
|
||||
/// The name of the chip as `&str`
|
||||
#[macro_export]
|
||||
macro_rules! chip {
|
||||
() => { #chip_name };
|
||||
}
|
||||
});
|
||||
|
||||
// Translate the chip properties into a macro that can be used in esp-hal:
|
||||
let arch = self.device.arch.as_ref();
|
||||
let cores = number(self.device.cores);
|
||||
let trm = &self.device.trm;
|
||||
|
||||
let peripheral_properties =
|
||||
self.device
|
||||
.peri_config
|
||||
.properties()
|
||||
.flat_map(|(name, value)| match value {
|
||||
Value::Unset => quote::quote! {},
|
||||
Value::Number(value) => {
|
||||
let value = number(value); // ensure no numeric suffix is added
|
||||
quote::quote! {
|
||||
(#name) => { #value };
|
||||
(#name, str) => { stringify!(#value) };
|
||||
}
|
||||
}
|
||||
Value::Boolean(value) => quote::quote! {
|
||||
(#name) => { #value };
|
||||
},
|
||||
});
|
||||
|
||||
// Not public API, can use a private macro:
|
||||
g.extend(quote::quote! {
|
||||
/// A link to the Technical Reference Manual (TRM) for the chip.
|
||||
#[doc(hidden)]
|
||||
#[macro_export]
|
||||
macro_rules! property {
|
||||
("chip") => { #chip_name };
|
||||
("arch") => { #arch };
|
||||
("cores") => { #cores };
|
||||
("cores", str) => { stringify!(#cores) };
|
||||
("trm") => { #trm };
|
||||
#(#peripheral_properties)*
|
||||
}
|
||||
});
|
||||
|
||||
let region_branches = self.memory().iter().map(|region| {
|
||||
let name = region.name.to_uppercase();
|
||||
let start = number(region.start as usize);
|
||||
let end = number(region.end as usize);
|
||||
|
||||
quote::quote! {
|
||||
( #name ) => {
|
||||
#start .. #end
|
||||
};
|
||||
}
|
||||
});
|
||||
|
||||
g.extend(quote::quote! {
|
||||
/// Macro to get the address range of the given memory region.
|
||||
#[macro_export]
|
||||
#[doc(hidden)]
|
||||
macro_rules! memory_range {
|
||||
#(#region_branches)*
|
||||
}
|
||||
});
|
||||
|
||||
std::fs::write(&out_file, g.to_string()).unwrap();
|
||||
}
|
||||
|
||||
fn generate_gpios(&self, out_dir: &Path, file_name: &str) {
|
||||
let out_file = out_dir.join(file_name).to_string_lossy().to_string();
|
||||
|
||||
let pins = self.device.peri_config.gpio.as_ref().unwrap().instances[0]
|
||||
.instance_config
|
||||
.pins
|
||||
.iter()
|
||||
.map(|pin| {
|
||||
let pin_number = number(pin.pin);
|
||||
|
||||
struct PinAttrs {
|
||||
input: bool,
|
||||
output: bool,
|
||||
analog: bool,
|
||||
rtc_io: bool,
|
||||
touch: bool,
|
||||
}
|
||||
|
||||
let mut pin_attrs = PinAttrs {
|
||||
input: false,
|
||||
output: false,
|
||||
analog: false,
|
||||
rtc_io: false,
|
||||
touch: false,
|
||||
};
|
||||
pin.kind.iter().for_each(|kind| match kind {
|
||||
cfg::PinCapability::Input => pin_attrs.input = true,
|
||||
cfg::PinCapability::Output => pin_attrs.output = true,
|
||||
cfg::PinCapability::Analog => pin_attrs.analog = true,
|
||||
cfg::PinCapability::Rtc => pin_attrs.rtc_io = true,
|
||||
cfg::PinCapability::Touch => pin_attrs.touch = true,
|
||||
});
|
||||
|
||||
let mut attrs = vec![];
|
||||
|
||||
if pin_attrs.input {
|
||||
attrs.push(quote::quote! { Input });
|
||||
}
|
||||
if pin_attrs.output {
|
||||
attrs.push(quote::quote! { Output });
|
||||
}
|
||||
if pin_attrs.analog {
|
||||
attrs.push(quote::quote! { Analog });
|
||||
}
|
||||
if pin_attrs.rtc_io {
|
||||
if !pin_attrs.output {
|
||||
attrs.push(quote::quote! { RtcIo });
|
||||
} else {
|
||||
attrs.push(quote::quote! { RtcIoInput });
|
||||
}
|
||||
}
|
||||
if pin_attrs.touch {
|
||||
attrs.push(quote::quote! { Touch });
|
||||
}
|
||||
|
||||
let mut input_afs = vec![];
|
||||
let mut output_afs = vec![];
|
||||
|
||||
for af in 0..6 {
|
||||
if let Some(signal) = pin.af_input.get(af) {
|
||||
let af = quote::format_ident!("_{af}");
|
||||
let signal = TokenStream::from_str(signal).unwrap();
|
||||
input_afs.push(quote::quote! { #af => #signal });
|
||||
}
|
||||
if let Some(signal) = pin.af_output.get(af) {
|
||||
let af = quote::format_ident!("_{af}");
|
||||
let signal = TokenStream::from_str(signal).unwrap();
|
||||
output_afs.push(quote::quote! { #af => #signal });
|
||||
}
|
||||
}
|
||||
|
||||
quote::quote! {
|
||||
( #pin_number, [#(#attrs),*] ( #(#input_afs)* ) ( #(#output_afs)* ) )
|
||||
}
|
||||
});
|
||||
|
||||
let g = quote::quote! {
|
||||
crate::gpio! {
|
||||
#(#pins)*
|
||||
}
|
||||
};
|
||||
|
||||
std::fs::write(&out_file, g.to_string()).unwrap();
|
||||
}
|
||||
}
|
||||
|
||||
/// Defines all possible symbols that _could_ be output from this crate
|
||||
/// regardless of the chosen configuration.
|
||||
///
|
||||
/// This is required to avoid triggering the unexpected-cfgs lint.
|
||||
fn define_all_possible_symbols() {
|
||||
// Used by our documentation builds to prevent the huge red warning banner.
|
||||
println!("cargo:rustc-check-cfg=cfg(not_really_docsrs)");
|
||||
|
||||
let mut cfg_values: HashMap<String, Vec<String>> = HashMap::new();
|
||||
|
||||
for chip in Chip::iter() {
|
||||
let config = Config::for_chip(&chip);
|
||||
for symbol in config.all() {
|
||||
if let Some((symbol_name, symbol_value)) = symbol.split_once('=') {
|
||||
// cfg's with values need special syntax, so let's collect all
|
||||
// of them separately.
|
||||
let symbol_name = symbol_name.replace('.', "_");
|
||||
let entry = cfg_values.entry(symbol_name).or_default();
|
||||
// Avoid duplicates in the same cfg.
|
||||
if !entry.contains(&symbol_value.to_string()) {
|
||||
entry.push(symbol_value.to_string());
|
||||
}
|
||||
} else {
|
||||
// https://doc.rust-lang.org/cargo/reference/build-scripts.html#rustc-check-cfg
|
||||
println!("cargo:rustc-check-cfg=cfg({})", symbol.replace('.', "_"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Now output all cfgs with values.
|
||||
for (symbol_name, symbol_values) in cfg_values {
|
||||
println!(
|
||||
"cargo:rustc-check-cfg=cfg({symbol_name}, values({}))",
|
||||
symbol_values.join(",")
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn generate_chip_support_status(output: &mut impl Write) -> std::fmt::Result {
|
||||
let nothing = "";
|
||||
|
||||
// Calculate the width of the first column.
|
||||
let driver_col_width = std::iter::once("Driver")
|
||||
.chain(PeriConfig::drivers().iter().map(|i| i.name))
|
||||
.map(|c| c.len())
|
||||
.max()
|
||||
.unwrap();
|
||||
|
||||
// Header
|
||||
write!(output, "| {:driver_col_width$} |", "Driver")?;
|
||||
for chip in Chip::iter() {
|
||||
write!(output, " {} |", chip.pretty_name())?;
|
||||
}
|
||||
writeln!(output)?;
|
||||
|
||||
// Header separator
|
||||
write!(output, "| {nothing:-<driver_col_width$} |")?;
|
||||
for chip in Chip::iter() {
|
||||
write!(
|
||||
output,
|
||||
":{nothing:-<width$}:|",
|
||||
width = chip.pretty_name().len()
|
||||
)?;
|
||||
}
|
||||
writeln!(output)?;
|
||||
|
||||
// Driver support status
|
||||
for SupportItem {
|
||||
name,
|
||||
symbols,
|
||||
config_group,
|
||||
} in PeriConfig::drivers()
|
||||
{
|
||||
write!(output, "| {name:driver_col_width$} |")?;
|
||||
for chip in Chip::iter() {
|
||||
let config = Config::for_chip(&chip);
|
||||
|
||||
let status = config
|
||||
.device
|
||||
.peri_config
|
||||
.support_status(config_group)
|
||||
.inspect(|status| {
|
||||
// TODO: this is good for double-checking, but it should probably go the
|
||||
// other way around. Driver config should define what peripheral symbols exist.
|
||||
assert!(
|
||||
matches!(status, SupportStatus::NotSupported)
|
||||
|| symbols.is_empty()
|
||||
|| symbols.iter().any(|p| config.contains(p)),
|
||||
"{} has configuration for {} but no compatible symbols have been defined",
|
||||
chip.pretty_name(),
|
||||
config_group
|
||||
);
|
||||
})
|
||||
.or_else(|| {
|
||||
// If the driver is not supported by the chip, we return None.
|
||||
if symbols.iter().any(|p| config.contains(p)) {
|
||||
Some(SupportStatus::NotSupported)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
});
|
||||
let status_icon = match status {
|
||||
None => " ",
|
||||
Some(status) => status.icon(),
|
||||
};
|
||||
// VSCode displays emojis just a bit wider than 2 characters, making this
|
||||
// approximation a bit too wide but good enough.
|
||||
let support_cell_width = chip.pretty_name().len() - status.is_some() as usize;
|
||||
write!(output, " {status_icon:support_cell_width$} |")?;
|
||||
}
|
||||
writeln!(output)?;
|
||||
}
|
||||
|
||||
writeln!(output)?;
|
||||
|
||||
// Print legend
|
||||
writeln!(output, " * Empty cell: not available")?;
|
||||
for s in [
|
||||
SupportStatus::NotSupported,
|
||||
SupportStatus::Partial,
|
||||
SupportStatus::Supported,
|
||||
] {
|
||||
writeln!(output, " * {}: {}", s.icon(), s.status())?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user