Start implementing interrupt

This commit is contained in:
hodasemi 2023-01-02 10:26:40 +01:00
parent 886c8135e7
commit 94c5c2a366
2 changed files with 147 additions and 99 deletions

View file

@ -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"

View file

@ -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