diff options
| -rwxr-xr-x | ci.sh | 2 | ||||
| -rw-r--r-- | embassy-nxp/Cargo.toml | 16 | ||||
| -rw-r--r-- | embassy-nxp/src/chips/lpc55.rs | 70 | ||||
| -rw-r--r-- | embassy-nxp/src/gpio.rs | 357 | ||||
| -rw-r--r-- | embassy-nxp/src/gpio/lpc55.rs (renamed from embassy-nxp/src/pac_utils.rs) | 354 | ||||
| -rw-r--r-- | embassy-nxp/src/lib.rs | 90 | ||||
| -rw-r--r-- | embassy-nxp/src/pint.rs | 3 | ||||
| -rw-r--r-- | examples/lpc55s69/Cargo.toml | 2 |
8 files changed, 461 insertions, 433 deletions
| @@ -178,7 +178,7 @@ cargo batch \ | |||
| 178 | --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv6m-none-eabi --features stm32u031r8,defmt,exti,time-driver-any,time \ | 178 | --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv6m-none-eabi --features stm32u031r8,defmt,exti,time-driver-any,time \ |
| 179 | --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv6m-none-eabi --features stm32u073mb,defmt,exti,time-driver-any,time \ | 179 | --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv6m-none-eabi --features stm32u073mb,defmt,exti,time-driver-any,time \ |
| 180 | --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv6m-none-eabi --features stm32u083rc,defmt,exti,time-driver-any,time \ | 180 | --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv6m-none-eabi --features stm32u083rc,defmt,exti,time-driver-any,time \ |
| 181 | --- build --release --manifest-path embassy-nxp/Cargo.toml --target thumbv8m.main-none-eabihf \ | 181 | --- build --release --manifest-path embassy-nxp/Cargo.toml --target thumbv8m.main-none-eabihf --features lpc55,defmt \ |
| 182 | --- build --release --manifest-path embassy-mspm0/Cargo.toml --target thumbv6m-none-eabi --features mspm0c1104dgs20,defmt,time-driver-any \ | 182 | --- build --release --manifest-path embassy-mspm0/Cargo.toml --target thumbv6m-none-eabi --features mspm0c1104dgs20,defmt,time-driver-any \ |
| 183 | --- build --release --manifest-path embassy-mspm0/Cargo.toml --target thumbv6m-none-eabi --features mspm0g3507pm,defmt,time-driver-any \ | 183 | --- build --release --manifest-path embassy-mspm0/Cargo.toml --target thumbv6m-none-eabi --features mspm0g3507pm,defmt,time-driver-any \ |
| 184 | --- build --release --manifest-path embassy-mspm0/Cargo.toml --target thumbv6m-none-eabi --features mspm0g3519pz,defmt,time-driver-any \ | 184 | --- build --release --manifest-path embassy-mspm0/Cargo.toml --target thumbv6m-none-eabi --features mspm0g3519pz,defmt,time-driver-any \ |
diff --git a/embassy-nxp/Cargo.toml b/embassy-nxp/Cargo.toml index 426af06a0..18e9d989c 100644 --- a/embassy-nxp/Cargo.toml +++ b/embassy-nxp/Cargo.toml | |||
| @@ -9,12 +9,24 @@ cortex-m-rt = "0.7.0" | |||
| 9 | critical-section = "1.1.2" | 9 | critical-section = "1.1.2" |
| 10 | embassy-hal-internal = { version = "0.2.0", path = "../embassy-hal-internal", features = ["cortex-m", "prio-bits-2"] } | 10 | embassy-hal-internal = { version = "0.2.0", path = "../embassy-hal-internal", features = ["cortex-m", "prio-bits-2"] } |
| 11 | embassy-sync = { version = "0.7.0", path = "../embassy-sync" } | 11 | embassy-sync = { version = "0.7.0", path = "../embassy-sync" } |
| 12 | lpc55-pac = "0.5.0" | ||
| 13 | defmt = { version = "1", optional = true } | 12 | defmt = { version = "1", optional = true } |
| 14 | 13 | ||
| 14 | ## Chip dependencies | ||
| 15 | lpc55-pac = { version = "0.5.0", optional = true } | ||
| 16 | |||
| 15 | [features] | 17 | [features] |
| 16 | default = ["rt"] | 18 | default = ["rt"] |
| 17 | rt = ["lpc55-pac/rt"] | 19 | # Enable PACs as optional dependencies, since some chip families will use different pac crates. |
| 20 | rt = ["lpc55-pac?/rt"] | ||
| 18 | 21 | ||
| 19 | ## Enable [defmt support](https://docs.rs/defmt) and enables `defmt` debug-log messages and formatting in embassy drivers. | 22 | ## Enable [defmt support](https://docs.rs/defmt) and enables `defmt` debug-log messages and formatting in embassy drivers. |
| 20 | defmt = ["dep:defmt", "embassy-hal-internal/defmt", "embassy-sync/defmt"] | 23 | defmt = ["dep:defmt", "embassy-hal-internal/defmt", "embassy-sync/defmt"] |
| 24 | |||
| 25 | ## Reexport the PAC for the currently enabled chip at `embassy_nxp::pac` (unstable) | ||
| 26 | unstable-pac = [] | ||
| 27 | # This is unstable because semver-minor (non-breaking) releases of embassy-nrf may major-bump (breaking) the PAC version. | ||
| 28 | # If this is an issue for you, you're encouraged to directly depend on a fixed version of the PAC. | ||
| 29 | # There are no plans to make this stable. | ||
| 30 | |||
| 31 | #! ### Chip selection features | ||
| 32 | lpc55 = ["lpc55-pac"] | ||
diff --git a/embassy-nxp/src/chips/lpc55.rs b/embassy-nxp/src/chips/lpc55.rs new file mode 100644 index 000000000..c95218af0 --- /dev/null +++ b/embassy-nxp/src/chips/lpc55.rs | |||
| @@ -0,0 +1,70 @@ | |||
| 1 | pub use lpc55_pac as pac; | ||
| 2 | |||
| 3 | embassy_hal_internal::peripherals! { | ||
| 4 | // External pins. These are not only GPIOs, they are multi-purpose pins and can be used by other | ||
| 5 | // peripheral types (e.g. I2C). | ||
| 6 | PIO0_0, | ||
| 7 | PIO0_1, | ||
| 8 | PIO0_2, | ||
| 9 | PIO0_3, | ||
| 10 | PIO0_4, | ||
| 11 | PIO0_5, | ||
| 12 | PIO0_6, | ||
| 13 | PIO0_7, | ||
| 14 | PIO0_8, | ||
| 15 | PIO0_9, | ||
| 16 | PIO0_10, | ||
| 17 | PIO0_11, | ||
| 18 | PIO0_12, | ||
| 19 | PIO0_13, | ||
| 20 | PIO0_14, | ||
| 21 | PIO0_15, | ||
| 22 | PIO0_16, | ||
| 23 | PIO0_17, | ||
| 24 | PIO0_18, | ||
| 25 | PIO0_19, | ||
| 26 | PIO0_20, | ||
| 27 | PIO0_21, | ||
| 28 | PIO0_22, | ||
| 29 | PIO0_23, | ||
| 30 | PIO0_24, | ||
| 31 | PIO0_25, | ||
| 32 | PIO0_26, | ||
| 33 | PIO0_27, | ||
| 34 | PIO0_28, | ||
| 35 | PIO0_29, | ||
| 36 | PIO0_30, | ||
| 37 | PIO0_31, | ||
| 38 | PIO1_0, | ||
| 39 | PIO1_1, | ||
| 40 | PIO1_2, | ||
| 41 | PIO1_3, | ||
| 42 | PIO1_4, | ||
| 43 | PIO1_5, | ||
| 44 | PIO1_6, | ||
| 45 | PIO1_7, | ||
| 46 | PIO1_8, | ||
| 47 | PIO1_9, | ||
| 48 | PIO1_10, | ||
| 49 | PIO1_11, | ||
| 50 | PIO1_12, | ||
| 51 | PIO1_13, | ||
| 52 | PIO1_14, | ||
| 53 | PIO1_15, | ||
| 54 | PIO1_16, | ||
| 55 | PIO1_17, | ||
| 56 | PIO1_18, | ||
| 57 | PIO1_19, | ||
| 58 | PIO1_20, | ||
| 59 | PIO1_21, | ||
| 60 | PIO1_22, | ||
| 61 | PIO1_23, | ||
| 62 | PIO1_24, | ||
| 63 | PIO1_25, | ||
| 64 | PIO1_26, | ||
| 65 | PIO1_27, | ||
| 66 | PIO1_28, | ||
| 67 | PIO1_29, | ||
| 68 | PIO1_30, | ||
| 69 | PIO1_31, | ||
| 70 | } | ||
diff --git a/embassy-nxp/src/gpio.rs b/embassy-nxp/src/gpio.rs index c7c78ce61..809903d97 100644 --- a/embassy-nxp/src/gpio.rs +++ b/embassy-nxp/src/gpio.rs | |||
| @@ -1,354 +1,5 @@ | |||
| 1 | use embassy_hal_internal::{impl_peripheral, PeripheralType}; | 1 | //! General purpose input/output (GPIO) driver. |
| 2 | 2 | ||
| 3 | use crate::pac_utils::*; | 3 | #[cfg_attr(feature = "lpc55", path = "./gpio/lpc55.rs")] |
| 4 | use crate::{peripherals, Peri}; | 4 | mod inner; |
| 5 | 5 | pub use inner::*; | |
| 6 | pub(crate) fn init() { | ||
| 7 | // Enable clocks for GPIO, PINT, and IOCON | ||
| 8 | syscon_reg() | ||
| 9 | .ahbclkctrl0 | ||
| 10 | .modify(|_, w| w.gpio0().enable().gpio1().enable().mux().enable().iocon().enable()); | ||
| 11 | } | ||
| 12 | |||
| 13 | /// The GPIO pin level for pins set on "Digital" mode. | ||
| 14 | #[derive(Debug, Eq, PartialEq, Clone, Copy)] | ||
| 15 | pub enum Level { | ||
| 16 | /// Logical low. Corresponds to 0V. | ||
| 17 | Low, | ||
| 18 | /// Logical high. Corresponds to VDD. | ||
| 19 | High, | ||
| 20 | } | ||
| 21 | |||
| 22 | /// Pull setting for a GPIO input set on "Digital" mode. | ||
| 23 | #[derive(Debug, Clone, Copy, Eq, PartialEq)] | ||
| 24 | pub enum Pull { | ||
| 25 | /// No pull. | ||
| 26 | None, | ||
| 27 | /// Internal pull-up resistor. | ||
| 28 | Up, | ||
| 29 | /// Internal pull-down resistor. | ||
| 30 | Down, | ||
| 31 | } | ||
| 32 | |||
| 33 | /// The LPC55 boards have two GPIO banks, each with 32 pins. This enum represents the two banks. | ||
| 34 | #[derive(Debug, Eq, PartialEq, Clone, Copy)] | ||
| 35 | pub enum Bank { | ||
| 36 | Bank0 = 0, | ||
| 37 | Bank1 = 1, | ||
| 38 | } | ||
| 39 | |||
| 40 | /// GPIO output driver. Internally, this is a specialized [Flex] pin. | ||
| 41 | pub struct Output<'d> { | ||
| 42 | pub(crate) pin: Flex<'d>, | ||
| 43 | } | ||
| 44 | |||
| 45 | impl<'d> Output<'d> { | ||
| 46 | /// Create GPIO output driver for a [Pin] with the provided [initial output](Level). | ||
| 47 | #[inline] | ||
| 48 | pub fn new(pin: Peri<'d, impl Pin>, initial_output: Level) -> Self { | ||
| 49 | let mut pin = Flex::new(pin); | ||
| 50 | pin.set_as_output(); | ||
| 51 | let mut result = Self { pin }; | ||
| 52 | |||
| 53 | match initial_output { | ||
| 54 | Level::High => result.set_high(), | ||
| 55 | Level::Low => result.set_low(), | ||
| 56 | }; | ||
| 57 | |||
| 58 | result | ||
| 59 | } | ||
| 60 | |||
| 61 | pub fn set_high(&mut self) { | ||
| 62 | gpio_reg().set[self.pin.pin_bank() as usize].write(|w| unsafe { w.bits(self.pin.bit()) }) | ||
| 63 | } | ||
| 64 | |||
| 65 | pub fn set_low(&mut self) { | ||
| 66 | gpio_reg().clr[self.pin.pin_bank() as usize].write(|w| unsafe { w.bits(self.pin.bit()) }) | ||
| 67 | } | ||
| 68 | |||
| 69 | pub fn toggle(&mut self) { | ||
| 70 | gpio_reg().not[self.pin.pin_bank() as usize].write(|w| unsafe { w.bits(self.pin.bit()) }) | ||
| 71 | } | ||
| 72 | |||
| 73 | /// Get the current output level of the pin. Note that the value returned by this function is | ||
| 74 | /// the voltage level reported by the pin, not the value set by the output driver. | ||
| 75 | pub fn level(&self) -> Level { | ||
| 76 | let bits = gpio_reg().pin[self.pin.pin_bank() as usize].read().bits(); | ||
| 77 | if bits & self.pin.bit() != 0 { | ||
| 78 | Level::High | ||
| 79 | } else { | ||
| 80 | Level::Low | ||
| 81 | } | ||
| 82 | } | ||
| 83 | } | ||
| 84 | |||
| 85 | /// GPIO input driver. Internally, this is a specialized [Flex] pin. | ||
| 86 | pub struct Input<'d> { | ||
| 87 | pub(crate) pin: Flex<'d>, | ||
| 88 | } | ||
| 89 | |||
| 90 | impl<'d> Input<'d> { | ||
| 91 | /// Create GPIO output driver for a [Pin] with the provided [Pull]. | ||
| 92 | #[inline] | ||
| 93 | pub fn new(pin: Peri<'d, impl Pin>, pull: Pull) -> Self { | ||
| 94 | let mut pin = Flex::new(pin); | ||
| 95 | pin.set_as_input(); | ||
| 96 | let mut result = Self { pin }; | ||
| 97 | result.set_pull(pull); | ||
| 98 | |||
| 99 | result | ||
| 100 | } | ||
| 101 | |||
| 102 | /// Set the pull configuration for the pin. To disable the pull, use [Pull::None]. | ||
| 103 | pub fn set_pull(&mut self, pull: Pull) { | ||
| 104 | match_iocon!(register, iocon_reg(), self.pin.pin_bank(), self.pin.pin_number(), { | ||
| 105 | register.modify(|_, w| match pull { | ||
| 106 | Pull::None => w.mode().inactive(), | ||
| 107 | Pull::Up => w.mode().pull_up(), | ||
| 108 | Pull::Down => w.mode().pull_down(), | ||
| 109 | }); | ||
| 110 | }); | ||
| 111 | } | ||
| 112 | |||
| 113 | /// Get the current input level of the pin. | ||
| 114 | pub fn read(&self) -> Level { | ||
| 115 | let bits = gpio_reg().pin[self.pin.pin_bank() as usize].read().bits(); | ||
| 116 | if bits & self.pin.bit() != 0 { | ||
| 117 | Level::High | ||
| 118 | } else { | ||
| 119 | Level::Low | ||
| 120 | } | ||
| 121 | } | ||
| 122 | } | ||
| 123 | |||
| 124 | /// A flexible GPIO (digital mode) pin whose mode is not yet determined. Under the hood, this is a | ||
| 125 | /// reference to a type-erased pin called ["AnyPin"](AnyPin). | ||
| 126 | pub struct Flex<'d> { | ||
| 127 | pub(crate) pin: Peri<'d, AnyPin>, | ||
| 128 | } | ||
| 129 | |||
| 130 | impl<'d> Flex<'d> { | ||
| 131 | /// Wrap the pin in a `Flex`. | ||
| 132 | /// | ||
| 133 | /// Note: you cannot assume that the pin will be in Digital mode after this call. | ||
| 134 | #[inline] | ||
| 135 | pub fn new(pin: Peri<'d, impl Pin>) -> Self { | ||
| 136 | Self { pin: pin.into() } | ||
| 137 | } | ||
| 138 | |||
| 139 | /// Get the bank of this pin. See also [Bank]. | ||
| 140 | /// | ||
| 141 | /// # Example | ||
| 142 | /// | ||
| 143 | /// ``` | ||
| 144 | /// use embassy_nxp::gpio::{Bank, Flex}; | ||
| 145 | /// | ||
| 146 | /// let p = embassy_nxp::init(Default::default()); | ||
| 147 | /// let pin = Flex::new(p.PIO1_15); | ||
| 148 | /// | ||
| 149 | /// assert_eq!(pin.pin_bank(), Bank::Bank1); | ||
| 150 | /// ``` | ||
| 151 | pub fn pin_bank(&self) -> Bank { | ||
| 152 | self.pin.pin_bank() | ||
| 153 | } | ||
| 154 | |||
| 155 | /// Get the number of this pin within its bank. See also [Bank]. | ||
| 156 | /// | ||
| 157 | /// # Example | ||
| 158 | /// | ||
| 159 | /// ``` | ||
| 160 | /// use embassy_nxp::gpio::Flex; | ||
| 161 | /// | ||
| 162 | /// let p = embassy_nxp::init(Default::default()); | ||
| 163 | /// let pin = Flex::new(p.PIO1_15); | ||
| 164 | /// | ||
| 165 | /// assert_eq!(pin.pin_number(), 15 as u8); | ||
| 166 | /// ``` | ||
| 167 | pub fn pin_number(&self) -> u8 { | ||
| 168 | self.pin.pin_number() | ||
| 169 | } | ||
| 170 | |||
| 171 | /// Get the bit mask for this pin. Useful for setting or clearing bits in a register. Note: | ||
| 172 | /// PIOx_0 is bit 0, PIOx_1 is bit 1, etc. | ||
| 173 | /// | ||
| 174 | /// # Example | ||
| 175 | /// | ||
| 176 | /// ``` | ||
| 177 | /// use embassy_nxp::gpio::Flex; | ||
| 178 | /// | ||
| 179 | /// let p = embassy_nxp::init(Default::default()); | ||
| 180 | /// let pin = Flex::new(p.PIO1_3); | ||
| 181 | /// | ||
| 182 | /// assert_eq!(pin.bit(), 0b0000_1000); | ||
| 183 | /// ``` | ||
| 184 | pub fn bit(&self) -> u32 { | ||
| 185 | 1 << self.pin.pin_number() | ||
| 186 | } | ||
| 187 | |||
| 188 | /// Set the pin to digital mode. This is required for using a pin as a GPIO pin. The default | ||
| 189 | /// setting for pins is (usually) non-digital. | ||
| 190 | fn set_as_digital(&mut self) { | ||
| 191 | match_iocon!(register, iocon_reg(), self.pin_bank(), self.pin_number(), { | ||
| 192 | register.modify(|_, w| w.digimode().digital()); | ||
| 193 | }); | ||
| 194 | } | ||
| 195 | |||
| 196 | /// Set the pin in output mode. This implies setting the pin to digital mode, which this | ||
| 197 | /// function handles itself. | ||
| 198 | pub fn set_as_output(&mut self) { | ||
| 199 | self.set_as_digital(); | ||
| 200 | gpio_reg().dirset[self.pin.pin_bank() as usize].write(|w| unsafe { w.dirsetp().bits(self.bit()) }) | ||
| 201 | } | ||
| 202 | |||
| 203 | pub fn set_as_input(&mut self) { | ||
| 204 | self.set_as_digital(); | ||
| 205 | gpio_reg().dirclr[self.pin.pin_bank() as usize].write(|w| unsafe { w.dirclrp().bits(self.bit()) }) | ||
| 206 | } | ||
| 207 | } | ||
| 208 | |||
| 209 | /// Sealed trait for pins. This trait is sealed and cannot be implemented outside of this crate. | ||
| 210 | pub(crate) trait SealedPin: Sized { | ||
| 211 | fn pin_bank(&self) -> Bank; | ||
| 212 | fn pin_number(&self) -> u8; | ||
| 213 | } | ||
| 214 | |||
| 215 | /// Interface for a Pin that can be configured by an [Input] or [Output] driver, or converted to an | ||
| 216 | /// [AnyPin]. By default, this trait is sealed and cannot be implemented outside of the | ||
| 217 | /// `embassy-nxp` crate due to the [SealedPin] trait. | ||
| 218 | #[allow(private_bounds)] | ||
| 219 | pub trait Pin: PeripheralType + Into<AnyPin> + SealedPin + Sized + 'static { | ||
| 220 | /// Returns the pin number within a bank | ||
| 221 | #[inline] | ||
| 222 | fn pin(&self) -> u8 { | ||
| 223 | self.pin_number() | ||
| 224 | } | ||
| 225 | |||
| 226 | /// Returns the bank of this pin | ||
| 227 | #[inline] | ||
| 228 | fn bank(&self) -> Bank { | ||
| 229 | self.pin_bank() | ||
| 230 | } | ||
| 231 | } | ||
| 232 | |||
| 233 | /// Type-erased GPIO pin. | ||
| 234 | pub struct AnyPin { | ||
| 235 | pin_bank: Bank, | ||
| 236 | pin_number: u8, | ||
| 237 | } | ||
| 238 | |||
| 239 | impl AnyPin { | ||
| 240 | /// Unsafely create a new type-erased pin. | ||
| 241 | /// | ||
| 242 | /// # Safety | ||
| 243 | /// | ||
| 244 | /// You must ensure that you’re only using one instance of this type at a time. | ||
| 245 | pub unsafe fn steal(pin_bank: Bank, pin_number: u8) -> Peri<'static, Self> { | ||
| 246 | Peri::new_unchecked(Self { pin_bank, pin_number }) | ||
| 247 | } | ||
| 248 | } | ||
| 249 | |||
| 250 | impl_peripheral!(AnyPin); | ||
| 251 | |||
| 252 | impl Pin for AnyPin {} | ||
| 253 | impl SealedPin for AnyPin { | ||
| 254 | #[inline] | ||
| 255 | fn pin_bank(&self) -> Bank { | ||
| 256 | self.pin_bank | ||
| 257 | } | ||
| 258 | |||
| 259 | #[inline] | ||
| 260 | fn pin_number(&self) -> u8 { | ||
| 261 | self.pin_number | ||
| 262 | } | ||
| 263 | } | ||
| 264 | |||
| 265 | macro_rules! impl_pin { | ||
| 266 | ($name:ident, $bank:expr, $pin_num:expr) => { | ||
| 267 | impl Pin for peripherals::$name {} | ||
| 268 | impl SealedPin for peripherals::$name { | ||
| 269 | #[inline] | ||
| 270 | fn pin_bank(&self) -> Bank { | ||
| 271 | $bank | ||
| 272 | } | ||
| 273 | |||
| 274 | #[inline] | ||
| 275 | fn pin_number(&self) -> u8 { | ||
| 276 | $pin_num | ||
| 277 | } | ||
| 278 | } | ||
| 279 | |||
| 280 | impl From<peripherals::$name> for crate::gpio::AnyPin { | ||
| 281 | fn from(val: peripherals::$name) -> Self { | ||
| 282 | Self { | ||
| 283 | pin_bank: val.pin_bank(), | ||
| 284 | pin_number: val.pin_number(), | ||
| 285 | } | ||
| 286 | } | ||
| 287 | } | ||
| 288 | }; | ||
| 289 | } | ||
| 290 | |||
| 291 | impl_pin!(PIO0_0, Bank::Bank0, 0); | ||
| 292 | impl_pin!(PIO0_1, Bank::Bank0, 1); | ||
| 293 | impl_pin!(PIO0_2, Bank::Bank0, 2); | ||
| 294 | impl_pin!(PIO0_3, Bank::Bank0, 3); | ||
| 295 | impl_pin!(PIO0_4, Bank::Bank0, 4); | ||
| 296 | impl_pin!(PIO0_5, Bank::Bank0, 5); | ||
| 297 | impl_pin!(PIO0_6, Bank::Bank0, 6); | ||
| 298 | impl_pin!(PIO0_7, Bank::Bank0, 7); | ||
| 299 | impl_pin!(PIO0_8, Bank::Bank0, 8); | ||
| 300 | impl_pin!(PIO0_9, Bank::Bank0, 9); | ||
| 301 | impl_pin!(PIO0_10, Bank::Bank0, 10); | ||
| 302 | impl_pin!(PIO0_11, Bank::Bank0, 11); | ||
| 303 | impl_pin!(PIO0_12, Bank::Bank0, 12); | ||
| 304 | impl_pin!(PIO0_13, Bank::Bank0, 13); | ||
| 305 | impl_pin!(PIO0_14, Bank::Bank0, 14); | ||
| 306 | impl_pin!(PIO0_15, Bank::Bank0, 15); | ||
| 307 | impl_pin!(PIO0_16, Bank::Bank0, 16); | ||
| 308 | impl_pin!(PIO0_17, Bank::Bank0, 17); | ||
| 309 | impl_pin!(PIO0_18, Bank::Bank0, 18); | ||
| 310 | impl_pin!(PIO0_19, Bank::Bank0, 19); | ||
| 311 | impl_pin!(PIO0_20, Bank::Bank0, 20); | ||
| 312 | impl_pin!(PIO0_21, Bank::Bank0, 21); | ||
| 313 | impl_pin!(PIO0_22, Bank::Bank0, 22); | ||
| 314 | impl_pin!(PIO0_23, Bank::Bank0, 23); | ||
| 315 | impl_pin!(PIO0_24, Bank::Bank0, 24); | ||
| 316 | impl_pin!(PIO0_25, Bank::Bank0, 25); | ||
| 317 | impl_pin!(PIO0_26, Bank::Bank0, 26); | ||
| 318 | impl_pin!(PIO0_27, Bank::Bank0, 27); | ||
| 319 | impl_pin!(PIO0_28, Bank::Bank0, 28); | ||
| 320 | impl_pin!(PIO0_29, Bank::Bank0, 29); | ||
| 321 | impl_pin!(PIO0_30, Bank::Bank0, 30); | ||
| 322 | impl_pin!(PIO0_31, Bank::Bank0, 31); | ||
| 323 | impl_pin!(PIO1_0, Bank::Bank1, 0); | ||
| 324 | impl_pin!(PIO1_1, Bank::Bank1, 1); | ||
| 325 | impl_pin!(PIO1_2, Bank::Bank1, 2); | ||
| 326 | impl_pin!(PIO1_3, Bank::Bank1, 3); | ||
| 327 | impl_pin!(PIO1_4, Bank::Bank1, 4); | ||
| 328 | impl_pin!(PIO1_5, Bank::Bank1, 5); | ||
| 329 | impl_pin!(PIO1_6, Bank::Bank1, 6); | ||
| 330 | impl_pin!(PIO1_7, Bank::Bank1, 7); | ||
| 331 | impl_pin!(PIO1_8, Bank::Bank1, 8); | ||
| 332 | impl_pin!(PIO1_9, Bank::Bank1, 9); | ||
| 333 | impl_pin!(PIO1_10, Bank::Bank1, 10); | ||
| 334 | impl_pin!(PIO1_11, Bank::Bank1, 11); | ||
| 335 | impl_pin!(PIO1_12, Bank::Bank1, 12); | ||
| 336 | impl_pin!(PIO1_13, Bank::Bank1, 13); | ||
| 337 | impl_pin!(PIO1_14, Bank::Bank1, 14); | ||
| 338 | impl_pin!(PIO1_15, Bank::Bank1, 15); | ||
| 339 | impl_pin!(PIO1_16, Bank::Bank1, 16); | ||
| 340 | impl_pin!(PIO1_17, Bank::Bank1, 17); | ||
| 341 | impl_pin!(PIO1_18, Bank::Bank1, 18); | ||
| 342 | impl_pin!(PIO1_19, Bank::Bank1, 19); | ||
| 343 | impl_pin!(PIO1_20, Bank::Bank1, 20); | ||
| 344 | impl_pin!(PIO1_21, Bank::Bank1, 21); | ||
| 345 | impl_pin!(PIO1_22, Bank::Bank1, 22); | ||
| 346 | impl_pin!(PIO1_23, Bank::Bank1, 23); | ||
| 347 | impl_pin!(PIO1_24, Bank::Bank1, 24); | ||
| 348 | impl_pin!(PIO1_25, Bank::Bank1, 25); | ||
| 349 | impl_pin!(PIO1_26, Bank::Bank1, 26); | ||
| 350 | impl_pin!(PIO1_27, Bank::Bank1, 27); | ||
| 351 | impl_pin!(PIO1_28, Bank::Bank1, 28); | ||
| 352 | impl_pin!(PIO1_29, Bank::Bank1, 29); | ||
| 353 | impl_pin!(PIO1_30, Bank::Bank1, 30); | ||
| 354 | impl_pin!(PIO1_31, Bank::Bank1, 31); | ||
diff --git a/embassy-nxp/src/pac_utils.rs b/embassy-nxp/src/gpio/lpc55.rs index 86a807f6c..94cd8b7f8 100644 --- a/embassy-nxp/src/pac_utils.rs +++ b/embassy-nxp/src/gpio/lpc55.rs | |||
| @@ -1,3 +1,266 @@ | |||
| 1 | use embassy_hal_internal::{impl_peripheral, PeripheralType}; | ||
| 2 | |||
| 3 | use crate::{peripherals, Peri}; | ||
| 4 | |||
| 5 | pub(crate) fn init() { | ||
| 6 | // Enable clocks for GPIO, PINT, and IOCON | ||
| 7 | syscon_reg() | ||
| 8 | .ahbclkctrl0 | ||
| 9 | .modify(|_, w| w.gpio0().enable().gpio1().enable().mux().enable().iocon().enable()); | ||
| 10 | } | ||
| 11 | |||
| 12 | /// The GPIO pin level for pins set on "Digital" mode. | ||
| 13 | #[derive(Debug, Eq, PartialEq, Clone, Copy)] | ||
| 14 | pub enum Level { | ||
| 15 | /// Logical low. Corresponds to 0V. | ||
| 16 | Low, | ||
| 17 | /// Logical high. Corresponds to VDD. | ||
| 18 | High, | ||
| 19 | } | ||
| 20 | |||
| 21 | /// Pull setting for a GPIO input set on "Digital" mode. | ||
| 22 | #[derive(Debug, Clone, Copy, Eq, PartialEq)] | ||
| 23 | pub enum Pull { | ||
| 24 | /// No pull. | ||
| 25 | None, | ||
| 26 | /// Internal pull-up resistor. | ||
| 27 | Up, | ||
| 28 | /// Internal pull-down resistor. | ||
| 29 | Down, | ||
| 30 | } | ||
| 31 | |||
| 32 | /// The LPC55 boards have two GPIO banks, each with 32 pins. This enum represents the two banks. | ||
| 33 | #[derive(Debug, Eq, PartialEq, Clone, Copy)] | ||
| 34 | pub enum Bank { | ||
| 35 | Bank0 = 0, | ||
| 36 | Bank1 = 1, | ||
| 37 | } | ||
| 38 | |||
| 39 | /// GPIO output driver. Internally, this is a specialized [Flex] pin. | ||
| 40 | pub struct Output<'d> { | ||
| 41 | pub(crate) pin: Flex<'d>, | ||
| 42 | } | ||
| 43 | |||
| 44 | impl<'d> Output<'d> { | ||
| 45 | /// Create GPIO output driver for a [Pin] with the provided [initial output](Level). | ||
| 46 | #[inline] | ||
| 47 | pub fn new(pin: Peri<'d, impl Pin>, initial_output: Level) -> Self { | ||
| 48 | let mut pin = Flex::new(pin); | ||
| 49 | pin.set_as_output(); | ||
| 50 | let mut result = Self { pin }; | ||
| 51 | |||
| 52 | match initial_output { | ||
| 53 | Level::High => result.set_high(), | ||
| 54 | Level::Low => result.set_low(), | ||
| 55 | }; | ||
| 56 | |||
| 57 | result | ||
| 58 | } | ||
| 59 | |||
| 60 | pub fn set_high(&mut self) { | ||
| 61 | gpio_reg().set[self.pin.pin_bank() as usize].write(|w| unsafe { w.bits(self.pin.bit()) }) | ||
| 62 | } | ||
| 63 | |||
| 64 | pub fn set_low(&mut self) { | ||
| 65 | gpio_reg().clr[self.pin.pin_bank() as usize].write(|w| unsafe { w.bits(self.pin.bit()) }) | ||
| 66 | } | ||
| 67 | |||
| 68 | pub fn toggle(&mut self) { | ||
| 69 | gpio_reg().not[self.pin.pin_bank() as usize].write(|w| unsafe { w.bits(self.pin.bit()) }) | ||
| 70 | } | ||
| 71 | |||
| 72 | /// Get the current output level of the pin. Note that the value returned by this function is | ||
| 73 | /// the voltage level reported by the pin, not the value set by the output driver. | ||
| 74 | pub fn level(&self) -> Level { | ||
| 75 | let bits = gpio_reg().pin[self.pin.pin_bank() as usize].read().bits(); | ||
| 76 | if bits & self.pin.bit() != 0 { | ||
| 77 | Level::High | ||
| 78 | } else { | ||
| 79 | Level::Low | ||
| 80 | } | ||
| 81 | } | ||
| 82 | } | ||
| 83 | |||
| 84 | /// GPIO input driver. Internally, this is a specialized [Flex] pin. | ||
| 85 | pub struct Input<'d> { | ||
| 86 | pub(crate) pin: Flex<'d>, | ||
| 87 | } | ||
| 88 | |||
| 89 | impl<'d> Input<'d> { | ||
| 90 | /// Create GPIO output driver for a [Pin] with the provided [Pull]. | ||
| 91 | #[inline] | ||
| 92 | pub fn new(pin: Peri<'d, impl Pin>, pull: Pull) -> Self { | ||
| 93 | let mut pin = Flex::new(pin); | ||
| 94 | pin.set_as_input(); | ||
| 95 | let mut result = Self { pin }; | ||
| 96 | result.set_pull(pull); | ||
| 97 | |||
| 98 | result | ||
| 99 | } | ||
| 100 | |||
| 101 | /// Set the pull configuration for the pin. To disable the pull, use [Pull::None]. | ||
| 102 | pub fn set_pull(&mut self, pull: Pull) { | ||
| 103 | match_iocon!(register, iocon_reg(), self.pin.pin_bank(), self.pin.pin_number(), { | ||
| 104 | register.modify(|_, w| match pull { | ||
| 105 | Pull::None => w.mode().inactive(), | ||
| 106 | Pull::Up => w.mode().pull_up(), | ||
| 107 | Pull::Down => w.mode().pull_down(), | ||
| 108 | }); | ||
| 109 | }); | ||
| 110 | } | ||
| 111 | |||
| 112 | /// Get the current input level of the pin. | ||
| 113 | pub fn read(&self) -> Level { | ||
| 114 | let bits = gpio_reg().pin[self.pin.pin_bank() as usize].read().bits(); | ||
| 115 | if bits & self.pin.bit() != 0 { | ||
| 116 | Level::High | ||
| 117 | } else { | ||
| 118 | Level::Low | ||
| 119 | } | ||
| 120 | } | ||
| 121 | } | ||
| 122 | |||
| 123 | /// A flexible GPIO (digital mode) pin whose mode is not yet determined. Under the hood, this is a | ||
| 124 | /// reference to a type-erased pin called ["AnyPin"](AnyPin). | ||
| 125 | pub struct Flex<'d> { | ||
| 126 | pub(crate) pin: Peri<'d, AnyPin>, | ||
| 127 | } | ||
| 128 | |||
| 129 | impl<'d> Flex<'d> { | ||
| 130 | /// Wrap the pin in a `Flex`. | ||
| 131 | /// | ||
| 132 | /// Note: you cannot assume that the pin will be in Digital mode after this call. | ||
| 133 | #[inline] | ||
| 134 | pub fn new(pin: Peri<'d, impl Pin>) -> Self { | ||
| 135 | Self { pin: pin.into() } | ||
| 136 | } | ||
| 137 | |||
| 138 | /// Get the bank of this pin. See also [Bank]. | ||
| 139 | /// | ||
| 140 | /// # Example | ||
| 141 | /// | ||
| 142 | /// ``` | ||
| 143 | /// use embassy_nxp::gpio::{Bank, Flex}; | ||
| 144 | /// | ||
| 145 | /// let p = embassy_nxp::init(Default::default()); | ||
| 146 | /// let pin = Flex::new(p.PIO1_15); | ||
| 147 | /// | ||
| 148 | /// assert_eq!(pin.pin_bank(), Bank::Bank1); | ||
| 149 | /// ``` | ||
| 150 | pub fn pin_bank(&self) -> Bank { | ||
| 151 | self.pin.pin_bank() | ||
| 152 | } | ||
| 153 | |||
| 154 | /// Get the number of this pin within its bank. See also [Bank]. | ||
| 155 | /// | ||
| 156 | /// # Example | ||
| 157 | /// | ||
| 158 | /// ``` | ||
| 159 | /// use embassy_nxp::gpio::Flex; | ||
| 160 | /// | ||
| 161 | /// let p = embassy_nxp::init(Default::default()); | ||
| 162 | /// let pin = Flex::new(p.PIO1_15); | ||
| 163 | /// | ||
| 164 | /// assert_eq!(pin.pin_number(), 15 as u8); | ||
| 165 | /// ``` | ||
| 166 | pub fn pin_number(&self) -> u8 { | ||
| 167 | self.pin.pin_number() | ||
| 168 | } | ||
| 169 | |||
| 170 | /// Get the bit mask for this pin. Useful for setting or clearing bits in a register. Note: | ||
| 171 | /// PIOx_0 is bit 0, PIOx_1 is bit 1, etc. | ||
| 172 | /// | ||
| 173 | /// # Example | ||
| 174 | /// | ||
| 175 | /// ``` | ||
| 176 | /// use embassy_nxp::gpio::Flex; | ||
| 177 | /// | ||
| 178 | /// let p = embassy_nxp::init(Default::default()); | ||
| 179 | /// let pin = Flex::new(p.PIO1_3); | ||
| 180 | /// | ||
| 181 | /// assert_eq!(pin.bit(), 0b0000_1000); | ||
| 182 | /// ``` | ||
| 183 | pub fn bit(&self) -> u32 { | ||
| 184 | 1 << self.pin.pin_number() | ||
| 185 | } | ||
| 186 | |||
| 187 | /// Set the pin to digital mode. This is required for using a pin as a GPIO pin. The default | ||
| 188 | /// setting for pins is (usually) non-digital. | ||
| 189 | fn set_as_digital(&mut self) { | ||
| 190 | match_iocon!(register, iocon_reg(), self.pin_bank(), self.pin_number(), { | ||
| 191 | register.modify(|_, w| w.digimode().digital()); | ||
| 192 | }); | ||
| 193 | } | ||
| 194 | |||
| 195 | /// Set the pin in output mode. This implies setting the pin to digital mode, which this | ||
| 196 | /// function handles itself. | ||
| 197 | pub fn set_as_output(&mut self) { | ||
| 198 | self.set_as_digital(); | ||
| 199 | gpio_reg().dirset[self.pin.pin_bank() as usize].write(|w| unsafe { w.dirsetp().bits(self.bit()) }) | ||
| 200 | } | ||
| 201 | |||
| 202 | pub fn set_as_input(&mut self) { | ||
| 203 | self.set_as_digital(); | ||
| 204 | gpio_reg().dirclr[self.pin.pin_bank() as usize].write(|w| unsafe { w.dirclrp().bits(self.bit()) }) | ||
| 205 | } | ||
| 206 | } | ||
| 207 | |||
| 208 | /// Sealed trait for pins. This trait is sealed and cannot be implemented outside of this crate. | ||
| 209 | pub(crate) trait SealedPin: Sized { | ||
| 210 | fn pin_bank(&self) -> Bank; | ||
| 211 | fn pin_number(&self) -> u8; | ||
| 212 | } | ||
| 213 | |||
| 214 | /// Interface for a Pin that can be configured by an [Input] or [Output] driver, or converted to an | ||
| 215 | /// [AnyPin]. By default, this trait is sealed and cannot be implemented outside of the | ||
| 216 | /// `embassy-nxp` crate due to the [SealedPin] trait. | ||
| 217 | #[allow(private_bounds)] | ||
| 218 | pub trait Pin: PeripheralType + Into<AnyPin> + SealedPin + Sized + 'static { | ||
| 219 | /// Returns the pin number within a bank | ||
| 220 | #[inline] | ||
| 221 | fn pin(&self) -> u8 { | ||
| 222 | self.pin_number() | ||
| 223 | } | ||
| 224 | |||
| 225 | /// Returns the bank of this pin | ||
| 226 | #[inline] | ||
| 227 | fn bank(&self) -> Bank { | ||
| 228 | self.pin_bank() | ||
| 229 | } | ||
| 230 | } | ||
| 231 | |||
| 232 | /// Type-erased GPIO pin. | ||
| 233 | pub struct AnyPin { | ||
| 234 | pin_bank: Bank, | ||
| 235 | pin_number: u8, | ||
| 236 | } | ||
| 237 | |||
| 238 | impl AnyPin { | ||
| 239 | /// Unsafely create a new type-erased pin. | ||
| 240 | /// | ||
| 241 | /// # Safety | ||
| 242 | /// | ||
| 243 | /// You must ensure that you’re only using one instance of this type at a time. | ||
| 244 | pub unsafe fn steal(pin_bank: Bank, pin_number: u8) -> Peri<'static, Self> { | ||
| 245 | Peri::new_unchecked(Self { pin_bank, pin_number }) | ||
| 246 | } | ||
| 247 | } | ||
| 248 | |||
| 249 | impl_peripheral!(AnyPin); | ||
| 250 | |||
| 251 | impl Pin for AnyPin {} | ||
| 252 | impl SealedPin for AnyPin { | ||
| 253 | #[inline] | ||
| 254 | fn pin_bank(&self) -> Bank { | ||
| 255 | self.pin_bank | ||
| 256 | } | ||
| 257 | |||
| 258 | #[inline] | ||
| 259 | fn pin_number(&self) -> u8 { | ||
| 260 | self.pin_number | ||
| 261 | } | ||
| 262 | } | ||
| 263 | |||
| 1 | /// Get the GPIO register block. This is used to configure all GPIO pins. | 264 | /// Get the GPIO register block. This is used to configure all GPIO pins. |
| 2 | /// | 265 | /// |
| 3 | /// # Safety | 266 | /// # Safety |
| @@ -321,3 +584,94 @@ macro_rules! match_iocon { | |||
| 321 | } | 584 | } |
| 322 | 585 | ||
| 323 | pub(crate) use match_iocon; | 586 | pub(crate) use match_iocon; |
| 587 | |||
| 588 | macro_rules! impl_pin { | ||
| 589 | ($name:ident, $bank:expr, $pin_num:expr) => { | ||
| 590 | impl Pin for peripherals::$name {} | ||
| 591 | impl SealedPin for peripherals::$name { | ||
| 592 | #[inline] | ||
| 593 | fn pin_bank(&self) -> Bank { | ||
| 594 | $bank | ||
| 595 | } | ||
| 596 | |||
| 597 | #[inline] | ||
| 598 | fn pin_number(&self) -> u8 { | ||
| 599 | $pin_num | ||
| 600 | } | ||
| 601 | } | ||
| 602 | |||
| 603 | impl From<peripherals::$name> for crate::gpio::AnyPin { | ||
| 604 | fn from(val: peripherals::$name) -> Self { | ||
| 605 | Self { | ||
| 606 | pin_bank: val.pin_bank(), | ||
| 607 | pin_number: val.pin_number(), | ||
| 608 | } | ||
| 609 | } | ||
| 610 | } | ||
| 611 | }; | ||
| 612 | } | ||
| 613 | |||
| 614 | impl_pin!(PIO0_0, Bank::Bank0, 0); | ||
| 615 | impl_pin!(PIO0_1, Bank::Bank0, 1); | ||
| 616 | impl_pin!(PIO0_2, Bank::Bank0, 2); | ||
| 617 | impl_pin!(PIO0_3, Bank::Bank0, 3); | ||
| 618 | impl_pin!(PIO0_4, Bank::Bank0, 4); | ||
| 619 | impl_pin!(PIO0_5, Bank::Bank0, 5); | ||
| 620 | impl_pin!(PIO0_6, Bank::Bank0, 6); | ||
| 621 | impl_pin!(PIO0_7, Bank::Bank0, 7); | ||
| 622 | impl_pin!(PIO0_8, Bank::Bank0, 8); | ||
| 623 | impl_pin!(PIO0_9, Bank::Bank0, 9); | ||
| 624 | impl_pin!(PIO0_10, Bank::Bank0, 10); | ||
| 625 | impl_pin!(PIO0_11, Bank::Bank0, 11); | ||
| 626 | impl_pin!(PIO0_12, Bank::Bank0, 12); | ||
| 627 | impl_pin!(PIO0_13, Bank::Bank0, 13); | ||
| 628 | impl_pin!(PIO0_14, Bank::Bank0, 14); | ||
| 629 | impl_pin!(PIO0_15, Bank::Bank0, 15); | ||
| 630 | impl_pin!(PIO0_16, Bank::Bank0, 16); | ||
| 631 | impl_pin!(PIO0_17, Bank::Bank0, 17); | ||
| 632 | impl_pin!(PIO0_18, Bank::Bank0, 18); | ||
| 633 | impl_pin!(PIO0_19, Bank::Bank0, 19); | ||
| 634 | impl_pin!(PIO0_20, Bank::Bank0, 20); | ||
| 635 | impl_pin!(PIO0_21, Bank::Bank0, 21); | ||
| 636 | impl_pin!(PIO0_22, Bank::Bank0, 22); | ||
| 637 | impl_pin!(PIO0_23, Bank::Bank0, 23); | ||
| 638 | impl_pin!(PIO0_24, Bank::Bank0, 24); | ||
| 639 | impl_pin!(PIO0_25, Bank::Bank0, 25); | ||
| 640 | impl_pin!(PIO0_26, Bank::Bank0, 26); | ||
| 641 | impl_pin!(PIO0_27, Bank::Bank0, 27); | ||
| 642 | impl_pin!(PIO0_28, Bank::Bank0, 28); | ||
| 643 | impl_pin!(PIO0_29, Bank::Bank0, 29); | ||
| 644 | impl_pin!(PIO0_30, Bank::Bank0, 30); | ||
| 645 | impl_pin!(PIO0_31, Bank::Bank0, 31); | ||
| 646 | impl_pin!(PIO1_0, Bank::Bank1, 0); | ||
| 647 | impl_pin!(PIO1_1, Bank::Bank1, 1); | ||
| 648 | impl_pin!(PIO1_2, Bank::Bank1, 2); | ||
| 649 | impl_pin!(PIO1_3, Bank::Bank1, 3); | ||
| 650 | impl_pin!(PIO1_4, Bank::Bank1, 4); | ||
| 651 | impl_pin!(PIO1_5, Bank::Bank1, 5); | ||
| 652 | impl_pin!(PIO1_6, Bank::Bank1, 6); | ||
| 653 | impl_pin!(PIO1_7, Bank::Bank1, 7); | ||
| 654 | impl_pin!(PIO1_8, Bank::Bank1, 8); | ||
| 655 | impl_pin!(PIO1_9, Bank::Bank1, 9); | ||
| 656 | impl_pin!(PIO1_10, Bank::Bank1, 10); | ||
| 657 | impl_pin!(PIO1_11, Bank::Bank1, 11); | ||
| 658 | impl_pin!(PIO1_12, Bank::Bank1, 12); | ||
| 659 | impl_pin!(PIO1_13, Bank::Bank1, 13); | ||
| 660 | impl_pin!(PIO1_14, Bank::Bank1, 14); | ||
| 661 | impl_pin!(PIO1_15, Bank::Bank1, 15); | ||
| 662 | impl_pin!(PIO1_16, Bank::Bank1, 16); | ||
| 663 | impl_pin!(PIO1_17, Bank::Bank1, 17); | ||
| 664 | impl_pin!(PIO1_18, Bank::Bank1, 18); | ||
| 665 | impl_pin!(PIO1_19, Bank::Bank1, 19); | ||
| 666 | impl_pin!(PIO1_20, Bank::Bank1, 20); | ||
| 667 | impl_pin!(PIO1_21, Bank::Bank1, 21); | ||
| 668 | impl_pin!(PIO1_22, Bank::Bank1, 22); | ||
| 669 | impl_pin!(PIO1_23, Bank::Bank1, 23); | ||
| 670 | impl_pin!(PIO1_24, Bank::Bank1, 24); | ||
| 671 | impl_pin!(PIO1_25, Bank::Bank1, 25); | ||
| 672 | impl_pin!(PIO1_26, Bank::Bank1, 26); | ||
| 673 | impl_pin!(PIO1_27, Bank::Bank1, 27); | ||
| 674 | impl_pin!(PIO1_28, Bank::Bank1, 28); | ||
| 675 | impl_pin!(PIO1_29, Bank::Bank1, 29); | ||
| 676 | impl_pin!(PIO1_30, Bank::Bank1, 30); | ||
| 677 | impl_pin!(PIO1_31, Bank::Bank1, 31); | ||
diff --git a/embassy-nxp/src/lib.rs b/embassy-nxp/src/lib.rs index ad2056c06..433aca9e0 100644 --- a/embassy-nxp/src/lib.rs +++ b/embassy-nxp/src/lib.rs | |||
| @@ -1,11 +1,19 @@ | |||
| 1 | #![no_std] | 1 | #![no_std] |
| 2 | 2 | ||
| 3 | pub mod gpio; | 3 | pub mod gpio; |
| 4 | mod pac_utils; | 4 | #[cfg(feature = "lpc55")] |
| 5 | pub mod pint; | 5 | pub mod pint; |
| 6 | 6 | ||
| 7 | pub use embassy_hal_internal::Peri; | 7 | // This mod MUST go last, so that it sees all the `impl_foo!` macros |
| 8 | pub use lpc55_pac as pac; | 8 | #[cfg_attr(feature = "lpc55", path = "chips/lpc55.rs")] |
| 9 | mod chip; | ||
| 10 | |||
| 11 | #[cfg(feature = "unstable-pac")] | ||
| 12 | pub use chip::pac; | ||
| 13 | #[cfg(not(feature = "unstable-pac"))] | ||
| 14 | pub(crate) use chip::pac; | ||
| 15 | pub use chip::{peripherals, Peripherals}; | ||
| 16 | pub use embassy_hal_internal::{Peri, PeripheralType}; | ||
| 9 | 17 | ||
| 10 | /// Initialize the `embassy-nxp` HAL with the provided configuration. | 18 | /// Initialize the `embassy-nxp` HAL with the provided configuration. |
| 11 | /// | 19 | /// |
| @@ -13,81 +21,15 @@ pub use lpc55_pac as pac; | |||
| 13 | /// | 21 | /// |
| 14 | /// This should only be called once and at startup, otherwise it panics. | 22 | /// This should only be called once and at startup, otherwise it panics. |
| 15 | pub fn init(_config: config::Config) -> Peripherals { | 23 | pub fn init(_config: config::Config) -> Peripherals { |
| 16 | gpio::init(); | 24 | #[cfg(feature = "lpc55")] |
| 17 | pint::init(); | 25 | { |
| 26 | gpio::init(); | ||
| 27 | pint::init(); | ||
| 28 | } | ||
| 18 | 29 | ||
| 19 | crate::Peripherals::take() | 30 | crate::Peripherals::take() |
| 20 | } | 31 | } |
| 21 | 32 | ||
| 22 | embassy_hal_internal::peripherals! { | ||
| 23 | // External pins. These are not only GPIOs, they are multi-purpose pins and can be used by other | ||
| 24 | // peripheral types (e.g. I2C). | ||
| 25 | PIO0_0, | ||
| 26 | PIO0_1, | ||
| 27 | PIO0_2, | ||
| 28 | PIO0_3, | ||
| 29 | PIO0_4, | ||
| 30 | PIO0_5, | ||
| 31 | PIO0_6, | ||
| 32 | PIO0_7, | ||
| 33 | PIO0_8, | ||
| 34 | PIO0_9, | ||
| 35 | PIO0_10, | ||
| 36 | PIO0_11, | ||
| 37 | PIO0_12, | ||
| 38 | PIO0_13, | ||
| 39 | PIO0_14, | ||
| 40 | PIO0_15, | ||
| 41 | PIO0_16, | ||
| 42 | PIO0_17, | ||
| 43 | PIO0_18, | ||
| 44 | PIO0_19, | ||
| 45 | PIO0_20, | ||
| 46 | PIO0_21, | ||
| 47 | PIO0_22, | ||
| 48 | PIO0_23, | ||
| 49 | PIO0_24, | ||
| 50 | PIO0_25, | ||
| 51 | PIO0_26, | ||
| 52 | PIO0_27, | ||
| 53 | PIO0_28, | ||
| 54 | PIO0_29, | ||
| 55 | PIO0_30, | ||
| 56 | PIO0_31, | ||
| 57 | PIO1_0, | ||
| 58 | PIO1_1, | ||
| 59 | PIO1_2, | ||
| 60 | PIO1_3, | ||
| 61 | PIO1_4, | ||
| 62 | PIO1_5, | ||
| 63 | PIO1_6, | ||
| 64 | PIO1_7, | ||
| 65 | PIO1_8, | ||
| 66 | PIO1_9, | ||
| 67 | PIO1_10, | ||
| 68 | PIO1_11, | ||
| 69 | PIO1_12, | ||
| 70 | PIO1_13, | ||
| 71 | PIO1_14, | ||
| 72 | PIO1_15, | ||
| 73 | PIO1_16, | ||
| 74 | PIO1_17, | ||
| 75 | PIO1_18, | ||
| 76 | PIO1_19, | ||
| 77 | PIO1_20, | ||
| 78 | PIO1_21, | ||
| 79 | PIO1_22, | ||
| 80 | PIO1_23, | ||
| 81 | PIO1_24, | ||
| 82 | PIO1_25, | ||
| 83 | PIO1_26, | ||
| 84 | PIO1_27, | ||
| 85 | PIO1_28, | ||
| 86 | PIO1_29, | ||
| 87 | PIO1_30, | ||
| 88 | PIO1_31, | ||
| 89 | } | ||
| 90 | |||
| 91 | /// HAL configuration for the NXP board. | 33 | /// HAL configuration for the NXP board. |
| 92 | pub mod config { | 34 | pub mod config { |
| 93 | #[derive(Default)] | 35 | #[derive(Default)] |
diff --git a/embassy-nxp/src/pint.rs b/embassy-nxp/src/pint.rs index 8d6dc1277..dc117e7e3 100644 --- a/embassy-nxp/src/pint.rs +++ b/embassy-nxp/src/pint.rs | |||
| @@ -7,9 +7,8 @@ use core::task::{Context, Poll}; | |||
| 7 | use critical_section::Mutex; | 7 | use critical_section::Mutex; |
| 8 | use embassy_sync::waitqueue::AtomicWaker; | 8 | use embassy_sync::waitqueue::AtomicWaker; |
| 9 | 9 | ||
| 10 | use crate::gpio::{self, AnyPin, Level, SealedPin}; | 10 | use crate::gpio::{self, inputmux_reg, pint_reg, syscon_reg, AnyPin, Level, SealedPin}; |
| 11 | use crate::pac::interrupt; | 11 | use crate::pac::interrupt; |
| 12 | use crate::pac_utils::*; | ||
| 13 | use crate::Peri; | 12 | use crate::Peri; |
| 14 | 13 | ||
| 15 | struct PinInterrupt { | 14 | struct PinInterrupt { |
diff --git a/examples/lpc55s69/Cargo.toml b/examples/lpc55s69/Cargo.toml index 7f81e9c7f..6ec6e51a8 100644 --- a/examples/lpc55s69/Cargo.toml +++ b/examples/lpc55s69/Cargo.toml | |||
| @@ -6,7 +6,7 @@ license = "MIT OR Apache-2.0" | |||
| 6 | 6 | ||
| 7 | 7 | ||
| 8 | [dependencies] | 8 | [dependencies] |
| 9 | embassy-nxp = { version = "0.1.0", path = "../../embassy-nxp", features = ["rt"] } | 9 | embassy-nxp = { version = "0.1.0", path = "../../embassy-nxp", features = ["lpc55", "rt"] } |
| 10 | embassy-executor = { version = "0.7.0", path = "../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "executor-interrupt"] } | 10 | embassy-executor = { version = "0.7.0", path = "../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "executor-interrupt"] } |
| 11 | embassy-sync = { version = "0.7.0", path = "../../embassy-sync", features = ["defmt"] } | 11 | embassy-sync = { version = "0.7.0", path = "../../embassy-sync", features = ["defmt"] } |
| 12 | embassy-time = { version = "0.4.0", path = "../../embassy-time", features = ["defmt"] } | 12 | embassy-time = { version = "0.4.0", path = "../../embassy-time", features = ["defmt"] } |
