Start implementing interrupt
This commit is contained in:
parent
886c8135e7
commit
94c5c2a366
2 changed files with 147 additions and 99 deletions
|
@ -6,6 +6,8 @@ version = "0.1.0"
|
||||||
[dependencies]
|
[dependencies]
|
||||||
cortex-m = "0.7.6"
|
cortex-m = "0.7.6"
|
||||||
cortex-m-rt = "0.7.2"
|
cortex-m-rt = "0.7.2"
|
||||||
|
cortex-m-rtic = "1.1.2"
|
||||||
|
fugit = "0.3.6"
|
||||||
embedded-hal = { version = "0.2.7", features = ["unproven"] }
|
embedded-hal = { version = "0.2.7", features = ["unproven"] }
|
||||||
embedded-time = "0.12.1"
|
embedded-time = "0.12.1"
|
||||||
|
|
||||||
|
|
|
@ -1,125 +1,171 @@
|
||||||
//! Blinks the LED on a Pico board
|
|
||||||
//!
|
|
||||||
//! This will blink an LED attached to GP25, which is the pin the Pico uses for the on-board LED.
|
|
||||||
#![no_std]
|
#![no_std]
|
||||||
#![no_main]
|
#![no_main]
|
||||||
|
|
||||||
mod serial;
|
mod serial;
|
||||||
|
|
||||||
use bsp::entry;
|
|
||||||
use embedded_hal::digital::v2::OutputPin;
|
|
||||||
use panic_probe as _;
|
use panic_probe as _;
|
||||||
|
|
||||||
// Provide an alias for our BSP so we can switch targets quickly.
|
#[rtic::app(device = rp_pico::hal::pac, peripherals = true)]
|
||||||
// Uncomment the BSP you included in Cargo.toml, the rest of the code does not need to change.
|
mod app {
|
||||||
use rp_pico as bsp;
|
// Provide an alias for our BSP so we can switch targets quickly.
|
||||||
|
// Uncomment the BSP you included in Cargo.toml, the rest of the code does not need to change.
|
||||||
|
use rp_pico as bsp;
|
||||||
|
|
||||||
use bsp::hal::{
|
use bsp::hal::{
|
||||||
clocks::{init_clocks_and_plls, Clock},
|
clocks::{init_clocks_and_plls, Clock},
|
||||||
pac,
|
gpio::{bank0::Gpio26, Floating, Input, Pin},
|
||||||
rom_data::reset_to_usb_boot,
|
rom_data::reset_to_usb_boot,
|
||||||
sio::Sio,
|
sio::Sio,
|
||||||
usb::UsbBus,
|
timer::{Alarm, Alarm0},
|
||||||
watchdog::Watchdog,
|
usb::UsbBus,
|
||||||
Adc,
|
watchdog::Watchdog,
|
||||||
};
|
Adc, Timer,
|
||||||
|
};
|
||||||
|
|
||||||
use embedded_hal::adc::OneShot;
|
use fugit::MicrosDurationU32;
|
||||||
|
|
||||||
use usb_device::{class_prelude::*, prelude::*};
|
use embedded_hal::{adc::OneShot, digital::v2::OutputPin};
|
||||||
|
use usb_device::{class_prelude::*, prelude::*};
|
||||||
|
|
||||||
use crate::serial::{Commands, Serial};
|
use crate::serial::{Commands, Serial};
|
||||||
|
|
||||||
#[entry]
|
const SCAN_TIME_US: MicrosDurationU32 = MicrosDurationU32::secs(1);
|
||||||
fn main() -> ! {
|
|
||||||
let mut pac = pac::Peripherals::take().unwrap();
|
|
||||||
let core = pac::CorePeripherals::take().unwrap();
|
|
||||||
let mut watchdog = Watchdog::new(pac.WATCHDOG);
|
|
||||||
|
|
||||||
// External high-speed crystal on the pico board is 12Mhz
|
struct Data {
|
||||||
let external_xtal_freq_hz = 12_000_000u32;
|
i: usize,
|
||||||
let clocks = init_clocks_and_plls(
|
usb_bus: UsbBusAllocator<UsbBus>,
|
||||||
external_xtal_freq_hz,
|
usb_dev: UsbDevice<'static, UsbBus>,
|
||||||
pac.XOSC,
|
|
||||||
pac.CLOCKS,
|
|
||||||
pac.PLL_SYS,
|
|
||||||
pac.PLL_USB,
|
|
||||||
&mut pac.RESETS,
|
|
||||||
&mut watchdog,
|
|
||||||
)
|
|
||||||
.ok()
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
let mut delay = cortex_m::delay::Delay::new(core.SYST, clocks.system_clock.freq().to_Hz());
|
serial: Serial<'static>,
|
||||||
|
|
||||||
let sio = Sio::new(pac.SIO);
|
adc: Adc,
|
||||||
|
adc_pin_0: Pin<Gpio26, Input<Floating>>,
|
||||||
|
}
|
||||||
|
|
||||||
let pins = bsp::Pins::new(
|
#[shared]
|
||||||
pac.IO_BANK0,
|
struct Shared {
|
||||||
pac.PADS_BANK0,
|
timer: Timer,
|
||||||
sio.gpio_bank0,
|
alarm: Alarm0,
|
||||||
&mut pac.RESETS,
|
|
||||||
);
|
|
||||||
|
|
||||||
let mut led_pin = pins.led.into_push_pull_output();
|
data: Data,
|
||||||
|
}
|
||||||
|
|
||||||
led_pin.set_low().unwrap();
|
#[local]
|
||||||
|
struct Local {}
|
||||||
|
|
||||||
// Set up the USB driver
|
#[init]
|
||||||
let usb_bus = UsbBusAllocator::new(UsbBus::new(
|
fn init(c: init::Context) -> (Shared, Local, init::Monotonics) {
|
||||||
pac.USBCTRL_REGS,
|
// Soft-reset does not release the hardware spinlocks
|
||||||
pac.USBCTRL_DPRAM,
|
// Release them now to avoid a deadlock after debug or watchdog reset
|
||||||
clocks.usb_clock,
|
unsafe {
|
||||||
true,
|
bsp::hal::sio::spinlock_reset();
|
||||||
&mut pac.RESETS,
|
|
||||||
));
|
|
||||||
|
|
||||||
let mut serial = Serial::new(&usb_bus);
|
|
||||||
|
|
||||||
// Create a USB device with a fake VID and PID
|
|
||||||
let mut usb_dev = UsbDeviceBuilder::new(&usb_bus, UsbVidPid(0x16c0, 0x27dd))
|
|
||||||
.manufacturer("Fake company")
|
|
||||||
.product("Serial port")
|
|
||||||
.serial_number("TEST")
|
|
||||||
.device_class(2) // from: https://www.usb.org/defined-class-codes
|
|
||||||
.build();
|
|
||||||
|
|
||||||
let mut adc = Adc::new(pac.ADC, &mut pac.RESETS);
|
|
||||||
|
|
||||||
let mut adc_pin_0 = pins.gpio26.into_floating_input();
|
|
||||||
// let mut adc_pin_1 = pins.gpio27.into_floating_input();
|
|
||||||
// let mut adc_pin_2 = pins.gpio28.into_floating_input();
|
|
||||||
|
|
||||||
let mut i = 0;
|
|
||||||
|
|
||||||
loop {
|
|
||||||
// serial.write("test".as_bytes());
|
|
||||||
|
|
||||||
// serial_send(&mut serial, "test");
|
|
||||||
// delay.delay_ms(1000);
|
|
||||||
|
|
||||||
i += 1;
|
|
||||||
|
|
||||||
if i == 100 {
|
|
||||||
i = 0;
|
|
||||||
|
|
||||||
let adc_0_value: u16 = adc.read(&mut adc_pin_0).unwrap();
|
|
||||||
// let adc_1_value: u16 = adc.read(&mut adc_pin_1).unwrap();
|
|
||||||
// let adc_2_value: u16 = adc.read(&mut adc_pin_2).unwrap();
|
|
||||||
|
|
||||||
serial.send(adc_0_value);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
delay.delay_ms(8);
|
let mut resets = c.device.RESETS;
|
||||||
|
let mut watchdog = Watchdog::new(c.device.WATCHDOG);
|
||||||
|
|
||||||
if usb_dev.poll(&mut [&mut serial]) {
|
let external_xtal_freq_hz = 12_000_000u32;
|
||||||
if let Some(command) = serial.read() {
|
let clocks = init_clocks_and_plls(
|
||||||
match command {
|
external_xtal_freq_hz,
|
||||||
Commands::Reset => reset_to_usb_boot(0, 0),
|
c.device.XOSC,
|
||||||
|
c.device.CLOCKS,
|
||||||
|
c.device.PLL_SYS,
|
||||||
|
c.device.PLL_USB,
|
||||||
|
&mut resets,
|
||||||
|
&mut watchdog,
|
||||||
|
)
|
||||||
|
.ok()
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
let sio = Sio::new(c.device.SIO);
|
||||||
|
let pins = rp_pico::Pins::new(
|
||||||
|
c.device.IO_BANK0,
|
||||||
|
c.device.PADS_BANK0,
|
||||||
|
sio.gpio_bank0,
|
||||||
|
&mut resets,
|
||||||
|
);
|
||||||
|
|
||||||
|
let mut timer = Timer::new(c.device.TIMER, &mut resets);
|
||||||
|
let mut alarm = timer.alarm_0().unwrap();
|
||||||
|
let _ = alarm.schedule(SCAN_TIME_US);
|
||||||
|
alarm.enable_interrupt();
|
||||||
|
|
||||||
|
let mut led_pin = pins.led.into_push_pull_output();
|
||||||
|
|
||||||
|
led_pin.set_low().unwrap();
|
||||||
|
|
||||||
|
// Set up the USB driver
|
||||||
|
let usb_bus = UsbBusAllocator::new(UsbBus::new(
|
||||||
|
c.device.USBCTRL_REGS,
|
||||||
|
c.device.USBCTRL_DPRAM,
|
||||||
|
clocks.usb_clock,
|
||||||
|
true,
|
||||||
|
&mut resets,
|
||||||
|
));
|
||||||
|
|
||||||
|
let serial = Serial::new(&usb_bus);
|
||||||
|
|
||||||
|
// Create a USB device with a fake VID and PID
|
||||||
|
let usb_dev = UsbDeviceBuilder::new(&usb_bus, UsbVidPid(0x16c0, 0x27dd))
|
||||||
|
.manufacturer("Fake company")
|
||||||
|
.product("Serial port")
|
||||||
|
.serial_number("TEST")
|
||||||
|
.device_class(2) // from: https://www.usb.org/defined-class-codes
|
||||||
|
.build();
|
||||||
|
|
||||||
|
let adc = Adc::new(c.device.ADC, &mut resets);
|
||||||
|
|
||||||
|
let adc_pin_0 = pins.gpio26.into_floating_input();
|
||||||
|
// let mut adc_pin_1 = pins.gpio27.into_floating_input();
|
||||||
|
// let mut adc_pin_2 = pins.gpio28.into_floating_input();
|
||||||
|
|
||||||
|
let data = Data {
|
||||||
|
i: 0,
|
||||||
|
usb_bus,
|
||||||
|
usb_dev,
|
||||||
|
|
||||||
|
serial,
|
||||||
|
|
||||||
|
adc,
|
||||||
|
adc_pin_0,
|
||||||
|
};
|
||||||
|
|
||||||
|
(Shared { timer, alarm, data }, Local {}, init::Monotonics())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[task(
|
||||||
|
binds = TIMER_IRQ_0,
|
||||||
|
priority = 1,
|
||||||
|
shared = [timer, alarm, data],
|
||||||
|
local = [tog: bool = true],
|
||||||
|
)]
|
||||||
|
fn timer_irq(mut c: timer_irq::Context) {
|
||||||
|
c.shared.data.lock(|data| {
|
||||||
|
data.i += 1;
|
||||||
|
|
||||||
|
if data.i == 100 {
|
||||||
|
data.i = 0;
|
||||||
|
|
||||||
|
let adc_0_value: u16 = data.adc.read(&mut data.adc_pin_0).unwrap();
|
||||||
|
// let adc_1_value: u16 = adc.read(&mut adc_pin_1).unwrap();
|
||||||
|
// let adc_2_value: u16 = adc.read(&mut adc_pin_2).unwrap();
|
||||||
|
|
||||||
|
data.serial.send(adc_0_value);
|
||||||
|
}
|
||||||
|
|
||||||
|
if data.usb_dev.poll(&mut [&mut data.serial]) {
|
||||||
|
if let Some(command) = data.serial.read() {
|
||||||
|
match command {
|
||||||
|
Commands::Reset => reset_to_usb_boot(0, 0),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
|
|
||||||
|
let mut alarm = c.shared.alarm;
|
||||||
|
(alarm).lock(|a| {
|
||||||
|
a.clear_interrupt();
|
||||||
|
let _ = a.schedule(SCAN_TIME_US);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// End of file
|
|
||||||
|
|
Loading…
Reference in a new issue