diff options
Diffstat (limited to 'embassy-mcxa/src')
| -rw-r--r-- | embassy-mcxa/src/adc.rs | 642 |
1 files changed, 365 insertions, 277 deletions
diff --git a/embassy-mcxa/src/adc.rs b/embassy-mcxa/src/adc.rs index d7d17cf5f..e4b24cffa 100644 --- a/embassy-mcxa/src/adc.rs +++ b/embassy-mcxa/src/adc.rs | |||
| @@ -1,4 +1,5 @@ | |||
| 1 | //! ADC driver | 1 | //! ADC driver |
| 2 | use core::future::Future; | ||
| 2 | use core::marker::PhantomData; | 3 | use core::marker::PhantomData; |
| 3 | 4 | ||
| 4 | use embassy_hal_internal::{Peri, PeripheralType}; | 5 | use embassy_hal_internal::{Peri, PeripheralType}; |
| @@ -12,12 +13,10 @@ use crate::interrupt::typelevel::{Handler, Interrupt}; | |||
| 12 | use crate::pac; | 13 | use crate::pac; |
| 13 | use crate::pac::adc1::cfg::{HptExdi, Pwrsel, Refsel, Tcmdres, Tprictrl, Tres}; | 14 | use crate::pac::adc1::cfg::{HptExdi, Pwrsel, Refsel, Tcmdres, Tprictrl, Tres}; |
| 14 | use crate::pac::adc1::cmdh1::{Avgs, Cmpen, Next, Sts}; | 15 | use crate::pac::adc1::cmdh1::{Avgs, Cmpen, Next, Sts}; |
| 15 | use crate::pac::adc1::cmdl1::{Adch, Mode}; | 16 | use crate::pac::adc1::cmdl1::Mode; |
| 16 | use crate::pac::adc1::ctrl::CalAvgs; | 17 | use crate::pac::adc1::ctrl::CalAvgs; |
| 17 | use crate::pac::adc1::tctrl::{Tcmd, Tpri}; | 18 | use crate::pac::adc1::tctrl::{Tcmd, Tpri}; |
| 18 | 19 | ||
| 19 | const G_LPADC_RESULT_SHIFT: u32 = 0; | ||
| 20 | |||
| 21 | /// Trigger priority policy for ADC conversions. | 20 | /// Trigger priority policy for ADC conversions. |
| 22 | #[derive(Debug, Clone, Copy, PartialEq, Eq)] | 21 | #[derive(Debug, Clone, Copy, PartialEq, Eq)] |
| 23 | #[repr(u8)] | 22 | #[repr(u8)] |
| @@ -59,10 +58,6 @@ pub struct LpadcConfig { | |||
| 59 | /// Controls the duration of pausing during command execution sequencing. The pause delay is a count of (convPauseDelay*4) ADCK cycles. | 58 | /// Controls the duration of pausing during command execution sequencing. The pause delay is a count of (convPauseDelay*4) ADCK cycles. |
| 60 | /// Only available when ADC pausing function is enabled. The available value range is in 9-bit. | 59 | /// Only available when ADC pausing function is enabled. The available value range is in 9-bit. |
| 61 | pub conv_pause_delay: u16, | 60 | pub conv_pause_delay: u16, |
| 62 | /// FIFO watermark level for interrupt generation. | ||
| 63 | /// When the number of datawords stored in the ADC Result FIFO is greater than the value in this field, | ||
| 64 | /// the ready flag would be asserted to indicate stored data has reached the programmable threshold. | ||
| 65 | pub fifo_watermark: u8, | ||
| 66 | /// Power configuration (normal/deep sleep behavior) | 61 | /// Power configuration (normal/deep sleep behavior) |
| 67 | pub power: PoweredClock, | 62 | pub power: PoweredClock, |
| 68 | /// ADC clock source selection | 63 | /// ADC clock source selection |
| @@ -83,7 +78,6 @@ impl Default for LpadcConfig { | |||
| 83 | trigger_priority_policy: TriggerPriorityPolicy::ConvPreemptImmediatelyNotAutoResumed, | 78 | trigger_priority_policy: TriggerPriorityPolicy::ConvPreemptImmediatelyNotAutoResumed, |
| 84 | enable_conv_pause: false, | 79 | enable_conv_pause: false, |
| 85 | conv_pause_delay: 0, | 80 | conv_pause_delay: 0, |
| 86 | fifo_watermark: 0, | ||
| 87 | power: PoweredClock::NormalEnabledDeepSleepDisabled, | 81 | power: PoweredClock::NormalEnabledDeepSleepDisabled, |
| 88 | source: AdcClockSel::FroLfDiv, | 82 | source: AdcClockSel::FroLfDiv, |
| 89 | div: Div4::no_div(), | 83 | div: Div4::no_div(), |
| @@ -96,7 +90,6 @@ impl Default for LpadcConfig { | |||
| 96 | /// Defines the parameters for a single ADC conversion operation. | 90 | /// Defines the parameters for a single ADC conversion operation. |
| 97 | #[derive(Debug, Clone, Copy, PartialEq, Eq)] | 91 | #[derive(Debug, Clone, Copy, PartialEq, Eq)] |
| 98 | pub struct ConvCommandConfig { | 92 | pub struct ConvCommandConfig { |
| 99 | pub channel_number: Adch, | ||
| 100 | pub chained_next_command_number: Next, | 93 | pub chained_next_command_number: Next, |
| 101 | pub enable_auto_channel_increment: bool, | 94 | pub enable_auto_channel_increment: bool, |
| 102 | pub loop_count: u8, | 95 | pub loop_count: u8, |
| @@ -109,6 +102,23 @@ pub struct ConvCommandConfig { | |||
| 109 | pub enable_wait_trigger: bool, | 102 | pub enable_wait_trigger: bool, |
| 110 | } | 103 | } |
| 111 | 104 | ||
| 105 | impl Default for ConvCommandConfig { | ||
| 106 | fn default() -> Self { | ||
| 107 | ConvCommandConfig { | ||
| 108 | chained_next_command_number: Next::NoNextCmdTerminateOnFinish, | ||
| 109 | enable_auto_channel_increment: false, | ||
| 110 | loop_count: 0, | ||
| 111 | hardware_average_mode: Avgs::NoAverage, | ||
| 112 | sample_time_mode: Sts::Sample3p5, | ||
| 113 | hardware_compare_mode: Cmpen::DisabledAlwaysStoreResult, | ||
| 114 | hardware_compare_value_high: 0, | ||
| 115 | hardware_compare_value_low: 0, | ||
| 116 | conversion_resolution_mode: Mode::Data12Bits, | ||
| 117 | enable_wait_trigger: false, | ||
| 118 | } | ||
| 119 | } | ||
| 120 | } | ||
| 121 | |||
| 112 | /// Configuration for a conversion trigger. | 122 | /// Configuration for a conversion trigger. |
| 113 | /// | 123 | /// |
| 114 | /// Defines how a trigger initiates ADC conversions. | 124 | /// Defines how a trigger initiates ADC conversions. |
| @@ -120,6 +130,17 @@ pub struct ConvTriggerConfig { | |||
| 120 | pub enable_hardware_trigger: bool, | 130 | pub enable_hardware_trigger: bool, |
| 121 | } | 131 | } |
| 122 | 132 | ||
| 133 | impl Default for ConvTriggerConfig { | ||
| 134 | fn default() -> Self { | ||
| 135 | ConvTriggerConfig { | ||
| 136 | target_command_id: Tcmd::NotValid, | ||
| 137 | delay_power: 0, | ||
| 138 | priority: Tpri::HighestPriority, | ||
| 139 | enable_hardware_trigger: false, | ||
| 140 | } | ||
| 141 | } | ||
| 142 | } | ||
| 143 | |||
| 123 | /// Shorthand for `Result<T>`. | 144 | /// Shorthand for `Result<T>`. |
| 124 | pub type Result<T> = core::result::Result<T, Error>; | 145 | pub type Result<T> = core::result::Result<T, Error>; |
| 125 | 146 | ||
| @@ -155,6 +176,7 @@ pub struct InterruptHandler<I: Instance> { | |||
| 155 | pub struct Adc<'a, I: Instance, M: ModeAdc> { | 176 | pub struct Adc<'a, I: Instance, M: ModeAdc> { |
| 156 | _inst: PhantomData<&'a mut I>, | 177 | _inst: PhantomData<&'a mut I>, |
| 157 | _phantom: PhantomData<M>, | 178 | _phantom: PhantomData<M>, |
| 179 | index: u8, | ||
| 158 | } | 180 | } |
| 159 | 181 | ||
| 160 | impl<'a, I: Instance> Adc<'a, I, Blocking> { | 182 | impl<'a, I: Instance> Adc<'a, I, Blocking> { |
| @@ -166,6 +188,104 @@ impl<'a, I: Instance> Adc<'a, I, Blocking> { | |||
| 166 | pub fn new_blocking(_inst: Peri<'a, I>, pin: Peri<'a, impl AdcPin<I>>, config: LpadcConfig) -> Result<Self> { | 188 | pub fn new_blocking(_inst: Peri<'a, I>, pin: Peri<'a, impl AdcPin<I>>, config: LpadcConfig) -> Result<Self> { |
| 167 | Self::new_inner(_inst, pin, config) | 189 | Self::new_inner(_inst, pin, config) |
| 168 | } | 190 | } |
| 191 | |||
| 192 | /// Enable ADC interrupts. | ||
| 193 | /// | ||
| 194 | /// Enables the interrupt sources specified in the bitmask. | ||
| 195 | /// | ||
| 196 | /// # Arguments | ||
| 197 | /// * `mask` - Bitmask of interrupt sources to enable | ||
| 198 | pub fn enable_interrupt(&mut self, mask: u32) { | ||
| 199 | let adc = I::ptr(); | ||
| 200 | adc.ie().modify(|r, w| unsafe { w.bits(r.bits() | mask) }); | ||
| 201 | } | ||
| 202 | |||
| 203 | /// Disable ADC interrupts. | ||
| 204 | /// | ||
| 205 | /// Disables the interrupt sources specified in the bitmask. | ||
| 206 | /// | ||
| 207 | /// # Arguments | ||
| 208 | /// * `mask` - Bitmask of interrupt sources to disable | ||
| 209 | pub fn disable_interrupt(&mut self, mask: u32) { | ||
| 210 | let adc = I::ptr(); | ||
| 211 | adc.ie().modify(|r, w| unsafe { w.bits(r.bits() & !mask) }); | ||
| 212 | } | ||
| 213 | |||
| 214 | pub fn set_fifo_watermark(&mut self, watermark: u8) -> Result<()> { | ||
| 215 | if watermark > 0b111 { | ||
| 216 | return Err(Error::InvalidConfig); | ||
| 217 | } | ||
| 218 | I::ptr().fctrl0().modify(|_r, w| unsafe { w.fwmark().bits(watermark) }); | ||
| 219 | Ok(()) | ||
| 220 | } | ||
| 221 | |||
| 222 | /// Trigger ADC conversion(s) via software. | ||
| 223 | /// | ||
| 224 | /// Initiates conversion(s) for the trigger(s) specified in the bitmask. | ||
| 225 | /// Each bit in the mask corresponds to a trigger ID (bit 0 = trigger 0, etc.). | ||
| 226 | /// | ||
| 227 | /// # Arguments | ||
| 228 | /// * `trigger_id_mask` - Bitmask of trigger IDs to activate (bit N = trigger N) | ||
| 229 | /// | ||
| 230 | /// # Returns | ||
| 231 | /// * `Ok(())` if the triger mask was valid | ||
| 232 | /// * `Err(Error::InvalidConfig)` if the mask was greater than `0b1111` | ||
| 233 | pub fn do_software_trigger(&self, trigger_id_mask: u8) -> Result<()> { | ||
| 234 | if trigger_id_mask > 0b1111 { | ||
| 235 | return Err(Error::InvalidConfig); | ||
| 236 | } | ||
| 237 | let adc = I::ptr(); | ||
| 238 | adc.swtrig().write(|w| unsafe { w.bits(trigger_id_mask as u32) }); | ||
| 239 | Ok(()) | ||
| 240 | } | ||
| 241 | |||
| 242 | /// Set conversion command configuration. | ||
| 243 | /// | ||
| 244 | /// Configures a conversion command slot with the specified parameters. | ||
| 245 | /// Commands define how conversions are performed (channel, resolution, etc.). | ||
| 246 | /// | ||
| 247 | /// # Arguments | ||
| 248 | /// * `index` - Command index (Must be in range 1..=7) | ||
| 249 | /// * `config` - Command configuration | ||
| 250 | /// | ||
| 251 | /// # Returns | ||
| 252 | /// * `Ok(())` if the command was configured successfully | ||
| 253 | /// * `Err(Error::InvalidConfig)` if the index is out of range | ||
| 254 | pub fn set_conv_command_config(&self, index: usize, config: &ConvCommandConfig) -> Result<()> { | ||
| 255 | self.set_conv_command_config_inner(index, config) | ||
| 256 | } | ||
| 257 | |||
| 258 | /// Set conversion trigger configuration. | ||
| 259 | /// | ||
| 260 | /// Configures a trigger to initiate conversions. Triggers can be | ||
| 261 | /// activated by software or hardware signals. | ||
| 262 | /// | ||
| 263 | /// # Arguments | ||
| 264 | /// * `trigger_id` - Trigger index (0..=3) | ||
| 265 | /// * `config` - Trigger configuration | ||
| 266 | pub fn set_conv_trigger_config(&self, trigger_id: usize, config: &ConvTriggerConfig) -> Result<()> { | ||
| 267 | self.set_conv_trigger_config_inner(trigger_id, config) | ||
| 268 | } | ||
| 269 | |||
| 270 | /// Reset the FIFO buffer. | ||
| 271 | /// | ||
| 272 | /// Clears all pending conversion results from the FIFO. | ||
| 273 | pub fn do_reset_fifo(&self) { | ||
| 274 | let adc = I::ptr(); | ||
| 275 | adc.ctrl().modify(|_, w| w.rstfifo0().trigger_reset()); | ||
| 276 | } | ||
| 277 | |||
| 278 | /// Get conversion result from FIFO. | ||
| 279 | /// | ||
| 280 | /// Reads and returns the next conversion result from the FIFO. | ||
| 281 | /// Returns `None` if the FIFO is empty. | ||
| 282 | /// | ||
| 283 | /// # Returns | ||
| 284 | /// - `Some(ConvResult)` if a result is available | ||
| 285 | /// - `Err(Error::FifoEmpty)` if the FIFO is empty | ||
| 286 | pub fn get_conv_result(&self) -> Result<ConvResult> { | ||
| 287 | self.get_conv_result_inner() | ||
| 288 | } | ||
| 169 | } | 289 | } |
| 170 | 290 | ||
| 171 | impl<'a, I: Instance> Adc<'a, I, Async> { | 291 | impl<'a, I: Instance> Adc<'a, I, Async> { |
| @@ -182,12 +302,65 @@ impl<'a, I: Instance> Adc<'a, I, Async> { | |||
| 182 | _irq: impl crate::interrupt::typelevel::Binding<I::Interrupt, InterruptHandler<I>> + 'a, | 302 | _irq: impl crate::interrupt::typelevel::Binding<I::Interrupt, InterruptHandler<I>> + 'a, |
| 183 | config: LpadcConfig, | 303 | config: LpadcConfig, |
| 184 | ) -> Result<Self> { | 304 | ) -> Result<Self> { |
| 185 | let adc = Self::new_inner(_inst, pin, config); | 305 | let adc = Self::new_inner(_inst, pin, config)?; |
| 186 | 306 | ||
| 187 | I::Interrupt::unpend(); | 307 | I::Interrupt::unpend(); |
| 188 | unsafe { I::Interrupt::enable() }; | 308 | unsafe { I::Interrupt::enable() }; |
| 189 | 309 | ||
| 190 | adc | 310 | let cfg = ConvCommandConfig { |
| 311 | chained_next_command_number: Next::NoNextCmdTerminateOnFinish, | ||
| 312 | enable_auto_channel_increment: false, | ||
| 313 | loop_count: 0, | ||
| 314 | hardware_average_mode: Avgs::NoAverage, // todo: good config? | ||
| 315 | sample_time_mode: Sts::Sample3p5, // todo: good config? | ||
| 316 | hardware_compare_mode: Cmpen::DisabledAlwaysStoreResult, | ||
| 317 | hardware_compare_value_high: 0, | ||
| 318 | hardware_compare_value_low: 0, | ||
| 319 | conversion_resolution_mode: Mode::Data16Bits, // todo: good config? | ||
| 320 | enable_wait_trigger: false, | ||
| 321 | }; | ||
| 322 | |||
| 323 | // We always use command 1, so this cannot fail | ||
| 324 | _ = adc.set_conv_command_config_inner(1, &cfg); | ||
| 325 | |||
| 326 | let cfg = ConvTriggerConfig { | ||
| 327 | target_command_id: Tcmd::ExecuteCmd1, | ||
| 328 | delay_power: 0, | ||
| 329 | priority: Tpri::HighestPriority, | ||
| 330 | enable_hardware_trigger: false, | ||
| 331 | }; | ||
| 332 | |||
| 333 | // We always use trigger 0, so this cannot fail | ||
| 334 | _ = adc.set_conv_trigger_config_inner(0, &cfg); | ||
| 335 | |||
| 336 | // We always set the watermark to 0 (trigger when 1 is available) | ||
| 337 | I::ptr().fctrl0().modify(|_r, w| unsafe { w.fwmark().bits(0) }); | ||
| 338 | |||
| 339 | Ok(adc) | ||
| 340 | } | ||
| 341 | |||
| 342 | /// Set the number of averages | ||
| 343 | pub fn set_averages(&mut self, avgs: Avgs) { | ||
| 344 | // TODO: we should probably return a result or wait for idle? | ||
| 345 | // "A write to a CMD buffer while that CMD buffer is controlling the ADC operation may cause unpredictable behavior." | ||
| 346 | I::ptr().cmdh1().modify(|_r, w| w.avgs().variant(avgs)); | ||
| 347 | } | ||
| 348 | |||
| 349 | /// Set the sample time | ||
| 350 | pub fn set_sample_time(&mut self, st: Sts) { | ||
| 351 | // TODO: we should probably return a result or wait for idle? | ||
| 352 | // "A write to a CMD buffer while that CMD buffer is controlling the ADC operation may cause unpredictable behavior." | ||
| 353 | I::ptr().cmdh1().modify(|_r, w| w.sts().variant(st)); | ||
| 354 | } | ||
| 355 | |||
| 356 | pub fn set_resolution(&mut self, mode: Mode) { | ||
| 357 | // TODO: we should probably return a result or wait for idle? | ||
| 358 | // "A write to a CMD buffer while that CMD buffer is controlling the ADC operation may cause unpredictable behavior." | ||
| 359 | I::ptr().cmdl1().modify(|_r, w| w.mode().variant(mode)); | ||
| 360 | } | ||
| 361 | |||
| 362 | fn wait_idle(&mut self) -> impl Future<Output = core::result::Result<(), maitake_sync::Closed>> + use<'_, I> { | ||
| 363 | I::wait_cell().wait_for(|| I::ptr().ie().read().fwmie0().bit_is_clear()) | ||
| 191 | } | 364 | } |
| 192 | 365 | ||
| 193 | /// Read ADC value asynchronously. | 366 | /// Read ADC value asynchronously. |
| @@ -203,21 +376,29 @@ impl<'a, I: Instance> Adc<'a, I, Async> { | |||
| 203 | /// # Returns | 376 | /// # Returns |
| 204 | /// 16-bit ADC conversion value | 377 | /// 16-bit ADC conversion value |
| 205 | pub async fn read(&mut self) -> Result<u16> { | 378 | pub async fn read(&mut self) -> Result<u16> { |
| 206 | let wait = I::wait_cell().subscribe().await; | 379 | let adc = I::ptr(); |
| 207 | 380 | ||
| 208 | Adc::<'a, I, Async>::enable_interrupt(self, 0x1); | 381 | // If we cancelled a previous read, we might still be busy, wait |
| 209 | Adc::<'a, I, Async>::do_software_trigger(self, 1); | 382 | // until the interrupt is cleared (done by the interrupt) |
| 383 | _ = self.wait_idle().await; | ||
| 210 | 384 | ||
| 211 | let _ = wait.await; | 385 | // Clear the fifo |
| 386 | adc.ctrl().modify(|_, w| w.rstfifo0().trigger_reset()); | ||
| 387 | |||
| 388 | // Trigger a new conversion | ||
| 389 | adc.ie().modify(|_r, w| w.fwmie0().set_bit()); | ||
| 390 | adc.swtrig().write(|w| w.swt0().set_bit()); | ||
| 212 | 391 | ||
| 213 | let result = Adc::<'a, I, Async>::get_conv_result(self).unwrap().conv_value >> G_LPADC_RESULT_SHIFT; | 392 | // Wait for completion |
| 214 | Ok(result) | 393 | _ = self.wait_idle().await; |
| 394 | |||
| 395 | self.get_conv_result_inner().map(|r| r.conv_value) | ||
| 215 | } | 396 | } |
| 216 | } | 397 | } |
| 217 | 398 | ||
| 218 | impl<'a, I: Instance, M: ModeAdc> Adc<'a, I, M> { | 399 | impl<'a, I: Instance, M: ModeAdc> Adc<'a, I, M> { |
| 219 | /// Internal initialization function shared by `new_async` and `new_blocking`. | 400 | /// Internal initialization function shared by `new_async` and `new_blocking`. |
| 220 | fn new_inner(_inst: Peri<'a, I>, pin: Peri<'a, impl AdcPin<I>>, config: LpadcConfig) -> Result<Self> { | 401 | fn new_inner<P: AdcPin<I>>(_inst: Peri<'a, I>, pin: Peri<'a, P>, config: LpadcConfig) -> Result<Self> { |
| 221 | let adc = I::ptr(); | 402 | let adc = I::ptr(); |
| 222 | 403 | ||
| 223 | _ = unsafe { | 404 | _ = unsafe { |
| @@ -241,22 +422,16 @@ impl<'a, I: Instance, M: ModeAdc> Adc<'a, I, M> { | |||
| 241 | adc.ctrl().modify(|_, w| w.adcen().disabled()); | 422 | adc.ctrl().modify(|_, w| w.adcen().disabled()); |
| 242 | 423 | ||
| 243 | /* Configure the module generally. */ | 424 | /* Configure the module generally. */ |
| 244 | if config.enable_in_doze_mode { | 425 | adc.ctrl().modify(|_, w| w.dozen().bit(config.enable_in_doze_mode)); |
| 245 | adc.ctrl().modify(|_, w| w.dozen().enabled()); | ||
| 246 | } else { | ||
| 247 | adc.ctrl().modify(|_, w| w.dozen().disabled()); | ||
| 248 | } | ||
| 249 | 426 | ||
| 250 | /* Set calibration average mode. */ | 427 | /* Set calibration average mode. */ |
| 251 | adc.ctrl() | 428 | adc.ctrl() |
| 252 | .modify(|_, w| w.cal_avgs().variant(config.conversion_average_mode)); | 429 | .modify(|_, w| w.cal_avgs().variant(config.conversion_average_mode)); |
| 253 | 430 | ||
| 254 | adc.cfg().write(|w| unsafe { | 431 | adc.cfg().write(|w| unsafe { |
| 255 | let w = if config.enable_analog_preliminary { | 432 | if config.enable_analog_preliminary { |
| 256 | w.pwren().pre_enabled() | 433 | w.pwren().pre_enabled(); |
| 257 | } else { | 434 | } |
| 258 | w | ||
| 259 | }; | ||
| 260 | 435 | ||
| 261 | w.pudly() | 436 | w.pudly() |
| 262 | .bits(config.power_up_delay) | 437 | .bits(config.power_up_delay) |
| @@ -306,8 +481,7 @@ impl<'a, I: Instance, M: ModeAdc> Adc<'a, I, M> { | |||
| 306 | adc.pause().write(|w| unsafe { w.bits(0) }); | 481 | adc.pause().write(|w| unsafe { w.bits(0) }); |
| 307 | } | 482 | } |
| 308 | 483 | ||
| 309 | adc.fctrl0() | 484 | adc.fctrl0().write(|w| unsafe { w.fwmark().bits(0) }); |
| 310 | .write(|w| unsafe { w.fwmark().bits(config.fifo_watermark) }); | ||
| 311 | 485 | ||
| 312 | // Enable ADC | 486 | // Enable ADC |
| 313 | adc.ctrl().modify(|_, w| w.adcen().enabled()); | 487 | adc.ctrl().modify(|_, w| w.adcen().enabled()); |
| @@ -315,15 +489,10 @@ impl<'a, I: Instance, M: ModeAdc> Adc<'a, I, M> { | |||
| 315 | Ok(Self { | 489 | Ok(Self { |
| 316 | _inst: PhantomData, | 490 | _inst: PhantomData, |
| 317 | _phantom: PhantomData, | 491 | _phantom: PhantomData, |
| 492 | index: P::CHANNEL, | ||
| 318 | }) | 493 | }) |
| 319 | } | 494 | } |
| 320 | 495 | ||
| 321 | /// Deinitialize the ADC peripheral. | ||
| 322 | pub fn deinit(&self) { | ||
| 323 | let adc = I::ptr(); | ||
| 324 | adc.ctrl().modify(|_, w| w.adcen().disabled()); | ||
| 325 | } | ||
| 326 | |||
| 327 | /// Perform offset calibration. | 496 | /// Perform offset calibration. |
| 328 | /// Waits for calibration to complete before returning. | 497 | /// Waits for calibration to complete before returning. |
| 329 | pub fn do_offset_calibration(&self) { | 498 | pub fn do_offset_calibration(&self) { |
| @@ -369,7 +538,7 @@ impl<'a, I: Instance, M: ModeAdc> Adc<'a, I, M> { | |||
| 369 | while adc.gcc0().read().rdy().is_gain_cal_not_valid() {} | 538 | while adc.gcc0().read().rdy().is_gain_cal_not_valid() {} |
| 370 | 539 | ||
| 371 | let mut gcca = adc.gcc0().read().gain_cal().bits() as u32; | 540 | let mut gcca = adc.gcc0().read().gain_cal().bits() as u32; |
| 372 | if gcca & ((0xFFFF + 1) >> 1) != 0 { | 541 | if gcca & 0x8000 != 0 { |
| 373 | gcca |= !0xFFFF; | 542 | gcca |= !0xFFFF; |
| 374 | } | 543 | } |
| 375 | 544 | ||
| @@ -384,127 +553,58 @@ impl<'a, I: Instance, M: ModeAdc> Adc<'a, I, M> { | |||
| 384 | while adc.stat().read().cal_rdy().is_not_set() {} | 553 | while adc.stat().read().cal_rdy().is_not_set() {} |
| 385 | } | 554 | } |
| 386 | 555 | ||
| 387 | /// Trigger ADC conversion(s) via software. | 556 | fn set_conv_command_config_inner(&self, index: usize, config: &ConvCommandConfig) -> Result<()> { |
| 388 | /// | ||
| 389 | /// Initiates conversion(s) for the trigger(s) specified in the bitmask. | ||
| 390 | /// Each bit in the mask corresponds to a trigger ID (bit 0 = trigger 0, etc.). | ||
| 391 | /// | ||
| 392 | /// # Arguments | ||
| 393 | /// * `trigger_id_mask` - Bitmask of trigger IDs to activate (bit N = trigger N) | ||
| 394 | pub fn do_software_trigger(&self, trigger_id_mask: u32) { | ||
| 395 | let adc = I::ptr(); | 557 | let adc = I::ptr(); |
| 396 | adc.swtrig().write(|w| unsafe { w.bits(trigger_id_mask) }); | ||
| 397 | } | ||
| 398 | |||
| 399 | /// Get default conversion command configuration. | ||
| 400 | /// # Returns | ||
| 401 | /// Default conversion command configuration | ||
| 402 | pub fn get_default_conv_command_config(&self) -> ConvCommandConfig { | ||
| 403 | ConvCommandConfig { | ||
| 404 | channel_number: Adch::SelectCh0, | ||
| 405 | chained_next_command_number: Next::NoNextCmdTerminateOnFinish, | ||
| 406 | enable_auto_channel_increment: false, | ||
| 407 | loop_count: 0, | ||
| 408 | hardware_average_mode: Avgs::NoAverage, | ||
| 409 | sample_time_mode: Sts::Sample3p5, | ||
| 410 | hardware_compare_mode: Cmpen::DisabledAlwaysStoreResult, | ||
| 411 | hardware_compare_value_high: 0, | ||
| 412 | hardware_compare_value_low: 0, | ||
| 413 | conversion_resolution_mode: Mode::Data12Bits, | ||
| 414 | enable_wait_trigger: false, | ||
| 415 | } | ||
| 416 | } | ||
| 417 | 558 | ||
| 418 | /// Set conversion command configuration. | 559 | let (cmdl, cmdh) = match index { |
| 419 | /// | 560 | 1 => (adc.cmdl1(), adc.cmdh1()), |
| 420 | /// Configures a conversion command slot with the specified parameters. | 561 | 2 => (adc.cmdl2(), adc.cmdh2()), |
| 421 | /// Commands define how conversions are performed (channel, resolution, etc.). | 562 | 3 => (adc.cmdl3(), adc.cmdh3()), |
| 422 | /// | 563 | 4 => (adc.cmdl4(), adc.cmdh4()), |
| 423 | /// # Arguments | 564 | 5 => (adc.cmdl5(), adc.cmdh5()), |
| 424 | /// * `index` - Command index | 565 | 6 => (adc.cmdl6(), adc.cmdh6()), |
| 425 | /// * `config` - Command configuration | 566 | 7 => (adc.cmdl7(), adc.cmdh7()), |
| 426 | /// | 567 | _ => return Err(Error::InvalidConfig), |
| 427 | /// # Returns | 568 | }; |
| 428 | /// * `Ok(())` if the command was configured successfully | ||
| 429 | /// * `Err(Error::InvalidConfig)` if the index is out of range | ||
| 430 | pub fn set_conv_command_config(&self, index: u32, config: &ConvCommandConfig) -> Result<()> { | ||
| 431 | let adc = I::ptr(); | ||
| 432 | |||
| 433 | if index < 1 || index > 7 { | ||
| 434 | return Err(Error::InvalidConfig); | ||
| 435 | } | ||
| 436 | 569 | ||
| 437 | macro_rules! write_cmd { | 570 | cmdl.write(|w| { |
| 438 | ($idx:expr) => {{ | 571 | unsafe { |
| 439 | paste! { | 572 | w.adch().bits(self.index); |
| 440 | adc.[<cmdl $idx>]().write(|w| { | 573 | } |
| 441 | w.adch() | 574 | w.mode().variant(config.conversion_resolution_mode) |
| 442 | .variant(config.channel_number) | 575 | }); |
| 443 | .mode() | ||
| 444 | .variant(config.conversion_resolution_mode) | ||
| 445 | }); | ||
| 446 | adc.[<cmdh $idx>]().write(|w| unsafe { | ||
| 447 | w.next() | ||
| 448 | .variant(config.chained_next_command_number) | ||
| 449 | .loop_() | ||
| 450 | .bits(config.loop_count) | ||
| 451 | .avgs() | ||
| 452 | .variant(config.hardware_average_mode) | ||
| 453 | .sts() | ||
| 454 | .variant(config.sample_time_mode) | ||
| 455 | .cmpen() | ||
| 456 | .variant(config.hardware_compare_mode) | ||
| 457 | .wait_trig() | ||
| 458 | .bit(config.enable_wait_trigger) | ||
| 459 | .lwi() | ||
| 460 | .bit(config.enable_auto_channel_increment) | ||
| 461 | }); | ||
| 462 | } | ||
| 463 | }}; | ||
| 464 | } | ||
| 465 | 576 | ||
| 466 | match index { | 577 | cmdh.write(|w| { |
| 467 | 1 => write_cmd!(1), | 578 | w.next().variant(config.chained_next_command_number); |
| 468 | 2 => write_cmd!(2), | 579 | unsafe { |
| 469 | 3 => write_cmd!(3), | 580 | w.loop_().bits(config.loop_count); |
| 470 | 4 => write_cmd!(4), | 581 | } |
| 471 | 5 => write_cmd!(5), | 582 | w.avgs().variant(config.hardware_average_mode); |
| 472 | 6 => write_cmd!(6), | 583 | w.sts().variant(config.sample_time_mode); |
| 473 | 7 => write_cmd!(7), | 584 | w.cmpen().variant(config.hardware_compare_mode); |
| 474 | _ => unreachable!(), | 585 | w.wait_trig().bit(config.enable_wait_trigger); |
| 475 | } | 586 | w.lwi().bit(config.enable_auto_channel_increment); |
| 587 | w | ||
| 588 | }); | ||
| 476 | 589 | ||
| 477 | Ok(()) | 590 | Ok(()) |
| 478 | } | 591 | } |
| 479 | 592 | ||
| 480 | /// Get default conversion trigger configuration. | 593 | fn set_conv_trigger_config_inner(&self, trigger_id: usize, config: &ConvTriggerConfig) -> Result<()> { |
| 481 | /// | 594 | let adc = I::ptr(); |
| 482 | /// # Returns | 595 | |
| 483 | /// Default conversion trigger configuration | 596 | // 0..4 are valid |
| 484 | pub fn get_default_conv_trigger_config(&self) -> ConvTriggerConfig { | 597 | if trigger_id >= 4 { |
| 485 | ConvTriggerConfig { | 598 | return Err(Error::InvalidConfig); |
| 486 | target_command_id: Tcmd::NotValid, | ||
| 487 | delay_power: 0, | ||
| 488 | priority: Tpri::HighestPriority, | ||
| 489 | enable_hardware_trigger: false, | ||
| 490 | } | 599 | } |
| 491 | } | ||
| 492 | 600 | ||
| 493 | /// Set conversion trigger configuration. | ||
| 494 | /// | ||
| 495 | /// Configures a trigger to initiate conversions. Triggers can be | ||
| 496 | /// activated by software or hardware signals. | ||
| 497 | /// | ||
| 498 | /// # Arguments | ||
| 499 | /// * `trigger_id` - Trigger index (0-15) | ||
| 500 | /// * `config` - Trigger configuration | ||
| 501 | pub fn set_conv_trigger_config(&self, trigger_id: usize, config: &ConvTriggerConfig) { | ||
| 502 | let adc = I::ptr(); | ||
| 503 | let tctrl = &adc.tctrl(trigger_id); | 601 | let tctrl = &adc.tctrl(trigger_id); |
| 504 | 602 | ||
| 505 | tctrl.write(|w| unsafe { | 603 | tctrl.write(|w| { |
| 506 | let w = w.tcmd().variant(config.target_command_id); | 604 | w.tcmd().variant(config.target_command_id); |
| 507 | let w = w.tdly().bits(config.delay_power); | 605 | unsafe { |
| 606 | w.tdly().bits(config.delay_power); | ||
| 607 | } | ||
| 508 | w.tpri().variant(config.priority); | 608 | w.tpri().variant(config.priority); |
| 509 | if config.enable_hardware_trigger { | 609 | if config.enable_hardware_trigger { |
| 510 | w.hten().enabled() | 610 | w.hten().enabled() |
| @@ -512,36 +612,8 @@ impl<'a, I: Instance, M: ModeAdc> Adc<'a, I, M> { | |||
| 512 | w | 612 | w |
| 513 | } | 613 | } |
| 514 | }); | 614 | }); |
| 515 | } | ||
| 516 | 615 | ||
| 517 | /// Reset the FIFO buffer. | 616 | Ok(()) |
| 518 | /// | ||
| 519 | /// Clears all pending conversion results from the FIFO. | ||
| 520 | pub fn do_reset_fifo(&self) { | ||
| 521 | let adc = I::ptr(); | ||
| 522 | adc.ctrl().modify(|_, w| w.rstfifo0().trigger_reset()); | ||
| 523 | } | ||
| 524 | |||
| 525 | /// Enable ADC interrupts. | ||
| 526 | /// | ||
| 527 | /// Enables the interrupt sources specified in the bitmask. | ||
| 528 | /// | ||
| 529 | /// # Arguments | ||
| 530 | /// * `mask` - Bitmask of interrupt sources to enable | ||
| 531 | pub fn enable_interrupt(&self, mask: u32) { | ||
| 532 | let adc = I::ptr(); | ||
| 533 | adc.ie().modify(|r, w| unsafe { w.bits(r.bits() | mask) }); | ||
| 534 | } | ||
| 535 | |||
| 536 | /// Disable ADC interrupts. | ||
| 537 | /// | ||
| 538 | /// Disables the interrupt sources specified in the bitmask. | ||
| 539 | /// | ||
| 540 | /// # Arguments | ||
| 541 | /// * `mask` - Bitmask of interrupt sources to disable | ||
| 542 | pub fn disable_interrupt(&self, mask: u32) { | ||
| 543 | let adc = I::ptr(); | ||
| 544 | adc.ie().modify(|r, w| unsafe { w.bits(r.bits() & !mask) }); | ||
| 545 | } | 617 | } |
| 546 | 618 | ||
| 547 | /// Get conversion result from FIFO. | 619 | /// Get conversion result from FIFO. |
| @@ -552,7 +624,7 @@ impl<'a, I: Instance, M: ModeAdc> Adc<'a, I, M> { | |||
| 552 | /// # Returns | 624 | /// # Returns |
| 553 | /// - `Some(ConvResult)` if a result is available | 625 | /// - `Some(ConvResult)` if a result is available |
| 554 | /// - `Err(Error::FifoEmpty)` if the FIFO is empty | 626 | /// - `Err(Error::FifoEmpty)` if the FIFO is empty |
| 555 | pub fn get_conv_result(&self) -> Result<ConvResult> { | 627 | fn get_conv_result_inner(&self) -> Result<ConvResult> { |
| 556 | let adc = I::ptr(); | 628 | let adc = I::ptr(); |
| 557 | let fifo = adc.resfifo0().read(); | 629 | let fifo = adc.resfifo0().read(); |
| 558 | if !fifo.valid().is_valid() { | 630 | if !fifo.valid().is_valid() { |
| @@ -570,7 +642,7 @@ impl<'a, I: Instance, M: ModeAdc> Adc<'a, I, M> { | |||
| 570 | 642 | ||
| 571 | impl<T: Instance> Handler<T::Interrupt> for InterruptHandler<T> { | 643 | impl<T: Instance> Handler<T::Interrupt> for InterruptHandler<T> { |
| 572 | unsafe fn on_interrupt() { | 644 | unsafe fn on_interrupt() { |
| 573 | T::ptr().ie().modify(|r, w| w.bits(r.bits() & !0x1)); | 645 | T::ptr().ie().modify(|_r, w| w.fwmie0().clear_bit()); |
| 574 | T::wait_cell().wake(); | 646 | T::wait_cell().wake(); |
| 575 | } | 647 | } |
| 576 | } | 648 | } |
| @@ -621,6 +693,8 @@ macro_rules! impl_instance { | |||
| 621 | impl_instance!(0, 1, 2, 3); | 693 | impl_instance!(0, 1, 2, 3); |
| 622 | 694 | ||
| 623 | pub trait AdcPin<Instance>: GpioPin + sealed::Sealed + PeripheralType { | 695 | pub trait AdcPin<Instance>: GpioPin + sealed::Sealed + PeripheralType { |
| 696 | const CHANNEL: u8; | ||
| 697 | |||
| 624 | /// Set the given pin to the correct muxing state | 698 | /// Set the given pin to the correct muxing state |
| 625 | fn mux(&self); | 699 | fn mux(&self); |
| 626 | } | 700 | } |
| @@ -640,8 +714,10 @@ impl sealed::Sealed for Async {} | |||
| 640 | impl ModeAdc for Async {} | 714 | impl ModeAdc for Async {} |
| 641 | 715 | ||
| 642 | macro_rules! impl_pin { | 716 | macro_rules! impl_pin { |
| 643 | ($pin:ident, $peri:ident, $func:ident, $trait:ident) => { | 717 | ($pin:ident, $peri:ident, $func:ident, $channel:literal) => { |
| 644 | impl $trait<crate::peripherals::$peri> for crate::peripherals::$pin { | 718 | impl AdcPin<crate::peripherals::$peri> for crate::peripherals::$pin { |
| 719 | const CHANNEL: u8 = $channel; | ||
| 720 | |||
| 645 | fn mux(&self) { | 721 | fn mux(&self) { |
| 646 | self.set_pull(crate::gpio::Pull::Disabled); | 722 | self.set_pull(crate::gpio::Pull::Disabled); |
| 647 | self.set_slew_rate(crate::gpio::SlewRate::Fast.into()); | 723 | self.set_slew_rate(crate::gpio::SlewRate::Fast.into()); |
| @@ -652,101 +728,113 @@ macro_rules! impl_pin { | |||
| 652 | }; | 728 | }; |
| 653 | } | 729 | } |
| 654 | 730 | ||
| 655 | impl_pin!(P2_0, ADC0, Mux0, AdcPin); | 731 | impl_pin!(P2_0, ADC0, Mux0, 0); |
| 656 | impl_pin!(P2_4, ADC0, Mux0, AdcPin); | 732 | impl_pin!(P2_4, ADC0, Mux0, 1); |
| 657 | impl_pin!(P2_15, ADC0, Mux0, AdcPin); | 733 | impl_pin!(P2_15, ADC0, Mux0, 2); |
| 658 | impl_pin!(P2_3, ADC0, Mux0, AdcPin); | 734 | impl_pin!(P2_3, ADC0, Mux0, 3); |
| 659 | impl_pin!(P2_2, ADC0, Mux0, AdcPin); | 735 | impl_pin!(P2_2, ADC0, Mux0, 4); |
| 660 | impl_pin!(P2_12, ADC0, Mux0, AdcPin); | 736 | impl_pin!(P2_12, ADC0, Mux0, 5); |
| 661 | impl_pin!(P2_16, ADC0, Mux0, AdcPin); | 737 | impl_pin!(P2_16, ADC0, Mux0, 6); |
| 662 | impl_pin!(P2_7, ADC0, Mux0, AdcPin); | 738 | impl_pin!(P2_7, ADC0, Mux0, 7); |
| 663 | impl_pin!(P0_18, ADC0, Mux0, AdcPin); | 739 | impl_pin!(P0_18, ADC0, Mux0, 8); |
| 664 | impl_pin!(P0_19, ADC0, Mux0, AdcPin); | 740 | impl_pin!(P0_19, ADC0, Mux0, 9); |
| 665 | impl_pin!(P0_20, ADC0, Mux0, AdcPin); | 741 | impl_pin!(P0_20, ADC0, Mux0, 10); |
| 666 | impl_pin!(P0_21, ADC0, Mux0, AdcPin); | 742 | impl_pin!(P0_21, ADC0, Mux0, 11); |
| 667 | impl_pin!(P0_22, ADC0, Mux0, AdcPin); | 743 | impl_pin!(P0_22, ADC0, Mux0, 12); |
| 668 | impl_pin!(P0_23, ADC0, Mux0, AdcPin); | 744 | impl_pin!(P0_23, ADC0, Mux0, 13); |
| 669 | impl_pin!(P0_3, ADC0, Mux0, AdcPin); | 745 | impl_pin!(P0_3, ADC0, Mux0, 14); |
| 670 | impl_pin!(P0_6, ADC0, Mux0, AdcPin); | 746 | impl_pin!(P0_6, ADC0, Mux0, 15); |
| 671 | impl_pin!(P1_0, ADC0, Mux0, AdcPin); | 747 | impl_pin!(P1_0, ADC0, Mux0, 16); |
| 672 | impl_pin!(P1_1, ADC0, Mux0, AdcPin); | 748 | impl_pin!(P1_1, ADC0, Mux0, 17); |
| 673 | impl_pin!(P1_2, ADC0, Mux0, AdcPin); | 749 | impl_pin!(P1_2, ADC0, Mux0, 18); |
| 674 | impl_pin!(P1_3, ADC0, Mux0, AdcPin); | 750 | impl_pin!(P1_3, ADC0, Mux0, 19); |
| 675 | impl_pin!(P1_4, ADC0, Mux0, AdcPin); | 751 | impl_pin!(P1_4, ADC0, Mux0, 20); |
| 676 | impl_pin!(P1_5, ADC0, Mux0, AdcPin); | 752 | impl_pin!(P1_5, ADC0, Mux0, 21); |
| 677 | impl_pin!(P1_6, ADC0, Mux0, AdcPin); | 753 | impl_pin!(P1_6, ADC0, Mux0, 22); |
| 678 | impl_pin!(P1_7, ADC0, Mux0, AdcPin); | 754 | impl_pin!(P1_7, ADC0, Mux0, 23); |
| 679 | impl_pin!(P1_10, ADC0, Mux0, AdcPin); | 755 | |
| 680 | 756 | // ??? | |
| 681 | impl_pin!(P2_1, ADC1, Mux0, AdcPin); | 757 | // impl_pin!(P1_10, ADC0, Mux0, 255); |
| 682 | impl_pin!(P2_5, ADC1, Mux0, AdcPin); | 758 | |
| 683 | impl_pin!(P2_19, ADC1, Mux0, AdcPin); | 759 | impl_pin!(P2_1, ADC1, Mux0, 0); |
| 684 | impl_pin!(P2_6, ADC1, Mux0, AdcPin); | 760 | impl_pin!(P2_5, ADC1, Mux0, 1); |
| 685 | impl_pin!(P2_3, ADC1, Mux0, AdcPin); | 761 | impl_pin!(P2_19, ADC1, Mux0, 2); |
| 686 | impl_pin!(P2_13, ADC1, Mux0, AdcPin); | 762 | impl_pin!(P2_6, ADC1, Mux0, 3); |
| 687 | impl_pin!(P2_17, ADC1, Mux0, AdcPin); | 763 | impl_pin!(P2_3, ADC1, Mux0, 4); |
| 688 | impl_pin!(P2_7, ADC1, Mux0, AdcPin); | 764 | impl_pin!(P2_13, ADC1, Mux0, 5); |
| 689 | impl_pin!(P1_10, ADC1, Mux0, AdcPin); | 765 | impl_pin!(P2_17, ADC1, Mux0, 6); |
| 690 | impl_pin!(P1_11, ADC1, Mux0, AdcPin); | 766 | impl_pin!(P2_7, ADC1, Mux0, 7); |
| 691 | impl_pin!(P1_12, ADC1, Mux0, AdcPin); | 767 | impl_pin!(P1_10, ADC1, Mux0, 8); |
| 692 | impl_pin!(P1_13, ADC1, Mux0, AdcPin); | 768 | impl_pin!(P1_11, ADC1, Mux0, 9); |
| 693 | impl_pin!(P1_14, ADC1, Mux0, AdcPin); | 769 | impl_pin!(P1_12, ADC1, Mux0, 10); |
| 694 | impl_pin!(P1_15, ADC1, Mux0, AdcPin); | 770 | impl_pin!(P1_13, ADC1, Mux0, 11); |
| 695 | impl_pin!(P1_16, ADC1, Mux0, AdcPin); | 771 | impl_pin!(P1_14, ADC1, Mux0, 12); |
| 696 | impl_pin!(P1_17, ADC1, Mux0, AdcPin); | 772 | impl_pin!(P1_15, ADC1, Mux0, 13); |
| 697 | impl_pin!(P1_18, ADC1, Mux0, AdcPin); | 773 | // ??? |
| 698 | impl_pin!(P1_19, ADC1, Mux0, AdcPin); | 774 | // impl_pin!(P1_16, ADC1, Mux0, 255); |
| 699 | impl_pin!(P3_31, ADC1, Mux0, AdcPin); | 775 | // impl_pin!(P1_17, ADC1, Mux0, 255); |
| 700 | impl_pin!(P3_30, ADC1, Mux0, AdcPin); | 776 | // impl_pin!(P1_18, ADC1, Mux0, 255); |
| 701 | impl_pin!(P3_29, ADC1, Mux0, AdcPin); | 777 | // impl_pin!(P1_19, ADC1, Mux0, 255); |
| 702 | 778 | // ??? | |
| 703 | impl_pin!(P2_4, ADC2, Mux0, AdcPin); | 779 | impl_pin!(P3_31, ADC1, Mux0, 20); |
| 704 | impl_pin!(P2_10, ADC2, Mux0, AdcPin); | 780 | impl_pin!(P3_30, ADC1, Mux0, 21); |
| 705 | impl_pin!(P4_4, ADC2, Mux0, AdcPin); | 781 | impl_pin!(P3_29, ADC1, Mux0, 22); |
| 706 | impl_pin!(P2_24, ADC2, Mux0, AdcPin); | 782 | |
| 707 | impl_pin!(P2_16, ADC2, Mux0, AdcPin); | 783 | impl_pin!(P2_4, ADC2, Mux0, 0); |
| 708 | impl_pin!(P2_12, ADC2, Mux0, AdcPin); | 784 | impl_pin!(P2_10, ADC2, Mux0, 1); |
| 709 | impl_pin!(P2_20, ADC2, Mux0, AdcPin); | 785 | impl_pin!(P4_4, ADC2, Mux0, 2); |
| 710 | impl_pin!(P2_7, ADC2, Mux0, AdcPin); | 786 | // impl_pin!(P2_24, ADC2, Mux0, 255); ??? |
| 711 | impl_pin!(P0_2, ADC2, Mux0, AdcPin); | 787 | impl_pin!(P2_16, ADC2, Mux0, 4); |
| 712 | impl_pin!(P0_4, ADC2, Mux0, AdcPin); | 788 | impl_pin!(P2_12, ADC2, Mux0, 5); |
| 713 | impl_pin!(P0_5, ADC2, Mux0, AdcPin); | 789 | impl_pin!(P2_20, ADC2, Mux0, 6); |
| 714 | impl_pin!(P0_6, ADC2, Mux0, AdcPin); | 790 | impl_pin!(P2_7, ADC2, Mux0, 7); |
| 715 | impl_pin!(P0_7, ADC2, Mux0, AdcPin); | 791 | impl_pin!(P0_2, ADC2, Mux0, 8); |
| 716 | impl_pin!(P0_12, ADC2, Mux0, AdcPin); | 792 | // ??? |
| 717 | impl_pin!(P0_13, ADC2, Mux0, AdcPin); | 793 | // impl_pin!(P0_4, ADC2, Mux0, 255); |
| 718 | impl_pin!(P0_14, ADC2, Mux0, AdcPin); | 794 | // impl_pin!(P0_5, ADC2, Mux0, 255); |
| 719 | impl_pin!(P0_15, ADC2, Mux0, AdcPin); | 795 | // impl_pin!(P0_6, ADC2, Mux0, 255); |
| 720 | impl_pin!(P4_0, ADC2, Mux0, AdcPin); | 796 | // impl_pin!(P0_7, ADC2, Mux0, 255); |
| 721 | impl_pin!(P4_1, ADC2, Mux0, AdcPin); | 797 | // impl_pin!(P0_12, ADC2, Mux0, 255); |
| 722 | impl_pin!(P4_2, ADC2, Mux0, AdcPin); | 798 | // impl_pin!(P0_13, ADC2, Mux0, 255); |
| 723 | impl_pin!(P4_3, ADC2, Mux0, AdcPin); | 799 | // ??? |
| 724 | //impl_pin!(P4_4, ADC2, Mux0, AdcPin); // Conflit with ADC2_A3 and ADC2_A20 using the same pin | 800 | impl_pin!(P0_14, ADC2, Mux0, 14); |
| 725 | impl_pin!(P4_5, ADC2, Mux0, AdcPin); | 801 | impl_pin!(P0_15, ADC2, Mux0, 15); |
| 726 | impl_pin!(P4_6, ADC2, Mux0, AdcPin); | 802 | // ??? |
| 727 | impl_pin!(P4_7, ADC2, Mux0, AdcPin); | 803 | // impl_pin!(P4_0, ADC2, Mux0, 255); |
| 728 | 804 | // impl_pin!(P4_1, ADC2, Mux0, 255); | |
| 729 | impl_pin!(P2_5, ADC3, Mux0, AdcPin); | 805 | // ??? |
| 730 | impl_pin!(P2_11, ADC3, Mux0, AdcPin); | 806 | impl_pin!(P4_2, ADC2, Mux0, 18); |
| 731 | impl_pin!(P2_23, ADC3, Mux0, AdcPin); | 807 | impl_pin!(P4_3, ADC2, Mux0, 19); |
| 732 | impl_pin!(P2_25, ADC3, Mux0, AdcPin); | 808 | //impl_pin!(P4_4, ADC2, Mux0, 20); // Conflit with ADC2_A3 and ADC2_A20 using the same pin |
| 733 | impl_pin!(P2_17, ADC3, Mux0, AdcPin); | 809 | impl_pin!(P4_5, ADC2, Mux0, 21); |
| 734 | impl_pin!(P2_13, ADC3, Mux0, AdcPin); | 810 | impl_pin!(P4_6, ADC2, Mux0, 22); |
| 735 | impl_pin!(P2_21, ADC3, Mux0, AdcPin); | 811 | impl_pin!(P4_7, ADC2, Mux0, 23); |
| 736 | impl_pin!(P2_7, ADC3, Mux0, AdcPin); | 812 | |
| 737 | impl_pin!(P3_2, ADC3, Mux0, AdcPin); | 813 | impl_pin!(P2_5, ADC3, Mux0, 0); |
| 738 | impl_pin!(P3_3, ADC3, Mux0, AdcPin); | 814 | impl_pin!(P2_11, ADC3, Mux0, 1); |
| 739 | impl_pin!(P3_4, ADC3, Mux0, AdcPin); | 815 | impl_pin!(P2_23, ADC3, Mux0, 2); |
| 740 | impl_pin!(P3_5, ADC3, Mux0, AdcPin); | 816 | // impl_pin!(P2_25, ADC3, Mux0, 255); // ??? |
| 741 | impl_pin!(P3_6, ADC3, Mux0, AdcPin); | 817 | impl_pin!(P2_17, ADC3, Mux0, 4); |
| 742 | impl_pin!(P3_7, ADC3, Mux0, AdcPin); | 818 | impl_pin!(P2_13, ADC3, Mux0, 5); |
| 743 | impl_pin!(P3_12, ADC3, Mux0, AdcPin); | 819 | impl_pin!(P2_21, ADC3, Mux0, 6); |
| 744 | impl_pin!(P3_13, ADC3, Mux0, AdcPin); | 820 | impl_pin!(P2_7, ADC3, Mux0, 7); |
| 745 | impl_pin!(P3_14, ADC3, Mux0, AdcPin); | 821 | // ??? |
| 746 | impl_pin!(P3_15, ADC3, Mux0, AdcPin); | 822 | // impl_pin!(P3_2, ADC3, Mux0, 255); |
| 747 | impl_pin!(P3_20, ADC3, Mux0, AdcPin); | 823 | // impl_pin!(P3_3, ADC3, Mux0, 255); |
| 748 | impl_pin!(P3_21, ADC3, Mux0, AdcPin); | 824 | // impl_pin!(P3_4, ADC3, Mux0, 255); |
| 749 | impl_pin!(P3_22, ADC3, Mux0, AdcPin); | 825 | // impl_pin!(P3_5, ADC3, Mux0, 255); |
| 750 | impl_pin!(P3_23, ADC3, Mux0, AdcPin); | 826 | // ??? |
| 751 | impl_pin!(P3_24, ADC3, Mux0, AdcPin); | 827 | impl_pin!(P3_6, ADC3, Mux0, 12); |
| 752 | impl_pin!(P3_25, ADC3, Mux0, AdcPin); | 828 | impl_pin!(P3_7, ADC3, Mux0, 13); |
| 829 | impl_pin!(P3_12, ADC3, Mux0, 14); | ||
| 830 | impl_pin!(P3_13, ADC3, Mux0, 15); | ||
| 831 | impl_pin!(P3_14, ADC3, Mux0, 16); | ||
| 832 | impl_pin!(P3_15, ADC3, Mux0, 17); | ||
| 833 | impl_pin!(P3_20, ADC3, Mux0, 18); | ||
| 834 | impl_pin!(P3_21, ADC3, Mux0, 19); | ||
| 835 | impl_pin!(P3_22, ADC3, Mux0, 20); | ||
| 836 | // ??? | ||
| 837 | // impl_pin!(P3_23, ADC3, Mux0, 255); | ||
| 838 | // impl_pin!(P3_24, ADC3, Mux0, 255); | ||
| 839 | // impl_pin!(P3_25, ADC3, Mux0, 255); | ||
| 840 | // ??? | ||
