diff options
Diffstat (limited to 'embassy-nxp/src')
| -rw-r--r-- | embassy-nxp/src/chips/lpc55.rs | 115 | ||||
| -rw-r--r-- | embassy-nxp/src/chips/mimxrt1011.rs | 104 | ||||
| -rw-r--r-- | embassy-nxp/src/chips/mimxrt1062.rs | 273 | ||||
| -rw-r--r-- | embassy-nxp/src/dma.rs | 1 | ||||
| -rw-r--r-- | embassy-nxp/src/dma/lpc55.rs | 51 | ||||
| -rw-r--r-- | embassy-nxp/src/fmt.rs | 1 | ||||
| -rw-r--r-- | embassy-nxp/src/gpio/lpc55.rs | 157 | ||||
| -rw-r--r-- | embassy-nxp/src/gpio/rt1xxx.rs | 54 | ||||
| -rw-r--r-- | embassy-nxp/src/iomuxc.rs | 29 | ||||
| -rw-r--r-- | embassy-nxp/src/lib.rs | 26 | ||||
| -rw-r--r-- | embassy-nxp/src/pint.rs | 4 | ||||
| -rw-r--r-- | embassy-nxp/src/pwm.rs | 7 | ||||
| -rw-r--r-- | embassy-nxp/src/pwm/lpc55.rs | 248 | ||||
| -rw-r--r-- | embassy-nxp/src/sct.rs | 56 | ||||
| -rw-r--r-- | embassy-nxp/src/time_driver/rtc.rs | 4 | ||||
| -rw-r--r-- | embassy-nxp/src/usart.rs | 2 | ||||
| -rw-r--r-- | embassy-nxp/src/usart/lpc55.rs | 226 |
17 files changed, 560 insertions, 798 deletions
diff --git a/embassy-nxp/src/chips/lpc55.rs b/embassy-nxp/src/chips/lpc55.rs index 9f4e7269f..7967e07d1 100644 --- a/embassy-nxp/src/chips/lpc55.rs +++ b/embassy-nxp/src/chips/lpc55.rs | |||
| @@ -1,109 +1,10 @@ | |||
| 1 | pub use nxp_pac as pac; | 1 | pub(crate) mod _generated { |
| 2 | #![allow(dead_code)] | ||
| 3 | #![allow(unused_imports)] | ||
| 4 | #![allow(non_snake_case)] | ||
| 5 | #![allow(missing_docs)] | ||
| 2 | 6 | ||
| 3 | embassy_hal_internal::interrupt_mod!( | 7 | include!(concat!(env!("OUT_DIR"), "/_generated.rs")); |
| 4 | FLEXCOMM0, FLEXCOMM1, FLEXCOMM2, FLEXCOMM3, FLEXCOMM4, FLEXCOMM5, FLEXCOMM6, FLEXCOMM7 | ||
| 5 | ); | ||
| 6 | |||
| 7 | embassy_hal_internal::peripherals! { | ||
| 8 | // External pins. These are not only GPIOs, they are multi-purpose pins and can be used by other | ||
| 9 | // peripheral types (e.g. I2C). | ||
| 10 | PIO0_0, | ||
| 11 | PIO0_1, | ||
| 12 | PIO0_2, | ||
| 13 | PIO0_3, | ||
| 14 | PIO0_4, | ||
| 15 | PIO0_5, | ||
| 16 | PIO0_6, | ||
| 17 | PIO0_7, | ||
| 18 | PIO0_8, | ||
| 19 | PIO0_9, | ||
| 20 | PIO0_10, | ||
| 21 | PIO0_11, | ||
| 22 | PIO0_12, | ||
| 23 | PIO0_13, | ||
| 24 | PIO0_14, | ||
| 25 | PIO0_15, | ||
| 26 | PIO0_16, | ||
| 27 | PIO0_17, | ||
| 28 | PIO0_18, | ||
| 29 | PIO0_19, | ||
| 30 | PIO0_20, | ||
| 31 | PIO0_21, | ||
| 32 | PIO0_22, | ||
| 33 | PIO0_23, | ||
| 34 | PIO0_24, | ||
| 35 | PIO0_25, | ||
| 36 | PIO0_26, | ||
| 37 | PIO0_27, | ||
| 38 | PIO0_28, | ||
| 39 | PIO0_29, | ||
| 40 | PIO0_30, | ||
| 41 | PIO0_31, | ||
| 42 | PIO1_0, | ||
| 43 | PIO1_1, | ||
| 44 | PIO1_2, | ||
| 45 | PIO1_3, | ||
| 46 | PIO1_4, | ||
| 47 | PIO1_5, | ||
| 48 | PIO1_6, | ||
| 49 | PIO1_7, | ||
| 50 | PIO1_8, | ||
| 51 | PIO1_9, | ||
| 52 | PIO1_10, | ||
| 53 | PIO1_11, | ||
| 54 | PIO1_12, | ||
| 55 | PIO1_13, | ||
| 56 | PIO1_14, | ||
| 57 | PIO1_15, | ||
| 58 | PIO1_16, | ||
| 59 | PIO1_17, | ||
| 60 | PIO1_18, | ||
| 61 | PIO1_19, | ||
| 62 | PIO1_20, | ||
| 63 | PIO1_21, | ||
| 64 | PIO1_22, | ||
| 65 | PIO1_23, | ||
| 66 | PIO1_24, | ||
| 67 | PIO1_25, | ||
| 68 | PIO1_26, | ||
| 69 | PIO1_27, | ||
| 70 | PIO1_28, | ||
| 71 | PIO1_29, | ||
| 72 | PIO1_30, | ||
| 73 | PIO1_31, | ||
| 74 | |||
| 75 | // Direct Memory Access (DMA) channels. They are used for asynchronous modes of peripherals. | ||
| 76 | DMA_CH0, | ||
| 77 | DMA_CH1, | ||
| 78 | DMA_CH2, | ||
| 79 | DMA_CH3, | ||
| 80 | DMA_CH4, | ||
| 81 | DMA_CH5, | ||
| 82 | DMA_CH6, | ||
| 83 | DMA_CH7, | ||
| 84 | DMA_CH8, | ||
| 85 | DMA_CH9, | ||
| 86 | DMA_CH10, | ||
| 87 | DMA_CH11, | ||
| 88 | DMA_CH12, | ||
| 89 | DMA_CH13, | ||
| 90 | DMA_CH14, | ||
| 91 | DMA_CH15, | ||
| 92 | DMA_CH16, | ||
| 93 | DMA_CH17, | ||
| 94 | DMA_CH18, | ||
| 95 | DMA_CH19, | ||
| 96 | DMA_CH20, | ||
| 97 | DMA_CH21, | ||
| 98 | DMA_CH22, | ||
| 99 | |||
| 100 | // Universal Synchronous/Asynchronous Receiver/Transmitter (USART) instances. | ||
| 101 | USART0, | ||
| 102 | USART1, | ||
| 103 | USART2, | ||
| 104 | USART3, | ||
| 105 | USART4, | ||
| 106 | USART5, | ||
| 107 | USART6, | ||
| 108 | USART7 | ||
| 109 | } | 8 | } |
| 9 | |||
| 10 | pub use _generated::*; | ||
diff --git a/embassy-nxp/src/chips/mimxrt1011.rs b/embassy-nxp/src/chips/mimxrt1011.rs index a74d953fc..d5969a24b 100644 --- a/embassy-nxp/src/chips/mimxrt1011.rs +++ b/embassy-nxp/src/chips/mimxrt1011.rs | |||
| @@ -1,107 +1,5 @@ | |||
| 1 | // This must be imported so that __preinit is defined. | 1 | // This must be imported so that __preinit is defined. |
| 2 | use imxrt_rt as _; | 2 | use imxrt_rt as _; |
| 3 | pub use nxp_pac as pac; | ||
| 4 | |||
| 5 | embassy_hal_internal::peripherals! { | ||
| 6 | // External pins. These are not only GPIOs, they are multi-purpose pins and can be used by other | ||
| 7 | // peripheral types (e.g. I2C). | ||
| 8 | GPIO_00, | ||
| 9 | GPIO_01, | ||
| 10 | GPIO_02, | ||
| 11 | GPIO_03, | ||
| 12 | GPIO_04, | ||
| 13 | GPIO_05, | ||
| 14 | GPIO_06, | ||
| 15 | GPIO_07, | ||
| 16 | GPIO_08, | ||
| 17 | GPIO_09, | ||
| 18 | GPIO_10, | ||
| 19 | GPIO_11, | ||
| 20 | GPIO_12, | ||
| 21 | GPIO_13, | ||
| 22 | GPIO_AD_00, | ||
| 23 | GPIO_AD_01, | ||
| 24 | GPIO_AD_02, | ||
| 25 | GPIO_AD_03, | ||
| 26 | GPIO_AD_04, | ||
| 27 | GPIO_AD_05, | ||
| 28 | GPIO_AD_06, | ||
| 29 | GPIO_AD_07, | ||
| 30 | GPIO_AD_08, | ||
| 31 | GPIO_AD_09, | ||
| 32 | GPIO_AD_10, | ||
| 33 | GPIO_AD_11, | ||
| 34 | GPIO_AD_12, | ||
| 35 | GPIO_AD_13, | ||
| 36 | GPIO_AD_14, | ||
| 37 | GPIO_SD_00, | ||
| 38 | GPIO_SD_01, | ||
| 39 | GPIO_SD_02, | ||
| 40 | GPIO_SD_03, | ||
| 41 | GPIO_SD_04, | ||
| 42 | GPIO_SD_05, | ||
| 43 | GPIO_SD_06, | ||
| 44 | GPIO_SD_07, | ||
| 45 | GPIO_SD_08, | ||
| 46 | GPIO_SD_09, | ||
| 47 | GPIO_SD_10, | ||
| 48 | GPIO_SD_11, | ||
| 49 | GPIO_SD_12, | ||
| 50 | GPIO_SD_13, | ||
| 51 | PMIC_ON_REQ, | ||
| 52 | } | ||
| 53 | |||
| 54 | impl_gpio! { | ||
| 55 | // GPIO Bank 1 | ||
| 56 | GPIO_00(Gpio1, 0); | ||
| 57 | GPIO_01(Gpio1, 1); | ||
| 58 | GPIO_02(Gpio1, 2); | ||
| 59 | GPIO_03(Gpio1, 3); | ||
| 60 | GPIO_04(Gpio1, 4); | ||
| 61 | GPIO_05(Gpio1, 5); | ||
| 62 | GPIO_06(Gpio1, 6); | ||
| 63 | GPIO_07(Gpio1, 7); | ||
| 64 | GPIO_08(Gpio1, 8); | ||
| 65 | GPIO_09(Gpio1, 9); | ||
| 66 | GPIO_10(Gpio1, 10); | ||
| 67 | GPIO_11(Gpio1, 11); | ||
| 68 | GPIO_12(Gpio1, 12); | ||
| 69 | GPIO_13(Gpio1, 13); | ||
| 70 | GPIO_AD_00(Gpio1, 14); | ||
| 71 | GPIO_AD_01(Gpio1, 15); | ||
| 72 | GPIO_AD_02(Gpio1, 16); | ||
| 73 | GPIO_AD_03(Gpio1, 17); | ||
| 74 | GPIO_AD_04(Gpio1, 18); | ||
| 75 | GPIO_AD_05(Gpio1, 19); | ||
| 76 | GPIO_AD_06(Gpio1, 20); | ||
| 77 | GPIO_AD_07(Gpio1, 21); | ||
| 78 | GPIO_AD_08(Gpio1, 22); | ||
| 79 | GPIO_AD_09(Gpio1, 23); | ||
| 80 | GPIO_AD_10(Gpio1, 24); | ||
| 81 | GPIO_AD_11(Gpio1, 25); | ||
| 82 | GPIO_AD_12(Gpio1, 26); | ||
| 83 | GPIO_AD_13(Gpio1, 27); | ||
| 84 | GPIO_AD_14(Gpio1, 28); | ||
| 85 | |||
| 86 | // GPIO Bank 2 | ||
| 87 | GPIO_SD_00(Gpio2, 0); | ||
| 88 | GPIO_SD_01(Gpio2, 1); | ||
| 89 | GPIO_SD_02(Gpio2, 2); | ||
| 90 | GPIO_SD_03(Gpio2, 3); | ||
| 91 | GPIO_SD_04(Gpio2, 4); | ||
| 92 | GPIO_SD_05(Gpio2, 5); | ||
| 93 | GPIO_SD_06(Gpio2, 6); | ||
| 94 | GPIO_SD_07(Gpio2, 7); | ||
| 95 | GPIO_SD_08(Gpio2, 8); | ||
| 96 | GPIO_SD_09(Gpio2, 9); | ||
| 97 | GPIO_SD_10(Gpio2, 10); | ||
| 98 | GPIO_SD_11(Gpio2, 11); | ||
| 99 | GPIO_SD_12(Gpio2, 12); | ||
| 100 | GPIO_SD_13(Gpio2, 13); | ||
| 101 | |||
| 102 | // GPIO Bank 5 | ||
| 103 | PMIC_ON_REQ(Gpio5, 0); | ||
| 104 | } | ||
| 105 | 3 | ||
| 106 | pub(crate) mod _generated { | 4 | pub(crate) mod _generated { |
| 107 | #![allow(dead_code)] | 5 | #![allow(dead_code)] |
| @@ -111,3 +9,5 @@ pub(crate) mod _generated { | |||
| 111 | 9 | ||
| 112 | include!(concat!(env!("OUT_DIR"), "/_generated.rs")); | 10 | include!(concat!(env!("OUT_DIR"), "/_generated.rs")); |
| 113 | } | 11 | } |
| 12 | |||
| 13 | pub use _generated::*; | ||
diff --git a/embassy-nxp/src/chips/mimxrt1062.rs b/embassy-nxp/src/chips/mimxrt1062.rs index ef153bd66..d5969a24b 100644 --- a/embassy-nxp/src/chips/mimxrt1062.rs +++ b/embassy-nxp/src/chips/mimxrt1062.rs | |||
| @@ -1,276 +1,5 @@ | |||
| 1 | // This must be imported so that __preinit is defined. | 1 | // This must be imported so that __preinit is defined. |
| 2 | use imxrt_rt as _; | 2 | use imxrt_rt as _; |
| 3 | pub use nxp_pac as pac; | ||
| 4 | |||
| 5 | embassy_hal_internal::peripherals! { | ||
| 6 | // External pins. These are not only GPIOs, they are multi-purpose pins and can be used by other | ||
| 7 | // peripheral types (e.g. I2C). | ||
| 8 | GPIO_AD_B0_00, | ||
| 9 | GPIO_AD_B0_01, | ||
| 10 | GPIO_AD_B0_02, | ||
| 11 | GPIO_AD_B0_03, | ||
| 12 | GPIO_AD_B0_04, | ||
| 13 | GPIO_AD_B0_05, | ||
| 14 | GPIO_AD_B0_06, | ||
| 15 | GPIO_AD_B0_07, | ||
| 16 | GPIO_AD_B0_08, | ||
| 17 | GPIO_AD_B0_09, | ||
| 18 | GPIO_AD_B0_10, | ||
| 19 | GPIO_AD_B0_11, | ||
| 20 | GPIO_AD_B0_12, | ||
| 21 | GPIO_AD_B0_13, | ||
| 22 | GPIO_AD_B0_14, | ||
| 23 | GPIO_AD_B0_15, | ||
| 24 | GPIO_AD_B1_00, | ||
| 25 | GPIO_AD_B1_01, | ||
| 26 | GPIO_AD_B1_02, | ||
| 27 | GPIO_AD_B1_03, | ||
| 28 | GPIO_AD_B1_04, | ||
| 29 | GPIO_AD_B1_05, | ||
| 30 | GPIO_AD_B1_06, | ||
| 31 | GPIO_AD_B1_07, | ||
| 32 | GPIO_AD_B1_08, | ||
| 33 | GPIO_AD_B1_09, | ||
| 34 | GPIO_AD_B1_10, | ||
| 35 | GPIO_AD_B1_11, | ||
| 36 | GPIO_AD_B1_12, | ||
| 37 | GPIO_AD_B1_13, | ||
| 38 | GPIO_AD_B1_14, | ||
| 39 | GPIO_AD_B1_15, | ||
| 40 | GPIO_B0_00, | ||
| 41 | GPIO_B0_01, | ||
| 42 | GPIO_B0_02, | ||
| 43 | GPIO_B0_03, | ||
| 44 | GPIO_B0_04, | ||
| 45 | GPIO_B0_05, | ||
| 46 | GPIO_B0_06, | ||
| 47 | GPIO_B0_07, | ||
| 48 | GPIO_B0_08, | ||
| 49 | GPIO_B0_09, | ||
| 50 | GPIO_B0_10, | ||
| 51 | GPIO_B0_11, | ||
| 52 | GPIO_B0_12, | ||
| 53 | GPIO_B0_13, | ||
| 54 | GPIO_B0_14, | ||
| 55 | GPIO_B0_15, | ||
| 56 | GPIO_B1_00, | ||
| 57 | GPIO_B1_01, | ||
| 58 | GPIO_B1_02, | ||
| 59 | GPIO_B1_03, | ||
| 60 | GPIO_B1_04, | ||
| 61 | GPIO_B1_05, | ||
| 62 | GPIO_B1_06, | ||
| 63 | GPIO_B1_07, | ||
| 64 | GPIO_B1_08, | ||
| 65 | GPIO_B1_09, | ||
| 66 | GPIO_B1_10, | ||
| 67 | GPIO_B1_11, | ||
| 68 | GPIO_B1_12, | ||
| 69 | GPIO_B1_13, | ||
| 70 | GPIO_B1_14, | ||
| 71 | GPIO_B1_15, | ||
| 72 | GPIO_EMC_00, | ||
| 73 | GPIO_EMC_01, | ||
| 74 | GPIO_EMC_02, | ||
| 75 | GPIO_EMC_03, | ||
| 76 | GPIO_EMC_04, | ||
| 77 | GPIO_EMC_05, | ||
| 78 | GPIO_EMC_06, | ||
| 79 | GPIO_EMC_07, | ||
| 80 | GPIO_EMC_08, | ||
| 81 | GPIO_EMC_09, | ||
| 82 | GPIO_EMC_10, | ||
| 83 | GPIO_EMC_11, | ||
| 84 | GPIO_EMC_12, | ||
| 85 | GPIO_EMC_13, | ||
| 86 | GPIO_EMC_14, | ||
| 87 | GPIO_EMC_15, | ||
| 88 | GPIO_EMC_16, | ||
| 89 | GPIO_EMC_17, | ||
| 90 | GPIO_EMC_18, | ||
| 91 | GPIO_EMC_19, | ||
| 92 | GPIO_EMC_20, | ||
| 93 | GPIO_EMC_21, | ||
| 94 | GPIO_EMC_22, | ||
| 95 | GPIO_EMC_23, | ||
| 96 | GPIO_EMC_24, | ||
| 97 | GPIO_EMC_25, | ||
| 98 | GPIO_EMC_26, | ||
| 99 | GPIO_EMC_27, | ||
| 100 | GPIO_EMC_28, | ||
| 101 | GPIO_EMC_29, | ||
| 102 | GPIO_EMC_30, | ||
| 103 | GPIO_EMC_31, | ||
| 104 | GPIO_EMC_32, | ||
| 105 | GPIO_EMC_33, | ||
| 106 | GPIO_EMC_34, | ||
| 107 | GPIO_EMC_35, | ||
| 108 | GPIO_EMC_36, | ||
| 109 | GPIO_EMC_37, | ||
| 110 | GPIO_EMC_38, | ||
| 111 | GPIO_EMC_39, | ||
| 112 | GPIO_EMC_40, | ||
| 113 | GPIO_EMC_41, | ||
| 114 | GPIO_SD_B0_00, | ||
| 115 | GPIO_SD_B0_01, | ||
| 116 | GPIO_SD_B0_02, | ||
| 117 | GPIO_SD_B0_03, | ||
| 118 | GPIO_SD_B0_04, | ||
| 119 | GPIO_SD_B0_05, | ||
| 120 | GPIO_SD_B1_00, | ||
| 121 | GPIO_SD_B1_01, | ||
| 122 | GPIO_SD_B1_02, | ||
| 123 | GPIO_SD_B1_03, | ||
| 124 | GPIO_SD_B1_04, | ||
| 125 | GPIO_SD_B1_05, | ||
| 126 | GPIO_SD_B1_06, | ||
| 127 | GPIO_SD_B1_07, | ||
| 128 | GPIO_SD_B1_08, | ||
| 129 | GPIO_SD_B1_09, | ||
| 130 | GPIO_SD_B1_10, | ||
| 131 | GPIO_SD_B1_11, | ||
| 132 | WAKEUP, | ||
| 133 | PMIC_ON_REQ, | ||
| 134 | PMIC_STBY_REQ, | ||
| 135 | } | ||
| 136 | |||
| 137 | impl_gpio! { | ||
| 138 | // GPIO Bank 1 | ||
| 139 | GPIO_AD_B0_00(Gpio1, 0); | ||
| 140 | GPIO_AD_B0_01(Gpio1, 1); | ||
| 141 | GPIO_AD_B0_02(Gpio1, 2); | ||
| 142 | GPIO_AD_B0_03(Gpio1, 3); | ||
| 143 | GPIO_AD_B0_04(Gpio1, 4); | ||
| 144 | GPIO_AD_B0_05(Gpio1, 5); | ||
| 145 | GPIO_AD_B0_06(Gpio1, 6); | ||
| 146 | GPIO_AD_B0_07(Gpio1, 7); | ||
| 147 | GPIO_AD_B0_08(Gpio1, 8); | ||
| 148 | GPIO_AD_B0_09(Gpio1, 9); | ||
| 149 | GPIO_AD_B0_10(Gpio1, 10); | ||
| 150 | GPIO_AD_B0_11(Gpio1, 11); | ||
| 151 | GPIO_AD_B0_12(Gpio1, 12); | ||
| 152 | GPIO_AD_B0_13(Gpio1, 13); | ||
| 153 | GPIO_AD_B0_14(Gpio1, 14); | ||
| 154 | GPIO_AD_B0_15(Gpio1, 15); | ||
| 155 | GPIO_AD_B1_00(Gpio1, 16); | ||
| 156 | GPIO_AD_B1_01(Gpio1, 17); | ||
| 157 | GPIO_AD_B1_02(Gpio1, 18); | ||
| 158 | GPIO_AD_B1_03(Gpio1, 19); | ||
| 159 | GPIO_AD_B1_04(Gpio1, 20); | ||
| 160 | GPIO_AD_B1_05(Gpio1, 21); | ||
| 161 | GPIO_AD_B1_06(Gpio1, 22); | ||
| 162 | GPIO_AD_B1_07(Gpio1, 23); | ||
| 163 | GPIO_AD_B1_08(Gpio1, 24); | ||
| 164 | GPIO_AD_B1_09(Gpio1, 25); | ||
| 165 | GPIO_AD_B1_10(Gpio1, 26); | ||
| 166 | GPIO_AD_B1_11(Gpio1, 27); | ||
| 167 | GPIO_AD_B1_12(Gpio1, 28); | ||
| 168 | GPIO_AD_B1_13(Gpio1, 29); | ||
| 169 | GPIO_AD_B1_14(Gpio1, 30); | ||
| 170 | GPIO_AD_B1_15(Gpio1, 31); | ||
| 171 | |||
| 172 | // GPIO Bank 2 | ||
| 173 | GPIO_B0_00(Gpio2, 0); | ||
| 174 | GPIO_B0_01(Gpio2, 1); | ||
| 175 | GPIO_B0_02(Gpio2, 2); | ||
| 176 | GPIO_B0_03(Gpio2, 3); | ||
| 177 | GPIO_B0_04(Gpio2, 4); | ||
| 178 | GPIO_B0_05(Gpio2, 5); | ||
| 179 | GPIO_B0_06(Gpio2, 6); | ||
| 180 | GPIO_B0_07(Gpio2, 7); | ||
| 181 | GPIO_B0_08(Gpio2, 8); | ||
| 182 | GPIO_B0_09(Gpio2, 9); | ||
| 183 | GPIO_B0_10(Gpio2, 10); | ||
| 184 | GPIO_B0_11(Gpio2, 11); | ||
| 185 | GPIO_B0_12(Gpio2, 12); | ||
| 186 | GPIO_B0_13(Gpio2, 13); | ||
| 187 | GPIO_B0_14(Gpio2, 14); | ||
| 188 | GPIO_B0_15(Gpio2, 15); | ||
| 189 | GPIO_B1_00(Gpio2, 16); | ||
| 190 | GPIO_B1_01(Gpio2, 17); | ||
| 191 | GPIO_B1_02(Gpio2, 18); | ||
| 192 | GPIO_B1_03(Gpio2, 19); | ||
| 193 | GPIO_B1_04(Gpio2, 20); | ||
| 194 | GPIO_B1_05(Gpio2, 21); | ||
| 195 | GPIO_B1_06(Gpio2, 22); | ||
| 196 | GPIO_B1_07(Gpio2, 23); | ||
| 197 | GPIO_B1_08(Gpio2, 24); | ||
| 198 | GPIO_B1_09(Gpio2, 25); | ||
| 199 | GPIO_B1_10(Gpio2, 26); | ||
| 200 | GPIO_B1_11(Gpio2, 27); | ||
| 201 | GPIO_B1_12(Gpio2, 28); | ||
| 202 | GPIO_B1_13(Gpio2, 29); | ||
| 203 | GPIO_B1_14(Gpio2, 30); | ||
| 204 | GPIO_B1_15(Gpio2, 31); | ||
| 205 | |||
| 206 | // GPIO Bank 4 (EMC is 4, then 3) | ||
| 207 | GPIO_EMC_00(Gpio4, 0); | ||
| 208 | GPIO_EMC_01(Gpio4, 1); | ||
| 209 | GPIO_EMC_02(Gpio4, 2); | ||
| 210 | GPIO_EMC_03(Gpio4, 3); | ||
| 211 | GPIO_EMC_04(Gpio4, 4); | ||
| 212 | GPIO_EMC_05(Gpio4, 5); | ||
| 213 | GPIO_EMC_06(Gpio4, 6); | ||
| 214 | GPIO_EMC_07(Gpio4, 7); | ||
| 215 | GPIO_EMC_08(Gpio4, 8); | ||
| 216 | GPIO_EMC_09(Gpio4, 9); | ||
| 217 | GPIO_EMC_10(Gpio4, 10); | ||
| 218 | GPIO_EMC_11(Gpio4, 11); | ||
| 219 | GPIO_EMC_12(Gpio4, 12); | ||
| 220 | GPIO_EMC_13(Gpio4, 13); | ||
| 221 | GPIO_EMC_14(Gpio4, 14); | ||
| 222 | GPIO_EMC_15(Gpio4, 15); | ||
| 223 | GPIO_EMC_16(Gpio4, 16); | ||
| 224 | GPIO_EMC_17(Gpio4, 17); | ||
| 225 | GPIO_EMC_18(Gpio4, 18); | ||
| 226 | GPIO_EMC_19(Gpio4, 19); | ||
| 227 | GPIO_EMC_20(Gpio4, 20); | ||
| 228 | GPIO_EMC_21(Gpio4, 21); | ||
| 229 | GPIO_EMC_22(Gpio4, 22); | ||
| 230 | GPIO_EMC_23(Gpio4, 23); | ||
| 231 | GPIO_EMC_24(Gpio4, 24); | ||
| 232 | GPIO_EMC_25(Gpio4, 25); | ||
| 233 | GPIO_EMC_26(Gpio4, 26); | ||
| 234 | GPIO_EMC_27(Gpio4, 27); | ||
| 235 | GPIO_EMC_28(Gpio4, 28); | ||
| 236 | GPIO_EMC_29(Gpio4, 29); | ||
| 237 | GPIO_EMC_30(Gpio4, 30); | ||
| 238 | GPIO_EMC_31(Gpio4, 31); | ||
| 239 | |||
| 240 | // GPIO Bank 3 | ||
| 241 | GPIO_EMC_32(Gpio3, 18); | ||
| 242 | GPIO_EMC_33(Gpio3, 19); | ||
| 243 | GPIO_EMC_34(Gpio3, 20); | ||
| 244 | GPIO_EMC_35(Gpio3, 21); | ||
| 245 | GPIO_EMC_36(Gpio3, 22); | ||
| 246 | GPIO_EMC_37(Gpio3, 23); | ||
| 247 | GPIO_EMC_38(Gpio3, 24); | ||
| 248 | GPIO_EMC_39(Gpio3, 25); | ||
| 249 | GPIO_EMC_40(Gpio3, 26); | ||
| 250 | GPIO_EMC_41(Gpio3, 27); | ||
| 251 | GPIO_SD_B0_00(Gpio3, 12); | ||
| 252 | GPIO_SD_B0_01(Gpio3, 13); | ||
| 253 | GPIO_SD_B0_02(Gpio3, 14); | ||
| 254 | GPIO_SD_B0_03(Gpio3, 15); | ||
| 255 | GPIO_SD_B0_04(Gpio3, 16); | ||
| 256 | GPIO_SD_B0_05(Gpio3, 17); | ||
| 257 | GPIO_SD_B1_00(Gpio3, 0); | ||
| 258 | GPIO_SD_B1_01(Gpio3, 1); | ||
| 259 | GPIO_SD_B1_02(Gpio3, 2); | ||
| 260 | GPIO_SD_B1_03(Gpio3, 3); | ||
| 261 | GPIO_SD_B1_04(Gpio3, 4); | ||
| 262 | GPIO_SD_B1_05(Gpio3, 5); | ||
| 263 | GPIO_SD_B1_06(Gpio3, 6); | ||
| 264 | GPIO_SD_B1_07(Gpio3, 7); | ||
| 265 | GPIO_SD_B1_08(Gpio3, 8); | ||
| 266 | GPIO_SD_B1_09(Gpio3, 9); | ||
| 267 | GPIO_SD_B1_10(Gpio3, 10); | ||
| 268 | GPIO_SD_B1_11(Gpio3, 11); | ||
| 269 | |||
| 270 | WAKEUP(Gpio5, 0); | ||
| 271 | PMIC_ON_REQ(Gpio5, 1); | ||
| 272 | PMIC_STBY_REQ(Gpio5, 2); | ||
| 273 | } | ||
| 274 | 3 | ||
| 275 | pub(crate) mod _generated { | 4 | pub(crate) mod _generated { |
| 276 | #![allow(dead_code)] | 5 | #![allow(dead_code)] |
| @@ -280,3 +9,5 @@ pub(crate) mod _generated { | |||
| 280 | 9 | ||
| 281 | include!(concat!(env!("OUT_DIR"), "/_generated.rs")); | 10 | include!(concat!(env!("OUT_DIR"), "/_generated.rs")); |
| 282 | } | 11 | } |
| 12 | |||
| 13 | pub use _generated::*; | ||
diff --git a/embassy-nxp/src/dma.rs b/embassy-nxp/src/dma.rs index e2df65fc9..1f479122d 100644 --- a/embassy-nxp/src/dma.rs +++ b/embassy-nxp/src/dma.rs | |||
| @@ -1,3 +1,4 @@ | |||
| 1 | #![macro_use] | ||
| 1 | //! Direct Memory Access (DMA) driver. | 2 | //! Direct Memory Access (DMA) driver. |
| 2 | 3 | ||
| 3 | #[cfg_attr(feature = "lpc55-core0", path = "./dma/lpc55.rs")] | 4 | #[cfg_attr(feature = "lpc55-core0", path = "./dma/lpc55.rs")] |
diff --git a/embassy-nxp/src/dma/lpc55.rs b/embassy-nxp/src/dma/lpc55.rs index 578d1fd88..623644bf1 100644 --- a/embassy-nxp/src/dma/lpc55.rs +++ b/embassy-nxp/src/dma/lpc55.rs | |||
| @@ -1,17 +1,22 @@ | |||
| 1 | #![macro_use] | ||
| 2 | |||
| 1 | use core::cell::RefCell; | 3 | use core::cell::RefCell; |
| 2 | use core::future::Future; | 4 | use core::future::Future; |
| 3 | use core::pin::Pin; | 5 | use core::pin::Pin; |
| 4 | use core::sync::atomic::{compiler_fence, Ordering}; | 6 | use core::sync::atomic::{Ordering, compiler_fence}; |
| 5 | use core::task::{Context, Poll}; | 7 | use core::task::{Context, Poll}; |
| 6 | 8 | ||
| 7 | use critical_section::Mutex; | 9 | use critical_section::Mutex; |
| 8 | use embassy_hal_internal::interrupt::InterruptExt; | 10 | use embassy_hal_internal::interrupt::InterruptExt; |
| 9 | use embassy_hal_internal::{impl_peripheral, PeripheralType}; | 11 | use embassy_hal_internal::{PeripheralType, impl_peripheral}; |
| 10 | use embassy_sync::waitqueue::AtomicWaker; | 12 | use embassy_sync::waitqueue::AtomicWaker; |
| 11 | 13 | ||
| 12 | use crate::pac::{DMA0, SYSCON, *}; | 14 | use crate::Peri; |
| 13 | use crate::{peripherals, Peri}; | 15 | #[cfg(feature = "rt")] |
| 16 | use crate::pac::interrupt; | ||
| 17 | use crate::pac::{SYSCON, *}; | ||
| 14 | 18 | ||
| 19 | #[cfg(feature = "rt")] | ||
| 15 | #[interrupt] | 20 | #[interrupt] |
| 16 | fn DMA0() { | 21 | fn DMA0() { |
| 17 | let inta = DMA0.inta0().read().ia(); | 22 | let inta = DMA0.inta0().read().ia(); |
| @@ -278,7 +283,7 @@ static DMA_DESCRIPTORS: Mutex<RefCell<DmaDescriptorTable>> = Mutex::new(RefCell: | |||
| 278 | }; CHANNEL_COUNT], | 283 | }; CHANNEL_COUNT], |
| 279 | })); | 284 | })); |
| 280 | 285 | ||
| 281 | trait SealedChannel {} | 286 | pub(crate) trait SealedChannel {} |
| 282 | trait SealedWord {} | 287 | trait SealedWord {} |
| 283 | 288 | ||
| 284 | /// DMA channel interface. | 289 | /// DMA channel interface. |
| @@ -323,7 +328,7 @@ impl Word for u32 { | |||
| 323 | 328 | ||
| 324 | /// Type erased DMA channel. | 329 | /// Type erased DMA channel. |
| 325 | pub struct AnyChannel { | 330 | pub struct AnyChannel { |
| 326 | number: u8, | 331 | pub(crate) number: u8, |
| 327 | } | 332 | } |
| 328 | 333 | ||
| 329 | impl_peripheral!(AnyChannel); | 334 | impl_peripheral!(AnyChannel); |
| @@ -335,10 +340,10 @@ impl Channel for AnyChannel { | |||
| 335 | } | 340 | } |
| 336 | } | 341 | } |
| 337 | 342 | ||
| 338 | macro_rules! channel { | 343 | macro_rules! impl_dma_channel { |
| 339 | ($name:ident, $num:expr) => { | 344 | ($instance:ident, $name:ident, $num:expr) => { |
| 340 | impl SealedChannel for peripherals::$name {} | 345 | impl crate::dma::SealedChannel for crate::peripherals::$name {} |
| 341 | impl Channel for peripherals::$name { | 346 | impl crate::dma::Channel for crate::peripherals::$name { |
| 342 | fn number(&self) -> u8 { | 347 | fn number(&self) -> u8 { |
| 343 | $num | 348 | $num |
| 344 | } | 349 | } |
| @@ -346,32 +351,10 @@ macro_rules! channel { | |||
| 346 | 351 | ||
| 347 | impl From<peripherals::$name> for crate::dma::AnyChannel { | 352 | impl From<peripherals::$name> for crate::dma::AnyChannel { |
| 348 | fn from(val: peripherals::$name) -> Self { | 353 | fn from(val: peripherals::$name) -> Self { |
| 354 | use crate::dma::Channel; | ||
| 355 | |||
| 349 | Self { number: val.number() } | 356 | Self { number: val.number() } |
| 350 | } | 357 | } |
| 351 | } | 358 | } |
| 352 | }; | 359 | }; |
| 353 | } | 360 | } |
| 354 | |||
| 355 | channel!(DMA_CH0, 0); | ||
| 356 | channel!(DMA_CH1, 1); | ||
| 357 | channel!(DMA_CH2, 2); | ||
| 358 | channel!(DMA_CH3, 3); | ||
| 359 | channel!(DMA_CH4, 4); | ||
| 360 | channel!(DMA_CH5, 5); | ||
| 361 | channel!(DMA_CH6, 6); | ||
| 362 | channel!(DMA_CH7, 7); | ||
| 363 | channel!(DMA_CH8, 8); | ||
| 364 | channel!(DMA_CH9, 9); | ||
| 365 | channel!(DMA_CH10, 10); | ||
| 366 | channel!(DMA_CH11, 11); | ||
| 367 | channel!(DMA_CH12, 12); | ||
| 368 | channel!(DMA_CH13, 13); | ||
| 369 | channel!(DMA_CH14, 14); | ||
| 370 | channel!(DMA_CH15, 15); | ||
| 371 | channel!(DMA_CH16, 16); | ||
| 372 | channel!(DMA_CH17, 17); | ||
| 373 | channel!(DMA_CH18, 18); | ||
| 374 | channel!(DMA_CH19, 19); | ||
| 375 | channel!(DMA_CH20, 20); | ||
| 376 | channel!(DMA_CH21, 21); | ||
| 377 | channel!(DMA_CH22, 22); | ||
diff --git a/embassy-nxp/src/fmt.rs b/embassy-nxp/src/fmt.rs index 27d41ace6..11275235e 100644 --- a/embassy-nxp/src/fmt.rs +++ b/embassy-nxp/src/fmt.rs | |||
| @@ -1,5 +1,4 @@ | |||
| 1 | //! Copied from embassy-rp | 1 | //! Copied from embassy-rp |
| 2 | |||
| 3 | #![macro_use] | 2 | #![macro_use] |
| 4 | #![allow(unused)] | 3 | #![allow(unused)] |
| 5 | 4 | ||
diff --git a/embassy-nxp/src/gpio/lpc55.rs b/embassy-nxp/src/gpio/lpc55.rs index 36ea99d21..6be405463 100644 --- a/embassy-nxp/src/gpio/lpc55.rs +++ b/embassy-nxp/src/gpio/lpc55.rs | |||
| @@ -1,8 +1,11 @@ | |||
| 1 | use embassy_hal_internal::{impl_peripheral, PeripheralType}; | 1 | #![macro_use] |
| 2 | 2 | ||
| 3 | use embassy_hal_internal::{PeripheralType, impl_peripheral}; | ||
| 4 | |||
| 5 | use crate::Peri; | ||
| 6 | use crate::pac::common::{RW, Reg}; | ||
| 3 | use crate::pac::iocon::vals::{PioDigimode, PioMode}; | 7 | use crate::pac::iocon::vals::{PioDigimode, PioMode}; |
| 4 | use crate::pac::{GPIO, IOCON, SYSCON}; | 8 | use crate::pac::{GPIO, IOCON, SYSCON, iocon}; |
| 5 | use crate::{peripherals, Peri}; | ||
| 6 | 9 | ||
| 7 | pub(crate) fn init() { | 10 | pub(crate) fn init() { |
| 8 | // Enable clocks for GPIO, PINT, and IOCON | 11 | // Enable clocks for GPIO, PINT, and IOCON |
| @@ -38,8 +41,8 @@ pub enum Pull { | |||
| 38 | /// The LPC55 boards have two GPIO banks, each with 32 pins. This enum represents the two banks. | 41 | /// The LPC55 boards have two GPIO banks, each with 32 pins. This enum represents the two banks. |
| 39 | #[derive(Debug, Eq, PartialEq, Clone, Copy)] | 42 | #[derive(Debug, Eq, PartialEq, Clone, Copy)] |
| 40 | pub enum Bank { | 43 | pub enum Bank { |
| 41 | Bank0 = 0, | 44 | Gpio0 = 0, |
| 42 | Bank1 = 1, | 45 | Gpio1 = 1, |
| 43 | } | 46 | } |
| 44 | 47 | ||
| 45 | /// GPIO output driver. Internally, this is a specialized [Flex] pin. | 48 | /// GPIO output driver. Internally, this is a specialized [Flex] pin. |
| @@ -109,13 +112,7 @@ impl<'d> Input<'d> { | |||
| 109 | 112 | ||
| 110 | /// Set the pull configuration for the pin. To disable the pull, use [Pull::None]. | 113 | /// Set the pull configuration for the pin. To disable the pull, use [Pull::None]. |
| 111 | pub fn set_pull(&mut self, pull: Pull) { | 114 | pub fn set_pull(&mut self, pull: Pull) { |
| 112 | match_iocon!(register, self.pin.pin_bank(), self.pin.pin_number(), { | 115 | self.pin.set_pull(pull); |
| 113 | register.modify(|w| match pull { | ||
| 114 | Pull::None => w.set_mode(PioMode::INACTIVE), | ||
| 115 | Pull::Up => w.set_mode(PioMode::PULL_UP), | ||
| 116 | Pull::Down => w.set_mode(PioMode::PULL_DOWN), | ||
| 117 | }); | ||
| 118 | }); | ||
| 119 | } | 116 | } |
| 120 | 117 | ||
| 121 | /// Get the current input level of the pin. | 118 | /// Get the current input level of the pin. |
| @@ -193,11 +190,20 @@ impl<'d> Flex<'d> { | |||
| 193 | 1 << self.pin.pin_number() | 190 | 1 << self.pin.pin_number() |
| 194 | } | 191 | } |
| 195 | 192 | ||
| 193 | /// Set the pull configuration for the pin. To disable the pull, use [Pull::None]. | ||
| 194 | pub fn set_pull(&mut self, pull: Pull) { | ||
| 195 | self.pin.pio().modify(|w| match pull { | ||
| 196 | Pull::None => w.set_mode(PioMode::INACTIVE), | ||
| 197 | Pull::Up => w.set_mode(PioMode::PULL_UP), | ||
| 198 | Pull::Down => w.set_mode(PioMode::PULL_DOWN), | ||
| 199 | }); | ||
| 200 | } | ||
| 201 | |||
| 196 | /// Set the pin to digital mode. This is required for using a pin as a GPIO pin. The default | 202 | /// Set the pin to digital mode. This is required for using a pin as a GPIO pin. The default |
| 197 | /// setting for pins is (usually) non-digital. | 203 | /// setting for pins is (usually) non-digital. |
| 198 | fn set_as_digital(&mut self) { | 204 | fn set_as_digital(&mut self) { |
| 199 | match_iocon!(register, self.pin_bank(), self.pin_number(), { | 205 | self.pin.pio().modify(|w| { |
| 200 | register.modify(|w| w.set_digimode(PioDigimode::DIGITAL)); | 206 | w.set_digimode(PioDigimode::DIGITAL); |
| 201 | }); | 207 | }); |
| 202 | } | 208 | } |
| 203 | 209 | ||
| @@ -220,6 +226,14 @@ impl<'d> Flex<'d> { | |||
| 220 | pub(crate) trait SealedPin: Sized { | 226 | pub(crate) trait SealedPin: Sized { |
| 221 | fn pin_bank(&self) -> Bank; | 227 | fn pin_bank(&self) -> Bank; |
| 222 | fn pin_number(&self) -> u8; | 228 | fn pin_number(&self) -> u8; |
| 229 | |||
| 230 | #[inline] | ||
| 231 | fn pio(&self) -> Reg<iocon::regs::Pio, RW> { | ||
| 232 | match self.pin_bank() { | ||
| 233 | Bank::Gpio0 => IOCON.pio0(self.pin_number() as usize), | ||
| 234 | Bank::Gpio1 => IOCON.pio1(self.pin_number() as usize), | ||
| 235 | } | ||
| 236 | } | ||
| 223 | } | 237 | } |
| 224 | 238 | ||
| 225 | /// Interface for a Pin that can be configured by an [Input] or [Output] driver, or converted to an | 239 | /// Interface for a Pin that can be configured by an [Input] or [Output] driver, or converted to an |
| @@ -242,8 +256,8 @@ pub trait Pin: PeripheralType + Into<AnyPin> + SealedPin + Sized + 'static { | |||
| 242 | 256 | ||
| 243 | /// Type-erased GPIO pin. | 257 | /// Type-erased GPIO pin. |
| 244 | pub struct AnyPin { | 258 | pub struct AnyPin { |
| 245 | pin_bank: Bank, | 259 | pub(crate) pin_bank: Bank, |
| 246 | pin_number: u8, | 260 | pub(crate) pin_number: u8, |
| 247 | } | 261 | } |
| 248 | 262 | ||
| 249 | impl AnyPin { | 263 | impl AnyPin { |
| @@ -272,47 +286,13 @@ impl SealedPin for AnyPin { | |||
| 272 | } | 286 | } |
| 273 | } | 287 | } |
| 274 | 288 | ||
| 275 | /// Match the pin bank and number of a pin to the corresponding IOCON register. | ||
| 276 | /// | ||
| 277 | /// # Example | ||
| 278 | /// ``` | ||
| 279 | /// use embassy_nxp::gpio::Bank; | ||
| 280 | /// use embassy_nxp::pac_utils::{iocon_reg, match_iocon}; | ||
| 281 | /// | ||
| 282 | /// // Make pin PIO1_6 digital and set it to pull-down mode. | ||
| 283 | /// match_iocon!(register, Bank::Bank1, 6, { | ||
| 284 | /// register.modify(|w|{ | ||
| 285 | /// w.set_mode(PioMode::PULL_DOWN); | ||
| 286 | /// w.set_digimode(PioDigimode::DIGITAL); | ||
| 287 | /// | ||
| 288 | /// } | ||
| 289 | /// }); | ||
| 290 | /// ``` | ||
| 291 | macro_rules! match_iocon { | ||
| 292 | ($register:ident, $pin_bank:expr, $pin_number:expr, $action:expr) => { | ||
| 293 | match $pin_bank { | ||
| 294 | Bank::Bank0 => { | ||
| 295 | let $register = IOCON.pio0($pin_number as usize); | ||
| 296 | $action; | ||
| 297 | } | ||
| 298 | |||
| 299 | Bank::Bank1 => { | ||
| 300 | let $register = IOCON.pio1($pin_number as usize); | ||
| 301 | $action; | ||
| 302 | } | ||
| 303 | } | ||
| 304 | }; | ||
| 305 | } | ||
| 306 | |||
| 307 | pub(crate) use match_iocon; | ||
| 308 | |||
| 309 | macro_rules! impl_pin { | 289 | macro_rules! impl_pin { |
| 310 | ($name:ident, $bank:expr, $pin_num:expr) => { | 290 | ($name:ident, $bank:ident, $pin_num:expr) => { |
| 311 | impl Pin for peripherals::$name {} | 291 | impl crate::gpio::Pin for peripherals::$name {} |
| 312 | impl SealedPin for peripherals::$name { | 292 | impl crate::gpio::SealedPin for peripherals::$name { |
| 313 | #[inline] | 293 | #[inline] |
| 314 | fn pin_bank(&self) -> Bank { | 294 | fn pin_bank(&self) -> crate::gpio::Bank { |
| 315 | $bank | 295 | crate::gpio::Bank::$bank |
| 316 | } | 296 | } |
| 317 | 297 | ||
| 318 | #[inline] | 298 | #[inline] |
| @@ -323,6 +303,8 @@ macro_rules! impl_pin { | |||
| 323 | 303 | ||
| 324 | impl From<peripherals::$name> for crate::gpio::AnyPin { | 304 | impl From<peripherals::$name> for crate::gpio::AnyPin { |
| 325 | fn from(val: peripherals::$name) -> Self { | 305 | fn from(val: peripherals::$name) -> Self { |
| 306 | use crate::gpio::SealedPin; | ||
| 307 | |||
| 326 | Self { | 308 | Self { |
| 327 | pin_bank: val.pin_bank(), | 309 | pin_bank: val.pin_bank(), |
| 328 | pin_number: val.pin_number(), | 310 | pin_number: val.pin_number(), |
| @@ -331,68 +313,3 @@ macro_rules! impl_pin { | |||
| 331 | } | 313 | } |
| 332 | }; | 314 | }; |
| 333 | } | 315 | } |
| 334 | |||
| 335 | impl_pin!(PIO0_0, Bank::Bank0, 0); | ||
| 336 | impl_pin!(PIO0_1, Bank::Bank0, 1); | ||
| 337 | impl_pin!(PIO0_2, Bank::Bank0, 2); | ||
| 338 | impl_pin!(PIO0_3, Bank::Bank0, 3); | ||
| 339 | impl_pin!(PIO0_4, Bank::Bank0, 4); | ||
| 340 | impl_pin!(PIO0_5, Bank::Bank0, 5); | ||
| 341 | impl_pin!(PIO0_6, Bank::Bank0, 6); | ||
| 342 | impl_pin!(PIO0_7, Bank::Bank0, 7); | ||
| 343 | impl_pin!(PIO0_8, Bank::Bank0, 8); | ||
| 344 | impl_pin!(PIO0_9, Bank::Bank0, 9); | ||
| 345 | impl_pin!(PIO0_10, Bank::Bank0, 10); | ||
| 346 | impl_pin!(PIO0_11, Bank::Bank0, 11); | ||
| 347 | impl_pin!(PIO0_12, Bank::Bank0, 12); | ||
| 348 | impl_pin!(PIO0_13, Bank::Bank0, 13); | ||
| 349 | impl_pin!(PIO0_14, Bank::Bank0, 14); | ||
| 350 | impl_pin!(PIO0_15, Bank::Bank0, 15); | ||
| 351 | impl_pin!(PIO0_16, Bank::Bank0, 16); | ||
| 352 | impl_pin!(PIO0_17, Bank::Bank0, 17); | ||
| 353 | impl_pin!(PIO0_18, Bank::Bank0, 18); | ||
| 354 | impl_pin!(PIO0_19, Bank::Bank0, 19); | ||
| 355 | impl_pin!(PIO0_20, Bank::Bank0, 20); | ||
| 356 | impl_pin!(PIO0_21, Bank::Bank0, 21); | ||
| 357 | impl_pin!(PIO0_22, Bank::Bank0, 22); | ||
| 358 | impl_pin!(PIO0_23, Bank::Bank0, 23); | ||
| 359 | impl_pin!(PIO0_24, Bank::Bank0, 24); | ||
| 360 | impl_pin!(PIO0_25, Bank::Bank0, 25); | ||
| 361 | impl_pin!(PIO0_26, Bank::Bank0, 26); | ||
| 362 | impl_pin!(PIO0_27, Bank::Bank0, 27); | ||
| 363 | impl_pin!(PIO0_28, Bank::Bank0, 28); | ||
| 364 | impl_pin!(PIO0_29, Bank::Bank0, 29); | ||
| 365 | impl_pin!(PIO0_30, Bank::Bank0, 30); | ||
| 366 | impl_pin!(PIO0_31, Bank::Bank0, 31); | ||
| 367 | impl_pin!(PIO1_0, Bank::Bank1, 0); | ||
| 368 | impl_pin!(PIO1_1, Bank::Bank1, 1); | ||
| 369 | impl_pin!(PIO1_2, Bank::Bank1, 2); | ||
| 370 | impl_pin!(PIO1_3, Bank::Bank1, 3); | ||
| 371 | impl_pin!(PIO1_4, Bank::Bank1, 4); | ||
| 372 | impl_pin!(PIO1_5, Bank::Bank1, 5); | ||
| 373 | impl_pin!(PIO1_6, Bank::Bank1, 6); | ||
| 374 | impl_pin!(PIO1_7, Bank::Bank1, 7); | ||
| 375 | impl_pin!(PIO1_8, Bank::Bank1, 8); | ||
| 376 | impl_pin!(PIO1_9, Bank::Bank1, 9); | ||
| 377 | impl_pin!(PIO1_10, Bank::Bank1, 10); | ||
| 378 | impl_pin!(PIO1_11, Bank::Bank1, 11); | ||
| 379 | impl_pin!(PIO1_12, Bank::Bank1, 12); | ||
| 380 | impl_pin!(PIO1_13, Bank::Bank1, 13); | ||
| 381 | impl_pin!(PIO1_14, Bank::Bank1, 14); | ||
| 382 | impl_pin!(PIO1_15, Bank::Bank1, 15); | ||
| 383 | impl_pin!(PIO1_16, Bank::Bank1, 16); | ||
| 384 | impl_pin!(PIO1_17, Bank::Bank1, 17); | ||
| 385 | impl_pin!(PIO1_18, Bank::Bank1, 18); | ||
| 386 | impl_pin!(PIO1_19, Bank::Bank1, 19); | ||
| 387 | impl_pin!(PIO1_20, Bank::Bank1, 20); | ||
| 388 | impl_pin!(PIO1_21, Bank::Bank1, 21); | ||
| 389 | impl_pin!(PIO1_22, Bank::Bank1, 22); | ||
| 390 | impl_pin!(PIO1_23, Bank::Bank1, 23); | ||
| 391 | impl_pin!(PIO1_24, Bank::Bank1, 24); | ||
| 392 | impl_pin!(PIO1_25, Bank::Bank1, 25); | ||
| 393 | impl_pin!(PIO1_26, Bank::Bank1, 26); | ||
| 394 | impl_pin!(PIO1_27, Bank::Bank1, 27); | ||
| 395 | impl_pin!(PIO1_28, Bank::Bank1, 28); | ||
| 396 | impl_pin!(PIO1_29, Bank::Bank1, 29); | ||
| 397 | impl_pin!(PIO1_30, Bank::Bank1, 30); | ||
| 398 | impl_pin!(PIO1_31, Bank::Bank1, 31); | ||
diff --git a/embassy-nxp/src/gpio/rt1xxx.rs b/embassy-nxp/src/gpio/rt1xxx.rs index 1d60a0d51..8a560310c 100644 --- a/embassy-nxp/src/gpio/rt1xxx.rs +++ b/embassy-nxp/src/gpio/rt1xxx.rs | |||
| @@ -5,13 +5,13 @@ use core::ops::Not; | |||
| 5 | use core::pin::Pin as FuturePin; | 5 | use core::pin::Pin as FuturePin; |
| 6 | use core::task::{Context, Poll}; | 6 | use core::task::{Context, Poll}; |
| 7 | 7 | ||
| 8 | use embassy_hal_internal::{impl_peripheral, Peri, PeripheralType}; | 8 | use embassy_hal_internal::{Peri, PeripheralType, impl_peripheral}; |
| 9 | use embassy_sync::waitqueue::AtomicWaker; | 9 | use embassy_sync::waitqueue::AtomicWaker; |
| 10 | use nxp_pac::gpio::vals::Icr; | 10 | use nxp_pac::gpio::vals::Icr; |
| 11 | use nxp_pac::iomuxc::vals::Pus; | 11 | use nxp_pac::iomuxc::vals::Pus; |
| 12 | 12 | ||
| 13 | use crate::chip::{mux_address, pad_address}; | 13 | use crate::chip::{iomuxc_mux, iomuxc_pad}; |
| 14 | use crate::pac::common::{Reg, RW}; | 14 | use crate::pac::common::{RW, Reg}; |
| 15 | use crate::pac::gpio::Gpio; | 15 | use crate::pac::gpio::Gpio; |
| 16 | #[cfg(feature = "rt")] | 16 | #[cfg(feature = "rt")] |
| 17 | use crate::pac::interrupt; | 17 | use crate::pac::interrupt; |
| @@ -121,6 +121,10 @@ pub enum Bank { | |||
| 121 | /// Bank 5 | 121 | /// Bank 5 |
| 122 | #[cfg(gpio5)] | 122 | #[cfg(gpio5)] |
| 123 | Gpio5, | 123 | Gpio5, |
| 124 | |||
| 125 | #[cfg(gpio10)] | ||
| 126 | /// Bank 10 | ||
| 127 | Gpio10, | ||
| 124 | } | 128 | } |
| 125 | 129 | ||
| 126 | /// GPIO flexible pin. | 130 | /// GPIO flexible pin. |
| @@ -656,6 +660,8 @@ static GPIO3_WAKERS: [AtomicWaker; 32] = [const { AtomicWaker::new() }; 32]; | |||
| 656 | static GPIO4_WAKERS: [AtomicWaker; 32] = [const { AtomicWaker::new() }; 32]; | 660 | static GPIO4_WAKERS: [AtomicWaker; 32] = [const { AtomicWaker::new() }; 32]; |
| 657 | #[cfg(gpio5)] | 661 | #[cfg(gpio5)] |
| 658 | static GPIO5_WAKERS: [AtomicWaker; 32] = [const { AtomicWaker::new() }; 32]; | 662 | static GPIO5_WAKERS: [AtomicWaker; 32] = [const { AtomicWaker::new() }; 32]; |
| 663 | #[cfg(gpio10)] | ||
| 664 | static GPIO10_WAKERS: [AtomicWaker; 32] = [const { AtomicWaker::new() }; 32]; | ||
| 659 | 665 | ||
| 660 | /// Sealed trait for pins. This trait is sealed and cannot be implemented outside of this crate. | 666 | /// Sealed trait for pins. This trait is sealed and cannot be implemented outside of this crate. |
| 661 | pub(crate) trait SealedPin: Sized { | 667 | pub(crate) trait SealedPin: Sized { |
| @@ -676,13 +682,15 @@ pub(crate) trait SealedPin: Sized { | |||
| 676 | Bank::Gpio4 => pac::GPIO4, | 682 | Bank::Gpio4 => pac::GPIO4, |
| 677 | #[cfg(gpio5)] | 683 | #[cfg(gpio5)] |
| 678 | Bank::Gpio5 => pac::GPIO5, | 684 | Bank::Gpio5 => pac::GPIO5, |
| 685 | #[cfg(gpio10)] | ||
| 686 | Bank::Gpio10 => pac::GPIO10, | ||
| 679 | } | 687 | } |
| 680 | } | 688 | } |
| 681 | 689 | ||
| 682 | #[inline] | 690 | #[inline] |
| 683 | fn mux(&self) -> Reg<MuxCtl, RW> { | 691 | fn mux(&self) -> Reg<MuxCtl, RW> { |
| 684 | // SAFETY: The generated mux address table is valid since it is generated from the SVD files. | 692 | // SAFETY: The generated mux address table is valid since it is generated from the SVD files. |
| 685 | let address = unsafe { mux_address(self._bank(), self.pin_number()).unwrap_unchecked() }; | 693 | let address = unsafe { iomuxc_mux(self._bank(), self.pin_number()).unwrap_unchecked() }; |
| 686 | 694 | ||
| 687 | // SAFETY: The register at the address is an instance of MuxCtl. | 695 | // SAFETY: The register at the address is an instance of MuxCtl. |
| 688 | unsafe { Reg::from_ptr(address as *mut _) } | 696 | unsafe { Reg::from_ptr(address as *mut _) } |
| @@ -690,8 +698,7 @@ pub(crate) trait SealedPin: Sized { | |||
| 690 | 698 | ||
| 691 | #[inline] | 699 | #[inline] |
| 692 | fn pad(&self) -> Reg<Ctl, RW> { | 700 | fn pad(&self) -> Reg<Ctl, RW> { |
| 693 | // SAFETY: The generated pad address table is valid since it is generated from the SVD files. | 701 | let address = iomuxc_pad(self._bank(), self.pin_number()); |
| 694 | let address = unsafe { pad_address(self._bank(), self.pin_number()).unwrap_unchecked() }; | ||
| 695 | 702 | ||
| 696 | // SAFETY: The register at the address is an instance of Ctl. | 703 | // SAFETY: The register at the address is an instance of Ctl. |
| 697 | unsafe { Reg::from_ptr(address as *mut _) } | 704 | unsafe { Reg::from_ptr(address as *mut _) } |
| @@ -709,6 +716,8 @@ pub(crate) trait SealedPin: Sized { | |||
| 709 | Bank::Gpio4 => &GPIO4_WAKERS[self.pin_number() as usize], | 716 | Bank::Gpio4 => &GPIO4_WAKERS[self.pin_number() as usize], |
| 710 | #[cfg(gpio5)] | 717 | #[cfg(gpio5)] |
| 711 | Bank::Gpio5 => &GPIO5_WAKERS[self.pin_number() as usize], | 718 | Bank::Gpio5 => &GPIO5_WAKERS[self.pin_number() as usize], |
| 719 | #[cfg(gpio10)] | ||
| 720 | Bank::Gpio10 => &GPIO10_WAKERS[self.pin_number() as usize], | ||
| 712 | } | 721 | } |
| 713 | } | 722 | } |
| 714 | } | 723 | } |
| @@ -793,39 +802,6 @@ impl<'d> Future for InputFuture<'d> { | |||
| 793 | } | 802 | } |
| 794 | } | 803 | } |
| 795 | 804 | ||
| 796 | /// A macro to generate all GPIO pins. | ||
| 797 | /// | ||
| 798 | /// This generates a lookup table for IOMUX register addresses. | ||
| 799 | macro_rules! impl_gpio { | ||
| 800 | ( | ||
| 801 | $($name: ident($bank: ident, $pin_number: expr);)* | ||
| 802 | ) => { | ||
| 803 | #[inline] | ||
| 804 | pub(crate) const fn pad_address(bank: crate::gpio::Bank, pin: u8) -> Option<u32> { | ||
| 805 | match (bank, pin) { | ||
| 806 | $( | ||
| 807 | (crate::gpio::Bank::$bank, $pin_number) => Some(crate::chip::_generated::iomuxc::pads::$name), | ||
| 808 | )* | ||
| 809 | _ => None | ||
| 810 | } | ||
| 811 | } | ||
| 812 | |||
| 813 | #[inline] | ||
| 814 | pub(crate) const fn mux_address(bank: crate::gpio::Bank, pin: u8) -> Option<u32> { | ||
| 815 | match (bank, pin) { | ||
| 816 | $( | ||
| 817 | (crate::gpio::Bank::$bank, $pin_number) => Some(crate::chip::_generated::iomuxc::muxes::$name), | ||
| 818 | )* | ||
| 819 | _ => None | ||
| 820 | } | ||
| 821 | } | ||
| 822 | |||
| 823 | $( | ||
| 824 | impl_pin!($name, $bank, $pin_number); | ||
| 825 | )* | ||
| 826 | }; | ||
| 827 | } | ||
| 828 | |||
| 829 | macro_rules! impl_pin { | 805 | macro_rules! impl_pin { |
| 830 | ($name: ident, $bank: ident, $pin_num: expr) => { | 806 | ($name: ident, $bank: ident, $pin_num: expr) => { |
| 831 | impl crate::gpio::Pin for crate::peripherals::$name {} | 807 | impl crate::gpio::Pin for crate::peripherals::$name {} |
diff --git a/embassy-nxp/src/iomuxc.rs b/embassy-nxp/src/iomuxc.rs new file mode 100644 index 000000000..c015ecbc2 --- /dev/null +++ b/embassy-nxp/src/iomuxc.rs | |||
| @@ -0,0 +1,29 @@ | |||
| 1 | #![macro_use] | ||
| 2 | |||
| 3 | /// An IOMUXC pad. | ||
| 4 | /// | ||
| 5 | /// This trait does not imply that GPIO can be used with this pad. [`Pin`](crate::gpio::Pin) must | ||
| 6 | /// also be implemented for GPIO. | ||
| 7 | #[allow(private_bounds)] | ||
| 8 | pub trait Pad: SealedPad {} | ||
| 9 | |||
| 10 | pub(crate) trait SealedPad { | ||
| 11 | /// Address of the pad register for this pad. | ||
| 12 | const PAD: *mut (); | ||
| 13 | |||
| 14 | /// Address of the mux register for this pad. | ||
| 15 | /// | ||
| 16 | /// Some pads do not allow muxing (e.g. ONOFF). | ||
| 17 | const MUX: Option<*mut ()>; | ||
| 18 | } | ||
| 19 | |||
| 20 | macro_rules! impl_iomuxc_pad { | ||
| 21 | ($name: ident, $pad: expr, $mux: expr) => { | ||
| 22 | impl crate::iomuxc::SealedPad for crate::peripherals::$name { | ||
| 23 | const PAD: *mut () = $pad as *mut (); | ||
| 24 | const MUX: Option<*mut ()> = Some($mux as *mut ()); | ||
| 25 | } | ||
| 26 | |||
| 27 | impl crate::iomuxc::Pad for crate::peripherals::$name {} | ||
| 28 | }; | ||
| 29 | } | ||
diff --git a/embassy-nxp/src/lib.rs b/embassy-nxp/src/lib.rs index f0f0afb6c..4c3dbebb9 100644 --- a/embassy-nxp/src/lib.rs +++ b/embassy-nxp/src/lib.rs | |||
| @@ -1,4 +1,5 @@ | |||
| 1 | #![no_std] | 1 | #![no_std] |
| 2 | #![allow(unsafe_op_in_unsafe_fn)] | ||
| 2 | 3 | ||
| 3 | // This mod MUST go first, so that the others see its macros. | 4 | // This mod MUST go first, so that the others see its macros. |
| 4 | pub(crate) mod fmt; | 5 | pub(crate) mod fmt; |
| @@ -9,8 +10,15 @@ pub mod gpio; | |||
| 9 | #[cfg(feature = "lpc55-core0")] | 10 | #[cfg(feature = "lpc55-core0")] |
| 10 | pub mod pint; | 11 | pub mod pint; |
| 11 | #[cfg(feature = "lpc55-core0")] | 12 | #[cfg(feature = "lpc55-core0")] |
| 13 | pub mod pwm; | ||
| 14 | #[cfg(feature = "lpc55-core0")] | ||
| 15 | pub mod sct; | ||
| 16 | #[cfg(feature = "lpc55-core0")] | ||
| 12 | pub mod usart; | 17 | pub mod usart; |
| 13 | 18 | ||
| 19 | #[cfg(rt1xxx)] | ||
| 20 | mod iomuxc; | ||
| 21 | |||
| 14 | #[cfg(feature = "_time_driver")] | 22 | #[cfg(feature = "_time_driver")] |
| 15 | #[cfg_attr(feature = "time-driver-pit", path = "time_driver/pit.rs")] | 23 | #[cfg_attr(feature = "time-driver-pit", path = "time_driver/pit.rs")] |
| 16 | #[cfg_attr(feature = "time-driver-rtc", path = "time_driver/rtc.rs")] | 24 | #[cfg_attr(feature = "time-driver-rtc", path = "time_driver/rtc.rs")] |
| @@ -22,15 +30,12 @@ mod time_driver; | |||
| 22 | #[cfg_attr(feature = "mimxrt1062", path = "chips/mimxrt1062.rs")] | 30 | #[cfg_attr(feature = "mimxrt1062", path = "chips/mimxrt1062.rs")] |
| 23 | mod chip; | 31 | mod chip; |
| 24 | 32 | ||
| 25 | // TODO: Remove when this module is implemented for other chips | 33 | pub use chip::{Peripherals, interrupt, peripherals}; |
| 26 | #[cfg(feature = "lpc55-core0")] | 34 | pub use embassy_hal_internal::{Peri, PeripheralType}; |
| 27 | pub use chip::interrupt; | ||
| 28 | #[cfg(feature = "unstable-pac")] | 35 | #[cfg(feature = "unstable-pac")] |
| 29 | pub use chip::pac; | 36 | pub use nxp_pac as pac; |
| 30 | #[cfg(not(feature = "unstable-pac"))] | 37 | #[cfg(not(feature = "unstable-pac"))] |
| 31 | pub(crate) use chip::pac; | 38 | pub(crate) use nxp_pac as pac; |
| 32 | pub use chip::{peripherals, Peripherals}; | ||
| 33 | pub use embassy_hal_internal::{Peri, PeripheralType}; | ||
| 34 | 39 | ||
| 35 | /// Macro to bind interrupts to handlers. | 40 | /// Macro to bind interrupts to handlers. |
| 36 | /// (Copied from `embassy-rp`) | 41 | /// (Copied from `embassy-rp`) |
| @@ -67,7 +72,7 @@ macro_rules! bind_interrupts { | |||
| 67 | 72 | ||
| 68 | $( | 73 | $( |
| 69 | #[allow(non_snake_case)] | 74 | #[allow(non_snake_case)] |
| 70 | #[no_mangle] | 75 | #[unsafe(no_mangle)] |
| 71 | $(#[cfg($cond_irq)])? | 76 | $(#[cfg($cond_irq)])? |
| 72 | unsafe extern "C" fn $irq() { | 77 | unsafe extern "C" fn $irq() { |
| 73 | unsafe { | 78 | unsafe { |
| @@ -153,7 +158,10 @@ pub fn init(_config: config::Config) -> Peripherals { | |||
| 153 | gpio::init(); | 158 | gpio::init(); |
| 154 | 159 | ||
| 155 | #[cfg(feature = "lpc55-core0")] | 160 | #[cfg(feature = "lpc55-core0")] |
| 156 | pint::init(); | 161 | { |
| 162 | pint::init(); | ||
| 163 | pwm::Pwm::reset(); | ||
| 164 | } | ||
| 157 | 165 | ||
| 158 | #[cfg(feature = "_time_driver")] | 166 | #[cfg(feature = "_time_driver")] |
| 159 | time_driver::init(); | 167 | time_driver::init(); |
diff --git a/embassy-nxp/src/pint.rs b/embassy-nxp/src/pint.rs index e594aaa6a..5b10b4540 100644 --- a/embassy-nxp/src/pint.rs +++ b/embassy-nxp/src/pint.rs | |||
| @@ -8,9 +8,9 @@ use critical_section::Mutex; | |||
| 8 | use embassy_hal_internal::interrupt::InterruptExt; | 8 | use embassy_hal_internal::interrupt::InterruptExt; |
| 9 | use embassy_sync::waitqueue::AtomicWaker; | 9 | use embassy_sync::waitqueue::AtomicWaker; |
| 10 | 10 | ||
| 11 | use crate::gpio::{self, AnyPin, Level, SealedPin}; | ||
| 12 | use crate::pac::{interrupt, INPUTMUX, PINT, SYSCON}; | ||
| 13 | use crate::Peri; | 11 | use crate::Peri; |
| 12 | use crate::gpio::{self, AnyPin, Level, SealedPin}; | ||
| 13 | use crate::pac::{INPUTMUX, PINT, SYSCON, interrupt}; | ||
| 14 | 14 | ||
| 15 | struct PinInterrupt { | 15 | struct PinInterrupt { |
| 16 | assigned: bool, | 16 | assigned: bool, |
diff --git a/embassy-nxp/src/pwm.rs b/embassy-nxp/src/pwm.rs new file mode 100644 index 000000000..c87a39c34 --- /dev/null +++ b/embassy-nxp/src/pwm.rs | |||
| @@ -0,0 +1,7 @@ | |||
| 1 | #![macro_use] | ||
| 2 | |||
| 3 | //! Pulse-Width Modulation (PWM) driver. | ||
| 4 | |||
| 5 | #[cfg_attr(feature = "lpc55-core0", path = "./pwm/lpc55.rs")] | ||
| 6 | mod inner; | ||
| 7 | pub use inner::*; | ||
diff --git a/embassy-nxp/src/pwm/lpc55.rs b/embassy-nxp/src/pwm/lpc55.rs new file mode 100644 index 000000000..4cdbd8526 --- /dev/null +++ b/embassy-nxp/src/pwm/lpc55.rs | |||
| @@ -0,0 +1,248 @@ | |||
| 1 | #![macro_use] | ||
| 2 | |||
| 3 | use core::sync::atomic::{AtomicU8, AtomicU32, Ordering}; | ||
| 4 | |||
| 5 | use embassy_hal_internal::Peri; | ||
| 6 | |||
| 7 | use crate::gpio::AnyPin; | ||
| 8 | use crate::pac::iocon::vals::{PioDigimode, PioMode, PioOd, PioSlew}; | ||
| 9 | use crate::pac::sct0::vals; | ||
| 10 | use crate::pac::syscon::vals::{SctRst, SctclkselSel}; | ||
| 11 | use crate::pac::{SCT0, SYSCON}; | ||
| 12 | use crate::sct; | ||
| 13 | |||
| 14 | // Since for now the counter is shared, the TOP value has to be kept. | ||
| 15 | static TOP_VALUE: AtomicU32 = AtomicU32::new(0); | ||
| 16 | // To check if there are still active instances. | ||
| 17 | static REF_COUNT: AtomicU8 = AtomicU8::new(0); | ||
| 18 | |||
| 19 | /// The configuration of a PWM output. | ||
| 20 | /// Note the period in clock cycles of an output can be computed as: | ||
| 21 | /// `(top + 1) * (phase_correct ? 1 : 2) * divider * prescale_factor` | ||
| 22 | /// By default, the clock used is 96 MHz. | ||
| 23 | #[non_exhaustive] | ||
| 24 | #[derive(Clone)] | ||
| 25 | pub struct Config { | ||
| 26 | /// Inverts the PWM output signal. | ||
| 27 | pub invert: bool, | ||
| 28 | /// Enables phase-correct mode for PWM operation. | ||
| 29 | /// In phase-correct mode, the PWM signal is generated in such a way that | ||
| 30 | /// the pulse is always centered regardless of the duty cycle. | ||
| 31 | /// The output frequency is halved when phase-correct mode is enabled. | ||
| 32 | pub phase_correct: bool, | ||
| 33 | /// Enables the PWM output, allowing it to generate an output. | ||
| 34 | pub enable: bool, | ||
| 35 | /// A SYSCON clock divider allows precise control over | ||
| 36 | /// the PWM output frequency by gating the PWM counter increment. | ||
| 37 | /// A higher value will result in a slower output frequency. | ||
| 38 | /// The clock is divided by `divider + 1`. | ||
| 39 | pub divider: u8, | ||
| 40 | /// Specifies the factor by which the SCT clock is prescaled to produce the unified | ||
| 41 | /// counter clock. The counter clock is clocked at the rate of the SCT clock divided by | ||
| 42 | /// `PRE + 1`. | ||
| 43 | pub prescale_factor: u8, | ||
| 44 | /// The output goes high when `compare` is higher than the | ||
| 45 | /// counter. A compare of 0 will produce an always low output, while a | ||
| 46 | /// compare of `top` will produce an always high output. | ||
| 47 | pub compare: u32, | ||
| 48 | /// The point at which the counter resets, representing the maximum possible | ||
| 49 | /// period. The counter will either wrap to 0 or reverse depending on the | ||
| 50 | /// setting of `phase_correct`. | ||
| 51 | pub top: u32, | ||
| 52 | } | ||
| 53 | |||
| 54 | impl Config { | ||
| 55 | pub fn new(compare: u32, top: u32) -> Self { | ||
| 56 | Self { | ||
| 57 | invert: false, | ||
| 58 | phase_correct: false, | ||
| 59 | enable: true, | ||
| 60 | divider: 255, | ||
| 61 | prescale_factor: 255, | ||
| 62 | compare, | ||
| 63 | top, | ||
| 64 | } | ||
| 65 | } | ||
| 66 | } | ||
| 67 | |||
| 68 | /// PWM driver. | ||
| 69 | pub struct Pwm<'d> { | ||
| 70 | _pin: Peri<'d, AnyPin>, | ||
| 71 | output: usize, | ||
| 72 | } | ||
| 73 | |||
| 74 | impl<'d> Pwm<'d> { | ||
| 75 | pub(crate) fn reset() { | ||
| 76 | // Reset SCTimer => Reset counter and halt it. | ||
| 77 | // It should be done only once during the initialization of the board. | ||
| 78 | SYSCON.presetctrl1().modify(|w| w.set_sct_rst(SctRst::ASSERTED)); | ||
| 79 | SYSCON.presetctrl1().modify(|w| w.set_sct_rst(SctRst::RELEASED)); | ||
| 80 | } | ||
| 81 | fn new_inner<T: sct::Instance, O: sct::Output<T>>( | ||
| 82 | output: usize, | ||
| 83 | channel: Peri<'d, impl sct::OutputPin<T, O>>, | ||
| 84 | config: Config, | ||
| 85 | ) -> Self { | ||
| 86 | // Enable clocks (Syscon is enabled by default) | ||
| 87 | critical_section::with(|_cs| { | ||
| 88 | if !SYSCON.ahbclkctrl0().read().iocon() { | ||
| 89 | SYSCON.ahbclkctrl0().modify(|w| w.set_iocon(true)); | ||
| 90 | } | ||
| 91 | if !SYSCON.ahbclkctrl1().read().sct() { | ||
| 92 | SYSCON.ahbclkctrl1().modify(|w| w.set_sct(true)); | ||
| 93 | } | ||
| 94 | }); | ||
| 95 | |||
| 96 | // Choose the clock for PWM. | ||
| 97 | SYSCON.sctclksel().modify(|w| w.set_sel(SctclkselSel::ENUM_0X3)); | ||
| 98 | // For now, 96 MHz. | ||
| 99 | |||
| 100 | // IOCON Setup | ||
| 101 | channel.pio().modify(|w| { | ||
| 102 | w.set_func(channel.pin_func()); | ||
| 103 | w.set_digimode(PioDigimode::DIGITAL); | ||
| 104 | w.set_slew(PioSlew::STANDARD); | ||
| 105 | w.set_mode(PioMode::INACTIVE); | ||
| 106 | w.set_od(PioOd::NORMAL); | ||
| 107 | }); | ||
| 108 | |||
| 109 | Self::configure(output, &config); | ||
| 110 | REF_COUNT.fetch_add(1, Ordering::Relaxed); | ||
| 111 | Self { | ||
| 112 | _pin: channel.into(), | ||
| 113 | output, | ||
| 114 | } | ||
| 115 | } | ||
| 116 | |||
| 117 | /// Create PWM driver with a single 'a' pin as output. | ||
| 118 | #[inline] | ||
| 119 | pub fn new_output<T: sct::Instance, O: sct::Output<T>>( | ||
| 120 | output: Peri<'d, O>, | ||
| 121 | channel: Peri<'d, impl sct::OutputPin<T, O>>, | ||
| 122 | config: Config, | ||
| 123 | ) -> Self { | ||
| 124 | Self::new_inner::<T, O>(output.number(), channel, config) | ||
| 125 | } | ||
| 126 | |||
| 127 | /// Set the PWM config. | ||
| 128 | pub fn set_config(&mut self, config: &Config) { | ||
| 129 | Self::configure(self.output, config); | ||
| 130 | } | ||
| 131 | |||
| 132 | fn configure(output_number: usize, config: &Config) { | ||
| 133 | // Stop and reset the counter | ||
| 134 | SCT0.ctrl().modify(|w| { | ||
| 135 | if config.phase_correct { | ||
| 136 | w.set_bidir_l(vals::Bidir::UP_DOWN); | ||
| 137 | } else { | ||
| 138 | w.set_bidir_l(vals::Bidir::UP); | ||
| 139 | } | ||
| 140 | w.set_halt_l(true); // halt the counter to make new changes | ||
| 141 | w.set_clrctr_l(true); // clear the counter | ||
| 142 | }); | ||
| 143 | // Divides clock by 1-255 | ||
| 144 | SYSCON.sctclkdiv().modify(|w| w.set_div(config.divider)); | ||
| 145 | |||
| 146 | SCT0.config().modify(|w| { | ||
| 147 | w.set_unify(vals::Unify::UNIFIED_COUNTER); | ||
| 148 | w.set_clkmode(vals::Clkmode::SYSTEM_CLOCK_MODE); | ||
| 149 | w.set_noreload_l(true); | ||
| 150 | w.set_autolimit_l(true); | ||
| 151 | }); | ||
| 152 | |||
| 153 | // Before setting the match registers, we have to make sure that `compare` is lower or equal to `top`, | ||
| 154 | // otherwise the counter will not reach the match and, therefore, no events will happen. | ||
| 155 | assert!(config.compare <= config.top); | ||
| 156 | |||
| 157 | if TOP_VALUE.load(Ordering::Relaxed) == 0 { | ||
| 158 | // Match 0 will reset the timer using TOP value | ||
| 159 | SCT0.match_(0).modify(|w| { | ||
| 160 | w.set_matchn_l((config.top & 0xFFFF) as u16); | ||
| 161 | w.set_matchn_h((config.top >> 16) as u16); | ||
| 162 | }); | ||
| 163 | } else { | ||
| 164 | panic!("The top value cannot be changed after the initialization."); | ||
| 165 | } | ||
| 166 | // The actual matches that are used for event logic | ||
| 167 | SCT0.match_(output_number + 1).modify(|w| { | ||
| 168 | w.set_matchn_l((config.compare & 0xFFFF) as u16); | ||
| 169 | w.set_matchn_h((config.compare >> 16) as u16); | ||
| 170 | }); | ||
| 171 | |||
| 172 | SCT0.match_(15).modify(|w| { | ||
| 173 | w.set_matchn_l(0); | ||
| 174 | w.set_matchn_h(0); | ||
| 175 | }); | ||
| 176 | |||
| 177 | // Event configuration | ||
| 178 | critical_section::with(|_cs| { | ||
| 179 | // If it is already set, don't change | ||
| 180 | if SCT0.ev(0).ev_ctrl().read().matchsel() != 15 { | ||
| 181 | SCT0.ev(0).ev_ctrl().modify(|w| { | ||
| 182 | w.set_matchsel(15); | ||
| 183 | w.set_combmode(vals::Combmode::MATCH); | ||
| 184 | // STATE + statev, where STATE is a on-board variable. | ||
| 185 | w.set_stateld(vals::Stateld::ADD); | ||
| 186 | w.set_statev(0); | ||
| 187 | }); | ||
| 188 | } | ||
| 189 | }); | ||
| 190 | SCT0.ev(output_number + 1).ev_ctrl().modify(|w| { | ||
| 191 | w.set_matchsel((output_number + 1) as u8); | ||
| 192 | w.set_combmode(vals::Combmode::MATCH); | ||
| 193 | w.set_stateld(vals::Stateld::ADD); | ||
| 194 | // STATE + statev, where STATE is a on-board variable. | ||
| 195 | w.set_statev(0); | ||
| 196 | }); | ||
| 197 | |||
| 198 | // Assign events to states | ||
| 199 | SCT0.ev(0).ev_state().modify(|w| w.set_statemskn(1 << 0)); | ||
| 200 | SCT0.ev(output_number + 1) | ||
| 201 | .ev_state() | ||
| 202 | .modify(|w| w.set_statemskn(1 << 0)); | ||
| 203 | // TODO(frihetselsker): optimize nxp-pac so that `set_clr` and `set_set` are turned into a bit array. | ||
| 204 | if config.invert { | ||
| 205 | // Low when event 0 is active | ||
| 206 | SCT0.out(output_number).out_clr().modify(|w| w.set_clr(0, true)); | ||
| 207 | // High when event `output_number + 1` is active | ||
| 208 | SCT0.out(output_number) | ||
| 209 | .out_set() | ||
| 210 | .modify(|w| w.set_set(output_number, true)); | ||
| 211 | } else { | ||
| 212 | // High when event 0 is active | ||
| 213 | SCT0.out(output_number).out_set().modify(|w| w.set_set(0, true)); | ||
| 214 | // Low when event `output_number + 1` is active | ||
| 215 | SCT0.out(output_number) | ||
| 216 | .out_clr() | ||
| 217 | .modify(|w| w.set_clr(output_number, true)); | ||
| 218 | } | ||
| 219 | |||
| 220 | if config.phase_correct { | ||
| 221 | // Take into account the set matches and reverse their actions while counting back. | ||
| 222 | SCT0.outputdirctrl() | ||
| 223 | .modify(|w| w.set_setclr(output_number, vals::Setclr::L_REVERSED)); | ||
| 224 | } | ||
| 225 | |||
| 226 | // State 0 by default | ||
| 227 | SCT0.state().modify(|w| w.set_state_l(0)); | ||
| 228 | // Remove halt and start the actual counter | ||
| 229 | SCT0.ctrl().modify(|w| { | ||
| 230 | w.set_halt_l(!config.enable); | ||
| 231 | }); | ||
| 232 | } | ||
| 233 | |||
| 234 | /// Read PWM counter. | ||
| 235 | #[inline] | ||
| 236 | pub fn counter(&self) -> u32 { | ||
| 237 | SCT0.count().read().0 | ||
| 238 | } | ||
| 239 | } | ||
| 240 | |||
| 241 | impl<'d> Drop for Pwm<'d> { | ||
| 242 | fn drop(&mut self) { | ||
| 243 | REF_COUNT.fetch_sub(1, Ordering::AcqRel); | ||
| 244 | if REF_COUNT.load(Ordering::Acquire) == 0 { | ||
| 245 | TOP_VALUE.store(0, Ordering::Release); | ||
| 246 | } | ||
| 247 | } | ||
| 248 | } | ||
diff --git a/embassy-nxp/src/sct.rs b/embassy-nxp/src/sct.rs new file mode 100644 index 000000000..b6b0e35a9 --- /dev/null +++ b/embassy-nxp/src/sct.rs | |||
| @@ -0,0 +1,56 @@ | |||
| 1 | #![macro_use] | ||
| 2 | |||
| 3 | use embassy_hal_internal::PeripheralType; | ||
| 4 | use nxp_pac::iocon::vals::PioFunc; | ||
| 5 | |||
| 6 | use crate::gpio; | ||
| 7 | |||
| 8 | /// SCT instance. | ||
| 9 | #[allow(private_bounds)] | ||
| 10 | pub trait Instance: SealedInstance + PeripheralType {} | ||
| 11 | |||
| 12 | pub(crate) trait SealedInstance {} | ||
| 13 | |||
| 14 | /// An SCT output. | ||
| 15 | #[allow(private_bounds)] | ||
| 16 | pub trait Output<T: Instance>: SealedOutput + PeripheralType {} | ||
| 17 | |||
| 18 | pub(crate) trait SealedOutput { | ||
| 19 | /// Output number. | ||
| 20 | fn number(&self) -> usize; | ||
| 21 | } | ||
| 22 | |||
| 23 | /// An SCT output capable pin. | ||
| 24 | pub trait OutputPin<T: Instance, O: Output<T>>: gpio::Pin { | ||
| 25 | fn pin_func(&self) -> PioFunc; | ||
| 26 | } | ||
| 27 | |||
| 28 | macro_rules! impl_sct_instance { | ||
| 29 | ($instance: ident) => { | ||
| 30 | impl crate::sct::SealedInstance for crate::peripherals::$instance {} | ||
| 31 | impl crate::sct::Instance for crate::peripherals::$instance {} | ||
| 32 | }; | ||
| 33 | } | ||
| 34 | |||
| 35 | macro_rules! impl_sct_output_instance { | ||
| 36 | ($instance: ident, $name: ident, $num: expr) => { | ||
| 37 | impl crate::sct::SealedOutput for crate::peripherals::$name { | ||
| 38 | fn number(&self) -> usize { | ||
| 39 | $num as usize | ||
| 40 | } | ||
| 41 | } | ||
| 42 | impl crate::sct::Output<crate::peripherals::$instance> for crate::peripherals::$name {} | ||
| 43 | }; | ||
| 44 | } | ||
| 45 | |||
| 46 | macro_rules! impl_sct_output_pin { | ||
| 47 | ($instance: ident, $output_instance: ident, $pin: ident, $alt: ident) => { | ||
| 48 | impl crate::sct::OutputPin<crate::peripherals::$instance, crate::peripherals::$output_instance> | ||
| 49 | for crate::peripherals::$pin | ||
| 50 | { | ||
| 51 | fn pin_func(&self) -> crate::pac::iocon::vals::PioFunc { | ||
| 52 | crate::pac::iocon::vals::PioFunc::$alt | ||
| 53 | } | ||
| 54 | } | ||
| 55 | }; | ||
| 56 | } | ||
diff --git a/embassy-nxp/src/time_driver/rtc.rs b/embassy-nxp/src/time_driver/rtc.rs index fb6de6a5e..0883fa2e8 100644 --- a/embassy-nxp/src/time_driver/rtc.rs +++ b/embassy-nxp/src/time_driver/rtc.rs | |||
| @@ -4,10 +4,10 @@ use core::task::Waker; | |||
| 4 | use critical_section::CriticalSection; | 4 | use critical_section::CriticalSection; |
| 5 | use embassy_hal_internal::interrupt::{InterruptExt, Priority}; | 5 | use embassy_hal_internal::interrupt::{InterruptExt, Priority}; |
| 6 | use embassy_sync::blocking_mutex::CriticalSectionMutex as Mutex; | 6 | use embassy_sync::blocking_mutex::CriticalSectionMutex as Mutex; |
| 7 | use embassy_time_driver::{time_driver_impl, Driver}; | 7 | use embassy_time_driver::{Driver, time_driver_impl}; |
| 8 | use embassy_time_queue_utils::Queue; | 8 | use embassy_time_queue_utils::Queue; |
| 9 | 9 | ||
| 10 | use crate::pac::{interrupt, pmc, rtc, PMC, RTC, SYSCON}; | 10 | use crate::pac::{PMC, RTC, SYSCON, interrupt, pmc, rtc}; |
| 11 | 11 | ||
| 12 | struct AlarmState { | 12 | struct AlarmState { |
| 13 | timestamp: Cell<u64>, | 13 | timestamp: Cell<u64>, |
diff --git a/embassy-nxp/src/usart.rs b/embassy-nxp/src/usart.rs index 1d8886f24..af039dee4 100644 --- a/embassy-nxp/src/usart.rs +++ b/embassy-nxp/src/usart.rs | |||
| @@ -1,3 +1,5 @@ | |||
| 1 | #![macro_use] | ||
| 2 | |||
| 1 | //! Universal Synchronous/Asynchronous Receiver/Transmitter (USART) driver. | 3 | //! Universal Synchronous/Asynchronous Receiver/Transmitter (USART) driver. |
| 2 | 4 | ||
| 3 | #[cfg_attr(feature = "lpc55-core0", path = "./usart/lpc55.rs")] | 5 | #[cfg_attr(feature = "lpc55-core0", path = "./usart/lpc55.rs")] |
diff --git a/embassy-nxp/src/usart/lpc55.rs b/embassy-nxp/src/usart/lpc55.rs index 9034ed429..d77f08fd8 100644 --- a/embassy-nxp/src/usart/lpc55.rs +++ b/embassy-nxp/src/usart/lpc55.rs | |||
| @@ -1,19 +1,21 @@ | |||
| 1 | #![macro_use] | ||
| 2 | |||
| 1 | use core::fmt::Debug; | 3 | use core::fmt::Debug; |
| 2 | use core::future::poll_fn; | 4 | use core::future::poll_fn; |
| 3 | use core::marker::PhantomData; | 5 | use core::marker::PhantomData; |
| 4 | use core::sync::atomic::{AtomicBool, Ordering}; | 6 | use core::sync::atomic::{AtomicBool, Ordering}; |
| 5 | use core::task::Poll; | 7 | use core::task::Poll; |
| 6 | 8 | ||
| 7 | use embassy_futures::select::{select, Either}; | 9 | use embassy_futures::select::{Either, select}; |
| 8 | use embassy_hal_internal::interrupt::InterruptExt; | 10 | use embassy_hal_internal::interrupt::InterruptExt; |
| 9 | use embassy_hal_internal::{Peri, PeripheralType}; | 11 | use embassy_hal_internal::{Peri, PeripheralType}; |
| 10 | use embassy_sync::waitqueue::AtomicWaker; | 12 | use embassy_sync::waitqueue::AtomicWaker; |
| 11 | use embedded_io::{self, ErrorKind}; | 13 | use embedded_io::{self, ErrorKind}; |
| 12 | 14 | ||
| 13 | use crate::dma::{AnyChannel, Channel}; | 15 | use crate::dma::{AnyChannel, Channel}; |
| 14 | use crate::gpio::{match_iocon, AnyPin, Bank, SealedPin}; | 16 | use crate::gpio::{AnyPin, SealedPin}; |
| 15 | use crate::interrupt::typelevel::{Binding, Interrupt as _}; | ||
| 16 | use crate::interrupt::Interrupt; | 17 | use crate::interrupt::Interrupt; |
| 18 | use crate::interrupt::typelevel::Binding; | ||
| 17 | use crate::pac::flexcomm::Flexcomm as FlexcommReg; | 19 | use crate::pac::flexcomm::Flexcomm as FlexcommReg; |
| 18 | use crate::pac::iocon::vals::PioFunc; | 20 | use crate::pac::iocon::vals::PioFunc; |
| 19 | use crate::pac::usart::Usart as UsartReg; | 21 | use crate::pac::usart::Usart as UsartReg; |
| @@ -113,8 +115,8 @@ impl Default for Config { | |||
| 113 | 115 | ||
| 114 | /// Internal DMA state of UART RX. | 116 | /// Internal DMA state of UART RX. |
| 115 | pub struct DmaState { | 117 | pub struct DmaState { |
| 116 | rx_err_waker: AtomicWaker, | 118 | pub(crate) rx_err_waker: AtomicWaker, |
| 117 | rx_err: AtomicBool, | 119 | pub(crate) rx_err: AtomicBool, |
| 118 | } | 120 | } |
| 119 | 121 | ||
| 120 | /// # Type parameters | 122 | /// # Type parameters |
| @@ -146,7 +148,8 @@ impl<'d, M: Mode> UsartTx<'d, M> { | |||
| 146 | tx_dma: Peri<'d, impl Channel>, | 148 | tx_dma: Peri<'d, impl Channel>, |
| 147 | config: Config, | 149 | config: Config, |
| 148 | ) -> Self { | 150 | ) -> Self { |
| 149 | Usart::<M>::init::<T>(Some(tx.into()), None, config); | 151 | let tx_func = tx.pin_func(); |
| 152 | Usart::<M>::init::<T>(Some((tx.into(), tx_func)), None, config); | ||
| 150 | Self::new_inner(T::info(), Some(tx_dma.into())) | 153 | Self::new_inner(T::info(), Some(tx_dma.into())) |
| 151 | } | 154 | } |
| 152 | 155 | ||
| @@ -179,7 +182,8 @@ impl<'d, M: Mode> UsartTx<'d, M> { | |||
| 179 | 182 | ||
| 180 | impl<'d> UsartTx<'d, Blocking> { | 183 | impl<'d> UsartTx<'d, Blocking> { |
| 181 | pub fn new_blocking<T: Instance>(_usart: Peri<'d, T>, tx: Peri<'d, impl TxPin<T>>, config: Config) -> Self { | 184 | pub fn new_blocking<T: Instance>(_usart: Peri<'d, T>, tx: Peri<'d, impl TxPin<T>>, config: Config) -> Self { |
| 182 | Usart::<Blocking>::init::<T>(Some(tx.into()), None, config); | 185 | let tx_func = tx.pin_func(); |
| 186 | Usart::<Blocking>::init::<T>(Some((tx.into(), tx_func)), None, config); | ||
| 183 | Self::new_inner(T::info(), None) | 187 | Self::new_inner(T::info(), None) |
| 184 | } | 188 | } |
| 185 | } | 189 | } |
| @@ -208,7 +212,8 @@ impl<'d, M: Mode> UsartRx<'d, M> { | |||
| 208 | rx_dma: Peri<'d, impl Channel>, | 212 | rx_dma: Peri<'d, impl Channel>, |
| 209 | config: Config, | 213 | config: Config, |
| 210 | ) -> Self { | 214 | ) -> Self { |
| 211 | Usart::<M>::init::<T>(None, Some(rx.into()), config); | 215 | let rx_func = rx.pin_func(); |
| 216 | Usart::<M>::init::<T>(None, Some((rx.into(), rx_func)), config); | ||
| 212 | Self::new_inner(T::info(), T::dma_state(), has_irq, Some(rx_dma.into())) | 217 | Self::new_inner(T::info(), T::dma_state(), has_irq, Some(rx_dma.into())) |
| 213 | } | 218 | } |
| 214 | 219 | ||
| @@ -280,7 +285,8 @@ impl<'d, M: Mode> UsartRx<'d, M> { | |||
| 280 | 285 | ||
| 281 | impl<'d> UsartRx<'d, Blocking> { | 286 | impl<'d> UsartRx<'d, Blocking> { |
| 282 | pub fn new_blocking<T: Instance>(_usart: Peri<'d, T>, rx: Peri<'d, impl RxPin<T>>, config: Config) -> Self { | 287 | pub fn new_blocking<T: Instance>(_usart: Peri<'d, T>, rx: Peri<'d, impl RxPin<T>>, config: Config) -> Self { |
| 283 | Usart::<Blocking>::init::<T>(None, Some(rx.into()), config); | 288 | let rx_func = rx.pin_func(); |
| 289 | Usart::<Blocking>::init::<T>(None, Some((rx.into(), rx_func)), config); | ||
| 284 | Self::new_inner(T::info(), T::dma_state(), false, None) | 290 | Self::new_inner(T::info(), T::dma_state(), false, None) |
| 285 | } | 291 | } |
| 286 | } | 292 | } |
| @@ -405,7 +411,10 @@ impl<'d> Usart<'d, Blocking> { | |||
| 405 | rx: Peri<'d, impl RxPin<T>>, | 411 | rx: Peri<'d, impl RxPin<T>>, |
| 406 | config: Config, | 412 | config: Config, |
| 407 | ) -> Self { | 413 | ) -> Self { |
| 408 | Self::new_inner(usart, tx.into(), rx.into(), false, None, None, config) | 414 | let tx_func = tx.pin_func(); |
| 415 | let rx_func = rx.pin_func(); | ||
| 416 | |||
| 417 | Self::new_inner(usart, tx.into(), tx_func, rx.into(), rx_func, false, None, None, config) | ||
| 409 | } | 418 | } |
| 410 | } | 419 | } |
| 411 | 420 | ||
| @@ -419,10 +428,15 @@ impl<'d> Usart<'d, Async> { | |||
| 419 | rx_dma: Peri<'d, impl RxChannel<T>>, | 428 | rx_dma: Peri<'d, impl RxChannel<T>>, |
| 420 | config: Config, | 429 | config: Config, |
| 421 | ) -> Self { | 430 | ) -> Self { |
| 431 | let tx_func = tx.pin_func(); | ||
| 432 | let rx_func = rx.pin_func(); | ||
| 433 | |||
| 422 | Self::new_inner( | 434 | Self::new_inner( |
| 423 | uart, | 435 | uart, |
| 424 | tx.into(), | 436 | tx.into(), |
| 437 | tx_func, | ||
| 425 | rx.into(), | 438 | rx.into(), |
| 439 | rx_func, | ||
| 426 | true, | 440 | true, |
| 427 | Some(tx_dma.into()), | 441 | Some(tx_dma.into()), |
| 428 | Some(rx_dma.into()), | 442 | Some(rx_dma.into()), |
| @@ -435,20 +449,26 @@ impl<'d, M: Mode> Usart<'d, M> { | |||
| 435 | fn new_inner<T: Instance>( | 449 | fn new_inner<T: Instance>( |
| 436 | _usart: Peri<'d, T>, | 450 | _usart: Peri<'d, T>, |
| 437 | mut tx: Peri<'d, AnyPin>, | 451 | mut tx: Peri<'d, AnyPin>, |
| 452 | tx_func: PioFunc, | ||
| 438 | mut rx: Peri<'d, AnyPin>, | 453 | mut rx: Peri<'d, AnyPin>, |
| 454 | rx_func: PioFunc, | ||
| 439 | has_irq: bool, | 455 | has_irq: bool, |
| 440 | tx_dma: Option<Peri<'d, AnyChannel>>, | 456 | tx_dma: Option<Peri<'d, AnyChannel>>, |
| 441 | rx_dma: Option<Peri<'d, AnyChannel>>, | 457 | rx_dma: Option<Peri<'d, AnyChannel>>, |
| 442 | config: Config, | 458 | config: Config, |
| 443 | ) -> Self { | 459 | ) -> Self { |
| 444 | Self::init::<T>(Some(tx.reborrow()), Some(rx.reborrow()), config); | 460 | Self::init::<T>(Some((tx.reborrow(), tx_func)), Some((rx.reborrow(), rx_func)), config); |
| 445 | Self { | 461 | Self { |
| 446 | tx: UsartTx::new_inner(T::info(), tx_dma), | 462 | tx: UsartTx::new_inner(T::info(), tx_dma), |
| 447 | rx: UsartRx::new_inner(T::info(), T::dma_state(), has_irq, rx_dma), | 463 | rx: UsartRx::new_inner(T::info(), T::dma_state(), has_irq, rx_dma), |
| 448 | } | 464 | } |
| 449 | } | 465 | } |
| 450 | 466 | ||
| 451 | fn init<T: Instance>(tx: Option<Peri<'_, AnyPin>>, rx: Option<Peri<'_, AnyPin>>, config: Config) { | 467 | fn init<T: Instance>( |
| 468 | tx: Option<(Peri<'_, AnyPin>, PioFunc)>, | ||
| 469 | rx: Option<(Peri<'_, AnyPin>, PioFunc)>, | ||
| 470 | config: Config, | ||
| 471 | ) { | ||
| 452 | Self::configure_flexcomm(T::info().fc_reg, T::instance_number()); | 472 | Self::configure_flexcomm(T::info().fc_reg, T::instance_number()); |
| 453 | Self::configure_clock::<T>(&config); | 473 | Self::configure_clock::<T>(&config); |
| 454 | Self::pin_config::<T>(tx, rx); | 474 | Self::pin_config::<T>(tx, rx); |
| @@ -553,31 +573,27 @@ impl<'d, M: Mode> Usart<'d, M> { | |||
| 553 | .modify(|w| w.set_brgval((brg_value - 1) as u16)); | 573 | .modify(|w| w.set_brgval((brg_value - 1) as u16)); |
| 554 | } | 574 | } |
| 555 | 575 | ||
| 556 | fn pin_config<T: Instance>(tx: Option<Peri<'_, AnyPin>>, rx: Option<Peri<'_, AnyPin>>) { | 576 | fn pin_config<T: Instance>(tx: Option<(Peri<'_, AnyPin>, PioFunc)>, rx: Option<(Peri<'_, AnyPin>, PioFunc)>) { |
| 557 | if let Some(tx_pin) = tx { | 577 | if let Some((tx_pin, func)) = tx { |
| 558 | match_iocon!(register, tx_pin.pin_bank(), tx_pin.pin_number(), { | 578 | tx_pin.pio().modify(|w| { |
| 559 | register.modify(|w| { | 579 | w.set_func(func); |
| 560 | w.set_func(T::tx_pin_func()); | 580 | w.set_mode(iocon::vals::PioMode::INACTIVE); |
| 561 | w.set_mode(iocon::vals::PioMode::INACTIVE); | 581 | w.set_slew(iocon::vals::PioSlew::STANDARD); |
| 562 | w.set_slew(iocon::vals::PioSlew::STANDARD); | 582 | w.set_invert(false); |
| 563 | w.set_invert(false); | 583 | w.set_digimode(iocon::vals::PioDigimode::DIGITAL); |
| 564 | w.set_digimode(iocon::vals::PioDigimode::DIGITAL); | 584 | w.set_od(iocon::vals::PioOd::NORMAL); |
| 565 | w.set_od(iocon::vals::PioOd::NORMAL); | 585 | }); |
| 566 | }); | ||
| 567 | }) | ||
| 568 | } | 586 | } |
| 569 | 587 | ||
| 570 | if let Some(rx_pin) = rx { | 588 | if let Some((rx_pin, func)) = rx { |
| 571 | match_iocon!(register, rx_pin.pin_bank(), rx_pin.pin_number(), { | 589 | rx_pin.pio().modify(|w| { |
| 572 | register.modify(|w| { | 590 | w.set_func(func); |
| 573 | w.set_func(T::rx_pin_func()); | 591 | w.set_mode(iocon::vals::PioMode::INACTIVE); |
| 574 | w.set_mode(iocon::vals::PioMode::INACTIVE); | 592 | w.set_slew(iocon::vals::PioSlew::STANDARD); |
| 575 | w.set_slew(iocon::vals::PioSlew::STANDARD); | 593 | w.set_invert(false); |
| 576 | w.set_invert(false); | 594 | w.set_digimode(iocon::vals::PioDigimode::DIGITAL); |
| 577 | w.set_digimode(iocon::vals::PioDigimode::DIGITAL); | 595 | w.set_od(iocon::vals::PioOd::NORMAL); |
| 578 | w.set_od(iocon::vals::PioOd::NORMAL); | 596 | }); |
| 579 | }); | ||
| 580 | }) | ||
| 581 | }; | 597 | }; |
| 582 | } | 598 | } |
| 583 | 599 | ||
| @@ -804,18 +820,16 @@ impl<'d> embedded_io::Read for Usart<'d, Blocking> { | |||
| 804 | } | 820 | } |
| 805 | } | 821 | } |
| 806 | 822 | ||
| 807 | struct Info { | 823 | pub(crate) struct Info { |
| 808 | usart_reg: UsartReg, | 824 | pub(crate) usart_reg: UsartReg, |
| 809 | fc_reg: FlexcommReg, | 825 | pub(crate) fc_reg: FlexcommReg, |
| 810 | interrupt: Interrupt, | 826 | pub(crate) interrupt: Interrupt, |
| 811 | } | 827 | } |
| 812 | 828 | ||
| 813 | trait SealedInstance { | 829 | pub(crate) trait SealedInstance { |
| 814 | fn info() -> &'static Info; | 830 | fn info() -> &'static Info; |
| 815 | fn dma_state() -> &'static DmaState; | 831 | fn dma_state() -> &'static DmaState; |
| 816 | fn instance_number() -> usize; | 832 | fn instance_number() -> usize; |
| 817 | fn tx_pin_func() -> PioFunc; | ||
| 818 | fn rx_pin_func() -> PioFunc; | ||
| 819 | } | 833 | } |
| 820 | 834 | ||
| 821 | /// UART instance. | 835 | /// UART instance. |
| @@ -825,10 +839,13 @@ pub trait Instance: SealedInstance + PeripheralType { | |||
| 825 | type Interrupt: crate::interrupt::typelevel::Interrupt; | 839 | type Interrupt: crate::interrupt::typelevel::Interrupt; |
| 826 | } | 840 | } |
| 827 | 841 | ||
| 828 | macro_rules! impl_instance { | 842 | macro_rules! impl_usart_instance { |
| 829 | ($inst:ident, $fc:ident, $tx_pin:ident, $rx_pin:ident, $fc_num:expr) => { | 843 | ($inst:ident, $fc:ident, $fc_num:expr) => { |
| 830 | impl $crate::usart::inner::SealedInstance for $crate::peripherals::$inst { | 844 | impl crate::usart::SealedInstance for $crate::peripherals::$inst { |
| 831 | fn info() -> &'static Info { | 845 | fn info() -> &'static crate::usart::Info { |
| 846 | use crate::interrupt::typelevel::Interrupt; | ||
| 847 | use crate::usart::Info; | ||
| 848 | |||
| 832 | static INFO: Info = Info { | 849 | static INFO: Info = Info { |
| 833 | usart_reg: crate::pac::$inst, | 850 | usart_reg: crate::pac::$inst, |
| 834 | fc_reg: crate::pac::$fc, | 851 | fc_reg: crate::pac::$fc, |
| @@ -837,7 +854,13 @@ macro_rules! impl_instance { | |||
| 837 | &INFO | 854 | &INFO |
| 838 | } | 855 | } |
| 839 | 856 | ||
| 840 | fn dma_state() -> &'static DmaState { | 857 | fn dma_state() -> &'static crate::usart::DmaState { |
| 858 | use core::sync::atomic::AtomicBool; | ||
| 859 | |||
| 860 | use embassy_sync::waitqueue::AtomicWaker; | ||
| 861 | |||
| 862 | use crate::usart::DmaState; | ||
| 863 | |||
| 841 | static STATE: DmaState = DmaState { | 864 | static STATE: DmaState = DmaState { |
| 842 | rx_err_waker: AtomicWaker::new(), | 865 | rx_err_waker: AtomicWaker::new(), |
| 843 | rx_err: AtomicBool::new(false), | 866 | rx_err: AtomicBool::new(false), |
| @@ -848,14 +871,6 @@ macro_rules! impl_instance { | |||
| 848 | fn instance_number() -> usize { | 871 | fn instance_number() -> usize { |
| 849 | $fc_num | 872 | $fc_num |
| 850 | } | 873 | } |
| 851 | #[inline] | ||
| 852 | fn tx_pin_func() -> PioFunc { | ||
| 853 | PioFunc::$tx_pin | ||
| 854 | } | ||
| 855 | #[inline] | ||
| 856 | fn rx_pin_func() -> PioFunc { | ||
| 857 | PioFunc::$rx_pin | ||
| 858 | } | ||
| 859 | } | 874 | } |
| 860 | impl $crate::usart::Instance for $crate::peripherals::$inst { | 875 | impl $crate::usart::Instance for $crate::peripherals::$inst { |
| 861 | type Interrupt = crate::interrupt::typelevel::$fc; | 876 | type Interrupt = crate::interrupt::typelevel::$fc; |
| @@ -863,73 +878,62 @@ macro_rules! impl_instance { | |||
| 863 | }; | 878 | }; |
| 864 | } | 879 | } |
| 865 | 880 | ||
| 866 | impl_instance!(USART0, FLEXCOMM0, ALT1, ALT1, 0); | 881 | pub(crate) trait SealedTxPin<T: Instance>: crate::gpio::Pin { |
| 867 | impl_instance!(USART1, FLEXCOMM1, ALT2, ALT2, 1); | 882 | fn pin_func(&self) -> PioFunc; |
| 868 | impl_instance!(USART2, FLEXCOMM2, ALT1, ALT1, 2); | 883 | } |
| 869 | impl_instance!(USART3, FLEXCOMM3, ALT1, ALT1, 3); | 884 | |
| 870 | impl_instance!(USART4, FLEXCOMM4, ALT1, ALT2, 4); | 885 | pub(crate) trait SealedRxPin<T: Instance>: crate::gpio::Pin { |
| 871 | impl_instance!(USART5, FLEXCOMM5, ALT3, ALT3, 5); | 886 | fn pin_func(&self) -> PioFunc; |
| 872 | impl_instance!(USART6, FLEXCOMM6, ALT2, ALT2, 6); | 887 | } |
| 873 | impl_instance!(USART7, FLEXCOMM7, ALT7, ALT7, 7); | ||
| 874 | 888 | ||
| 875 | /// Trait for TX pins. | 889 | /// Trait for TX pins. |
| 876 | pub trait TxPin<T: Instance>: crate::gpio::Pin {} | 890 | #[allow(private_bounds)] |
| 891 | pub trait TxPin<T: Instance>: SealedTxPin<T> + crate::gpio::Pin {} | ||
| 892 | |||
| 877 | /// Trait for RX pins. | 893 | /// Trait for RX pins. |
| 878 | pub trait RxPin<T: Instance>: crate::gpio::Pin {} | 894 | #[allow(private_bounds)] |
| 895 | pub trait RxPin<T: Instance>: SealedRxPin<T> + crate::gpio::Pin {} | ||
| 896 | |||
| 897 | macro_rules! impl_usart_txd_pin { | ||
| 898 | ($pin:ident, $instance:ident, $func: ident) => { | ||
| 899 | impl crate::usart::SealedTxPin<crate::peripherals::$instance> for crate::peripherals::$pin { | ||
| 900 | fn pin_func(&self) -> crate::pac::iocon::vals::PioFunc { | ||
| 901 | use crate::pac::iocon::vals::PioFunc; | ||
| 902 | PioFunc::$func | ||
| 903 | } | ||
| 904 | } | ||
| 879 | 905 | ||
| 880 | macro_rules! impl_pin { | 906 | impl crate::usart::TxPin<crate::peripherals::$instance> for crate::peripherals::$pin {} |
| 881 | ($pin:ident, $instance:ident, Tx) => { | ||
| 882 | impl TxPin<crate::peripherals::$instance> for crate::peripherals::$pin {} | ||
| 883 | }; | 907 | }; |
| 884 | ($pin:ident, $instance:ident, Rx) => { | 908 | } |
| 885 | impl RxPin<crate::peripherals::$instance> for crate::peripherals::$pin {} | 909 | |
| 910 | macro_rules! impl_usart_rxd_pin { | ||
| 911 | ($pin:ident, $instance:ident, $func: ident) => { | ||
| 912 | impl crate::usart::SealedRxPin<crate::peripherals::$instance> for crate::peripherals::$pin { | ||
| 913 | fn pin_func(&self) -> crate::pac::iocon::vals::PioFunc { | ||
| 914 | use crate::pac::iocon::vals::PioFunc; | ||
| 915 | PioFunc::$func | ||
| 916 | } | ||
| 917 | } | ||
| 918 | |||
| 919 | impl crate::usart::RxPin<crate::peripherals::$instance> for crate::peripherals::$pin {} | ||
| 886 | }; | 920 | }; |
| 887 | } | 921 | } |
| 888 | 922 | ||
| 889 | impl_pin!(PIO1_6, USART0, Tx); | 923 | /// Marker trait indicating a DMA channel may be used for USART transmit. |
| 890 | impl_pin!(PIO1_5, USART0, Rx); | ||
| 891 | impl_pin!(PIO1_11, USART1, Tx); | ||
| 892 | impl_pin!(PIO1_10, USART1, Rx); | ||
| 893 | impl_pin!(PIO0_27, USART2, Tx); | ||
| 894 | impl_pin!(PIO1_24, USART2, Rx); | ||
| 895 | impl_pin!(PIO0_2, USART3, Tx); | ||
| 896 | impl_pin!(PIO0_3, USART3, Rx); | ||
| 897 | impl_pin!(PIO0_16, USART4, Tx); | ||
| 898 | impl_pin!(PIO0_5, USART4, Rx); | ||
| 899 | impl_pin!(PIO0_9, USART5, Tx); | ||
| 900 | impl_pin!(PIO0_8, USART5, Rx); | ||
| 901 | impl_pin!(PIO1_16, USART6, Tx); | ||
| 902 | impl_pin!(PIO1_13, USART6, Rx); | ||
| 903 | impl_pin!(PIO0_19, USART7, Tx); | ||
| 904 | impl_pin!(PIO0_20, USART7, Rx); | ||
| 905 | |||
| 906 | /// Trait for TX DMA channels. | ||
| 907 | pub trait TxChannel<T: Instance>: crate::dma::Channel {} | 924 | pub trait TxChannel<T: Instance>: crate::dma::Channel {} |
| 908 | /// Trait for RX DMA channels. | 925 | |
| 926 | /// Marker trait indicating a DMA channel may be used for USART recieve. | ||
| 909 | pub trait RxChannel<T: Instance>: crate::dma::Channel {} | 927 | pub trait RxChannel<T: Instance>: crate::dma::Channel {} |
| 910 | 928 | ||
| 911 | macro_rules! impl_channel { | 929 | macro_rules! impl_usart_tx_channel { |
| 912 | ($dma:ident, $instance:ident, Tx) => { | 930 | ($instance: ident, $channel: ident) => { |
| 913 | impl TxChannel<crate::peripherals::$instance> for crate::peripherals::$dma {} | 931 | impl crate::usart::TxChannel<crate::peripherals::$instance> for crate::peripherals::$channel {} |
| 914 | }; | ||
| 915 | ($dma:ident, $instance:ident, Rx) => { | ||
| 916 | impl RxChannel<crate::peripherals::$instance> for crate::peripherals::$dma {} | ||
| 917 | }; | 932 | }; |
| 918 | } | 933 | } |
| 919 | 934 | ||
| 920 | impl_channel!(DMA_CH4, USART0, Rx); | 935 | macro_rules! impl_usart_rx_channel { |
| 921 | impl_channel!(DMA_CH5, USART0, Tx); | 936 | ($instance: ident, $channel: ident) => { |
| 922 | impl_channel!(DMA_CH6, USART1, Rx); | 937 | impl crate::usart::RxChannel<crate::peripherals::$instance> for crate::peripherals::$channel {} |
| 923 | impl_channel!(DMA_CH7, USART1, Tx); | 938 | }; |
| 924 | impl_channel!(DMA_CH10, USART2, Rx); | 939 | } |
| 925 | impl_channel!(DMA_CH11, USART2, Tx); | ||
| 926 | impl_channel!(DMA_CH8, USART3, Rx); | ||
| 927 | impl_channel!(DMA_CH9, USART3, Tx); | ||
| 928 | impl_channel!(DMA_CH12, USART4, Rx); | ||
| 929 | impl_channel!(DMA_CH13, USART4, Tx); | ||
| 930 | impl_channel!(DMA_CH14, USART5, Rx); | ||
| 931 | impl_channel!(DMA_CH15, USART5, Tx); | ||
| 932 | impl_channel!(DMA_CH16, USART6, Rx); | ||
| 933 | impl_channel!(DMA_CH17, USART6, Tx); | ||
| 934 | impl_channel!(DMA_CH18, USART7, Rx); | ||
| 935 | impl_channel!(DMA_CH19, USART7, Tx); | ||
