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:
Dániel Buga 2025-06-20 09:45:49 +02:00 committed by GitHub
parent 4be232dea4
commit b98631570f
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
19 changed files with 1728 additions and 1321 deletions

View File

@ -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
),
)*

View File

@ -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)* ) )*
}
}
$(

View File

@ -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"));

View File

@ -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"));

View File

@ -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"));

View File

@ -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"));

View File

@ -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"));

View File

@ -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"));

View File

@ -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"));

View File

@ -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"

View File

@ -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"

View File

@ -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"

View File

@ -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"

View File

@ -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"

View File

@ -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" }]

View File

@ -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
View 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

View File

@ -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(())
}