-
Notifications
You must be signed in to change notification settings - Fork 249
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Initial pass at converting ADC example to use the fifo
- Loading branch information
Showing
2 changed files
with
187 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,182 @@ | ||
//! # ADC Example | ||
//! | ||
//! This application demonstrates how to read ADC samples from the temperature | ||
//! sensor and pin and output them to the UART on pins 1 and 2 at 9600 baud. | ||
//! | ||
//! It may need to be adapted to your particular board layout and/or pin assignment. | ||
//! | ||
//! See the `Cargo.toml` file for Copyright and licence details. | ||
#![no_std] | ||
#![no_main] | ||
|
||
// The macro for our start-up function | ||
use cortex_m_rt::entry; | ||
|
||
// Ensure we halt the program on panic (if we don't mention this crate it won't | ||
// be linked) | ||
use panic_halt as _; | ||
|
||
// Alias for our HAL crate | ||
use rp2040_hal as hal; | ||
|
||
// Some traits we need | ||
use core::fmt::Write; | ||
use embedded_hal::adc::OneShot; | ||
use embedded_time::fixed_point::FixedPoint; | ||
use pac::interrupt; | ||
use rp2040_hal::Clock; | ||
// A shorter alias for the Peripheral Access Crate, which provides low-level | ||
// register access | ||
use hal::{pac, Adc}; | ||
|
||
/// The linker will place this boot block at the start of our program image. We | ||
/// need this to help the ROM bootloader get our code up and running. | ||
#[link_section = ".boot2"] | ||
#[used] | ||
pub static BOOT2: [u8; 256] = rp2040_boot2::BOOT_LOADER_W25Q080; | ||
|
||
/// External high-speed crystal on the Raspberry Pi Pico board is 12 MHz. Adjust | ||
/// if your board has a different frequency | ||
const XTAL_FREQ_HZ: u32 = 12_000_000u32; | ||
|
||
use core::cell::RefCell; | ||
use cortex_m::interrupt::Mutex; | ||
use rp2040_hal::Adc as RpAdc; | ||
static ADC_OBJ: Mutex<RefCell<Option<RpAdc>>> = Mutex::new(RefCell::new(None)); | ||
|
||
/// Entry point to our bare-metal application. | ||
/// | ||
/// The `#[entry]` macro ensures the Cortex-M start-up code calls this function | ||
/// as soon as all global variables are initialised. | ||
/// | ||
/// The function configures the RP2040 peripherals, then prints the temperature | ||
/// in an infinite loop. | ||
#[entry] | ||
fn main() -> ! { | ||
// Grab our singleton objects | ||
let mut pac = pac::Peripherals::take().unwrap(); | ||
let core = pac::CorePeripherals::take().unwrap(); | ||
|
||
// Set up the watchdog driver - needed by the clock setup code | ||
let mut watchdog = hal::Watchdog::new(pac.WATCHDOG); | ||
|
||
// Configure the clocks | ||
let clocks = hal::clocks::init_clocks_and_plls( | ||
XTAL_FREQ_HZ, | ||
pac.XOSC, | ||
pac.CLOCKS, | ||
pac.PLL_SYS, | ||
pac.PLL_USB, | ||
&mut pac.RESETS, | ||
&mut watchdog, | ||
) | ||
.ok() | ||
.unwrap(); | ||
|
||
// The delay object lets us wait for specified amounts of time (in | ||
// milliseconds) | ||
let mut delay = cortex_m::delay::Delay::new(core.SYST, clocks.system_clock.freq().integer()); | ||
|
||
// The single-cycle I/O block controls our GPIO pins | ||
let sio = hal::Sio::new(pac.SIO); | ||
|
||
// Set the pins to their default state | ||
let pins = hal::gpio::Pins::new( | ||
pac.IO_BANK0, | ||
pac.PADS_BANK0, | ||
sio.gpio_bank0, | ||
&mut pac.RESETS, | ||
); | ||
|
||
// UART TX (characters sent from pico) on pin 1 (GPIO0) and RX (on pin 2 (GPIO1) | ||
let uart_pins = ( | ||
pins.gpio0.into_mode::<hal::gpio::FunctionUart>(), | ||
pins.gpio1.into_mode::<hal::gpio::FunctionUart>(), | ||
); | ||
|
||
// Create a UART driver | ||
let mut uart = hal::uart::UartPeripheral::new(pac.UART0, uart_pins, &mut pac.RESETS) | ||
.enable( | ||
hal::uart::common_configs::_9600_8_N_1, | ||
clocks.peripheral_clock.into(), | ||
) | ||
.unwrap(); | ||
|
||
// Write to the UART | ||
uart.write_full_blocking(b"ADC example\r\n"); | ||
|
||
// Enable ADC | ||
let mut adc = hal::Adc::new(pac.ADC, &mut pac.RESETS); | ||
|
||
// Enable the temperature sense channel | ||
let mut temperature_sensor = adc.enable_temp_sensor(); | ||
|
||
// Configure GPIO26 as an ADC input | ||
let mut adc_pin_0 = pins.gpio26.into_floating_input(); | ||
cortex_m::interrupt::free(|cs| { | ||
adc.start_many_round_robin(0b1); | ||
ADC_OBJ.borrow(cs).replace(Some(adc)); | ||
}); | ||
loop { | ||
cortex_m::interrupt::free(|cs| { | ||
if let Some(adc) = ADC_OBJ.borrow(cs).borrow_mut().as_mut() { | ||
if adc.interrupt_pending(){ | ||
writeln!( | ||
uart, | ||
"Interrupt pending\r\n" | ||
) | ||
.unwrap(); | ||
} | ||
writeln!( | ||
uart, | ||
"fifo len {:?}\r\n", | ||
adc.fifo_len() | ||
) | ||
.unwrap(); | ||
// adc.enable_fifo_interrupt(1); | ||
} | ||
}); | ||
delay.delay_ms(1000); | ||
} | ||
} | ||
|
||
#[interrupt] | ||
fn ADC_IRQ_FIFO() { | ||
unsafe { | ||
let (mut adc0, mut adc1, mut adc2, mut adc3) = (0, 0, 0, 0); | ||
cortex_m::interrupt::free(|cs| { | ||
let adc = ADC_OBJ.borrow(cs).take(); | ||
|
||
if let Some(mut adc) = adc { | ||
if adc.fifo_len() < 4 { | ||
//info!("fifo was not full enough"); | ||
while adc.fifo_len() > 0 { | ||
let a = adc.read_fifo(); | ||
//info!("fifo contained {:?}", a); | ||
} | ||
} | ||
if let Some(a) = adc.read_fifo() { | ||
adc0 = a; | ||
} | ||
if let Some(a) = adc.read_fifo() { | ||
adc1 = a; | ||
} | ||
if let Some(a) = adc.read_fifo() { | ||
adc2 = a; | ||
} | ||
if let Some(a) = adc.read_fifo() { | ||
adc3 = a; | ||
} | ||
} else { | ||
//info!("no adc?"); | ||
} | ||
}); | ||
// info!( | ||
// "ADC readings: Pin: {:02}, pin1 {:02}, pin2 {:02}, pin3 {:02}\r\n", | ||
// adc0, adc1, adc2, adc3 | ||
// ); | ||
} | ||
} | ||
|
||
// End of file |