From 73063870abac5ebf6ea448eb3d9f941ba15e53dd Mon Sep 17 00:00:00 2001 From: Michaela Murray Date: Wed, 29 Jan 2020 18:07:42 -0500 Subject: [PATCH 01/39] QDEC changes initial --- boards/nordic/nrf52840dk/src/main.rs | 4 +- boards/nordic/nrf52840dk/src/qdec.rs | 52 +++++++ capsules/README.md | 2 +- capsules/src/qdec.rs | 30 ++++ chips/nrf5x/src/qdec.rs | 222 +++++++++++++++++++++++++++ chips/nrf5x/src/references.txt | 13 ++ chips/nrf5x/src/timer.rs | 2 +- kernel/src/hil/qdec.rs | 23 +++ qdec_questions.txt | 5 + 9 files changed, 350 insertions(+), 3 deletions(-) create mode 100644 boards/nordic/nrf52840dk/src/qdec.rs create mode 100644 capsules/src/qdec.rs create mode 100644 chips/nrf5x/src/qdec.rs create mode 100644 chips/nrf5x/src/references.txt create mode 100644 kernel/src/hil/qdec.rs create mode 100644 qdec_questions.txt diff --git a/boards/nordic/nrf52840dk/src/main.rs b/boards/nordic/nrf52840dk/src/main.rs index 83f148076ad..f5c2a1c772b 100644 --- a/boards/nordic/nrf52840dk/src/main.rs +++ b/boards/nordic/nrf52840dk/src/main.rs @@ -112,6 +112,8 @@ static mut APP_MEMORY: [u8; 245760] = [0; 245760]; static mut PROCESSES: [Option<&'static dyn kernel::procs::ProcessType>; NUM_PROCS] = [None, None, None, None, None, None, None, None]; + + /// Dummy buffer that causes the linker to reserve enough space for the stack. #[no_mangle] #[link_section = ".stack_buffer"] @@ -290,7 +292,7 @@ pub unsafe fn reset_handler() { } let board_kernel = static_init!(kernel::Kernel, kernel::Kernel::new(&PROCESSES)); - + nrf52dk_base::setup_board( board_kernel, BUTTON_RST_PIN, diff --git a/boards/nordic/nrf52840dk/src/qdec.rs b/boards/nordic/nrf52840dk/src/qdec.rs new file mode 100644 index 00000000000..4b54f3bdc30 --- /dev/null +++ b/boards/nordic/nrf52840dk/src/qdec.rs @@ -0,0 +1,52 @@ +//! Move all development to chips/src +//! Check spec for all registers to be seit + +use core::cell::Cell; +use kernel::hil; +use kernel::{AppId, Callback, Driver, ReturnCode}; + +pub struct QDEC<'a, Q: hil::qdec::QDEC + 'a> { + //QDEC Driver + qdec: &'a A, + channels: &'a [&'a ::Channel], + pins_init: &'a [(&'a dyn gpio::Pin, ActivationMode)], + //App State + callback: Cell>, //what is this useful for EXACTLY????? +} + +impl<'a, Q: hil::qdec::QDEC> QDEC<'a, Q> { + pub fn new( + qdec: &'a A, + pins_init: &'a [(&'a dyn gpio::Pin, ActivationMode)] + channels: &'a[&'a ::Channel], + ) -> QDEC<'a, Q> { + //FINISH PINS CODE!! + QDEC { + //QDEC driver + qdec: qdec, + channels: channels, + + //App state + callback: Cell::new(None), + } + } + fn initialize_pins (&self) -> ReturnCode { + //initializes selected GPIO pins + } + + fn rotation(&self) -> ReturnCode { + //rotation of the rotary encoder + } + + fn pressed_button(&self) -> ReturnCode { + //pressing buttons + } + + fn releasd_button(&self) -> ReturnCode { + //releasing buttons + } + + fn toggle(&self) -> ReturnCode { + //toggle buttons + } +} diff --git a/capsules/README.md b/capsules/README.md index 8bace344a12..41b9780a758 100644 --- a/capsules/README.md +++ b/capsules/README.md @@ -81,7 +81,7 @@ These capsules provide a `Driver` interface for common MCU peripherals. - **[I2C_MASTER_SLAVE](src/i2c_master_slave_driver.rs)**: I2C master and slave access. - **[RNG](src/rng.rs)**: Random number generation. - **[SPI](src/spi.rs)**: SPI master and slave. - +- **[QDEC](src/qdec.rs)**: QDEC for quadrature-encoded sensor signals ### Helpful Userspace Capsules diff --git a/capsules/src/qdec.rs b/capsules/src/qdec.rs new file mode 100644 index 00000000000..71aa69cb215 --- /dev/null +++ b/capsules/src/qdec.rs @@ -0,0 +1,30 @@ +//! There will be lots of comments here eventually... +//! +//! +//! +//! KK will add all those later +//! + +use core::cell::Cell; +use kernel::hil::gpio; +use crate::driver; + + +#[derive(Clone, Copy)] +pub enum Position { + PositionUp, + PositionDown, +} + +///I want to create some public struct for the QDEC +pub struct QDEC<'a> { + ///what do I want to put in here? +} + +impl<'a> QDEC<'a> { + +} + +impl<'a> Driver for QDEC<'a> { //! this is for the hil +} + diff --git a/chips/nrf5x/src/qdec.rs b/chips/nrf5x/src/qdec.rs new file mode 100644 index 00000000000..abce6db9261 --- /dev/null +++ b/chips/nrf5x/src/qdec.rs @@ -0,0 +1,222 @@ +//! QDEC driver, nRF5x-family +//! set_client(), enable, get_ticks, +//! The nRF5x quadrature decoder +//! + + +use kernel::common::cells::OptionalCell; +use kernel::common::registers::{self, register_bitfields, ReadOnly, ReadWrite, ReadOnly}; +use kernel::common::StaticRef; +use kernel::hil; + + +//! In this section I declare a struct called QDECRegisters, which contains all the +//! relevant registers as outlined in the Nordic 5x specification of the QDEC. +//! TODO: add in missing registers; TODO: add in register reserves +register_structs! { + struct QDEC { + /// Start QDEC sampling + (0x000 => tasks_start: WriteOnly), + /// Stop QDEC sampling + (0x004 => tasks_stop: WriteOnly), + /// Read and clear ACC and ACCDBL + (0x008 => tasks_readclracc: ReadWrite), + /// Read and clear ACC + (0x00C => tasks_rdclracc: ReadWrite), + /// Read nad clear ACCDBL + (0x010 => tasks_rdclrdbl: ReadWrite), + ///Reserve space so tasks_rdclrdbl has access to its entire address space (?) + (0x0012 => _reserved), + (0x0014 => word: ReadWrite), + /// All the events which have interrupts! + (0x100 => events_arr: ReadWrite), + /// Event being generated for every new sample + ///(0x100 => events_samplerdy: Write), + /// Non-null report ready + ///(0x104 => events_reportrdy: Write), + /// ACC or ACCDBL register overflow + ///(0x108 => events_accof: Write), + /// Double displacement detected + ///(0x10C => events_dblrdy: Read), + /// events stopped + ///(0x110 => events_stopped: Read), + ///Reserve space so events_stopped has access to its entire address space (?) + (0x0102 => _reserved2), + (0x0104 => word: Read), + /// Shortcut register + (0x200 => shorts: Read), + ///Reserve space so shorts has access to its entire address space (?) + (0x204 => _reserved3), + (0x208 => word: ReadWrite), + /// Enable interrupt + (0x304 => intenset: ReadWrite), + /// Disable Interrupt + (0x308 => intenclr: ReadWrite), + /// Enable the quad decoder + (0x500 => enable: ReadWrite), + /// <----- MISSING A REGISTER ----> //// + /// Sampling-rate register + (0x508 => sample_per: WriteOnly), + /// Sample register (receives all samples) + (0x50C => sample: WriteOnly), + /// Reportper + (0x510 => report_per: ReadOnly), + /// Accumulating motion-sample values register + (0x514 => acc: ReadOnly), + /// Reserve space for the rest of the registers ? + (0x0102 => _reserved4), + (0x0104 => word: Read), + /// <------MISSING MORE REGISTERS ----> //// + (0x550 => @END), + } +} + + +//! In this section, I initialize all the bitfields associated with the type +//! of register assigned to each member of the struct above. (is that right?) +register_bitfields![u32, + Task [ + ENABLE 0 + ], + Shorts [ + /// Write '1' to Enable shortcut on EVENTS_COMPARE\[0\] event + REPORTRDY_READCLRACC 0, + /// Write '1' to Enable shortcut on EVENTS_COMPARE\[1\] event + SAMPLERDY_STOP 1, + /// Write '1' to Enable shortcut on EVENTS_COMPARE\[2\] event + REPORTRDY_RDCLRACC 2, + /// Write '1' to Enable shortcut on EVENTS_COMPARE\[3\] event + REPORTRDY_STOP 3, + /// Write '1' to Enable shortcut on EVENTS_COMPARE\[4\] event + DBLRDY_RDCLRDBL 4, + /// Write '1' to Enable shortcut on EVENTS_COMPARE\[5\] event + DBLRDY_STOP 5, + /// Write '1' to Enable shortcut on EVENTS_COMPARE\[6\] event + SAMPLERDY_READCLRACC 6, + ], + Inte [ + /// Write '1' to Enable interrupt on EVENTS_COMPARE\[0\] event + SAMPLERDY 0, + /// Write '1' to Enable interrupt on EVENTS_COMPARE\[1\] event + REPORTRDY 1, + /// Write '1' to Enable interrupt on EVENTS_COMPARE\[2\] event + ACCOF 2, + /// Write '1' to Enable interrupt on EVENTS_COMPARE\[3\] event + DBLRDY 3, + /// Write '1' to Enable interrupt on EVENTS_COMPARE\[4\] event + STOPPED 4, + /// Write '1' to Enable interrupt on EVENTS_COMPARE\[5\] event + ///COMPARE5 21 + ], + Ena [ + /// idk... + ENABLE 1 + ], + Sample [ + SAMPLE 1 + ], + SampPer [ + SAMPLEPER 1 + ], + Report [ + REPORTPER 1 + ], + Acc [ + ACC 1 + ], +]; + +//! This defines the beginning of memory which is memory-mapped to the QDEC +//! This base is declared under the Registers Table 3 +const QDEC_BASE: StaticRef = unsafe { StaticRef::new(0x40012000 as *const QdecRegisters) }; + +/// The client referenced here is the capsule code which will be built on top of this +pub trait CompareClient { + fn compare(&self); +} + +/// QDEC type declaration: gives the QDEC instance registers and a client +pub struct QDEC<'a> { + registers: StaticRef, + client: OptionalCell<&'static dyn CompareClient>, +} + +pub static mut QDEC: QDEC = QDEC { + registers: QDEC_BASE, + client: OptionalCell<&'static dyn CompareClient>, +}; + +/// QDEC impl: provides the QDEC type with vital functionality including: +/// FIRST DESIRED FUNCTIONALITY: new(arg1, arg2, ..., argN) -> define QDEC struct +/// TODO: Set up the mess that is functionality of QDEC +impl QDEC<'a> { + pub const fn new(registers: StaticRef, sample: usize) -> QDEC { + QDEC { + registers: QDEC_BASE, + client: OptionalCell::empty(), + } + } + + pub fn set_client(&self, client: &'static dyn CompareClient) { + self.client.set(client); + } + + /// When an interrupt occurs, check to see if any + /// of the interrupt register bits are set. If it + /// is, then put it in the client's bitmask + + pub fn handle_interrupt(&self) { + self.client.map(|client| { + let mut val = 0; + // For each of 4 possible compare events, if it's happened, + // clear it and sort its bit in val to pass in callback + for i in 0..4 { // TODO: either add events_compare or add each individual register + if self.registers.events_arr[i].is_set(Event::READY) { + val = val | 1 << i; + self.registers.events_arr[i].write(Event::READY::CLEAR); + // Disable corresponding interrupt + let interrupt_bit = match i { + 0 => Inte::SAMPLERDY::SET, + 1 => Inte::REPORTRDY::SET, + 2 => Inte::ACCOF::SET, + 3 => Inte::DBLRDY::SET, + 4 => Inte::STOPPED::SET, + }; + self.registers.intenclr.write(interrupt_bit); + } + } + client.compare(val as u32); + }); + } + + //add more functions here! + fn enable_interrupts(&self) { ///IS THIS THE RIGHT MACRO TO USE? + let regs = &*self.registers; + regs.intenset.write(Inte::____::SET /*TODO: Correct macro */); + } + + fn disable_interrupts(&self) { + let regs = &*self.registers; + regs.intenclr.write(/*MACRO*/); + } + + fn interrupts_enable(&self) -> bool { + let regs = &*self.registers; + self.registers.intenset.is_set(/*MACRO*/); + } + + pub fn enable(&self) -> ReturnCode { + let regs = &*self.registers; + self.registers.enable.write(/*MACRO*/); + } + + fn is_enabled(&self) { + let regs = &*self.registers; + self.registers.enable.is_set(/*MACRO*/); + } + + pub fn get_ticks(&self) -> Result { + let regs = &*self.registers; + self.registers.accumulate.read(/*MACRO*/); + } +} diff --git a/chips/nrf5x/src/references.txt b/chips/nrf5x/src/references.txt new file mode 100644 index 00000000000..15a53a18166 --- /dev/null +++ b/chips/nrf5x/src/references.txt @@ -0,0 +1,13 @@ +& -> this is a regular reference to a regular string (i.e. immutable) + +mut & -> this is a mutable reference to a mutable string + -can only have one mutable reference to a piece of data in + a particular scope + + -also rules about combining mutable and immutable references + to a mutable object + +compiler guarantees dangling references: for example, cannot declare +string within function then return reference to string + + diff --git a/chips/nrf5x/src/timer.rs b/chips/nrf5x/src/timer.rs index ac64a4745de..a0936b98e15 100644 --- a/chips/nrf5x/src/timer.rs +++ b/chips/nrf5x/src/timer.rs @@ -304,7 +304,7 @@ impl TimerAlarm<'a> { } fn interrupts_enabled(&self) -> bool { - self.registers.intenset.is_set(ALARM_INTERRUPT_BIT) + self.registers.intenset.is_set(ALARM_INTERRUPT_BIT); } fn value(&self) -> u32 { diff --git a/kernel/src/hil/qdec.rs b/kernel/src/hil/qdec.rs new file mode 100644 index 00000000000..621d59eb33b --- /dev/null +++ b/kernel/src/hil/qdec.rs @@ -0,0 +1,23 @@ +//! This is a new hardware interface for the QDEC! +//! Generic QDEC for any board +use crate::hil::gpio; + +pub trait QDEC { + //! + fn set_client(); + fn enable(); + fn get_ticks(&self) -> Result; + fn enable(&self) -> ReturnCode; //! success or error + //! ACC register, enable debounce?, prob 0 for sample rate + fn rotation(&mut self); + //!USE BUTTON HIL FOR THIS + //!fn pressed_button(&mut self); + //!fn released_button(&mut self); + fn initialize_pins (&mut self); +} + +//! In kernel test in the boards folder +//! create a new qdec, config, and then call fxns avail +//! Need to set a timer +//! Samples imix -> src -> udp_lowpan_test +//! Where to proceed from here? diff --git a/qdec_questions.txt b/qdec_questions.txt new file mode 100644 index 00000000000..2d06ae63b0c --- /dev/null +++ b/qdec_questions.txt @@ -0,0 +1,5 @@ +Do I need to implement an HIL for the QDEC? + +Since QDEC is going to be a capsule, it will need to be taken into acconut in the hardware-interface-layer right? + + From 48e8d02c7676b3161c5df4637e43a9d15b33e601 Mon Sep 17 00:00:00 2001 From: Hudson Ayers Date: Wed, 29 Jan 2020 20:24:00 -0800 Subject: [PATCH 02/39] pair programming updates --- boards/nordic/nrf52dk_base/src/lib.rs | 6 + boards/nordic/nrf52dk_base/src/qdec_test.rs | 53 ++++++ chips/nrf52/src/lib.rs | 1 + chips/{nrf5x => nrf52}/src/qdec.rs | 176 +++++++++++--------- chips/nrf5x/src/timer.rs | 2 +- 5 files changed, 156 insertions(+), 82 deletions(-) create mode 100644 boards/nordic/nrf52dk_base/src/qdec_test.rs rename chips/{nrf5x => nrf52}/src/qdec.rs (58%) diff --git a/boards/nordic/nrf52dk_base/src/lib.rs b/boards/nordic/nrf52dk_base/src/lib.rs index 7cd63a477be..a09917940ed 100644 --- a/boards/nordic/nrf52dk_base/src/lib.rs +++ b/boards/nordic/nrf52dk_base/src/lib.rs @@ -21,6 +21,8 @@ pub mod nrf52_components; use nrf52_components::ble::BLEComponent; use nrf52_components::ieee802154::Ieee802154Component; +mod qdec_test; + // Constants related to the configuration of the 15.4 network stack const SRC_MAC: u16 = 0xf00f; const PAN_ID: u16 = 0xABCD; @@ -427,6 +429,7 @@ pub unsafe fn setup_board( DynamicDeferredCall::new(dynamic_deferred_call_clients) ); DynamicDeferredCall::set_global_instance(dynamic_deferred_call); + let qdec_test = qdec_test::initialize_all(mux_alarm); let platform = Platform { button: button, @@ -447,6 +450,9 @@ pub unsafe fn setup_board( debug!("Initialization complete. Entering main loop\r"); debug!("{}", &nrf52::ficr::FICR_INSTANCE); + qdec_test.start(); + debug!("Started QDEC"); + extern "C" { /// Beginning of the ROM region containing app images. static _sapps: u8; diff --git a/boards/nordic/nrf52dk_base/src/qdec_test.rs b/boards/nordic/nrf52dk_base/src/qdec_test.rs new file mode 100644 index 00000000000..e8124f70e7b --- /dev/null +++ b/boards/nordic/nrf52dk_base/src/qdec_test.rs @@ -0,0 +1,53 @@ +use capsules::virtual_alarm::{MuxAlarm, VirtualMuxAlarm}; +use kernel::hil::time; +use kernel::hil::time::{Alarm, Frequency}; +use kernel::{debug, static_init}; +use nrf52::qdec::Qdec; + +pub const TEST_DELAY_MS: u32 = 1000; + +pub struct QdecTest<'a, A: time::Alarm<'a>> { + alarm: &'a A, + qdec: &'a Qdec, +} + +pub unsafe fn initialize_all( + mux_alarm: &'static MuxAlarm<'static, nrf52::rtc::Rtc<'static>>, +) -> &'static QdecTest< + 'static, + capsules::virtual_alarm::VirtualMuxAlarm<'static, nrf52::rtc::Rtc<'static>>, +> { + let qdec_alarm = static_init!( + VirtualMuxAlarm<'static, nrf52::rtc::Rtc>, + VirtualMuxAlarm::new(mux_alarm) + ); + let qdec_test = static_init!( + QdecTest>>, + QdecTest { + alarm: qdec_alarm, + qdec: &nrf52::qdec::QDEC, + } + ); + qdec_alarm.set_client(qdec_test); + qdec_test +} + +impl<'a, A: time::Alarm<'a>> QdecTest<'a, A> { + pub fn start(&self) { + self.schedule_next(); + } + + fn schedule_next(&self) { + let delta = (A::Frequency::frequency() * TEST_DELAY_MS) / 1000; + let next = self.alarm.now().wrapping_add(delta); + self.alarm.set_alarm(next); + } +} + +impl<'a, A: time::Alarm<'a>> time::AlarmClient for QdecTest<'a, A> { + fn fired(&self) { + let acc = self.qdec.get_acc(); + debug!("Acc: {:?}", acc); + self.schedule_next(); + } +} diff --git a/chips/nrf52/src/lib.rs b/chips/nrf52/src/lib.rs index 2434ef1325e..656c0575000 100644 --- a/chips/nrf52/src/lib.rs +++ b/chips/nrf52/src/lib.rs @@ -16,6 +16,7 @@ pub mod nvmc; pub mod power; pub mod ppi; pub mod pwm; +pub mod qdec; pub mod spi; pub mod uart; pub mod uicr; diff --git a/chips/nrf5x/src/qdec.rs b/chips/nrf52/src/qdec.rs similarity index 58% rename from chips/nrf5x/src/qdec.rs rename to chips/nrf52/src/qdec.rs index abce6db9261..f24c78c9bac 100644 --- a/chips/nrf5x/src/qdec.rs +++ b/chips/nrf52/src/qdec.rs @@ -1,35 +1,35 @@ -//! QDEC driver, nRF5x-family +//! Qdec driver, nRF5x-family //! set_client(), enable, get_ticks, -//! The nRF5x quadrature decoder +//! The nRF5x quadrature decoder //! - use kernel::common::cells::OptionalCell; -use kernel::common::registers::{self, register_bitfields, ReadOnly, ReadWrite, ReadOnly}; +use kernel::common::registers::{ + self, register_bitfields, register_structs, ReadOnly, ReadWrite, WriteOnly, +}; use kernel::common::StaticRef; use kernel::hil; +use kernel::ReturnCode; - -//! In this section I declare a struct called QDECRegisters, which contains all the -//! relevant registers as outlined in the Nordic 5x specification of the QDEC. -//! TODO: add in missing registers; TODO: add in register reserves +// In this section I declare a struct called QdecRegisters, which contains all the +// relevant registers as outlined in the Nordic 5x specification of the Qdec. +// TODO: add in missing registers; TODO: add in register reserves register_structs! { - struct QDEC { - /// Start QDEC sampling + pub QdecRegisters { + /// Start Qdec sampling (0x000 => tasks_start: WriteOnly), - /// Stop QDEC sampling + /// Stop Qdec sampling (0x004 => tasks_stop: WriteOnly), /// Read and clear ACC and ACCDBL - (0x008 => tasks_readclracc: ReadWrite), + (0x008 => tasks_readclracc: WriteOnly), /// Read and clear ACC - (0x00C => tasks_rdclracc: ReadWrite), + (0x00C => tasks_rdclracc: WriteOnly), /// Read nad clear ACCDBL - (0x010 => tasks_rdclrdbl: ReadWrite), + (0x010 => tasks_rdclrdbl: WriteOnly), ///Reserve space so tasks_rdclrdbl has access to its entire address space (?) - (0x0012 => _reserved), - (0x0014 => word: ReadWrite), + (0x0014 => _reserved), /// All the events which have interrupts! - (0x100 => events_arr: ReadWrite), + (0x100 => events_arr: [ReadWrite; 5]), /// Event being generated for every new sample ///(0x100 => events_samplerdy: Write), /// Non-null report ready @@ -40,40 +40,38 @@ register_structs! { ///(0x10C => events_dblrdy: Read), /// events stopped ///(0x110 => events_stopped: Read), - ///Reserve space so events_stopped has access to its entire address space (?) - (0x0102 => _reserved2), - (0x0104 => word: Read), + (0x0114 => _reserved2), /// Shortcut register - (0x200 => shorts: Read), - ///Reserve space so shorts has access to its entire address space (?) + (0x200 => shorts: ReadWrite), (0x204 => _reserved3), - (0x208 => word: ReadWrite), /// Enable interrupt (0x304 => intenset: ReadWrite), /// Disable Interrupt (0x308 => intenclr: ReadWrite), + (0x30C => _reserved4), /// Enable the quad decoder - (0x500 => enable: ReadWrite), - /// <----- MISSING A REGISTER ----> //// + (0x500 => enable: ReadWrite), + /// Set the LED output pin polarity + (0x504 => ledpol: WriteOnly), /// Sampling-rate register (0x508 => sample_per: WriteOnly), /// Sample register (receives all samples) (0x50C => sample: WriteOnly), /// Reportper - (0x510 => report_per: ReadOnly), + (0x510 => report_per: ReadOnly), /// Accumulating motion-sample values register (0x514 => acc: ReadOnly), - /// Reserve space for the rest of the registers ? - (0x0102 => _reserved4), - (0x0104 => word: Read), - /// <------MISSING MORE REGISTERS ----> //// + (0x518 => acc_read: ReadOnly), + (0x51C => reserved6), + (0x520 => psel_a: ReadWrite), + (0x524 => psel_b: ReadWrite), + (0x528 => reserved5), (0x550 => @END), } } - -//! In this section, I initialize all the bitfields associated with the type -//! of register assigned to each member of the struct above. (is that right?) +// In this section, I initialize all the bitfields associated with the type +// of register assigned to each member of the struct above. (is that right?) register_bitfields![u32, Task [ ENABLE 0 @@ -92,7 +90,15 @@ register_bitfields![u32, /// Write '1' to Enable shortcut on EVENTS_COMPARE\[5\] event DBLRDY_STOP 5, /// Write '1' to Enable shortcut on EVENTS_COMPARE\[6\] event - SAMPLERDY_READCLRACC 6, + SAMPLERDY_READCLRACC 6 + ], + Event [ + READY 0 + ], + PinSelect [ + Pin OFFSET(0) NUMBITS(5), + Port OFFSET(5) NUMBITS(1), + Connect OFFSET(31) NUMBITS(1) ], Inte [ /// Write '1' to Enable interrupt on EVENTS_COMPARE\[0\] event @@ -104,67 +110,64 @@ register_bitfields![u32, /// Write '1' to Enable interrupt on EVENTS_COMPARE\[3\] event DBLRDY 3, /// Write '1' to Enable interrupt on EVENTS_COMPARE\[4\] event - STOPPED 4, - /// Write '1' to Enable interrupt on EVENTS_COMPARE\[5\] event - ///COMPARE5 21 + STOPPED 4 ], - Ena [ - /// idk... - ENABLE 1 + LedPol [ + LedPol OFFSET(0) NUMBITS(1) [ + ActiveLow = 0, + ActiveHigh = 1 + ] ], Sample [ SAMPLE 1 ], SampPer [ - SAMPLEPER 1 + SAMPLEPER OFFSET(0) NUMBITS(4) [ + us128 = 0, + us256 = 1 + // TODO: Fill out rest + ] ], - Report [ - REPORTPER 1 + ReportPer [ + REPORTPER OFFSET(0) NUMBITS(4) [ + hz10 = 0, + hz40 = 1 + // TODO: fill out rest + ] ], Acc [ - ACC 1 - ], + ACC OFFSET(0) NUMBITS(32) + ] ]; -//! This defines the beginning of memory which is memory-mapped to the QDEC -//! This base is declared under the Registers Table 3 -const QDEC_BASE: StaticRef = unsafe { StaticRef::new(0x40012000 as *const QdecRegisters) }; - -/// The client referenced here is the capsule code which will be built on top of this -pub trait CompareClient { - fn compare(&self); -} +/// This defines the beginning of memory which is memory-mapped to the Qdec +/// This base is declared under the Registers Table 3 +const QDEC_BASE: StaticRef = + unsafe { StaticRef::new(0x40012000 as *const QdecRegisters) }; -/// QDEC type declaration: gives the QDEC instance registers and a client -pub struct QDEC<'a> { - registers: StaticRef, - client: OptionalCell<&'static dyn CompareClient>, +/// Qdec type declaration: gives the Qdec instance registers and a client +pub struct Qdec { + registers: StaticRef, } -pub static mut QDEC: QDEC = QDEC { - registers: QDEC_BASE, - client: OptionalCell<&'static dyn CompareClient>, +pub static mut QDEC: Qdec = Qdec { + registers: QDEC_BASE, }; -/// QDEC impl: provides the QDEC type with vital functionality including: -/// FIRST DESIRED FUNCTIONALITY: new(arg1, arg2, ..., argN) -> define QDEC struct -/// TODO: Set up the mess that is functionality of QDEC -impl QDEC<'a> { - pub const fn new(registers: StaticRef, sample: usize) -> QDEC { - QDEC { - registers: QDEC_BASE, - client: OptionalCell::empty(), - } - } - +/// Qdec impl: provides the Qdec type with vital functionality including: +/// FIRST DESIRED FUNCTIONALITY: new(arg1, arg2, ..., argN) -> define Qdec struct +/// TODO: Set up the mess that is functionality of Qdec +impl Qdec { + /* pub fn set_client(&self, client: &'static dyn CompareClient) { self.client.set(client); } + */ /// When an interrupt occurs, check to see if any /// of the interrupt register bits are set. If it /// is, then put it in the client's bitmask - + /* pub fn handle_interrupt(&self) { self.client.map(|client| { let mut val = 0; @@ -185,11 +188,13 @@ impl QDEC<'a> { self.registers.intenclr.write(interrupt_bit); } } - client.compare(val as u32); + client.compare(val as u32); }); } + */ //add more functions here! + /* fn enable_interrupts(&self) { ///IS THIS THE RIGHT MACRO TO USE? let regs = &*self.registers; regs.intenset.write(Inte::____::SET /*TODO: Correct macro */); @@ -200,23 +205,32 @@ impl QDEC<'a> { regs.intenclr.write(/*MACRO*/); } - fn interrupts_enable(&self) -> bool { + fn interrupts_enabled(&self) -> bool { let regs = &*self.registers; self.registers.intenset.is_set(/*MACRO*/); } + */ - pub fn enable(&self) -> ReturnCode { + pub fn enable(&self) { let regs = &*self.registers; - self.registers.enable.write(/*MACRO*/); + regs.psel_a.write(PinSelect::Pin.val(30)); + regs.psel_a.write(PinSelect::Port.val(0)); + regs.psel_a.write(PinSelect::Connect.val(0)); + regs.psel_b.write(PinSelect::Pin.val(31)); + regs.psel_b.write(PinSelect::Port.val(0)); + regs.psel_b.write(PinSelect::Connect.val(0)); + regs.enable.write(Task::ENABLE::SET); + regs.tasks_start.write(Task::ENABLE::SET); } - fn is_enabled(&self) { + fn is_enabled(&self) -> bool { let regs = &*self.registers; - self.registers.enable.is_set(/*MACRO*/); + regs.enable.is_set(Task::ENABLE) } - pub fn get_ticks(&self) -> Result { + pub fn get_acc(&self) -> u32 { let regs = &*self.registers; - self.registers.accumulate.read(/*MACRO*/); - } + regs.tasks_readclracc.write(Task::ENABLE::SET); + regs.acc_read.read(Acc::ACC) + } } diff --git a/chips/nrf5x/src/timer.rs b/chips/nrf5x/src/timer.rs index a0936b98e15..ac64a4745de 100644 --- a/chips/nrf5x/src/timer.rs +++ b/chips/nrf5x/src/timer.rs @@ -304,7 +304,7 @@ impl TimerAlarm<'a> { } fn interrupts_enabled(&self) -> bool { - self.registers.intenset.is_set(ALARM_INTERRUPT_BIT); + self.registers.intenset.is_set(ALARM_INTERRUPT_BIT) } fn value(&self) -> u32 { From 7746864b6571717b93cdbef9fe8566fc64818d61 Mon Sep 17 00:00:00 2001 From: Hudson Ayers Date: Wed, 12 Feb 2020 16:09:32 -0800 Subject: [PATCH 03/39] addl changes to configure pins --- boards/nordic/nrf52840dk/src/main.rs | 10 ++++++---- boards/nordic/nrf52dk_base/src/lib.rs | 23 +++++++++++++++++++++++ chips/nrf52/src/qdec.rs | 3 ++- 3 files changed, 31 insertions(+), 5 deletions(-) diff --git a/boards/nordic/nrf52840dk/src/main.rs b/boards/nordic/nrf52840dk/src/main.rs index f5c2a1c772b..03334ed5fae 100644 --- a/boards/nordic/nrf52840dk/src/main.rs +++ b/boards/nordic/nrf52840dk/src/main.rs @@ -68,7 +68,7 @@ use kernel::{debug, debug_gpio, debug_verbose, static_init}; use nrf52840::gpio::Pin; -use nrf52dk_base::{SpiMX25R6435FPins, SpiPins, UartPins}; +use nrf52dk_base::{QdecPins, SpiMX25R6435FPins, SpiPins, UartPins}; // The nRF52840DK LEDs (see back of board) const LED1_PIN: Pin = Pin::P0_13; @@ -96,6 +96,9 @@ const SPI_MX25R6435F_CHIP_SELECT: Pin = Pin::P0_17; const SPI_MX25R6435F_WRITE_PROTECT_PIN: Pin = Pin::P0_22; const SPI_MX25R6435F_HOLD_PIN: Pin = Pin::P0_23; +const QDEC_PIN_A: Pin = Pin::P0_02; +const QDEC_PIN_B: Pin = Pin::P0_29; + /// UART Writer pub mod io; @@ -112,8 +115,6 @@ static mut APP_MEMORY: [u8; 245760] = [0; 245760]; static mut PROCESSES: [Option<&'static dyn kernel::procs::ProcessType>; NUM_PROCS] = [None, None, None, None, None, None, None, None]; - - /// Dummy buffer that causes the linker to reserve enough space for the stack. #[no_mangle] #[link_section = ".stack_buffer"] @@ -292,7 +293,7 @@ pub unsafe fn reset_handler() { } let board_kernel = static_init!(kernel::Kernel, kernel::Kernel::new(&PROCESSES)); - + nrf52dk_base::setup_board( board_kernel, BUTTON_RST_PIN, @@ -316,5 +317,6 @@ pub unsafe fn reset_handler() { FAULT_RESPONSE, nrf52840::uicr::Regulator0Output::DEFAULT, false, + &QdecPins::new(QDEC_PIN_A, QDEC_PIN_B), ); } diff --git a/boards/nordic/nrf52dk_base/src/lib.rs b/boards/nordic/nrf52dk_base/src/lib.rs index a09917940ed..ddcb0d3ba76 100644 --- a/boards/nordic/nrf52dk_base/src/lib.rs +++ b/boards/nordic/nrf52dk_base/src/lib.rs @@ -11,6 +11,7 @@ use capsules::virtual_uart::MuxUart; use kernel::capabilities; use kernel::component::Component; use kernel::hil; +use kernel::hil::gpio::{Configure, FloatingState}; use nrf52::gpio::Pin; use nrf52::rtc::Rtc; use nrf52::uicr::Regulator0Output; @@ -74,6 +75,19 @@ impl UartPins { } } +/// Pins for the UART +#[derive(Debug)] +pub struct QdecPins { + pin_a: Pin, + pin_b: Pin, +} + +impl QdecPins { + pub fn new(pin_a: Pin, pin_b: Pin) -> Self { + Self { pin_a, pin_b } + } +} + /// Supported drivers by the platform pub struct Platform { ble_radio: &'static capsules::ble_advertising_driver::BLE< @@ -152,6 +166,7 @@ pub unsafe fn setup_board( app_fault_response: kernel::procs::FaultResponse, reg_vout: Regulator0Output, nfc_as_gpios: bool, + qdec_pins: &QdecPins, ) { // Make non-volatile memory writable and activate the reset button let uicr = nrf52::uicr::Uicr::new(); @@ -429,6 +444,14 @@ pub unsafe fn setup_board( DynamicDeferredCall::new(dynamic_deferred_call_clients) ); DynamicDeferredCall::set_global_instance(dynamic_deferred_call); + + //We think this is needed bc the MBEDOS driver does that + gpio_port[qdec_pins.pin_a].make_input(); + gpio_port[qdec_pins.pin_b].make_input(); + gpio_port[qdec_pins.pin_a].set_floating_state(FloatingState::PullNone); + gpio_port[qdec_pins.pin_b].set_floating_state(FloatingState::PullNone); + + // TODO: Use pinmux let qdec_test = qdec_test::initialize_all(mux_alarm); let platform = Platform { diff --git a/chips/nrf52/src/qdec.rs b/chips/nrf52/src/qdec.rs index f24c78c9bac..2ac802bb425 100644 --- a/chips/nrf52/src/qdec.rs +++ b/chips/nrf52/src/qdec.rs @@ -9,6 +9,7 @@ use kernel::common::registers::{ }; use kernel::common::StaticRef; use kernel::hil; +use kernel::hil::gpio::Pin; use kernel::ReturnCode; // In this section I declare a struct called QdecRegisters, which contains all the @@ -210,9 +211,9 @@ impl Qdec { self.registers.intenset.is_set(/*MACRO*/); } */ - pub fn enable(&self) { let regs = &*self.registers; + //TODO: Use `Pinmux` struct here instead of usize to prevent collisions regs.psel_a.write(PinSelect::Pin.val(30)); regs.psel_a.write(PinSelect::Port.val(0)); regs.psel_a.write(PinSelect::Connect.val(0)); From 14a06fbb848f8f62c21fa40a4aca79ff13d1f1ed Mon Sep 17 00:00:00 2001 From: Michaela Murray Date: Thu, 13 Feb 2020 01:30:54 -0500 Subject: [PATCH 04/39] New changes to QDEC --- boards/nordic/nrf52840dk/src/qdec.rs | 52 --------------------- boards/nordic/nrf52dk_base/src/lib.rs | 2 +- boards/nordic/nrf52dk_base/src/qdec_test.rs | 1 + chips/nrf52/src/qdec.rs | 31 ++++++++++-- 4 files changed, 28 insertions(+), 58 deletions(-) delete mode 100644 boards/nordic/nrf52840dk/src/qdec.rs diff --git a/boards/nordic/nrf52840dk/src/qdec.rs b/boards/nordic/nrf52840dk/src/qdec.rs deleted file mode 100644 index 4b54f3bdc30..00000000000 --- a/boards/nordic/nrf52840dk/src/qdec.rs +++ /dev/null @@ -1,52 +0,0 @@ -//! Move all development to chips/src -//! Check spec for all registers to be seit - -use core::cell::Cell; -use kernel::hil; -use kernel::{AppId, Callback, Driver, ReturnCode}; - -pub struct QDEC<'a, Q: hil::qdec::QDEC + 'a> { - //QDEC Driver - qdec: &'a A, - channels: &'a [&'a ::Channel], - pins_init: &'a [(&'a dyn gpio::Pin, ActivationMode)], - //App State - callback: Cell>, //what is this useful for EXACTLY????? -} - -impl<'a, Q: hil::qdec::QDEC> QDEC<'a, Q> { - pub fn new( - qdec: &'a A, - pins_init: &'a [(&'a dyn gpio::Pin, ActivationMode)] - channels: &'a[&'a ::Channel], - ) -> QDEC<'a, Q> { - //FINISH PINS CODE!! - QDEC { - //QDEC driver - qdec: qdec, - channels: channels, - - //App state - callback: Cell::new(None), - } - } - fn initialize_pins (&self) -> ReturnCode { - //initializes selected GPIO pins - } - - fn rotation(&self) -> ReturnCode { - //rotation of the rotary encoder - } - - fn pressed_button(&self) -> ReturnCode { - //pressing buttons - } - - fn releasd_button(&self) -> ReturnCode { - //releasing buttons - } - - fn toggle(&self) -> ReturnCode { - //toggle buttons - } -} diff --git a/boards/nordic/nrf52dk_base/src/lib.rs b/boards/nordic/nrf52dk_base/src/lib.rs index a09917940ed..b1ee160bc1d 100644 --- a/boards/nordic/nrf52dk_base/src/lib.rs +++ b/boards/nordic/nrf52dk_base/src/lib.rs @@ -430,7 +430,7 @@ pub unsafe fn setup_board( ); DynamicDeferredCall::set_global_instance(dynamic_deferred_call); let qdec_test = qdec_test::initialize_all(mux_alarm); - + debug!("Testing: Qdec Initialized!"); let platform = Platform { button: button, ble_radio: ble_radio, diff --git a/boards/nordic/nrf52dk_base/src/qdec_test.rs b/boards/nordic/nrf52dk_base/src/qdec_test.rs index e8124f70e7b..35dcb8dd610 100644 --- a/boards/nordic/nrf52dk_base/src/qdec_test.rs +++ b/boards/nordic/nrf52dk_base/src/qdec_test.rs @@ -17,6 +17,7 @@ pub unsafe fn initialize_all( 'static, capsules::virtual_alarm::VirtualMuxAlarm<'static, nrf52::rtc::Rtc<'static>>, > { + debug!("Hello"); let qdec_alarm = static_init!( VirtualMuxAlarm<'static, nrf52::rtc::Rtc>, VirtualMuxAlarm::new(mux_alarm) diff --git a/chips/nrf52/src/qdec.rs b/chips/nrf52/src/qdec.rs index f24c78c9bac..6075b8a9184 100644 --- a/chips/nrf52/src/qdec.rs +++ b/chips/nrf52/src/qdec.rs @@ -10,6 +10,9 @@ use kernel::common::registers::{ use kernel::common::StaticRef; use kernel::hil; use kernel::ReturnCode; +use nrf5x::gpio::GPIOPin; +const QDEC_A: GPIOPin = Pin::P0_29; +const QDEC_B: GPIOPin = Pin::P0_02; // In this section I declare a struct called QdecRegisters, which contains all the // relevant registers as outlined in the Nordic 5x specification of the Qdec. @@ -124,14 +127,30 @@ register_bitfields![u32, SampPer [ SAMPLEPER OFFSET(0) NUMBITS(4) [ us128 = 0, - us256 = 1 + us256 = 1, + us512 = 2, + us1024 = 3, + us2048 = 4, + us4096 = 5, + us8192 = 6, + us16384 = 7, + ms32 = 8, + ms65 = 9, + ms131 = 10 // TODO: Fill out rest ] ], ReportPer [ REPORTPER OFFSET(0) NUMBITS(4) [ hz10 = 0, - hz40 = 1 + hz40 = 1, + hz80 = 2, + hz120 = 3, + hz160 = 4, + hz200 = 5, + hz240 = 6, + hz280 = 7, + hz1 = 8 // TODO: fill out rest ] ], @@ -156,7 +175,6 @@ pub static mut QDEC: Qdec = Qdec { /// Qdec impl: provides the Qdec type with vital functionality including: /// FIRST DESIRED FUNCTIONALITY: new(arg1, arg2, ..., argN) -> define Qdec struct -/// TODO: Set up the mess that is functionality of Qdec impl Qdec { /* pub fn set_client(&self, client: &'static dyn CompareClient) { @@ -212,14 +230,17 @@ impl Qdec { */ pub fn enable(&self) { + QDEC_A.set_floating_state(kernel::hil::gpio::FloatingState::PullNone); + //QDEC_B.set_floating_state(kernel::hil::gpio::FloatingState::PullNone); let regs = &*self.registers; - regs.psel_a.write(PinSelect::Pin.val(30)); + regs.psel_a.write(PinSelect::Pin.val(2)); regs.psel_a.write(PinSelect::Port.val(0)); regs.psel_a.write(PinSelect::Connect.val(0)); - regs.psel_b.write(PinSelect::Pin.val(31)); + regs.psel_b.write(PinSelect::Pin.val(29)); regs.psel_b.write(PinSelect::Port.val(0)); regs.psel_b.write(PinSelect::Connect.val(0)); regs.enable.write(Task::ENABLE::SET); + regs.sample_per.write(SampPer::SAMPLEPER.val(5)); regs.tasks_start.write(Task::ENABLE::SET); } From 4e4238f168959e561880bd6259b077984f07bf1d Mon Sep 17 00:00:00 2001 From: mmurray22 Date: Thu, 13 Feb 2020 16:16:48 -0500 Subject: [PATCH 05/39] Enables the pins at the beginning --- boards/nordic/nrf52dk_base/src/lib.rs | 1 + boards/nordic/nrf52dk_base/src/qdec_test.rs | 3 ++- chips/nrf52/src/qdec.rs | 14 ++++---------- 3 files changed, 7 insertions(+), 11 deletions(-) diff --git a/boards/nordic/nrf52dk_base/src/lib.rs b/boards/nordic/nrf52dk_base/src/lib.rs index 7c2ad0cc51d..b215a1f1add 100644 --- a/boards/nordic/nrf52dk_base/src/lib.rs +++ b/boards/nordic/nrf52dk_base/src/lib.rs @@ -452,6 +452,7 @@ pub unsafe fn setup_board( gpio_port[qdec_pins.pin_b].set_floating_state(FloatingState::PullNone); // TODO: Use pinmux + debug!("Initializing QDEC test!"); let qdec_test = qdec_test::initialize_all(mux_alarm); debug!("Testing: Qdec Initialized!"); let platform = Platform { diff --git a/boards/nordic/nrf52dk_base/src/qdec_test.rs b/boards/nordic/nrf52dk_base/src/qdec_test.rs index 35dcb8dd610..35037e2ca61 100644 --- a/boards/nordic/nrf52dk_base/src/qdec_test.rs +++ b/boards/nordic/nrf52dk_base/src/qdec_test.rs @@ -17,7 +17,6 @@ pub unsafe fn initialize_all( 'static, capsules::virtual_alarm::VirtualMuxAlarm<'static, nrf52::rtc::Rtc<'static>>, > { - debug!("Hello"); let qdec_alarm = static_init!( VirtualMuxAlarm<'static, nrf52::rtc::Rtc>, VirtualMuxAlarm::new(mux_alarm) @@ -35,6 +34,7 @@ pub unsafe fn initialize_all( impl<'a, A: time::Alarm<'a>> QdecTest<'a, A> { pub fn start(&self) { + self.qdec.enable(); self.schedule_next(); } @@ -48,6 +48,7 @@ impl<'a, A: time::Alarm<'a>> QdecTest<'a, A> { impl<'a, A: time::Alarm<'a>> time::AlarmClient for QdecTest<'a, A> { fn fired(&self) { let acc = self.qdec.get_acc(); + debug!("Is enabled: {:?}", self.qdec.is_enabled()); debug!("Acc: {:?}", acc); self.schedule_next(); } diff --git a/chips/nrf52/src/qdec.rs b/chips/nrf52/src/qdec.rs index a756f661c20..3ed21390ca4 100644 --- a/chips/nrf52/src/qdec.rs +++ b/chips/nrf52/src/qdec.rs @@ -12,8 +12,6 @@ use kernel::hil; use kernel::hil::gpio::Pin; use kernel::ReturnCode; use nrf5x::gpio::GPIOPin; -const QDEC_A: GPIOPin = Pin::P0_29; -const QDEC_B: GPIOPin = Pin::P0_02; // In this section I declare a struct called QdecRegisters, which contains all the // relevant registers as outlined in the Nordic 5x specification of the Qdec. @@ -138,7 +136,6 @@ register_bitfields![u32, ms32 = 8, ms65 = 9, ms131 = 10 - // TODO: Fill out rest ] ], ReportPer [ @@ -152,7 +149,6 @@ register_bitfields![u32, hz240 = 6, hz280 = 7, hz1 = 8 - // TODO: fill out rest ] ], Acc [ @@ -230,12 +226,9 @@ impl Qdec { } */ pub fn enable(&self) { - QDEC_A.set_floating_state(kernel::hil::gpio::FloatingState::PullNone); - //QDEC_B.set_floating_state(kernel::hil::gpio::FloatingState::PullNone); let regs = &*self.registers; - regs.psel_a.write(PinSelect::Pin.val(2)); //TODO: Use `Pinmux` struct here instead of usize to prevent collisions - regs.psel_a.write(PinSelect::Pin.val(30)); + regs.psel_a.write(PinSelect::Pin.val(2)); regs.psel_a.write(PinSelect::Port.val(0)); regs.psel_a.write(PinSelect::Connect.val(0)); regs.psel_b.write(PinSelect::Pin.val(29)); @@ -246,7 +239,7 @@ impl Qdec { regs.tasks_start.write(Task::ENABLE::SET); } - fn is_enabled(&self) -> bool { + pub fn is_enabled(&self) -> bool { let regs = &*self.registers; regs.enable.is_set(Task::ENABLE) } @@ -254,6 +247,7 @@ impl Qdec { pub fn get_acc(&self) -> u32 { let regs = &*self.registers; regs.tasks_readclracc.write(Task::ENABLE::SET); - regs.acc_read.read(Acc::ACC) + let dummy = regs.acc_read.read(Acc::ACC); + dummy } } From f522a26c8901e842bbf12297d747e437188fdb73 Mon Sep 17 00:00:00 2001 From: Michaela Murray Date: Thu, 13 Feb 2020 18:25:39 -0500 Subject: [PATCH 06/39] QDEC is responding to input! --- boards/nordic/nrf52dk_base/src/lib.rs | 6 +++--- boards/nordic/nrf52dk_base/src/qdec_test.rs | 2 ++ chips/nrf52/src/qdec.rs | 19 +++++++++++-------- 3 files changed, 16 insertions(+), 11 deletions(-) diff --git a/boards/nordic/nrf52dk_base/src/lib.rs b/boards/nordic/nrf52dk_base/src/lib.rs index b215a1f1add..35d55dc6e77 100644 --- a/boards/nordic/nrf52dk_base/src/lib.rs +++ b/boards/nordic/nrf52dk_base/src/lib.rs @@ -1,7 +1,7 @@ //! Shared setup for nrf52dk boards. #![no_std] - +#![allow(dead_code)] #[allow(unused_imports)] use kernel::{create_capability, debug, debug_gpio, debug_verbose, static_init}; @@ -448,8 +448,8 @@ pub unsafe fn setup_board( //We think this is needed bc the MBEDOS driver does that gpio_port[qdec_pins.pin_a].make_input(); gpio_port[qdec_pins.pin_b].make_input(); - gpio_port[qdec_pins.pin_a].set_floating_state(FloatingState::PullNone); - gpio_port[qdec_pins.pin_b].set_floating_state(FloatingState::PullNone); + gpio_port[qdec_pins.pin_a].set_floating_state(FloatingState::PullUp); + gpio_port[qdec_pins.pin_b].set_floating_state(FloatingState::PullUp); // TODO: Use pinmux debug!("Initializing QDEC test!"); diff --git a/boards/nordic/nrf52dk_base/src/qdec_test.rs b/boards/nordic/nrf52dk_base/src/qdec_test.rs index 35037e2ca61..504055410e6 100644 --- a/boards/nordic/nrf52dk_base/src/qdec_test.rs +++ b/boards/nordic/nrf52dk_base/src/qdec_test.rs @@ -1,3 +1,5 @@ +#[allow(unused_imports)] + use capsules::virtual_alarm::{MuxAlarm, VirtualMuxAlarm}; use kernel::hil::time; use kernel::hil::time::{Alarm, Frequency}; diff --git a/chips/nrf52/src/qdec.rs b/chips/nrf52/src/qdec.rs index 3ed21390ca4..f35f01b5dc3 100644 --- a/chips/nrf52/src/qdec.rs +++ b/chips/nrf52/src/qdec.rs @@ -2,11 +2,12 @@ //! set_client(), enable, get_ticks, //! The nRF5x quadrature decoder //! - +#[allow(unused_imports)] use kernel::common::cells::OptionalCell; use kernel::common::registers::{ self, register_bitfields, register_structs, ReadOnly, ReadWrite, WriteOnly, }; +use kernel::{debug}; use kernel::common::StaticRef; use kernel::hil; use kernel::hil::gpio::Pin; @@ -15,7 +16,6 @@ use nrf5x::gpio::GPIOPin; // In this section I declare a struct called QdecRegisters, which contains all the // relevant registers as outlined in the Nordic 5x specification of the Qdec. -// TODO: add in missing registers; TODO: add in register reserves register_structs! { pub QdecRegisters { /// Start Qdec sampling @@ -228,17 +228,17 @@ impl Qdec { pub fn enable(&self) { let regs = &*self.registers; //TODO: Use `Pinmux` struct here instead of usize to prevent collisions - regs.psel_a.write(PinSelect::Pin.val(2)); - regs.psel_a.write(PinSelect::Port.val(0)); - regs.psel_a.write(PinSelect::Connect.val(0)); - regs.psel_b.write(PinSelect::Pin.val(29)); - regs.psel_b.write(PinSelect::Port.val(0)); - regs.psel_b.write(PinSelect::Connect.val(0)); + regs.psel_a.write(PinSelect::Pin.val(2) + PinSelect::Port.val(0) + + PinSelect::Connect.val(0)); + regs.psel_b.write(PinSelect::Pin.val(29) + PinSelect::Port.val(0) + + PinSelect::Connect.val(0)); regs.enable.write(Task::ENABLE::SET); regs.sample_per.write(SampPer::SAMPLEPER.val(5)); regs.tasks_start.write(Task::ENABLE::SET); + debug!("Enabled!"); } + pub fn is_enabled(&self) -> bool { let regs = &*self.registers; regs.enable.is_set(Task::ENABLE) @@ -247,6 +247,9 @@ impl Qdec { pub fn get_acc(&self) -> u32 { let regs = &*self.registers; regs.tasks_readclracc.write(Task::ENABLE::SET); + /*TODO: Test code, not sure if this will work*/ + //regs.tasks_readclraccdbl.write(Task::ENABLE::SET); + /*TODO: End of Test code*/ let dummy = regs.acc_read.read(Acc::ACC); dummy } From cbbd06a4375b71ca497cdd0033233a626a30d100 Mon Sep 17 00:00:00 2001 From: mmurray22 Date: Thu, 13 Feb 2020 20:31:37 -0500 Subject: [PATCH 07/39] Issue with OptionalCell and accessing the Pinmux u32 value in enable function --- boards/nordic/nrf52dk_base/src/lib.rs | 5 +-- boards/nordic/nrf52dk_base/src/qdec_test.rs | 8 +++-- chips/nrf52/src/qdec.rs | 39 +++++++++++++++++---- 3 files changed, 40 insertions(+), 12 deletions(-) diff --git a/boards/nordic/nrf52dk_base/src/lib.rs b/boards/nordic/nrf52dk_base/src/lib.rs index 35d55dc6e77..69baa2b61c2 100644 --- a/boards/nordic/nrf52dk_base/src/lib.rs +++ b/boards/nordic/nrf52dk_base/src/lib.rs @@ -453,7 +453,7 @@ pub unsafe fn setup_board( // TODO: Use pinmux debug!("Initializing QDEC test!"); - let qdec_test = qdec_test::initialize_all(mux_alarm); + let qdec_test = qdec_test::initialize_all(mux_alarm); debug!("Testing: Qdec Initialized!"); let platform = Platform { button: button, @@ -473,7 +473,8 @@ pub unsafe fn setup_board( debug!("Initialization complete. Entering main loop\r"); debug!("{}", &nrf52::ficr::FICR_INSTANCE); - + qdec_test.qdec.set_pins (nrf52::pinmux::Pinmux::new(qdec_pins.pin_a as u32), + nrf52::pinmux::Pinmux::new(qdec_pins.pin_b as u32)); qdec_test.start(); debug!("Started QDEC"); diff --git a/boards/nordic/nrf52dk_base/src/qdec_test.rs b/boards/nordic/nrf52dk_base/src/qdec_test.rs index 504055410e6..bc0b0af0866 100644 --- a/boards/nordic/nrf52dk_base/src/qdec_test.rs +++ b/boards/nordic/nrf52dk_base/src/qdec_test.rs @@ -5,12 +5,13 @@ use kernel::hil::time; use kernel::hil::time::{Alarm, Frequency}; use kernel::{debug, static_init}; use nrf52::qdec::Qdec; +//use nrf5x::pinmux; pub const TEST_DELAY_MS: u32 = 1000; pub struct QdecTest<'a, A: time::Alarm<'a>> { alarm: &'a A, - qdec: &'a Qdec, + pub qdec: &'a mut Qdec, } pub unsafe fn initialize_all( @@ -27,7 +28,7 @@ pub unsafe fn initialize_all( QdecTest>>, QdecTest { alarm: qdec_alarm, - qdec: &nrf52::qdec::QDEC, + qdec: &mut nrf52::qdec::QDEC, } ); qdec_alarm.set_client(qdec_test); @@ -35,7 +36,8 @@ pub unsafe fn initialize_all( } impl<'a, A: time::Alarm<'a>> QdecTest<'a, A> { - pub fn start(&self) { + pub fn start(&self) + { self.qdec.enable(); self.schedule_next(); } diff --git a/chips/nrf52/src/qdec.rs b/chips/nrf52/src/qdec.rs index f35f01b5dc3..35aea26a3f8 100644 --- a/chips/nrf52/src/qdec.rs +++ b/chips/nrf52/src/qdec.rs @@ -3,6 +3,8 @@ //! The nRF5x quadrature decoder //! #[allow(unused_imports)] +use core; +use core::cell::Cell; use kernel::common::cells::OptionalCell; use kernel::common::registers::{ self, register_bitfields, register_structs, ReadOnly, ReadWrite, WriteOnly, @@ -13,7 +15,7 @@ use kernel::hil; use kernel::hil::gpio::Pin; use kernel::ReturnCode; use nrf5x::gpio::GPIOPin; - +use nrf5x::pinmux; // In this section I declare a struct called QdecRegisters, which contains all the // relevant registers as outlined in the Nordic 5x specification of the Qdec. register_structs! { @@ -164,15 +166,25 @@ const QDEC_BASE: StaticRef = /// Qdec type declaration: gives the Qdec instance registers and a client pub struct Qdec { registers: StaticRef, + args_pin_a: OptionalCell, + args_pin_b: OptionalCell, } pub static mut QDEC: Qdec = Qdec { registers: QDEC_BASE, + args_pin_a: OptionalCell::empty(), + args_pin_b: OptionalCell::empty(), }; /// Qdec impl: provides the Qdec type with vital functionality including: /// FIRST DESIRED FUNCTIONALITY: new(arg1, arg2, ..., argN) -> define Qdec struct impl Qdec { + + pub fn set_pins(&self, pin_a: pinmux::Pinmux, pin_b: pinmux::Pinmux) + { + self.args_pin_a.set(pin_a); + self.args_pin_b.set(pin_b); + } /* pub fn set_client(&self, client: &'static dyn CompareClient) { self.client.set(client); @@ -227,11 +239,26 @@ impl Qdec { */ pub fn enable(&self) { let regs = &*self.registers; + (self.args_pin_a).map_or_else( + || { + // Rather than setting this here, set it in the initialization of the struct + // (might require adding a new() function) + // And if this map_or() fails, return an error code. + regs.psel_a.write(PinSelect::Connect.val(1)); + }, + |pin_a| { + regs.psel_a.write(PinSelect::Pin.val(pin_a.into()) + PinSelect::Port.val(0) + PinSelect::Connect.val(0)); + } + ); + (self.args_pin_b).map_or_else( + || { + regs.psel_a.write(PinSelect::Connect.val(1)); + }, + |pin_b| { + regs.psel_b.write(PinSelect::Pin.val(pin_b.into()) + PinSelect::Port.val(0) + PinSelect::Connect.val(0)); + } + ); //TODO: Use `Pinmux` struct here instead of usize to prevent collisions - regs.psel_a.write(PinSelect::Pin.val(2) + PinSelect::Port.val(0) + - PinSelect::Connect.val(0)); - regs.psel_b.write(PinSelect::Pin.val(29) + PinSelect::Port.val(0) + - PinSelect::Connect.val(0)); regs.enable.write(Task::ENABLE::SET); regs.sample_per.write(SampPer::SAMPLEPER.val(5)); regs.tasks_start.write(Task::ENABLE::SET); @@ -247,8 +274,6 @@ impl Qdec { pub fn get_acc(&self) -> u32 { let regs = &*self.registers; regs.tasks_readclracc.write(Task::ENABLE::SET); - /*TODO: Test code, not sure if this will work*/ - //regs.tasks_readclraccdbl.write(Task::ENABLE::SET); /*TODO: End of Test code*/ let dummy = regs.acc_read.read(Acc::ACC); dummy From f782d7d016ad3b7d861a930a44115bb4a99ed7c4 Mon Sep 17 00:00:00 2001 From: Hudson Ayers Date: Fri, 14 Feb 2020 11:24:21 -0800 Subject: [PATCH 08/39] fix pin setting by moving it into initialization so pin collisions are caught at startup --- boards/nordic/nrf52dk_base/src/lib.rs | 12 +++- boards/nordic/nrf52dk_base/src/qdec_test.rs | 9 ++- chips/nrf52/src/qdec.rs | 63 +++++++-------------- 3 files changed, 33 insertions(+), 51 deletions(-) diff --git a/boards/nordic/nrf52dk_base/src/lib.rs b/boards/nordic/nrf52dk_base/src/lib.rs index 69baa2b61c2..f41fea516b0 100644 --- a/boards/nordic/nrf52dk_base/src/lib.rs +++ b/boards/nordic/nrf52dk_base/src/lib.rs @@ -13,6 +13,7 @@ use kernel::component::Component; use kernel::hil; use kernel::hil::gpio::{Configure, FloatingState}; use nrf52::gpio::Pin; +use nrf52::qdec::Qdec; use nrf52::rtc::Rtc; use nrf52::uicr::Regulator0Output; @@ -453,7 +454,14 @@ pub unsafe fn setup_board( // TODO: Use pinmux debug!("Initializing QDEC test!"); - let qdec_test = qdec_test::initialize_all(mux_alarm); + let qdec = static_init!( + Qdec, + Qdec::new( + nrf52::pinmux::Pinmux::new(qdec_pins.pin_a as u32), + nrf52::pinmux::Pinmux::new(qdec_pins.pin_b as u32), + ) + ); + let qdec_test = qdec_test::initialize_all(mux_alarm, qdec); debug!("Testing: Qdec Initialized!"); let platform = Platform { button: button, @@ -473,8 +481,6 @@ pub unsafe fn setup_board( debug!("Initialization complete. Entering main loop\r"); debug!("{}", &nrf52::ficr::FICR_INSTANCE); - qdec_test.qdec.set_pins (nrf52::pinmux::Pinmux::new(qdec_pins.pin_a as u32), - nrf52::pinmux::Pinmux::new(qdec_pins.pin_b as u32)); qdec_test.start(); debug!("Started QDEC"); diff --git a/boards/nordic/nrf52dk_base/src/qdec_test.rs b/boards/nordic/nrf52dk_base/src/qdec_test.rs index bc0b0af0866..1be0419edd6 100644 --- a/boards/nordic/nrf52dk_base/src/qdec_test.rs +++ b/boards/nordic/nrf52dk_base/src/qdec_test.rs @@ -1,5 +1,4 @@ -#[allow(unused_imports)] - +#[allow(unused_imports)] use capsules::virtual_alarm::{MuxAlarm, VirtualMuxAlarm}; use kernel::hil::time; use kernel::hil::time::{Alarm, Frequency}; @@ -16,6 +15,7 @@ pub struct QdecTest<'a, A: time::Alarm<'a>> { pub unsafe fn initialize_all( mux_alarm: &'static MuxAlarm<'static, nrf52::rtc::Rtc<'static>>, + qdec: &'static mut Qdec, ) -> &'static QdecTest< 'static, capsules::virtual_alarm::VirtualMuxAlarm<'static, nrf52::rtc::Rtc<'static>>, @@ -28,7 +28,7 @@ pub unsafe fn initialize_all( QdecTest>>, QdecTest { alarm: qdec_alarm, - qdec: &mut nrf52::qdec::QDEC, + qdec: qdec, } ); qdec_alarm.set_client(qdec_test); @@ -36,8 +36,7 @@ pub unsafe fn initialize_all( } impl<'a, A: time::Alarm<'a>> QdecTest<'a, A> { - pub fn start(&self) - { + pub fn start(&self) { self.qdec.enable(); self.schedule_next(); } diff --git a/chips/nrf52/src/qdec.rs b/chips/nrf52/src/qdec.rs index 35aea26a3f8..fbbe2b1dc15 100644 --- a/chips/nrf52/src/qdec.rs +++ b/chips/nrf52/src/qdec.rs @@ -2,19 +2,14 @@ //! set_client(), enable, get_ticks, //! The nRF5x quadrature decoder //! -#[allow(unused_imports)] +#[allow(unused_imports)] use core; -use core::cell::Cell; -use kernel::common::cells::OptionalCell; use kernel::common::registers::{ - self, register_bitfields, register_structs, ReadOnly, ReadWrite, WriteOnly, + register_bitfields, register_structs, ReadOnly, ReadWrite, WriteOnly, }; -use kernel::{debug}; use kernel::common::StaticRef; +use kernel::debug; use kernel::hil; -use kernel::hil::gpio::Pin; -use kernel::ReturnCode; -use nrf5x::gpio::GPIOPin; use nrf5x::pinmux; // In this section I declare a struct called QdecRegisters, which contains all the // relevant registers as outlined in the Nordic 5x specification of the Qdec. @@ -166,25 +161,28 @@ const QDEC_BASE: StaticRef = /// Qdec type declaration: gives the Qdec instance registers and a client pub struct Qdec { registers: StaticRef, - args_pin_a: OptionalCell, - args_pin_b: OptionalCell, } -pub static mut QDEC: Qdec = Qdec { - registers: QDEC_BASE, - args_pin_a: OptionalCell::empty(), - args_pin_b: OptionalCell::empty(), -}; - /// Qdec impl: provides the Qdec type with vital functionality including: /// FIRST DESIRED FUNCTIONALITY: new(arg1, arg2, ..., argN) -> define Qdec struct impl Qdec { - - pub fn set_pins(&self, pin_a: pinmux::Pinmux, pin_b: pinmux::Pinmux) - { - self.args_pin_a.set(pin_a); - self.args_pin_b.set(pin_b); - } + pub unsafe fn new(pin_a: pinmux::Pinmux, pin_b: pinmux::Pinmux) -> Qdec { + let qdec = Qdec { + registers: QDEC_BASE, + }; + let regs = qdec.registers; + regs.psel_a.write( + PinSelect::Pin.val(pin_a.into()) + PinSelect::Port.val(0) + PinSelect::Connect.val(0), + ); + regs.psel_b.write( + PinSelect::Pin.val(pin_b.into()) + PinSelect::Port.val(0) + PinSelect::Connect.val(0), + ); + qdec + } + /*pub fn set_pins(&self, pin_a: pinmux::Pinmux, pin_b: pinmux::Pinmux) { + ); + } + */ /* pub fn set_client(&self, client: &'static dyn CompareClient) { self.client.set(client); @@ -239,33 +237,12 @@ impl Qdec { */ pub fn enable(&self) { let regs = &*self.registers; - (self.args_pin_a).map_or_else( - || { - // Rather than setting this here, set it in the initialization of the struct - // (might require adding a new() function) - // And if this map_or() fails, return an error code. - regs.psel_a.write(PinSelect::Connect.val(1)); - }, - |pin_a| { - regs.psel_a.write(PinSelect::Pin.val(pin_a.into()) + PinSelect::Port.val(0) + PinSelect::Connect.val(0)); - } - ); - (self.args_pin_b).map_or_else( - || { - regs.psel_a.write(PinSelect::Connect.val(1)); - }, - |pin_b| { - regs.psel_b.write(PinSelect::Pin.val(pin_b.into()) + PinSelect::Port.val(0) + PinSelect::Connect.val(0)); - } - ); - //TODO: Use `Pinmux` struct here instead of usize to prevent collisions regs.enable.write(Task::ENABLE::SET); regs.sample_per.write(SampPer::SAMPLEPER.val(5)); regs.tasks_start.write(Task::ENABLE::SET); debug!("Enabled!"); } - pub fn is_enabled(&self) -> bool { let regs = &*self.registers; regs.enable.is_set(Task::ENABLE) From 5830fd05cd77c001de7f5c84be6306f369b7f0ea Mon Sep 17 00:00:00 2001 From: mmurray22 Date: Tue, 18 Feb 2020 18:35:29 -0500 Subject: [PATCH 09/39] Updated QDEC hil and capsule. Almost done-one compiler error --- boards/nordic/nrf52dk_base/src/lib.rs | 5 +++ capsules/src/driver.rs | 1 + capsules/src/lib.rs | 1 + capsules/src/qdec.rs | 60 +++++++++++++++++++-------- chips/nrf52/src/qdec.rs | 14 ++++--- kernel/src/hil/mod.rs | 2 +- kernel/src/hil/qdec.rs | 36 +++++++--------- 7 files changed, 74 insertions(+), 45 deletions(-) diff --git a/boards/nordic/nrf52dk_base/src/lib.rs b/boards/nordic/nrf52dk_base/src/lib.rs index f41fea516b0..5583dcf8166 100644 --- a/boards/nordic/nrf52dk_base/src/lib.rs +++ b/boards/nordic/nrf52dk_base/src/lib.rs @@ -8,6 +8,7 @@ use kernel::{create_capability, debug, debug_gpio, debug_verbose, static_init}; use capsules::virtual_alarm::VirtualMuxAlarm; use capsules::virtual_spi::MuxSpiMaster; use capsules::virtual_uart::MuxUart; +use capsules; use kernel::capabilities; use kernel::component::Component; use kernel::hil; @@ -111,6 +112,8 @@ pub struct Platform { // The nRF52dk does not have the flash chip on it, so we make this optional. nonvolatile_storage: Option<&'static capsules::nonvolatile_storage_driver::NonvolatileStorage<'static>>, + qdec: &'static capsules::qdec::Qdec<'static>, + //_ => f(None), } impl kernel::Platform for Platform { @@ -125,6 +128,7 @@ impl kernel::Platform for Platform { capsules::led::DRIVER_NUM => f(Some(self.led)), capsules::button::DRIVER_NUM => f(Some(self.button)), capsules::rng::DRIVER_NUM => f(Some(self.rng)), + capsules::qdec::DRIVER_NUM => f(Some(self.qdec)), capsules::ble_advertising_driver::DRIVER_NUM => f(Some(self.ble_radio)), capsules::ieee802154::DRIVER_NUM => match self.ieee802154_radio { Some(radio) => f(Some(radio)), @@ -474,6 +478,7 @@ pub unsafe fn setup_board( temp: temp, alarm: alarm, nonvolatile_storage: nonvolatile_storage, + qdec: capsules::qdec, ipc: kernel::ipc::IPC::new(board_kernel, &memory_allocation_capability), }; diff --git a/capsules/src/driver.rs b/capsules/src/driver.rs index 9305e6a7bae..e49f393441a 100644 --- a/capsules/src/driver.rs +++ b/capsules/src/driver.rs @@ -60,5 +60,6 @@ pub enum NUM { // Misc Buzzer = 0x90000, + QDEC = 0x90001, } } diff --git a/capsules/src/lib.rs b/capsules/src/lib.rs index 30683888ca7..d32ab4db1a3 100644 --- a/capsules/src/lib.rs +++ b/capsules/src/lib.rs @@ -61,3 +61,4 @@ pub mod virtual_i2c; pub mod virtual_pwm; pub mod virtual_spi; pub mod virtual_uart; +pub mod qdec; diff --git a/capsules/src/qdec.rs b/capsules/src/qdec.rs index 71aa69cb215..d0bcc203a43 100644 --- a/capsules/src/qdec.rs +++ b/capsules/src/qdec.rs @@ -1,30 +1,54 @@ -//! There will be lots of comments here eventually... -//! -//! -//! -//! KK will add all those later -//! +//! Capsule for QDEC -use core::cell::Cell; -use kernel::hil::gpio; use crate::driver; +use core::cell::Cell; +use kernel::hil; +use kernel::{AppId, ReturnCode, Driver, Grant}; +pub const DRIVER_NUM: usize = driver::NUM::QDEC as usize; -#[derive(Clone, Copy)] -pub enum Position { - PositionUp, - PositionDown, +pub struct Qdec<'a> { + driver: &'a dyn hil::qdec::Qdec<'a>, + apps: Grant, } -///I want to create some public struct for the QDEC -pub struct QDEC<'a> { - ///what do I want to put in here? +pub struct App { + threshold: usize, } -impl<'a> QDEC<'a> { - +impl Default for App { + fn default() -> App { + App { + threshold: 0, + } + } } -impl<'a> Driver for QDEC<'a> { //! this is for the hil +impl Qdec<'a> { + pub fn new (driver: &'a dyn hil::qdec::Qdec<'a>, grant: Grant) -> Qdec<'a> { + Qdec { + driver: driver, + apps: grant, + } + } + + fn enable_qdec (&self) -> ReturnCode { + self.driver.enable(); + self.driver.is_enabled() + } + + fn get_rotation_changes (&self) -> u32 { + self.driver.get_acc() + } } +impl Driver for Qdec<'a> { + fn command (&self, command_num: usize, data: usize, data2: usize, appid: AppId) -> ReturnCode { + match command_num { + 0 => ReturnCode::SUCCESS, + 1 => self.enable_qdec (), + //2 => self.get_rotation_changes (&self) + _ => ReturnCode::ENOSUPPORT + } + } +} diff --git a/chips/nrf52/src/qdec.rs b/chips/nrf52/src/qdec.rs index fbbe2b1dc15..2a18abc95cb 100644 --- a/chips/nrf52/src/qdec.rs +++ b/chips/nrf52/src/qdec.rs @@ -7,6 +7,7 @@ use core; use kernel::common::registers::{ register_bitfields, register_structs, ReadOnly, ReadWrite, WriteOnly, }; +use kernel::ReturnCode; use kernel::common::StaticRef; use kernel::debug; use kernel::hil; @@ -243,16 +244,19 @@ impl Qdec { debug!("Enabled!"); } - pub fn is_enabled(&self) -> bool { + pub fn is_enabled(&self) -> ReturnCode { let regs = &*self.registers; - regs.enable.is_set(Task::ENABLE) + let result = if regs.enable.is_set(Task::ENABLE) { + ReturnCode::SUCCESS + } else { + ReturnCode::FAIL + }; + result } pub fn get_acc(&self) -> u32 { let regs = &*self.registers; regs.tasks_readclracc.write(Task::ENABLE::SET); - /*TODO: End of Test code*/ - let dummy = regs.acc_read.read(Acc::ACC); - dummy + regs.acc_read.read(Acc::ACC) } } diff --git a/kernel/src/hil/mod.rs b/kernel/src/hil/mod.rs index e30392b8125..c78c39cbbea 100644 --- a/kernel/src/hil/mod.rs +++ b/kernel/src/hil/mod.rs @@ -23,7 +23,7 @@ pub mod time; pub mod uart; pub mod usb; pub mod watchdog; - +pub mod qdec; /// Shared interface for configuring components. pub trait Controller { type Config; diff --git a/kernel/src/hil/qdec.rs b/kernel/src/hil/qdec.rs index 621d59eb33b..641eb7f7c9f 100644 --- a/kernel/src/hil/qdec.rs +++ b/kernel/src/hil/qdec.rs @@ -1,23 +1,17 @@ -//! This is a new hardware interface for the QDEC! -//! Generic QDEC for any board -use crate::hil::gpio; +/// A basic interface for a QDEC compatible chip +/// +/// This trait provides a stanfard interface for chips that +/// contain a quadrature encoder. Any interface functions that +/// a chip cannot implement can be ignored by the chip capsule +/// and an error will automatically be returned. -pub trait QDEC { - //! - fn set_client(); - fn enable(); - fn get_ticks(&self) -> Result; - fn enable(&self) -> ReturnCode; //! success or error - //! ACC register, enable debounce?, prob 0 for sample rate - fn rotation(&mut self); - //!USE BUTTON HIL FOR THIS - //!fn pressed_button(&mut self); - //!fn released_button(&mut self); - fn initialize_pins (&mut self); -} +use crate::returncode::ReturnCode; +//use nrf5x::pinmux; + +pub trait Qdec<'a> { + fn enable(&self); -//! In kernel test in the boards folder -//! create a new qdec, config, and then call fxns avail -//! Need to set a timer -//! Samples imix -> src -> udp_lowpan_test -//! Where to proceed from here? + fn is_enabled (&self) -> ReturnCode; + + fn get_acc (&self) -> u32; +} From 389eddeb963c84315a6eef289714eedd7f6f89ef Mon Sep 17 00:00:00 2001 From: Michaela Murray Date: Mon, 24 Feb 2020 12:42:00 -0500 Subject: [PATCH 10/39] All changes compile and general structure locked in. --- boards/nordic/nrf52dk_base/src/lib.rs | 29 +++++++++--------- capsules/src/qdec.rs | 16 +++++----- chips/nrf52/src/qdec.rs | 42 ++++++++++++++++++++------- kernel/src/hil/qdec.rs | 4 +-- 4 files changed, 56 insertions(+), 35 deletions(-) diff --git a/boards/nordic/nrf52dk_base/src/lib.rs b/boards/nordic/nrf52dk_base/src/lib.rs index 5583dcf8166..4d73fe18ea1 100644 --- a/boards/nordic/nrf52dk_base/src/lib.rs +++ b/boards/nordic/nrf52dk_base/src/lib.rs @@ -4,11 +4,10 @@ #![allow(dead_code)] #[allow(unused_imports)] use kernel::{create_capability, debug, debug_gpio, debug_verbose, static_init}; - use capsules::virtual_alarm::VirtualMuxAlarm; use capsules::virtual_spi::MuxSpiMaster; use capsules::virtual_uart::MuxUart; -use capsules; +use capsules::qdec::QdecInterface; use kernel::capabilities; use kernel::component::Component; use kernel::hil; @@ -24,8 +23,6 @@ pub mod nrf52_components; use nrf52_components::ble::BLEComponent; use nrf52_components::ieee802154::Ieee802154Component; -mod qdec_test; - // Constants related to the configuration of the 15.4 network stack const SRC_MAC: u16 = 0xf00f; const PAN_ID: u16 = 0xABCD; @@ -77,7 +74,7 @@ impl UartPins { } } -/// Pins for the UART +/// Pins for the QDEC #[derive(Debug)] pub struct QdecPins { pin_a: Pin, @@ -112,7 +109,7 @@ pub struct Platform { // The nRF52dk does not have the flash chip on it, so we make this optional. nonvolatile_storage: Option<&'static capsules::nonvolatile_storage_driver::NonvolatileStorage<'static>>, - qdec: &'static capsules::qdec::Qdec<'static>, + qdec: &'static capsules::qdec::QdecInterface<'static>, //_ => f(None), } @@ -450,23 +447,29 @@ pub unsafe fn setup_board( ); DynamicDeferredCall::set_global_instance(dynamic_deferred_call); - //We think this is needed bc the MBEDOS driver does that + //START: QDEC INITIALIZATION gpio_port[qdec_pins.pin_a].make_input(); gpio_port[qdec_pins.pin_b].make_input(); gpio_port[qdec_pins.pin_a].set_floating_state(FloatingState::PullUp); gpio_port[qdec_pins.pin_b].set_floating_state(FloatingState::PullUp); - // TODO: Use pinmux - debug!("Initializing QDEC test!"); - let qdec = static_init!( + let qdec_pin_initialize = static_init!( Qdec, Qdec::new( nrf52::pinmux::Pinmux::new(qdec_pins.pin_a as u32), nrf52::pinmux::Pinmux::new(qdec_pins.pin_b as u32), ) ); - let qdec_test = qdec_test::initialize_all(mux_alarm, qdec); + let qdec = static_init!( + capsules::qdec::QdecInterface<'static>, + capsules::qdec::QdecInterface::new( + qdec_pin_initialize, + board_kernel.create_grant(&memory_allocation_capability) + ) + ); debug!("Testing: Qdec Initialized!"); + //END: QDEC INITIALIZATION + let platform = Platform { button: button, ble_radio: ble_radio, @@ -478,7 +481,7 @@ pub unsafe fn setup_board( temp: temp, alarm: alarm, nonvolatile_storage: nonvolatile_storage, - qdec: capsules::qdec, + qdec: qdec, ipc: kernel::ipc::IPC::new(board_kernel, &memory_allocation_capability), }; @@ -486,8 +489,6 @@ pub unsafe fn setup_board( debug!("Initialization complete. Entering main loop\r"); debug!("{}", &nrf52::ficr::FICR_INSTANCE); - qdec_test.start(); - debug!("Started QDEC"); extern "C" { /// Beginning of the ROM region containing app images. diff --git a/capsules/src/qdec.rs b/capsules/src/qdec.rs index d0bcc203a43..12a21a773be 100644 --- a/capsules/src/qdec.rs +++ b/capsules/src/qdec.rs @@ -1,14 +1,13 @@ //! Capsule for QDEC use crate::driver; -use core::cell::Cell; use kernel::hil; use kernel::{AppId, ReturnCode, Driver, Grant}; pub const DRIVER_NUM: usize = driver::NUM::QDEC as usize; -pub struct Qdec<'a> { - driver: &'a dyn hil::qdec::Qdec<'a>, +pub struct QdecInterface<'a> { + driver: &'a dyn hil::qdec::QdecDriver, apps: Grant, } @@ -24,9 +23,9 @@ impl Default for App { } } -impl Qdec<'a> { - pub fn new (driver: &'a dyn hil::qdec::Qdec<'a>, grant: Grant) -> Qdec<'a> { - Qdec { +impl QdecInterface<'a> { + pub fn new (driver: &'a dyn hil::qdec::QdecDriver, grant: Grant) -> QdecInterface<'a> { + QdecInterface { driver: driver, apps: grant, } @@ -42,12 +41,11 @@ impl Qdec<'a> { } } -impl Driver for Qdec<'a> { - fn command (&self, command_num: usize, data: usize, data2: usize, appid: AppId) -> ReturnCode { +impl Driver for QdecInterface<'a> { + fn command (&self, command_num: usize, _data: usize, _data2: usize, _appid: AppId) -> ReturnCode { match command_num { 0 => ReturnCode::SUCCESS, 1 => self.enable_qdec (), - //2 => self.get_rotation_changes (&self) _ => ReturnCode::ENOSUPPORT } } diff --git a/chips/nrf52/src/qdec.rs b/chips/nrf52/src/qdec.rs index 2a18abc95cb..6e995a5a6af 100644 --- a/chips/nrf52/src/qdec.rs +++ b/chips/nrf52/src/qdec.rs @@ -10,7 +10,6 @@ use kernel::common::registers::{ use kernel::ReturnCode; use kernel::common::StaticRef; use kernel::debug; -use kernel::hil; use nrf5x::pinmux; // In this section I declare a struct called QdecRegisters, which contains all the // relevant registers as outlined in the Nordic 5x specification of the Qdec. @@ -180,15 +179,12 @@ impl Qdec { ); qdec } - /*pub fn set_pins(&self, pin_a: pinmux::Pinmux, pin_b: pinmux::Pinmux) { - ); - } - */ - /* - pub fn set_client(&self, client: &'static dyn CompareClient) { +} + + /*pub fn set_client(&self, client: &'static dyn CompareClient) { self.client.set(client); - } - */ + }*/ + /// When an interrupt occurs, check to see if any /// of the interrupt register bits are set. If it @@ -236,7 +232,7 @@ impl Qdec { self.registers.intenset.is_set(/*MACRO*/); } */ - pub fn enable(&self) { + /*pub fn enable(&self) { let regs = &*self.registers; regs.enable.write(Task::ENABLE::SET); regs.sample_per.write(SampPer::SAMPLEPER.val(5)); @@ -258,5 +254,31 @@ impl Qdec { let regs = &*self.registers; regs.tasks_readclracc.write(Task::ENABLE::SET); regs.acc_read.read(Acc::ACC) + }*/ + +//TODO: FIX SPACING! +impl kernel::hil::qdec::QdecDriver for Qdec { + fn enable(&self) { + let regs = &*self.registers; + regs.enable.write(Task::ENABLE::SET); + regs.sample_per.write(SampPer::SAMPLEPER.val(5)); + regs.tasks_start.write(Task::ENABLE::SET); + debug!("Enabled!"); + } + + fn is_enabled(&self) -> ReturnCode { + let regs = &*self.registers; + let result = if regs.enable.is_set(Task::ENABLE) { + ReturnCode::SUCCESS + } else { + ReturnCode::FAIL + }; + result + } + + fn get_acc(&self) -> u32 { + let regs = &*self.registers; + regs.tasks_readclracc.write(Task::ENABLE::SET); + regs.acc_read.read(Acc::ACC) } } diff --git a/kernel/src/hil/qdec.rs b/kernel/src/hil/qdec.rs index 641eb7f7c9f..6f59445dd14 100644 --- a/kernel/src/hil/qdec.rs +++ b/kernel/src/hil/qdec.rs @@ -6,9 +6,9 @@ /// and an error will automatically be returned. use crate::returncode::ReturnCode; -//use nrf5x::pinmux; -pub trait Qdec<'a> { +pub trait QdecDriver { + fn enable(&self); fn is_enabled (&self) -> ReturnCode; From 1174a6c3af86fd05d2023b17df9c9ae6fcd97e39 Mon Sep 17 00:00:00 2001 From: mmurray22 Date: Mon, 24 Feb 2020 16:08:45 -0500 Subject: [PATCH 11/39] Added interrupts. Next step is creating userprog --- boards/nordic/nrf52dk_base/src/lib.rs | 2 +- capsules/src/qdec.rs | 85 ++++++++++++++++++++------- chips/nrf52/src/qdec.rs | 74 ++++++++++------------- kernel/src/hil/qdec.rs | 16 ++++- 4 files changed, 111 insertions(+), 66 deletions(-) diff --git a/boards/nordic/nrf52dk_base/src/lib.rs b/boards/nordic/nrf52dk_base/src/lib.rs index 4d73fe18ea1..8ba1d037255 100644 --- a/boards/nordic/nrf52dk_base/src/lib.rs +++ b/boards/nordic/nrf52dk_base/src/lib.rs @@ -7,7 +7,6 @@ use kernel::{create_capability, debug, debug_gpio, debug_verbose, static_init}; use capsules::virtual_alarm::VirtualMuxAlarm; use capsules::virtual_spi::MuxSpiMaster; use capsules::virtual_uart::MuxUart; -use capsules::qdec::QdecInterface; use kernel::capabilities; use kernel::component::Component; use kernel::hil; @@ -467,6 +466,7 @@ pub unsafe fn setup_board( board_kernel.create_grant(&memory_allocation_capability) ) ); + kernel::hil::qdec::QdecDriver::set_client(qdec_pin_initialize, qdec); debug!("Testing: Qdec Initialized!"); //END: QDEC INITIALIZATION diff --git a/capsules/src/qdec.rs b/capsules/src/qdec.rs index 12a21a773be..f4a1408ca08 100644 --- a/capsules/src/qdec.rs +++ b/capsules/src/qdec.rs @@ -1,51 +1,96 @@ //! Capsule for QDEC use crate::driver; -use kernel::hil; -use kernel::{AppId, ReturnCode, Driver, Grant}; +use kernel::hil; +use core::cell::Cell; +use kernel::{AppId, Callback, ReturnCode, Driver, Grant}; pub const DRIVER_NUM: usize = driver::NUM::QDEC as usize; pub struct QdecInterface<'a> { driver: &'a dyn hil::qdec::QdecDriver, apps: Grant, + busy: Cell, } +#[derive(Default)] pub struct App { - threshold: usize, -} - -impl Default for App { - fn default() -> App { - App { - threshold: 0, - } - } + callback: Option, + subscribed: bool, } impl QdecInterface<'a> { - pub fn new (driver: &'a dyn hil::qdec::QdecDriver, grant: Grant) -> QdecInterface<'a> { + pub fn new ( + driver: &'a dyn hil::qdec::QdecDriver, + grant: Grant, + ) -> QdecInterface<'a> { QdecInterface { driver: driver, apps: grant, + busy: Cell::new(false), } } - fn enable_qdec (&self) -> ReturnCode { - self.driver.enable(); - self.driver.is_enabled() + fn enqueue_command(&self, appid: AppId) -> ReturnCode { + self.apps + .enter(appid, |app, _| { + if !self.busy.get() { + app.subscribed = true; + self.busy.set(true); + self.driver.enable_qdec() + } else { + ReturnCode::EBUSY + } + }) + .unwrap_or_else(|err| err.into()) } - - fn get_rotation_changes (&self) -> u32 { - self.driver.get_acc() + + fn configure_callback(&self, callback: Option, app_id: AppId) -> ReturnCode { + self.apps + .enter(app_id, |app, _| { + app.callback = callback; + ReturnCode::SUCCESS + }) + .unwrap_or_else(|err| err.into()) + } +} + +impl hil::qdec::QdecClient for QdecInterface<'a> { + fn callback(&self, qdec_val: usize) { + for cntr in self.apps.iter() { + cntr.enter(|app, _| { + if app.subscribed { + self.busy.set(false); + app.subscribed = false; + app.callback.map(|mut cb| cb.schedule(qdec_val, 0,0)); } + }); + } + } + + fn compare (&self, val: u32) -> bool { + val > 0 } } impl Driver for QdecInterface<'a> { - fn command (&self, command_num: usize, _data: usize, _data2: usize, _appid: AppId) -> ReturnCode { + fn subscribe( + &self, + subscribe_num: usize, + callback: Option, + app_id: AppId, + ) -> ReturnCode { + match subscribe_num { + // subscribe to qdec reading with callback + 0 => self.configure_callback(callback, app_id), + _ => ReturnCode::ENOSUPPORT, + } + } + + fn command (&self, command_num: usize, _: usize, _: usize, appid: AppId) -> ReturnCode { match command_num { 0 => ReturnCode::SUCCESS, - 1 => self.enable_qdec (), + 1 => self.enqueue_command (appid), + //2 => self.get_acc(), _ => ReturnCode::ENOSUPPORT } } diff --git a/chips/nrf52/src/qdec.rs b/chips/nrf52/src/qdec.rs index 6e995a5a6af..c774b976695 100644 --- a/chips/nrf52/src/qdec.rs +++ b/chips/nrf52/src/qdec.rs @@ -4,6 +4,7 @@ //! #[allow(unused_imports)] use core; +use kernel::common::cells::OptionalCell; use kernel::common::registers::{ register_bitfields, register_structs, ReadOnly, ReadWrite, WriteOnly, }; @@ -161,6 +162,7 @@ const QDEC_BASE: StaticRef = /// Qdec type declaration: gives the Qdec instance registers and a client pub struct Qdec { registers: StaticRef, + client: OptionalCell<&'static dyn kernel::hil::qdec::QdecClient>, } /// Qdec impl: provides the Qdec type with vital functionality including: @@ -169,6 +171,7 @@ impl Qdec { pub unsafe fn new(pin_a: pinmux::Pinmux, pin_b: pinmux::Pinmux) -> Qdec { let qdec = Qdec { registers: QDEC_BASE, + client: OptionalCell::empty(), }; let regs = qdec.registers; regs.psel_a.write( @@ -179,18 +182,20 @@ impl Qdec { ); qdec } -} + - /*pub fn set_client(&self, client: &'static dyn CompareClient) { + pub fn set_client(&self, client: &'static dyn kernel::hil::qdec::QdecClient) { self.client.set(client); - }*/ + } /// When an interrupt occurs, check to see if any /// of the interrupt register bits are set. If it /// is, then put it in the client's bitmask - /* + /// TODO: DO I NEED TO DISABLE INTERRUPTS + /// TODO: ADD CLIENT CODE TO HIL/CAPSULE/LIB pub fn handle_interrupt(&self) { + self.disable_interrupts(); self.client.map(|client| { let mut val = 0; // For each of 4 possible compare events, if it's happened, @@ -206,6 +211,7 @@ impl Qdec { 2 => Inte::ACCOF::SET, 3 => Inte::DBLRDY::SET, 4 => Inte::STOPPED::SET, + _ => Inte::STOPPED::SET, }; self.registers.intenclr.write(interrupt_bit); } @@ -213,51 +219,18 @@ impl Qdec { client.compare(val as u32); }); } - */ - //add more functions here! - /* - fn enable_interrupts(&self) { ///IS THIS THE RIGHT MACRO TO USE? + // NOTE: ALL INTERRUPTS ARE ONLY FOR SAMPLING RIGHT NOW + fn enable_interrupts(&self) { //IS THIS THE RIGHT MACRO TO USE? let regs = &*self.registers; - regs.intenset.write(Inte::____::SET /*TODO: Correct macro */); + regs.intenset.write(Inte::SAMPLERDY::SET); } fn disable_interrupts(&self) { let regs = &*self.registers; - regs.intenclr.write(/*MACRO*/); - } - - fn interrupts_enabled(&self) -> bool { - let regs = &*self.registers; - self.registers.intenset.is_set(/*MACRO*/); - } - */ - /*pub fn enable(&self) { - let regs = &*self.registers; - regs.enable.write(Task::ENABLE::SET); - regs.sample_per.write(SampPer::SAMPLEPER.val(5)); - regs.tasks_start.write(Task::ENABLE::SET); - debug!("Enabled!"); - } - - pub fn is_enabled(&self) -> ReturnCode { - let regs = &*self.registers; - let result = if regs.enable.is_set(Task::ENABLE) { - ReturnCode::SUCCESS - } else { - ReturnCode::FAIL - }; - result + regs.intenclr.write(Inte::SAMPLERDY::SET); } - - pub fn get_acc(&self) -> u32 { - let regs = &*self.registers; - regs.tasks_readclracc.write(Task::ENABLE::SET); - regs.acc_read.read(Acc::ACC) - }*/ - -//TODO: FIX SPACING! -impl kernel::hil::qdec::QdecDriver for Qdec { + fn enable(&self) { let regs = &*self.registers; regs.enable.write(Task::ENABLE::SET); @@ -276,9 +249,26 @@ impl kernel::hil::qdec::QdecDriver for Qdec { result } + /*fn interrupts_enabled(&self) -> bool { + let regs = &*self.registers; + self.registers.intenset.is_set(Inte::SAMPLERDY) + }i*/ +} +//TODO: FIX SPACING! +impl kernel::hil::qdec::QdecDriver for Qdec { + fn enable_qdec (&self) -> ReturnCode { + self.enable(); + self.is_enabled() + } + fn get_acc(&self) -> u32 { let regs = &*self.registers; + self.enable_interrupts(); regs.tasks_readclracc.write(Task::ENABLE::SET); regs.acc_read.read(Acc::ACC) } + + fn set_client(&self, client: &'static dyn kernel::hil::qdec::QdecClient) { + self.client.set(client); + } } diff --git a/kernel/src/hil/qdec.rs b/kernel/src/hil/qdec.rs index 6f59445dd14..5191ad46c79 100644 --- a/kernel/src/hil/qdec.rs +++ b/kernel/src/hil/qdec.rs @@ -9,9 +9,19 @@ use crate::returncode::ReturnCode; pub trait QdecDriver { - fn enable(&self); + fn set_client(&self, client: &'static dyn QdecClient); + + /*fn enable(&self); + + fn is_enabled (&self) -> ReturnCode;*/ + + fn enable_qdec (&self) -> ReturnCode; - fn is_enabled (&self) -> ReturnCode; - fn get_acc (&self) -> u32; } + +pub trait QdecClient { + fn compare (&self, val: u32) -> bool; + + fn callback(&self, value: usize); +} From 1c20e7617266840c31a74cce5affa9428ce99e72 Mon Sep 17 00:00:00 2001 From: mmurray22 Date: Tue, 25 Feb 2020 16:36:00 -0500 Subject: [PATCH 12/39] Interrupts seem to work now! --- boards/nordic/nrf52dk_base/src/lib.rs | 28 +++++++------- boards/nordic/nrf52dk_base/src/qdec_test.rs | 17 +++++++- capsules/src/qdec.rs | 11 ++---- chips/nrf52/src/chip.rs | 2 + chips/nrf52/src/qdec.rs | 43 +++++++++++++++++---- kernel/src/hil/qdec.rs | 9 +++-- 6 files changed, 76 insertions(+), 34 deletions(-) diff --git a/boards/nordic/nrf52dk_base/src/lib.rs b/boards/nordic/nrf52dk_base/src/lib.rs index 8ba1d037255..0011fa3a23e 100644 --- a/boards/nordic/nrf52dk_base/src/lib.rs +++ b/boards/nordic/nrf52dk_base/src/lib.rs @@ -12,12 +12,11 @@ use kernel::component::Component; use kernel::hil; use kernel::hil::gpio::{Configure, FloatingState}; use nrf52::gpio::Pin; -use nrf52::qdec::Qdec; use nrf52::rtc::Rtc; use nrf52::uicr::Regulator0Output; use kernel::common::dynamic_deferred_call::{DynamicDeferredCall, DynamicDeferredCallClientState}; - +pub mod qdec_test; pub mod nrf52_components; use nrf52_components::ble::BLEComponent; use nrf52_components::ieee802154::Ieee802154Component; @@ -108,7 +107,7 @@ pub struct Platform { // The nRF52dk does not have the flash chip on it, so we make this optional. nonvolatile_storage: Option<&'static capsules::nonvolatile_storage_driver::NonvolatileStorage<'static>>, - qdec: &'static capsules::qdec::QdecInterface<'static>, + //qdec: &'static capsules::qdec::QdecInterface<'static>, //_ => f(None), } @@ -124,7 +123,7 @@ impl kernel::Platform for Platform { capsules::led::DRIVER_NUM => f(Some(self.led)), capsules::button::DRIVER_NUM => f(Some(self.button)), capsules::rng::DRIVER_NUM => f(Some(self.rng)), - capsules::qdec::DRIVER_NUM => f(Some(self.qdec)), + //capsules::qdec::DRIVER_NUM => f(Some(self.qdec)), capsules::ble_advertising_driver::DRIVER_NUM => f(Some(self.ble_radio)), capsules::ieee802154::DRIVER_NUM => match self.ieee802154_radio { Some(radio) => f(Some(radio)), @@ -452,22 +451,22 @@ pub unsafe fn setup_board( gpio_port[qdec_pins.pin_a].set_floating_state(FloatingState::PullUp); gpio_port[qdec_pins.pin_b].set_floating_state(FloatingState::PullUp); - let qdec_pin_initialize = static_init!( - Qdec, - Qdec::new( + let qdec_nrf52 = &mut nrf52::qdec::QDEC; + qdec_nrf52.set_pins( nrf52::pinmux::Pinmux::new(qdec_pins.pin_a as u32), nrf52::pinmux::Pinmux::new(qdec_pins.pin_b as u32), - ) - ); - let qdec = static_init!( + ); + /*let qdec = static_init!( capsules::qdec::QdecInterface<'static>, capsules::qdec::QdecInterface::new( qdec_pin_initialize, board_kernel.create_grant(&memory_allocation_capability) ) - ); - kernel::hil::qdec::QdecDriver::set_client(qdec_pin_initialize, qdec); - debug!("Testing: Qdec Initialized!"); + );*/ + //kernel::hil::qdec::QdecDriver::set_client(qdec_pin_initialize, qdec); + let qdec_test = qdec_test::initialize_all(mux_alarm, qdec_nrf52); + //qdec_nrf52.set_client(qdec_test); + //debug!("Testing: Qdec Initialized!"); TODO DELETE DEBUG STATEMENTS //END: QDEC INITIALIZATION let platform = Platform { @@ -481,13 +480,14 @@ pub unsafe fn setup_board( temp: temp, alarm: alarm, nonvolatile_storage: nonvolatile_storage, - qdec: qdec, + // qdec: qdec, ipc: kernel::ipc::IPC::new(board_kernel, &memory_allocation_capability), }; let chip = static_init!(nrf52::chip::NRF52, nrf52::chip::NRF52::new(gpio_port)); debug!("Initialization complete. Entering main loop\r"); + qdec_test.start(); debug!("{}", &nrf52::ficr::FICR_INSTANCE); extern "C" { diff --git a/boards/nordic/nrf52dk_base/src/qdec_test.rs b/boards/nordic/nrf52dk_base/src/qdec_test.rs index 1be0419edd6..a4dd8d4ebe1 100644 --- a/boards/nordic/nrf52dk_base/src/qdec_test.rs +++ b/boards/nordic/nrf52dk_base/src/qdec_test.rs @@ -4,6 +4,7 @@ use kernel::hil::time; use kernel::hil::time::{Alarm, Frequency}; use kernel::{debug, static_init}; use nrf52::qdec::Qdec; +use kernel::hil::qdec::QdecDriver; //use nrf5x::pinmux; pub const TEST_DELAY_MS: u32 = 1000; @@ -32,12 +33,16 @@ pub unsafe fn initialize_all( } ); qdec_alarm.set_client(qdec_test); + qdec_test.qdec.set_client(qdec_test); qdec_test } impl<'a, A: time::Alarm<'a>> QdecTest<'a, A> { pub fn start(&self) { - self.qdec.enable(); + self.qdec.enable_qdec(); + debug!("Is enabled?"); + self.qdec.enable_interrupts_qdec(); + debug!("Is interruptable?"); self.schedule_next(); } @@ -50,9 +55,17 @@ impl<'a, A: time::Alarm<'a>> QdecTest<'a, A> { impl<'a, A: time::Alarm<'a>> time::AlarmClient for QdecTest<'a, A> { fn fired(&self) { + self.qdec.enable_qdec(); + //self.qdec.enable_interrupts_qdec(); let acc = self.qdec.get_acc(); - debug!("Is enabled: {:?}", self.qdec.is_enabled()); + debug!("Is enabled?"); debug!("Acc: {:?}", acc); self.schedule_next(); } } + +impl<'a, A: time::Alarm<'a>> kernel::hil::qdec::QdecClient for QdecTest<'a, A> { + fn sample_ready (&self, acc:u32) { //TODO go back and change name + debug!("Val:{:?}", acc); + } +} diff --git a/capsules/src/qdec.rs b/capsules/src/qdec.rs index f4a1408ca08..7ea6c9e63c2 100644 --- a/capsules/src/qdec.rs +++ b/capsules/src/qdec.rs @@ -55,8 +55,8 @@ impl QdecInterface<'a> { } } -impl hil::qdec::QdecClient for QdecInterface<'a> { - fn callback(&self, qdec_val: usize) { +/*TODO: impl hil::qdec::QdecClient for QdecInterface<'a> { + /* fn callback(&self, qdec_val: usize) { for cntr in self.apps.iter() { cntr.enter(|app, _| { if app.subscribed { @@ -65,12 +65,9 @@ impl hil::qdec::QdecClient for QdecInterface<'a> { app.callback.map(|mut cb| cb.schedule(qdec_val, 0,0)); } }); } - } + }*/ - fn compare (&self, val: u32) -> bool { - val > 0 - } -} +}*/ impl Driver for QdecInterface<'a> { fn subscribe( diff --git a/chips/nrf52/src/chip.rs b/chips/nrf52/src/chip.rs index bcd28a70aac..002640fe667 100644 --- a/chips/nrf52/src/chip.rs +++ b/chips/nrf52/src/chip.rs @@ -7,6 +7,7 @@ use crate::nvmc; use crate::power; use crate::spi; use crate::uart; +use crate::qdec; use cortexm4::{self, nvic}; use kernel::common::deferred_call; use kernel::debug; @@ -111,6 +112,7 @@ impl kernel::Chip for NRF52 { } peripheral_interrupts::SPIM2_SPIS2_SPI2 => spi::SPIM2.handle_interrupt(), peripheral_interrupts::ADC => adc::ADC.handle_interrupt(), + peripheral_interrupts::QDEC => qdec::QDEC.handle_interrupt(), _ => debug!("NvicIdx not supported by Tock"), } let n = nvic::Nvic::new(interrupt); diff --git a/chips/nrf52/src/qdec.rs b/chips/nrf52/src/qdec.rs index c774b976695..52aebe409fc 100644 --- a/chips/nrf52/src/qdec.rs +++ b/chips/nrf52/src/qdec.rs @@ -159,6 +159,8 @@ register_bitfields![u32, const QDEC_BASE: StaticRef = unsafe { StaticRef::new(0x40012000 as *const QdecRegisters) }; +pub static mut QDEC: Qdec = Qdec::new(); + /// Qdec type declaration: gives the Qdec instance registers and a client pub struct Qdec { registers: StaticRef, @@ -168,21 +170,32 @@ pub struct Qdec { /// Qdec impl: provides the Qdec type with vital functionality including: /// FIRST DESIRED FUNCTIONALITY: new(arg1, arg2, ..., argN) -> define Qdec struct impl Qdec { - pub unsafe fn new(pin_a: pinmux::Pinmux, pin_b: pinmux::Pinmux) -> Qdec { + //TODO ok to be safe + const fn new() -> Qdec { let qdec = Qdec { registers: QDEC_BASE, client: OptionalCell::empty(), }; - let regs = qdec.registers; + /*let regs = qdec.registers; regs.psel_a.write( PinSelect::Pin.val(pin_a.into()) + PinSelect::Port.val(0) + PinSelect::Connect.val(0), ); regs.psel_b.write( PinSelect::Pin.val(pin_b.into()) + PinSelect::Port.val(0) + PinSelect::Connect.val(0), - ); + );*/ qdec } + pub fn set_pins(&self, pin_a: pinmux::Pinmux, pin_b: pinmux::Pinmux) { + let regs = self.registers; + regs.psel_a.write( + PinSelect::Pin.val(pin_a.into()) + PinSelect::Port.val(0) + PinSelect::Connect.val(0), + ); + regs.psel_b.write( + PinSelect::Pin.val(pin_b.into()) + PinSelect::Port.val(0) + PinSelect::Connect.val(0), + ); + } + pub fn set_client(&self, client: &'static dyn kernel::hil::qdec::QdecClient) { self.client.set(client); @@ -195,7 +208,7 @@ impl Qdec { /// TODO: DO I NEED TO DISABLE INTERRUPTS /// TODO: ADD CLIENT CODE TO HIL/CAPSULE/LIB pub fn handle_interrupt(&self) { - self.disable_interrupts(); + //self.disable_interrupts(); self.client.map(|client| { let mut val = 0; // For each of 4 possible compare events, if it's happened, @@ -211,12 +224,18 @@ impl Qdec { 2 => Inte::ACCOF::SET, 3 => Inte::DBLRDY::SET, 4 => Inte::STOPPED::SET, - _ => Inte::STOPPED::SET, + _ => Inte::STOPPED::SET, //TODO throw an error? }; self.registers.intenclr.write(interrupt_bit); } } - client.compare(val as u32); + let regs = &*self.registers; + //self.enable_interrupts(); + regs.tasks_readclracc.write(Task::ENABLE::SET); + let val_ret = regs.acc_read.read(Acc::ACC); + //TODO things + debug!("Val!!"); + client.sample_ready (val_ret); }); } @@ -224,6 +243,12 @@ impl Qdec { fn enable_interrupts(&self) { //IS THIS THE RIGHT MACRO TO USE? let regs = &*self.registers; regs.intenset.write(Inte::SAMPLERDY::SET); + regs.intenset.write(Inte::SAMPLERDY::ENABLED); + regs.intenset.write(Inte::REPORTRDY::SET); + regs.intenset.write(Inte::ACCOF::SET); + regs.intenset.write(Inte::DBLRDY::SET); + regs.intenset.write(Inte::STOPPED::SET); + //ReturnCode::SUCCESS } fn disable_interrupts(&self) { @@ -261,9 +286,13 @@ impl kernel::hil::qdec::QdecDriver for Qdec { self.is_enabled() } + fn enable_interrupts_qdec (&self) { + self.enable_interrupts(); + } + fn get_acc(&self) -> u32 { let regs = &*self.registers; - self.enable_interrupts(); + //self.enable_interrupts(); regs.tasks_readclracc.write(Task::ENABLE::SET); regs.acc_read.read(Acc::ACC) } diff --git a/kernel/src/hil/qdec.rs b/kernel/src/hil/qdec.rs index 5191ad46c79..f7006b8fb01 100644 --- a/kernel/src/hil/qdec.rs +++ b/kernel/src/hil/qdec.rs @@ -7,10 +7,11 @@ use crate::returncode::ReturnCode; -pub trait QdecDriver { +pub trait QdecDriver { /* TODO: change name sometime */ fn set_client(&self, client: &'static dyn QdecClient); + fn enable_interrupts_qdec (&self); /*fn enable(&self); fn is_enabled (&self) -> ReturnCode;*/ @@ -21,7 +22,7 @@ pub trait QdecDriver { } pub trait QdecClient { - fn compare (&self, val: u32) -> bool; - - fn callback(&self, value: usize); + fn sample_ready (&self, val: u32); + + //fn callback(&self, value: usize); } From 3c95a1e0e8dbdbd2ef6320c6fdf8c1ee37c0c4ae Mon Sep 17 00:00:00 2001 From: mmurray22 Date: Mon, 23 Mar 2020 15:36:16 -0400 Subject: [PATCH 13/39] I believe these are all the latest changes. Working on sampling accuracy as of now --- boards/nordic/nrf52dk_base/src/lib.rs | 20 ++++++------- capsules/src/driver.rs | 2 +- capsules/src/qdec.rs | 41 +++++++++++++++++++++------ chips/nrf52/src/qdec.rs | 31 +++++++++----------- kernel/src/hil/qdec.rs | 2 +- 5 files changed, 57 insertions(+), 39 deletions(-) diff --git a/boards/nordic/nrf52dk_base/src/lib.rs b/boards/nordic/nrf52dk_base/src/lib.rs index 0011fa3a23e..f9decf1a7bf 100644 --- a/boards/nordic/nrf52dk_base/src/lib.rs +++ b/boards/nordic/nrf52dk_base/src/lib.rs @@ -16,7 +16,7 @@ use nrf52::rtc::Rtc; use nrf52::uicr::Regulator0Output; use kernel::common::dynamic_deferred_call::{DynamicDeferredCall, DynamicDeferredCallClientState}; -pub mod qdec_test; +//pub mod qdec_test; pub mod nrf52_components; use nrf52_components::ble::BLEComponent; use nrf52_components::ieee802154::Ieee802154Component; @@ -107,7 +107,7 @@ pub struct Platform { // The nRF52dk does not have the flash chip on it, so we make this optional. nonvolatile_storage: Option<&'static capsules::nonvolatile_storage_driver::NonvolatileStorage<'static>>, - //qdec: &'static capsules::qdec::QdecInterface<'static>, + qdec: &'static capsules::qdec::QdecInterface<'static>, //_ => f(None), } @@ -123,7 +123,7 @@ impl kernel::Platform for Platform { capsules::led::DRIVER_NUM => f(Some(self.led)), capsules::button::DRIVER_NUM => f(Some(self.button)), capsules::rng::DRIVER_NUM => f(Some(self.rng)), - //capsules::qdec::DRIVER_NUM => f(Some(self.qdec)), + capsules::qdec::DRIVER_NUM => f(Some(self.qdec)), capsules::ble_advertising_driver::DRIVER_NUM => f(Some(self.ble_radio)), capsules::ieee802154::DRIVER_NUM => match self.ieee802154_radio { Some(radio) => f(Some(radio)), @@ -456,15 +456,15 @@ pub unsafe fn setup_board( nrf52::pinmux::Pinmux::new(qdec_pins.pin_a as u32), nrf52::pinmux::Pinmux::new(qdec_pins.pin_b as u32), ); - /*let qdec = static_init!( + let qdec = static_init!( capsules::qdec::QdecInterface<'static>, capsules::qdec::QdecInterface::new( - qdec_pin_initialize, + qdec_nrf52, board_kernel.create_grant(&memory_allocation_capability) ) - );*/ - //kernel::hil::qdec::QdecDriver::set_client(qdec_pin_initialize, qdec); - let qdec_test = qdec_test::initialize_all(mux_alarm, qdec_nrf52); + ); + kernel::hil::qdec::QdecDriver::set_client(qdec_nrf52, qdec); + //let qdec_test = qdec_test::initialize_all(mux_alarm, qdec_nrf52); //qdec_nrf52.set_client(qdec_test); //debug!("Testing: Qdec Initialized!"); TODO DELETE DEBUG STATEMENTS //END: QDEC INITIALIZATION @@ -480,14 +480,14 @@ pub unsafe fn setup_board( temp: temp, alarm: alarm, nonvolatile_storage: nonvolatile_storage, - // qdec: qdec, + qdec: qdec, ipc: kernel::ipc::IPC::new(board_kernel, &memory_allocation_capability), }; let chip = static_init!(nrf52::chip::NRF52, nrf52::chip::NRF52::new(gpio_port)); debug!("Initialization complete. Entering main loop\r"); - qdec_test.start(); + //qdec_test.start(); debug!("{}", &nrf52::ficr::FICR_INSTANCE); extern "C" { diff --git a/capsules/src/driver.rs b/capsules/src/driver.rs index e49f393441a..81f383273ca 100644 --- a/capsules/src/driver.rs +++ b/capsules/src/driver.rs @@ -60,6 +60,6 @@ pub enum NUM { // Misc Buzzer = 0x90000, - QDEC = 0x90001, + Qdec = 0x90001, } } diff --git a/capsules/src/qdec.rs b/capsules/src/qdec.rs index 7ea6c9e63c2..b03fd44e9a5 100644 --- a/capsules/src/qdec.rs +++ b/capsules/src/qdec.rs @@ -2,10 +2,11 @@ use crate::driver; use kernel::hil; +use kernel::debug; use core::cell::Cell; use kernel::{AppId, Callback, ReturnCode, Driver, Grant}; -pub const DRIVER_NUM: usize = driver::NUM::QDEC as usize; +pub const DRIVER_NUM: usize = driver::NUM::Qdec as usize; pub struct QdecInterface<'a> { driver: &'a dyn hil::qdec::QdecDriver, @@ -31,13 +32,18 @@ impl QdecInterface<'a> { } } - fn enqueue_command(&self, appid: AppId) -> ReturnCode { + fn enable_qdec_command(&self, appid: AppId) -> ReturnCode { + self.driver.enable_qdec() + } + + fn enable_qdec_interrupts(&self, appid: AppId) -> ReturnCode { self.apps .enter(appid, |app, _| { if !self.busy.get() { app.subscribed = true; self.busy.set(true); - self.driver.enable_qdec() + self.driver.enable_interrupts_qdec(); //TODO names + ReturnCode::SUCCESS } else { ReturnCode::EBUSY } @@ -45,6 +51,11 @@ impl QdecInterface<'a> { .unwrap_or_else(|err| err.into()) } + + fn get_qdec_acc(&self) -> u32 { + self.driver.get_acc() + } + fn configure_callback(&self, callback: Option, app_id: AppId) -> ReturnCode { self.apps .enter(app_id, |app, _| { @@ -55,8 +66,8 @@ impl QdecInterface<'a> { } } -/*TODO: impl hil::qdec::QdecClient for QdecInterface<'a> { - /* fn callback(&self, qdec_val: usize) { +impl hil::qdec::QdecClient for QdecInterface<'a> { + fn callback(&self, qdec_val: usize) { for cntr in self.apps.iter() { cntr.enter(|app, _| { if app.subscribed { @@ -65,9 +76,12 @@ impl QdecInterface<'a> { app.callback.map(|mut cb| cb.schedule(qdec_val, 0,0)); } }); } - }*/ + } -}*/ + fn sample_ready (&self, acc:u32) { //TODO go back and change name + debug!("Val:{:?}", acc); + } +} impl Driver for QdecInterface<'a> { fn subscribe( @@ -85,9 +99,18 @@ impl Driver for QdecInterface<'a> { fn command (&self, command_num: usize, _: usize, _: usize, appid: AppId) -> ReturnCode { match command_num { + //dummy value 0 => ReturnCode::SUCCESS, - 1 => self.enqueue_command (appid), - //2 => self.get_acc(), + // enable qdec + 1 => self.enable_qdec_command (appid), + // enable interrupts + 2 => self.enable_qdec_interrupts (appid), + //get qdec acc + 3 => + ReturnCode::SuccessWithValue{ + value: self.get_qdec_acc() as usize, + }, + //default _ => ReturnCode::ENOSUPPORT } } diff --git a/chips/nrf52/src/qdec.rs b/chips/nrf52/src/qdec.rs index 52aebe409fc..e79d4021465 100644 --- a/chips/nrf52/src/qdec.rs +++ b/chips/nrf52/src/qdec.rs @@ -66,6 +66,8 @@ register_structs! { (0x520 => psel_a: ReadWrite), (0x524 => psel_b: ReadWrite), (0x528 => reserved5), + (0x544 => accdbl: ReadOnly), + (0x548 => accdbl_read: ReadOnly), (0x550 => @END), } } @@ -151,6 +153,9 @@ register_bitfields![u32, ], Acc [ ACC OFFSET(0) NUMBITS(32) + ], + AccDbl [ + ACCDBL OFFSET(0) NUMBITS(4) ] ]; @@ -176,13 +181,6 @@ impl Qdec { registers: QDEC_BASE, client: OptionalCell::empty(), }; - /*let regs = qdec.registers; - regs.psel_a.write( - PinSelect::Pin.val(pin_a.into()) + PinSelect::Port.val(0) + PinSelect::Connect.val(0), - ); - regs.psel_b.write( - PinSelect::Pin.val(pin_b.into()) + PinSelect::Port.val(0) + PinSelect::Connect.val(0), - );*/ qdec } @@ -208,7 +206,7 @@ impl Qdec { /// TODO: DO I NEED TO DISABLE INTERRUPTS /// TODO: ADD CLIENT CODE TO HIL/CAPSULE/LIB pub fn handle_interrupt(&self) { - //self.disable_interrupts(); + self.disable_interrupts(); self.client.map(|client| { let mut val = 0; // For each of 4 possible compare events, if it's happened, @@ -237,18 +235,17 @@ impl Qdec { debug!("Val!!"); client.sample_ready (val_ret); }); + self.enable_interrupts(); } // NOTE: ALL INTERRUPTS ARE ONLY FOR SAMPLING RIGHT NOW fn enable_interrupts(&self) { //IS THIS THE RIGHT MACRO TO USE? let regs = &*self.registers; regs.intenset.write(Inte::SAMPLERDY::SET); - regs.intenset.write(Inte::SAMPLERDY::ENABLED); regs.intenset.write(Inte::REPORTRDY::SET); regs.intenset.write(Inte::ACCOF::SET); regs.intenset.write(Inte::DBLRDY::SET); regs.intenset.write(Inte::STOPPED::SET); - //ReturnCode::SUCCESS } fn disable_interrupts(&self) { @@ -274,22 +271,20 @@ impl Qdec { result } - /*fn interrupts_enabled(&self) -> bool { - let regs = &*self.registers; - self.registers.intenset.is_set(Inte::SAMPLERDY) - }i*/ } //TODO: FIX SPACING! impl kernel::hil::qdec::QdecDriver for Qdec { + fn enable_interrupts_qdec (&self) { + self.enable_interrupts(); + } + fn enable_qdec (&self) -> ReturnCode { + //Maybe expose to HIL + self.registers.sample_per.write(SampPer::SAMPLEPER::ms131); self.enable(); self.is_enabled() } - fn enable_interrupts_qdec (&self) { - self.enable_interrupts(); - } - fn get_acc(&self) -> u32 { let regs = &*self.registers; //self.enable_interrupts(); diff --git a/kernel/src/hil/qdec.rs b/kernel/src/hil/qdec.rs index f7006b8fb01..ceb1b8e0d6c 100644 --- a/kernel/src/hil/qdec.rs +++ b/kernel/src/hil/qdec.rs @@ -24,5 +24,5 @@ pub trait QdecDriver { /* TODO: change name sometime */ pub trait QdecClient { fn sample_ready (&self, val: u32); - //fn callback(&self, value: usize); + fn callback(&self, value: usize); } From 22199567b817b9f4f1c48f7ee8036fd649553b49 Mon Sep 17 00:00:00 2001 From: mmurray22 Date: Thu, 2 Apr 2020 14:54:25 -0400 Subject: [PATCH 14/39] qdec changes --- capsules/src/qdec.rs | 3 ++- chips/nrf52/src/qdec.rs | 15 +++++++++++++-- kernel/src/hil/qdec.rs | 7 +++---- 3 files changed, 18 insertions(+), 7 deletions(-) diff --git a/capsules/src/qdec.rs b/capsules/src/qdec.rs index b03fd44e9a5..7054dc068a4 100644 --- a/capsules/src/qdec.rs +++ b/capsules/src/qdec.rs @@ -53,7 +53,8 @@ impl QdecInterface<'a> { fn get_qdec_acc(&self) -> u32 { - self.driver.get_acc() + self.driver.set_sample_rate(); + self.driver.get_acc() } fn configure_callback(&self, callback: Option, app_id: AppId) -> ReturnCode { diff --git a/chips/nrf52/src/qdec.rs b/chips/nrf52/src/qdec.rs index e79d4021465..4a214a78605 100644 --- a/chips/nrf52/src/qdec.rs +++ b/chips/nrf52/src/qdec.rs @@ -224,7 +224,11 @@ impl Qdec { 4 => Inte::STOPPED::SET, _ => Inte::STOPPED::SET, //TODO throw an error? }; - self.registers.intenclr.write(interrupt_bit); + if i == 0 { + self.registers.intenclr.write(interrupt_bit); + } else if i == 4 { + debug!("Received stopped signal!"); + } } } let regs = &*self.registers; @@ -272,6 +276,7 @@ impl Qdec { } } + //TODO: FIX SPACING! impl kernel::hil::qdec::QdecDriver for Qdec { fn enable_interrupts_qdec (&self) { @@ -280,11 +285,17 @@ impl kernel::hil::qdec::QdecDriver for Qdec { fn enable_qdec (&self) -> ReturnCode { //Maybe expose to HIL - self.registers.sample_per.write(SampPer::SAMPLEPER::ms131); + //self.registers.sample_per.write(SampPer::SAMPLEPER::ms131); self.enable(); self.is_enabled() } + fn set_sample_rate (&self) { + self.registers.intenset.write(Inte::STOPPED::SET); + self.registers.sample_per.write(SampPer::SAMPLEPER::ms131); + self.registers.intenclr.write(Inte::STOPPED::SET); + } + fn get_acc(&self) -> u32 { let regs = &*self.registers; //self.enable_interrupts(); diff --git a/kernel/src/hil/qdec.rs b/kernel/src/hil/qdec.rs index ceb1b8e0d6c..84ed15c6d4e 100644 --- a/kernel/src/hil/qdec.rs +++ b/kernel/src/hil/qdec.rs @@ -12,10 +12,9 @@ pub trait QdecDriver { /* TODO: change name sometime */ fn set_client(&self, client: &'static dyn QdecClient); fn enable_interrupts_qdec (&self); - /*fn enable(&self); - - fn is_enabled (&self) -> ReturnCode;*/ - + + fn set_sample_rate (&self); + fn enable_qdec (&self) -> ReturnCode; fn get_acc (&self) -> u32; From 4dec2ed26cac2c0af93690c629e16c5a348c83ce Mon Sep 17 00:00:00 2001 From: mmurray22 Date: Wed, 8 Apr 2020 22:46:49 -0700 Subject: [PATCH 15/39] Kernel hil seems complete. --- capsules/src/qdec.rs | 42 +++++++---------------------------------- chips/nrf52/src/qdec.rs | 14 +++----------- kernel/src/hil/qdec.rs | 13 ++++--------- 3 files changed, 14 insertions(+), 55 deletions(-) diff --git a/capsules/src/qdec.rs b/capsules/src/qdec.rs index 7054dc068a4..e63fada31be 100644 --- a/capsules/src/qdec.rs +++ b/capsules/src/qdec.rs @@ -11,7 +11,7 @@ pub const DRIVER_NUM: usize = driver::NUM::Qdec as usize; pub struct QdecInterface<'a> { driver: &'a dyn hil::qdec::QdecDriver, apps: Grant, - busy: Cell, + curr_acc: u32, } #[derive(Default)] @@ -28,36 +28,12 @@ impl QdecInterface<'a> { QdecInterface { driver: driver, apps: grant, - busy: Cell::new(false), + curr_acc: 0, } } - - fn enable_qdec_command(&self, appid: AppId) -> ReturnCode { - self.driver.enable_qdec() - } - - fn enable_qdec_interrupts(&self, appid: AppId) -> ReturnCode { - self.apps - .enter(appid, |app, _| { - if !self.busy.get() { - app.subscribed = true; - self.busy.set(true); - self.driver.enable_interrupts_qdec(); //TODO names - ReturnCode::SUCCESS - } else { - ReturnCode::EBUSY - } - }) - .unwrap_or_else(|err| err.into()) - } - - - fn get_qdec_acc(&self) -> u32 { - self.driver.set_sample_rate(); - self.driver.get_acc() - } fn configure_callback(&self, callback: Option, app_id: AppId) -> ReturnCode { + self.driver.enable_interrupts(); self.apps .enter(app_id, |app, _| { app.callback = callback; @@ -68,20 +44,16 @@ impl QdecInterface<'a> { } impl hil::qdec::QdecClient for QdecInterface<'a> { - fn callback(&self, qdec_val: usize) { + fn sample_rate (&self, qdec_val: usize) { for cntr in self.apps.iter() { cntr.enter(|app, _| { if app.subscribed { - self.busy.set(false); + self.driver.get_acc(); /*TODO*/ app.subscribed = false; app.callback.map(|mut cb| cb.schedule(qdec_val, 0,0)); } }); } } - - fn sample_ready (&self, acc:u32) { //TODO go back and change name - debug!("Val:{:?}", acc); - } } impl Driver for QdecInterface<'a> { @@ -103,13 +75,13 @@ impl Driver for QdecInterface<'a> { //dummy value 0 => ReturnCode::SUCCESS, // enable qdec - 1 => self.enable_qdec_command (appid), + 1 => self.driver.enable(), // enable interrupts 2 => self.enable_qdec_interrupts (appid), //get qdec acc 3 => ReturnCode::SuccessWithValue{ - value: self.get_qdec_acc() as usize, + value: self.get_acc() as usize, }, //default _ => ReturnCode::ENOSUPPORT diff --git a/chips/nrf52/src/qdec.rs b/chips/nrf52/src/qdec.rs index 4a214a78605..7b8c5ac0e2a 100644 --- a/chips/nrf52/src/qdec.rs +++ b/chips/nrf52/src/qdec.rs @@ -194,11 +194,9 @@ impl Qdec { ); } - pub fn set_client(&self, client: &'static dyn kernel::hil::qdec::QdecClient) { self.client.set(client); } - /// When an interrupt occurs, check to see if any /// of the interrupt register bits are set. If it @@ -232,11 +230,8 @@ impl Qdec { } } let regs = &*self.registers; - //self.enable_interrupts(); regs.tasks_readclracc.write(Task::ENABLE::SET); let val_ret = regs.acc_read.read(Acc::ACC); - //TODO things - debug!("Val!!"); client.sample_ready (val_ret); }); self.enable_interrupts(); @@ -246,10 +241,7 @@ impl Qdec { fn enable_interrupts(&self) { //IS THIS THE RIGHT MACRO TO USE? let regs = &*self.registers; regs.intenset.write(Inte::SAMPLERDY::SET); - regs.intenset.write(Inte::REPORTRDY::SET); - regs.intenset.write(Inte::ACCOF::SET); - regs.intenset.write(Inte::DBLRDY::SET); - regs.intenset.write(Inte::STOPPED::SET); + regs.intenset.write(Inte::STOPPED::SET); /*SET SAMPLE READY*/ } fn disable_interrupts(&self) { @@ -260,7 +252,7 @@ impl Qdec { fn enable(&self) { let regs = &*self.registers; regs.enable.write(Task::ENABLE::SET); - regs.sample_per.write(SampPer::SAMPLEPER.val(5)); + regs.sample_per.write(SampPer::SAMPLEPER.val(5)); /*Taken care of?*/ regs.tasks_start.write(Task::ENABLE::SET); debug!("Enabled!"); } @@ -279,7 +271,7 @@ impl Qdec { //TODO: FIX SPACING! impl kernel::hil::qdec::QdecDriver for Qdec { - fn enable_interrupts_qdec (&self) { + fn enable_interrupts (&self) { self.enable_interrupts(); } diff --git a/kernel/src/hil/qdec.rs b/kernel/src/hil/qdec.rs index 84ed15c6d4e..cf461bd6598 100644 --- a/kernel/src/hil/qdec.rs +++ b/kernel/src/hil/qdec.rs @@ -7,21 +7,16 @@ use crate::returncode::ReturnCode; -pub trait QdecDriver { /* TODO: change name sometime */ - +pub trait QdecDriver { fn set_client(&self, client: &'static dyn QdecClient); - fn enable_interrupts_qdec (&self); - - fn set_sample_rate (&self); + fn enable_interrupts (&self); - fn enable_qdec (&self) -> ReturnCode; + fn enable (&self) -> ReturnCode; fn get_acc (&self) -> u32; } pub trait QdecClient { - fn sample_ready (&self, val: u32); - - fn callback(&self, value: usize); + fn sample_ready (&self); } From 69d0f544b4ade1d6fb92e6f7f7997ca1f1f8fc31 Mon Sep 17 00:00:00 2001 From: mmurray22 Date: Thu, 9 Apr 2020 00:11:57 -0700 Subject: [PATCH 16/39] Edits to capsule-seems sufficient? --- capsules/src/qdec.rs | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/capsules/src/qdec.rs b/capsules/src/qdec.rs index e63fada31be..bde20730e02 100644 --- a/capsules/src/qdec.rs +++ b/capsules/src/qdec.rs @@ -44,11 +44,11 @@ impl QdecInterface<'a> { } impl hil::qdec::QdecClient for QdecInterface<'a> { - fn sample_rate (&self, qdec_val: usize) { + fn sample_ready (&self, qdec_val: usize) { for cntr in self.apps.iter() { cntr.enter(|app, _| { if app.subscribed { - self.driver.get_acc(); /*TODO*/ + self.curr_acc = self.driver.get_acc(); app.subscribed = false; app.callback.map(|mut cb| cb.schedule(qdec_val, 0,0)); } }); @@ -74,15 +74,18 @@ impl Driver for QdecInterface<'a> { match command_num { //dummy value 0 => ReturnCode::SUCCESS, - // enable qdec + //enable qdec 1 => self.driver.enable(), - // enable interrupts - 2 => self.enable_qdec_interrupts (appid), //get qdec acc - 3 => - ReturnCode::SuccessWithValue{ + 2 => + ReturnCode::SuccessWithValue { value: self.get_acc() as usize, }, + // + /*TODO: any others? 3 => + ReturnCode::SuccessWithValue { + value: + }*/ //default _ => ReturnCode::ENOSUPPORT } From 4d93ab93af8ef47eb963c0260c93dc271b79b25c Mon Sep 17 00:00:00 2001 From: mmurray22 Date: Thu, 9 Apr 2020 11:17:03 -0700 Subject: [PATCH 17/39] Changes to driver-1/2 done --- chips/nrf52/src/qdec.rs | 24 ++++++++++++++++++------ 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/chips/nrf52/src/qdec.rs b/chips/nrf52/src/qdec.rs index 7b8c5ac0e2a..f48b0947f1b 100644 --- a/chips/nrf52/src/qdec.rs +++ b/chips/nrf52/src/qdec.rs @@ -205,6 +205,7 @@ impl Qdec { /// TODO: ADD CLIENT CODE TO HIL/CAPSULE/LIB pub fn handle_interrupt(&self) { self.disable_interrupts(); + let regs = &*self.registers; self.client.map(|client| { let mut val = 0; // For each of 4 possible compare events, if it's happened, @@ -216,20 +217,24 @@ impl Qdec { // Disable corresponding interrupt let interrupt_bit = match i { 0 => Inte::SAMPLERDY::SET, - 1 => Inte::REPORTRDY::SET, - 2 => Inte::ACCOF::SET, - 3 => Inte::DBLRDY::SET, + //1 => Inte::REPORTRDY::SET, + //2 => Inte::ACCOF::SET, + //3 => Inte::DBLRDY::SET, 4 => Inte::STOPPED::SET, _ => Inte::STOPPED::SET, //TODO throw an error? }; if i == 0 { self.registers.intenclr.write(interrupt_bit); + regs.tasks_readclracc.write(Task::ENABLE::SET); + let val_ret = regs.acc_read.read(Acc::ACC); + client.sample_ready (val_ret); } else if i == 4 { debug!("Received stopped signal!"); + regs.sample_per.write(SampPer::SAMPLEPER.val(5)); } } } - let regs = &*self.registers; + regs.tasks_readclracc.write(Task::ENABLE::SET); let val_ret = regs.acc_read.read(Acc::ACC); client.sample_ready (val_ret); @@ -248,11 +253,17 @@ impl Qdec { let regs = &*self.registers; regs.intenclr.write(Inte::SAMPLERDY::SET); } - + + fn set_sample_rate (&self) { + regs.intenset.write(Inte::STOPPED::SET); + regs.sample_per.write(SampPer::SAMPLEPER.val(5)); + /*TODO*/ + } + fn enable(&self) { let regs = &*self.registers; regs.enable.write(Task::ENABLE::SET); - regs.sample_per.write(SampPer::SAMPLEPER.val(5)); /*Taken care of?*/ + regs.sample_per.write(SampPer::SAMPLEPER.val(5)); regs.tasks_start.write(Task::ENABLE::SET); debug!("Enabled!"); } @@ -279,6 +290,7 @@ impl kernel::hil::qdec::QdecDriver for Qdec { //Maybe expose to HIL //self.registers.sample_per.write(SampPer::SAMPLEPER::ms131); self.enable(); + self.set_sample_rate(); self.is_enabled() } From 7aa0aca9a3a433fa77c6db6ffec927c89d30c15b Mon Sep 17 00:00:00 2001 From: mmurray22 Date: Thu, 9 Apr 2020 12:38:19 -0700 Subject: [PATCH 18/39] chips and capsule code updated-need to test functionality --- capsules/src/qdec.rs | 5 ++--- chips/nrf52/src/qdec.rs | 34 ++++++++++++++++++---------------- 2 files changed, 20 insertions(+), 19 deletions(-) diff --git a/capsules/src/qdec.rs b/capsules/src/qdec.rs index bde20730e02..11a55fc12db 100644 --- a/capsules/src/qdec.rs +++ b/capsules/src/qdec.rs @@ -44,13 +44,12 @@ impl QdecInterface<'a> { } impl hil::qdec::QdecClient for QdecInterface<'a> { - fn sample_ready (&self, qdec_val: usize) { + fn sample_ready (&self) { for cntr in self.apps.iter() { cntr.enter(|app, _| { if app.subscribed { - self.curr_acc = self.driver.get_acc(); app.subscribed = false; - app.callback.map(|mut cb| cb.schedule(qdec_val, 0,0)); } + app.callback.map(|mut cb| cb.schedule(self.driver.get_acc(), 0,0)); } }); } } diff --git a/chips/nrf52/src/qdec.rs b/chips/nrf52/src/qdec.rs index f48b0947f1b..dff147990b6 100644 --- a/chips/nrf52/src/qdec.rs +++ b/chips/nrf52/src/qdec.rs @@ -166,10 +166,17 @@ const QDEC_BASE: StaticRef = pub static mut QDEC: Qdec = Qdec::new(); +enum QdecState { + SAMPLE_RATE_STOP, + START, +} + /// Qdec type declaration: gives the Qdec instance registers and a client pub struct Qdec { registers: StaticRef, client: OptionalCell<&'static dyn kernel::hil::qdec::QdecClient>, + state: QdecState, /*correct enum declaration?*/ + sample_rate: u32, } /// Qdec impl: provides the Qdec type with vital functionality including: @@ -180,6 +187,7 @@ impl Qdec { let qdec = Qdec { registers: QDEC_BASE, client: OptionalCell::empty(), + state: QdecState::START, }; qdec } @@ -221,29 +229,23 @@ impl Qdec { //2 => Inte::ACCOF::SET, //3 => Inte::DBLRDY::SET, 4 => Inte::STOPPED::SET, - _ => Inte::STOPPED::SET, //TODO throw an error? + _ => panic!("Unknown interrupt value!"), }; if i == 0 { - self.registers.intenclr.write(interrupt_bit); - regs.tasks_readclracc.write(Task::ENABLE::SET); - let val_ret = regs.acc_read.read(Acc::ACC); - client.sample_ready (val_ret); - } else if i == 4 { + client.sample_ready (); + } else if i == 4 && self.qdec.state == SAMPLE_RATE_STOP { debug!("Received stopped signal!"); regs.sample_per.write(SampPer::SAMPLEPER.val(5)); + regs.task_start.write(Task::ENABLE::SET); } } } - - regs.tasks_readclracc.write(Task::ENABLE::SET); - let val_ret = regs.acc_read.read(Acc::ACC); - client.sample_ready (val_ret); }); self.enable_interrupts(); } // NOTE: ALL INTERRUPTS ARE ONLY FOR SAMPLING RIGHT NOW - fn enable_interrupts(&self) { //IS THIS THE RIGHT MACRO TO USE? + fn enable_interrupts(&self) { let regs = &*self.registers; regs.intenset.write(Inte::SAMPLERDY::SET); regs.intenset.write(Inte::STOPPED::SET); /*SET SAMPLE READY*/ @@ -254,16 +256,16 @@ impl Qdec { regs.intenclr.write(Inte::SAMPLERDY::SET); } - fn set_sample_rate (&self) { - regs.intenset.write(Inte::STOPPED::SET); - regs.sample_per.write(SampPer::SAMPLEPER.val(5)); - /*TODO*/ + fn set_sample_rate (&self) { + regs.task_stop.write(Task::ENABLE::SET); + self.qdec.state = SAMPLE_RATE_STOP; + regs.tasks_stop.write(Task::ENABLE::SET); /*induce stop*/ } fn enable(&self) { let regs = &*self.registers; regs.enable.write(Task::ENABLE::SET); - regs.sample_per.write(SampPer::SAMPLEPER.val(5)); + set_sample_rate(); /*set sample rate to maximum sample rate*/ regs.tasks_start.write(Task::ENABLE::SET); debug!("Enabled!"); } From 57038afe60c5fe42463f6e3e1e6e1ee4366683c9 Mon Sep 17 00:00:00 2001 From: mmurray22 Date: Sun, 12 Apr 2020 10:25:15 -0700 Subject: [PATCH 19/39] Final changes before very first commit --- capsules/src/qdec.rs | 51 +++++++++++++++++++++++++++++------------- kernel/src/hil/qdec.rs | 16 ++++++++----- 2 files changed, 46 insertions(+), 21 deletions(-) diff --git a/capsules/src/qdec.rs b/capsules/src/qdec.rs index 11a55fc12db..c793c4c3c76 100644 --- a/capsules/src/qdec.rs +++ b/capsules/src/qdec.rs @@ -1,4 +1,24 @@ -//! Capsule for QDEC +//! Provides userspace access to the Qdec on a board. +//! +//! Usage +//! ----- +//! +//! ```` +//! let qdec = static_init!( +//! capsules::qdec::Qdec<'static>, +//! capsules::qdec::QdecInterface::new(&nrf52::qdec::QDEC, +//! kernel::Grant::create()) +//! ); +//! kernel::hil::QdecDriver.set_client(qdec); +//! ```` +//! +//! #Number of Qdecs +//! The number of qdecs available depends on the +//! board/microcontroller +//! +//! #Interrupt Spurred Readings versus Regular Readings +//! An application can either enable interrupts to get the +//! accumulation value or manually read it whenever it wants use crate::driver; use kernel::hil; @@ -8,31 +28,34 @@ use kernel::{AppId, Callback, ReturnCode, Driver, Grant}; pub const DRIVER_NUM: usize = driver::NUM::Qdec as usize; +/// This struct contains the resources necessary for the QdecInterface pub struct QdecInterface<'a> { driver: &'a dyn hil::qdec::QdecDriver, apps: Grant, - curr_acc: u32, } #[derive(Default)] +/// This struct contains the necessary fields for an app pub struct App { callback: Option, subscribed: bool, } impl QdecInterface<'a> { + /// Create a new instance of the QdecInterface pub fn new ( - driver: &'a dyn hil::qdec::QdecDriver, + driver: &'a dyn hil::qdec::QdecDriver, grant: Grant, ) -> QdecInterface<'a> { QdecInterface { driver: driver, apps: grant, - curr_acc: 0, } } - fn configure_callback(&self, callback: Option, app_id: AppId) -> ReturnCode { + /// Configure callback + fn configure_callback(&self, callback: Option, app_id: AppId) + -> ReturnCode { self.driver.enable_interrupts(); self.apps .enter(app_id, |app, _| { @@ -44,6 +67,8 @@ impl QdecInterface<'a> { } impl hil::qdec::QdecClient for QdecInterface<'a> { + /// Goes through all the apps and if the app is + /// subscribed then it sends back the acc value fn sample_ready (&self) { for cntr in self.apps.iter() { cntr.enter(|app, _| { @@ -56,6 +81,7 @@ impl hil::qdec::QdecClient for QdecInterface<'a> { } impl Driver for QdecInterface<'a> { + /// Subscribes a client to (newly enabled) interrupts fn subscribe( &self, subscribe_num: usize, @@ -63,29 +89,24 @@ impl Driver for QdecInterface<'a> { app_id: AppId, ) -> ReturnCode { match subscribe_num { - // subscribe to qdec reading with callback 0 => self.configure_callback(callback, app_id), _ => ReturnCode::ENOSUPPORT, } } + /// Command switch statement for various essential processes fn command (&self, command_num: usize, _: usize, _: usize, appid: AppId) -> ReturnCode { match command_num { - //dummy value + /// dummy value 0 => ReturnCode::SUCCESS, - //enable qdec + /// enable qdec 1 => self.driver.enable(), - //get qdec acc + /// get qdec acc 2 => ReturnCode::SuccessWithValue { value: self.get_acc() as usize, }, - // - /*TODO: any others? 3 => - ReturnCode::SuccessWithValue { - value: - }*/ - //default + /// default _ => ReturnCode::ENOSUPPORT } } diff --git a/kernel/src/hil/qdec.rs b/kernel/src/hil/qdec.rs index cf461bd6598..b52ff3b642b 100644 --- a/kernel/src/hil/qdec.rs +++ b/kernel/src/hil/qdec.rs @@ -1,22 +1,26 @@ -/// A basic interface for a QDEC compatible chip -/// -/// This trait provides a stanfard interface for chips that -/// contain a quadrature encoder. Any interface functions that -/// a chip cannot implement can be ignored by the chip capsule -/// and an error will automatically be returned. +//! Interface for a Qdec compatible chip +//! +//! This trait provides a stanfard interface for chips a +//! quadrature decoder. Any interface functions that +//! a chip cannot implement can be ignored by the chip capsule use crate::returncode::ReturnCode; pub trait QdecDriver { + /// Sets the client which will receive interrupts fn set_client(&self, client: &'static dyn QdecClient); + /// Enables the SAMPLERDY interrupt fn enable_interrupts (&self); + /// Enables the Qdec, returning error if Qdec does not exist fn enable (&self) -> ReturnCode; + /// Gets the accumulation value fn get_acc (&self) -> u32; } pub trait QdecClient { + /// Callback function fn sample_ready (&self); } From 926a4f9de84f94a1278863dabb8327fcbe359302 Mon Sep 17 00:00:00 2001 From: mmurray22 Date: Mon, 13 Apr 2020 21:58:29 -0700 Subject: [PATCH 20/39] First rough draft PR suggestions --- boards/nordic/nrf52dk_base/src/lib.rs | 8 ------ boards/nordic/nrf52dk_base/src/qdec_test.rs | 4 --- capsules/README.md | 2 +- capsules/src/qdec.rs | 6 ---- chips/nrf52/src/qdec.rs | 32 +++++++++------------ chips/nrf5x/src/references.txt | 13 --------- kernel/src/hil/qdec.rs | 4 +-- qdec_questions.txt | 5 ---- 8 files changed, 16 insertions(+), 58 deletions(-) delete mode 100644 chips/nrf5x/src/references.txt delete mode 100644 qdec_questions.txt diff --git a/boards/nordic/nrf52dk_base/src/lib.rs b/boards/nordic/nrf52dk_base/src/lib.rs index f9decf1a7bf..5bf22803f3d 100644 --- a/boards/nordic/nrf52dk_base/src/lib.rs +++ b/boards/nordic/nrf52dk_base/src/lib.rs @@ -1,7 +1,6 @@ //! Shared setup for nrf52dk boards. #![no_std] -#![allow(dead_code)] #[allow(unused_imports)] use kernel::{create_capability, debug, debug_gpio, debug_verbose, static_init}; use capsules::virtual_alarm::VirtualMuxAlarm; @@ -16,7 +15,6 @@ use nrf52::rtc::Rtc; use nrf52::uicr::Regulator0Output; use kernel::common::dynamic_deferred_call::{DynamicDeferredCall, DynamicDeferredCallClientState}; -//pub mod qdec_test; pub mod nrf52_components; use nrf52_components::ble::BLEComponent; use nrf52_components::ieee802154::Ieee802154Component; @@ -107,7 +105,6 @@ pub struct Platform { // The nRF52dk does not have the flash chip on it, so we make this optional. nonvolatile_storage: Option<&'static capsules::nonvolatile_storage_driver::NonvolatileStorage<'static>>, - qdec: &'static capsules::qdec::QdecInterface<'static>, //_ => f(None), } @@ -463,11 +460,6 @@ pub unsafe fn setup_board( board_kernel.create_grant(&memory_allocation_capability) ) ); - kernel::hil::qdec::QdecDriver::set_client(qdec_nrf52, qdec); - //let qdec_test = qdec_test::initialize_all(mux_alarm, qdec_nrf52); - //qdec_nrf52.set_client(qdec_test); - //debug!("Testing: Qdec Initialized!"); TODO DELETE DEBUG STATEMENTS - //END: QDEC INITIALIZATION let platform = Platform { button: button, diff --git a/boards/nordic/nrf52dk_base/src/qdec_test.rs b/boards/nordic/nrf52dk_base/src/qdec_test.rs index a4dd8d4ebe1..0d76672fdc9 100644 --- a/boards/nordic/nrf52dk_base/src/qdec_test.rs +++ b/boards/nordic/nrf52dk_base/src/qdec_test.rs @@ -2,10 +2,6 @@ use capsules::virtual_alarm::{MuxAlarm, VirtualMuxAlarm}; use kernel::hil::time; use kernel::hil::time::{Alarm, Frequency}; -use kernel::{debug, static_init}; -use nrf52::qdec::Qdec; -use kernel::hil::qdec::QdecDriver; -//use nrf5x::pinmux; pub const TEST_DELAY_MS: u32 = 1000; diff --git a/capsules/README.md b/capsules/README.md index 41b9780a758..6ab2e69c6b0 100644 --- a/capsules/README.md +++ b/capsules/README.md @@ -81,7 +81,7 @@ These capsules provide a `Driver` interface for common MCU peripherals. - **[I2C_MASTER_SLAVE](src/i2c_master_slave_driver.rs)**: I2C master and slave access. - **[RNG](src/rng.rs)**: Random number generation. - **[SPI](src/spi.rs)**: SPI master and slave. -- **[QDEC](src/qdec.rs)**: QDEC for quadrature-encoded sensor signals +- **[QDEC](src/qdec.rs)**: Quadrature DECoder for quadrature-encoded sensor signals ### Helpful Userspace Capsules diff --git a/capsules/src/qdec.rs b/capsules/src/qdec.rs index c793c4c3c76..3a8569d0ff9 100644 --- a/capsules/src/qdec.rs +++ b/capsules/src/qdec.rs @@ -11,11 +11,6 @@ //! ); //! kernel::hil::QdecDriver.set_client(qdec); //! ```` -//! -//! #Number of Qdecs -//! The number of qdecs available depends on the -//! board/microcontroller -//! //! #Interrupt Spurred Readings versus Regular Readings //! An application can either enable interrupts to get the //! accumulation value or manually read it whenever it wants @@ -53,7 +48,6 @@ impl QdecInterface<'a> { } } - /// Configure callback fn configure_callback(&self, callback: Option, app_id: AppId) -> ReturnCode { self.driver.enable_interrupts(); diff --git a/chips/nrf52/src/qdec.rs b/chips/nrf52/src/qdec.rs index dff147990b6..3a61fe851ec 100644 --- a/chips/nrf52/src/qdec.rs +++ b/chips/nrf52/src/qdec.rs @@ -73,7 +73,7 @@ register_structs! { } // In this section, I initialize all the bitfields associated with the type -// of register assigned to each member of the struct above. (is that right?) +// of register assigned to each member of the struct above. register_bitfields![u32, Task [ ENABLE 0 @@ -175,14 +175,12 @@ enum QdecState { pub struct Qdec { registers: StaticRef, client: OptionalCell<&'static dyn kernel::hil::qdec::QdecClient>, - state: QdecState, /*correct enum declaration?*/ + state: QdecState, sample_rate: u32, } /// Qdec impl: provides the Qdec type with vital functionality including: -/// FIRST DESIRED FUNCTIONALITY: new(arg1, arg2, ..., argN) -> define Qdec struct impl Qdec { - //TODO ok to be safe const fn new() -> Qdec { let qdec = Qdec { registers: QDEC_BASE, @@ -192,6 +190,7 @@ impl Qdec { qdec } + /// sets pins_a and pins_b to be the output pins for whatever the encoding device is pub fn set_pins(&self, pin_a: pinmux::Pinmux, pin_b: pinmux::Pinmux) { let regs = self.registers; regs.psel_a.write( @@ -209,8 +208,6 @@ impl Qdec { /// When an interrupt occurs, check to see if any /// of the interrupt register bits are set. If it /// is, then put it in the client's bitmask - /// TODO: DO I NEED TO DISABLE INTERRUPTS - /// TODO: ADD CLIENT CODE TO HIL/CAPSULE/LIB pub fn handle_interrupt(&self) { self.disable_interrupts(); let regs = &*self.registers; @@ -218,7 +215,7 @@ impl Qdec { let mut val = 0; // For each of 4 possible compare events, if it's happened, // clear it and sort its bit in val to pass in callback - for i in 0..4 { // TODO: either add events_compare or add each individual register + for i in 0..regs.events_arr.len() { if self.registers.events_arr[i].is_set(Event::READY) { val = val | 1 << i; self.registers.events_arr[i].write(Event::READY::CLEAR); @@ -229,14 +226,14 @@ impl Qdec { //2 => Inte::ACCOF::SET, //3 => Inte::DBLRDY::SET, 4 => Inte::STOPPED::SET, - _ => panic!("Unknown interrupt value!"), + _ => panic!("Unsupported interrupt value!"), }; - if i == 0 { + if interrupt_bit == 0 { client.sample_ready (); - } else if i == 4 && self.qdec.state == SAMPLE_RATE_STOP { - debug!("Received stopped signal!"); + } else if interrupt_bit == 4 && self.qdec.state == SAMPLE_RATE_STOP { regs.sample_per.write(SampPer::SAMPLEPER.val(5)); regs.task_start.write(Task::ENABLE::SET); + self.qdec.state = START; } } } @@ -244,14 +241,12 @@ impl Qdec { self.enable_interrupts(); } - // NOTE: ALL INTERRUPTS ARE ONLY FOR SAMPLING RIGHT NOW - fn enable_interrupts(&self) { + fn enable_samplerdy_interrupts(&self) { let regs = &*self.registers; - regs.intenset.write(Inte::SAMPLERDY::SET); - regs.intenset.write(Inte::STOPPED::SET); /*SET SAMPLE READY*/ + regs.intenset.write(Inte::SAMPLERDY::SET); /*SET SAMPLE READY*/ } - fn disable_interrupts(&self) { + fn disable_samplerdy_interrupts(&self) { let regs = &*self.registers; regs.intenclr.write(Inte::SAMPLERDY::SET); } @@ -265,7 +260,7 @@ impl Qdec { fn enable(&self) { let regs = &*self.registers; regs.enable.write(Task::ENABLE::SET); - set_sample_rate(); /*set sample rate to maximum sample rate*/ + set_sample_rate(); regs.tasks_start.write(Task::ENABLE::SET); debug!("Enabled!"); } @@ -280,9 +275,8 @@ impl Qdec { result } -} +} -//TODO: FIX SPACING! impl kernel::hil::qdec::QdecDriver for Qdec { fn enable_interrupts (&self) { self.enable_interrupts(); diff --git a/chips/nrf5x/src/references.txt b/chips/nrf5x/src/references.txt deleted file mode 100644 index 15a53a18166..00000000000 --- a/chips/nrf5x/src/references.txt +++ /dev/null @@ -1,13 +0,0 @@ -& -> this is a regular reference to a regular string (i.e. immutable) - -mut & -> this is a mutable reference to a mutable string - -can only have one mutable reference to a piece of data in - a particular scope - - -also rules about combining mutable and immutable references - to a mutable object - -compiler guarantees dangling references: for example, cannot declare -string within function then return reference to string - - diff --git a/kernel/src/hil/qdec.rs b/kernel/src/hil/qdec.rs index b52ff3b642b..9787486535d 100644 --- a/kernel/src/hil/qdec.rs +++ b/kernel/src/hil/qdec.rs @@ -1,6 +1,6 @@ //! Interface for a Qdec compatible chip //! -//! This trait provides a stanfard interface for chips a +//! This trait provides a stanfard interface for chips with a //! quadrature decoder. Any interface functions that //! a chip cannot implement can be ignored by the chip capsule @@ -16,7 +16,7 @@ pub trait QdecDriver { /// Enables the Qdec, returning error if Qdec does not exist fn enable (&self) -> ReturnCode; - /// Gets the accumulation value + /// Reads the accumulator value and resets it fn get_acc (&self) -> u32; } diff --git a/qdec_questions.txt b/qdec_questions.txt deleted file mode 100644 index 2d06ae63b0c..00000000000 --- a/qdec_questions.txt +++ /dev/null @@ -1,5 +0,0 @@ -Do I need to implement an HIL for the QDEC? - -Since QDEC is going to be a capsule, it will need to be taken into acconut in the hardware-interface-layer right? - - From 0239252f9a5f4cab7ff77be514fd827279c00ff7 Mon Sep 17 00:00:00 2001 From: mmurray22 Date: Mon, 13 Apr 2020 22:03:59 -0700 Subject: [PATCH 21/39] Some more PR changes --- chips/nrf52/src/qdec.rs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/chips/nrf52/src/qdec.rs b/chips/nrf52/src/qdec.rs index 3a61fe851ec..9b9404f883c 100644 --- a/chips/nrf52/src/qdec.rs +++ b/chips/nrf52/src/qdec.rs @@ -283,8 +283,6 @@ impl kernel::hil::qdec::QdecDriver for Qdec { } fn enable_qdec (&self) -> ReturnCode { - //Maybe expose to HIL - //self.registers.sample_per.write(SampPer::SAMPLEPER::ms131); self.enable(); self.set_sample_rate(); self.is_enabled() @@ -292,13 +290,13 @@ impl kernel::hil::qdec::QdecDriver for Qdec { fn set_sample_rate (&self) { self.registers.intenset.write(Inte::STOPPED::SET); + /// currently this driver always sets the sample rate to the highest possible value self.registers.sample_per.write(SampPer::SAMPLEPER::ms131); self.registers.intenclr.write(Inte::STOPPED::SET); } fn get_acc(&self) -> u32 { let regs = &*self.registers; - //self.enable_interrupts(); regs.tasks_readclracc.write(Task::ENABLE::SET); regs.acc_read.read(Acc::ACC) } From 7315b2d8e018744789b5f4eb59b5301773f46fa8 Mon Sep 17 00:00:00 2001 From: mmurray22 Date: Fri, 17 Apr 2020 06:10:00 +0800 Subject: [PATCH 22/39] Resolving a lot of issues-still some compilation errors --- capsules/src/qdec.rs | 15 +++++-------- chips/nrf52/src/qdec.rs | 49 +++++++++++++++++------------------------ kernel/src/hil/qdec.rs | 2 +- 3 files changed, 26 insertions(+), 40 deletions(-) diff --git a/capsules/src/qdec.rs b/capsules/src/qdec.rs index 3a8569d0ff9..142eaed63f0 100644 --- a/capsules/src/qdec.rs +++ b/capsules/src/qdec.rs @@ -17,8 +17,6 @@ use crate::driver; use kernel::hil; -use kernel::debug; -use core::cell::Cell; use kernel::{AppId, Callback, ReturnCode, Driver, Grant}; pub const DRIVER_NUM: usize = driver::NUM::Qdec as usize; @@ -68,7 +66,8 @@ impl hil::qdec::QdecClient for QdecInterface<'a> { cntr.enter(|app, _| { if app.subscribed { app.subscribed = false; - app.callback.map(|mut cb| cb.schedule(self.driver.get_acc(), 0,0)); } + //TODO: FIGURE OUT self.driver.get_acc() ->u32 + app.callback.map(|mut cb| cb.schedule(self.driver.get_acc() as usize,0,0)); } }); } } @@ -89,18 +88,14 @@ impl Driver for QdecInterface<'a> { } /// Command switch statement for various essential processes - fn command (&self, command_num: usize, _: usize, _: usize, appid: AppId) -> ReturnCode { + fn command (&self, command_num: usize, _: usize, _: usize, _app_id: AppId) -> ReturnCode { match command_num { - /// dummy value 0 => ReturnCode::SUCCESS, - /// enable qdec - 1 => self.driver.enable(), - /// get qdec acc + 1 => self.driver.enable_qdec(), 2 => ReturnCode::SuccessWithValue { - value: self.get_acc() as usize, + value: self.driver.get_acc() as usize, }, - /// default _ => ReturnCode::ENOSUPPORT } } diff --git a/chips/nrf52/src/qdec.rs b/chips/nrf52/src/qdec.rs index 9b9404f883c..2e5a1fb1412 100644 --- a/chips/nrf52/src/qdec.rs +++ b/chips/nrf52/src/qdec.rs @@ -167,8 +167,8 @@ const QDEC_BASE: StaticRef = pub static mut QDEC: Qdec = Qdec::new(); enum QdecState { - SAMPLE_RATE_STOP, - START, + SampleRateStop, + Start, } /// Qdec type declaration: gives the Qdec instance registers and a client @@ -176,7 +176,6 @@ pub struct Qdec { registers: StaticRef, client: OptionalCell<&'static dyn kernel::hil::qdec::QdecClient>, state: QdecState, - sample_rate: u32, } /// Qdec impl: provides the Qdec type with vital functionality including: @@ -185,7 +184,7 @@ impl Qdec { let qdec = Qdec { registers: QDEC_BASE, client: OptionalCell::empty(), - state: QdecState::START, + state: QdecState::Start, }; qdec } @@ -209,7 +208,7 @@ impl Qdec { /// of the interrupt register bits are set. If it /// is, then put it in the client's bitmask pub fn handle_interrupt(&self) { - self.disable_interrupts(); + self.disable_samplerdy_interrupts(); let regs = &*self.registers; self.client.map(|client| { let mut val = 0; @@ -221,24 +220,24 @@ impl Qdec { self.registers.events_arr[i].write(Event::READY::CLEAR); // Disable corresponding interrupt let interrupt_bit = match i { - 0 => Inte::SAMPLERDY::SET, + 0 => Inte::SAMPLERDY, //1 => Inte::REPORTRDY::SET, //2 => Inte::ACCOF::SET, //3 => Inte::DBLRDY::SET, - 4 => Inte::STOPPED::SET, + 4 => Inte::STOPPED, _ => panic!("Unsupported interrupt value!"), }; - if interrupt_bit == 0 { + if interrupt_bit == Inte::SAMPLERDY { client.sample_ready (); - } else if interrupt_bit == 4 && self.qdec.state == SAMPLE_RATE_STOP { - regs.sample_per.write(SampPer::SAMPLEPER.val(5)); - regs.task_start.write(Task::ENABLE::SET); - self.qdec.state = START; + } else if interrupt_bit == Inte::STOPPED /*&& self.state == QdecState::SampleRateStop*/ { + self.registers.sample_per.write(SampPer::SAMPLEPER.val(5)); + self.registers.tasks_start.write(Task::ENABLE::SET); + self.state = &QdecState::Start; } } } }); - self.enable_interrupts(); + self.enable_samplerdy_interrupts(); } fn enable_samplerdy_interrupts(&self) { @@ -251,16 +250,15 @@ impl Qdec { regs.intenclr.write(Inte::SAMPLERDY::SET); } - fn set_sample_rate (&self) { - regs.task_stop.write(Task::ENABLE::SET); - self.qdec.state = SAMPLE_RATE_STOP; - regs.tasks_stop.write(Task::ENABLE::SET); /*induce stop*/ - } - fn enable(&self) { let regs = &*self.registers; regs.enable.write(Task::ENABLE::SET); - set_sample_rate(); + + //set_sample_rate + regs.tasks_stop.write(Task::ENABLE::SET); + self.state = &QdecState::SampleRateStop; + regs.tasks_stop.write(Task::ENABLE::SET); /*induce stop*/ + regs.tasks_start.write(Task::ENABLE::SET); debug!("Enabled!"); } @@ -278,23 +276,16 @@ impl Qdec { } impl kernel::hil::qdec::QdecDriver for Qdec { + fn enable_interrupts (&self) { - self.enable_interrupts(); + self.enable_samplerdy_interrupts(); } fn enable_qdec (&self) -> ReturnCode { self.enable(); - self.set_sample_rate(); self.is_enabled() } - fn set_sample_rate (&self) { - self.registers.intenset.write(Inte::STOPPED::SET); - /// currently this driver always sets the sample rate to the highest possible value - self.registers.sample_per.write(SampPer::SAMPLEPER::ms131); - self.registers.intenclr.write(Inte::STOPPED::SET); - } - fn get_acc(&self) -> u32 { let regs = &*self.registers; regs.tasks_readclracc.write(Task::ENABLE::SET); diff --git a/kernel/src/hil/qdec.rs b/kernel/src/hil/qdec.rs index 9787486535d..f5fe5d90898 100644 --- a/kernel/src/hil/qdec.rs +++ b/kernel/src/hil/qdec.rs @@ -14,7 +14,7 @@ pub trait QdecDriver { fn enable_interrupts (&self); /// Enables the Qdec, returning error if Qdec does not exist - fn enable (&self) -> ReturnCode; + fn enable_qdec (&self) -> ReturnCode; /// Reads the accumulator value and resets it fn get_acc (&self) -> u32; From 71ed2ab8860344b8a9943c36c7e441ee563ab2c4 Mon Sep 17 00:00:00 2001 From: mmurray22 Date: Thu, 23 Apr 2020 11:04:39 +0800 Subject: [PATCH 23/39] All compiles! --- boards/nordic/nrf52dk_base/src/lib.rs | 1 + chips/nrf52/src/qdec.rs | 38 +++++++++++++-------------- 2 files changed, 19 insertions(+), 20 deletions(-) diff --git a/boards/nordic/nrf52dk_base/src/lib.rs b/boards/nordic/nrf52dk_base/src/lib.rs index b6e6a9370cc..b14cc94895a 100644 --- a/boards/nordic/nrf52dk_base/src/lib.rs +++ b/boards/nordic/nrf52dk_base/src/lib.rs @@ -111,6 +111,7 @@ pub struct Platform { 'static, capsules::virtual_alarm::VirtualMuxAlarm<'static, nrf52::rtc::Rtc<'static>>, >, + qdec: &'static capsules::qdec::QdecInterface<'static>, // The nRF52dk does not have the flash chip on it, so we make this optional. nonvolatile_storage: Option<&'static capsules::nonvolatile_storage_driver::NonvolatileStorage<'static>>, diff --git a/chips/nrf52/src/qdec.rs b/chips/nrf52/src/qdec.rs index 2e5a1fb1412..ebcbd8752ba 100644 --- a/chips/nrf52/src/qdec.rs +++ b/chips/nrf52/src/qdec.rs @@ -166,16 +166,16 @@ const QDEC_BASE: StaticRef = pub static mut QDEC: Qdec = Qdec::new(); -enum QdecState { - SampleRateStop, - Start, -} +/*enum QdecState { + SampleRateStop, //1 + Start, //0 +}*/ /// Qdec type declaration: gives the Qdec instance registers and a client pub struct Qdec { registers: StaticRef, client: OptionalCell<&'static dyn kernel::hil::qdec::QdecClient>, - state: QdecState, + state: usize, } /// Qdec impl: provides the Qdec type with vital functionality including: @@ -184,7 +184,7 @@ impl Qdec { let qdec = Qdec { registers: QDEC_BASE, client: OptionalCell::empty(), - state: QdecState::Start, + state: 0, //Start }; qdec } @@ -219,21 +219,19 @@ impl Qdec { val = val | 1 << i; self.registers.events_arr[i].write(Event::READY::CLEAR); // Disable corresponding interrupt - let interrupt_bit = match i { - 0 => Inte::SAMPLERDY, - //1 => Inte::REPORTRDY::SET, - //2 => Inte::ACCOF::SET, - //3 => Inte::DBLRDY::SET, - 4 => Inte::STOPPED, + let _interrupt_bit = match i { + 0 => { + client.sample_ready (); + }, + 4 => { + if self.state == 1 { + self.registers.sample_per.write(SampPer::SAMPLEPER.val(5)); + self.registers.tasks_start.write(Task::ENABLE::SET); + //self.state = 0; + } + }, _ => panic!("Unsupported interrupt value!"), }; - if interrupt_bit == Inte::SAMPLERDY { - client.sample_ready (); - } else if interrupt_bit == Inte::STOPPED /*&& self.state == QdecState::SampleRateStop*/ { - self.registers.sample_per.write(SampPer::SAMPLEPER.val(5)); - self.registers.tasks_start.write(Task::ENABLE::SET); - self.state = &QdecState::Start; - } } } }); @@ -256,7 +254,7 @@ impl Qdec { //set_sample_rate regs.tasks_stop.write(Task::ENABLE::SET); - self.state = &QdecState::SampleRateStop; + //self.state = 1; //SampleRateStop regs.tasks_stop.write(Task::ENABLE::SET); /*induce stop*/ regs.tasks_start.write(Task::ENABLE::SET); From 92507c2c910fbba6aaa05970f2b29fd17f326ef2 Mon Sep 17 00:00:00 2001 From: mmurray22 Date: Thu, 30 Apr 2020 15:01:18 +0800 Subject: [PATCH 24/39] changes --- boards/nordic/nrf52dk_base/src/lib.rs | 2 +- chips/nrf52/src/chip.rs | 2 +- chips/nrf52/src/qdec.rs | 10 ++++------ kernel/src/hil/qdec.rs | 3 +++ 4 files changed, 9 insertions(+), 8 deletions(-) diff --git a/boards/nordic/nrf52dk_base/src/lib.rs b/boards/nordic/nrf52dk_base/src/lib.rs index b14cc94895a..4655d1697c4 100644 --- a/boards/nordic/nrf52dk_base/src/lib.rs +++ b/boards/nordic/nrf52dk_base/src/lib.rs @@ -485,6 +485,6 @@ pub unsafe fn setup_board( app_fault_response, &process_management_capability, ); - + debug!("HELLO PLEASE PRINT THIS!"); board_kernel.kernel_loop(&platform, chip, Some(&platform.ipc), &main_loop_capability); } diff --git a/chips/nrf52/src/chip.rs b/chips/nrf52/src/chip.rs index ba06619a178..612a79bdf03 100644 --- a/chips/nrf52/src/chip.rs +++ b/chips/nrf52/src/chip.rs @@ -4,7 +4,7 @@ use crate::nvmc; // use crate::power; // use crate::spi; // use crate::uart; -use crate::qdec; +// use crate::qdec; use cortexm4::{self, nvic}; use kernel::common::deferred_call; use kernel::debug; diff --git a/chips/nrf52/src/qdec.rs b/chips/nrf52/src/qdec.rs index ebcbd8752ba..c40f61ad2c7 100644 --- a/chips/nrf52/src/qdec.rs +++ b/chips/nrf52/src/qdec.rs @@ -166,11 +166,6 @@ const QDEC_BASE: StaticRef = pub static mut QDEC: Qdec = Qdec::new(); -/*enum QdecState { - SampleRateStop, //1 - Start, //0 -}*/ - /// Qdec type declaration: gives the Qdec instance registers and a client pub struct Qdec { registers: StaticRef, @@ -254,7 +249,6 @@ impl Qdec { //set_sample_rate regs.tasks_stop.write(Task::ENABLE::SET); - //self.state = 1; //SampleRateStop regs.tasks_stop.write(Task::ENABLE::SET); /*induce stop*/ regs.tasks_start.write(Task::ENABLE::SET); @@ -284,6 +278,10 @@ impl kernel::hil::qdec::QdecDriver for Qdec { self.is_enabled() } + fn enabled (&self) -> ReturnCode { + self.is_enabled() + } + fn get_acc(&self) -> u32 { let regs = &*self.registers; regs.tasks_readclracc.write(Task::ENABLE::SET); diff --git a/kernel/src/hil/qdec.rs b/kernel/src/hil/qdec.rs index f5fe5d90898..fdaa2bfa1de 100644 --- a/kernel/src/hil/qdec.rs +++ b/kernel/src/hil/qdec.rs @@ -16,6 +16,9 @@ pub trait QdecDriver { /// Enables the Qdec, returning error if Qdec does not exist fn enable_qdec (&self) -> ReturnCode; + /// Checks if the qdec has been enabled + fn enabled (&self) -> ReturnCode; + /// Reads the accumulator value and resets it fn get_acc (&self) -> u32; } From 5907026eb05d9321189ce05e3d04f40bab5a3667 Mon Sep 17 00:00:00 2001 From: mmurray22 Date: Tue, 5 May 2020 15:43:58 +0800 Subject: [PATCH 25/39] Qdec edits + starting to add new event ACCOF --- boards/nordic/nrf52dk_base/src/lib.rs | 1 - capsules/src/qdec.rs | 20 ++++++++++++++++++-- chips/nrf52/src/qdec.rs | 20 +++++++++++++------- kernel/src/hil/qdec.rs | 6 ++++-- 4 files changed, 35 insertions(+), 12 deletions(-) diff --git a/boards/nordic/nrf52dk_base/src/lib.rs b/boards/nordic/nrf52dk_base/src/lib.rs index 4655d1697c4..4c2792508e9 100644 --- a/boards/nordic/nrf52dk_base/src/lib.rs +++ b/boards/nordic/nrf52dk_base/src/lib.rs @@ -485,6 +485,5 @@ pub unsafe fn setup_board( app_fault_response, &process_management_capability, ); - debug!("HELLO PLEASE PRINT THIS!"); board_kernel.kernel_loop(&platform, chip, Some(&platform.ipc), &main_loop_capability); } diff --git a/capsules/src/qdec.rs b/capsules/src/qdec.rs index 142eaed63f0..a11d2621fa2 100644 --- a/capsules/src/qdec.rs +++ b/capsules/src/qdec.rs @@ -67,7 +67,21 @@ impl hil::qdec::QdecClient for QdecInterface<'a> { if app.subscribed { app.subscribed = false; //TODO: FIGURE OUT self.driver.get_acc() ->u32 - app.callback.map(|mut cb| cb.schedule(self.driver.get_acc() as usize,0,0)); } + app.callback.map(|mut cb| cb.schedule(self.driver.get_acc() as usize,0,0)); + } + }); + } + } + + /// + fn overflow (&self) { + for cntr in self.apps.iter() { + cntr.enter(|app, _| { + if app.subscribed { + app.subscribed = false; + //TODO: FIGURE OUT self.driver.get_acc() ->u32 + app.callback.map(|mut cb| cb.schedule(self.driver.get_acc() as usize,0,0)); + } }); } } @@ -92,7 +106,9 @@ impl Driver for QdecInterface<'a> { match command_num { 0 => ReturnCode::SUCCESS, 1 => self.driver.enable_qdec(), - 2 => + 2 => self.driver.enabled(), + 3 => ReturnCode::SUCCESS,//self.driver.enable_interrupts(), + 4 => ReturnCode::SuccessWithValue { value: self.driver.get_acc() as usize, }, diff --git a/chips/nrf52/src/qdec.rs b/chips/nrf52/src/qdec.rs index c40f61ad2c7..20306bc5442 100644 --- a/chips/nrf52/src/qdec.rs +++ b/chips/nrf52/src/qdec.rs @@ -218,6 +218,9 @@ impl Qdec { 0 => { client.sample_ready (); }, + 2 => { + client.overflow (); + }, 4 => { if self.state == 1 { self.registers.sample_per.write(SampPer::SAMPLEPER.val(5)); @@ -236,11 +239,13 @@ impl Qdec { fn enable_samplerdy_interrupts(&self) { let regs = &*self.registers; regs.intenset.write(Inte::SAMPLERDY::SET); /*SET SAMPLE READY*/ + regs.intenset.write(Inte::ACCOF::SET); /*SET ACCOF READY*/ } fn disable_samplerdy_interrupts(&self) { let regs = &*self.registers; regs.intenclr.write(Inte::SAMPLERDY::SET); + regs.intenclr.write(Inte::ACCOF::SET); } fn enable(&self) { @@ -248,11 +253,8 @@ impl Qdec { regs.enable.write(Task::ENABLE::SET); //set_sample_rate - regs.tasks_stop.write(Task::ENABLE::SET); - regs.tasks_stop.write(Task::ENABLE::SET); /*induce stop*/ - - regs.tasks_start.write(Task::ENABLE::SET); - debug!("Enabled!"); + //regs.tasks_stop.write(Task::ENABLE::SET); /*induce stop*/ + //regs.tasks_start.write(Task::ENABLE::SET); } fn is_enabled(&self) -> ReturnCode { @@ -269,12 +271,16 @@ impl Qdec { impl kernel::hil::qdec::QdecDriver for Qdec { - fn enable_interrupts (&self) { + fn enable_interrupts (&self) -> ReturnCode { self.enable_samplerdy_interrupts(); + debug!("HALLO"); + ReturnCode::SUCCESS } fn enable_qdec (&self) -> ReturnCode { - self.enable(); + if self.is_enabled() != ReturnCode::SUCCESS { + self.enable() + } self.is_enabled() } diff --git a/kernel/src/hil/qdec.rs b/kernel/src/hil/qdec.rs index fdaa2bfa1de..3c321dcfd45 100644 --- a/kernel/src/hil/qdec.rs +++ b/kernel/src/hil/qdec.rs @@ -11,7 +11,7 @@ pub trait QdecDriver { fn set_client(&self, client: &'static dyn QdecClient); /// Enables the SAMPLERDY interrupt - fn enable_interrupts (&self); + fn enable_interrupts (&self) -> ReturnCode; /// Enables the Qdec, returning error if Qdec does not exist fn enable_qdec (&self) -> ReturnCode; @@ -24,6 +24,8 @@ pub trait QdecDriver { } pub trait QdecClient { - /// Callback function + /// Callback function 1 fn sample_ready (&self); + /// Callback function 2 + fn overflow (&self); } From d15b57dc6d4594a297310e4eb3253efde42d3ca3 Mon Sep 17 00:00:00 2001 From: mmurray22 Date: Tue, 12 May 2020 23:53:25 +0800 Subject: [PATCH 26/39] changes for qdec --- boards/nordic/nrf52dk_base/src/lib.rs | 2 +- capsules/src/qdec.rs | 4 +++- chips/nrf52/src/qdec.rs | 1 + 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/boards/nordic/nrf52dk_base/src/lib.rs b/boards/nordic/nrf52dk_base/src/lib.rs index 4c2792508e9..88680e536d9 100644 --- a/boards/nordic/nrf52dk_base/src/lib.rs +++ b/boards/nordic/nrf52dk_base/src/lib.rs @@ -449,7 +449,7 @@ pub unsafe fn setup_board( board_kernel.create_grant(&memory_allocation_capability) ) ); - + let platform = Platform { button: button, ble_radio: ble_radio, diff --git a/capsules/src/qdec.rs b/capsules/src/qdec.rs index a11d2621fa2..698cddbf59e 100644 --- a/capsules/src/qdec.rs +++ b/capsules/src/qdec.rs @@ -17,7 +17,7 @@ use crate::driver; use kernel::hil; -use kernel::{AppId, Callback, ReturnCode, Driver, Grant}; +use kernel::{AppId, Callback, ReturnCode, Driver, Grant, debug}; pub const DRIVER_NUM: usize = driver::NUM::Qdec as usize; @@ -40,6 +40,7 @@ impl QdecInterface<'a> { driver: &'a dyn hil::qdec::QdecDriver, grant: Grant, ) -> QdecInterface<'a> { + driver.enable_interrupts(); QdecInterface { driver: driver, apps: grant, @@ -62,6 +63,7 @@ impl hil::qdec::QdecClient for QdecInterface<'a> { /// Goes through all the apps and if the app is /// subscribed then it sends back the acc value fn sample_ready (&self) { + debug!("HELLO"); for cntr in self.apps.iter() { cntr.enter(|app, _| { if app.subscribed { diff --git a/chips/nrf52/src/qdec.rs b/chips/nrf52/src/qdec.rs index 20306bc5442..c4ccfedbefc 100644 --- a/chips/nrf52/src/qdec.rs +++ b/chips/nrf52/src/qdec.rs @@ -216,6 +216,7 @@ impl Qdec { // Disable corresponding interrupt let _interrupt_bit = match i { 0 => { + debug!("Interrupt handler!"); client.sample_ready (); }, 2 => { From c0e9b0749e165a886a949ae65db2af0048ae542b Mon Sep 17 00:00:00 2001 From: tock Date: Fri, 22 May 2020 05:36:43 +0800 Subject: [PATCH 27/39] In kernel tests work, other things do not, not ready to be used with userspace apps at this time --- boards/nordic/nrf52dk_base/src/lib.rs | 21 ++++++++++++-------- boards/nordic/nrf52dk_base/src/qdec_test.rs | 9 ++++++--- capsules/src/qdec.rs | 13 ++++-------- chips/nrf52/src/qdec.rs | 22 +++++++++++++++------ kernel/src/hil/qdec.rs | 4 ++-- 5 files changed, 41 insertions(+), 28 deletions(-) diff --git a/boards/nordic/nrf52dk_base/src/lib.rs b/boards/nordic/nrf52dk_base/src/lib.rs index 88680e536d9..4608115dae5 100644 --- a/boards/nordic/nrf52dk_base/src/lib.rs +++ b/boards/nordic/nrf52dk_base/src/lib.rs @@ -17,7 +17,7 @@ use nrf52::rtc::Rtc; use nrf52::uicr::Regulator0Output; //use kernel::common::dynamic_deferred_call::{DynamicDeferredCall, DynamicDeferredCallClientState}; - +pub mod qdec_test; pub mod nrf52_components; use nrf52_components::ble::BLEComponent; use nrf52_components::ieee802154::Ieee802154Component; @@ -111,7 +111,7 @@ pub struct Platform { 'static, capsules::virtual_alarm::VirtualMuxAlarm<'static, nrf52::rtc::Rtc<'static>>, >, - qdec: &'static capsules::qdec::QdecInterface<'static>, + //qdec: &'static capsules::qdec::QdecInterface<'static>, // The nRF52dk does not have the flash chip on it, so we make this optional. nonvolatile_storage: Option<&'static capsules::nonvolatile_storage_driver::NonvolatileStorage<'static>>, @@ -130,7 +130,7 @@ impl kernel::Platform for Platform { capsules::led::DRIVER_NUM => f(Some(self.led)), capsules::button::DRIVER_NUM => f(Some(self.button)), capsules::rng::DRIVER_NUM => f(Some(self.rng)), - capsules::qdec::DRIVER_NUM => f(Some(self.qdec)), + //capsules::qdec::DRIVER_NUM => f(Some(self.qdec)), capsules::ble_advertising_driver::DRIVER_NUM => f(Some(self.ble_radio)), capsules::ieee802154::DRIVER_NUM => match self.ieee802154_radio { Some(radio) => f(Some(radio)), @@ -442,14 +442,16 @@ pub unsafe fn setup_board( nrf52::pinmux::Pinmux::new(qdec_pins.pin_a as u32), nrf52::pinmux::Pinmux::new(qdec_pins.pin_b as u32), ); - let qdec = static_init!( + let qdec_test = qdec_test::initialize_all(mux_alarm, qdec_nrf52); + /*let qdec = static_init!( capsules::qdec::QdecInterface<'static>, capsules::qdec::QdecInterface::new( qdec_nrf52, board_kernel.create_grant(&memory_allocation_capability) ) - ); - + );*/ + //kernel::hil::qdec::QdecDriver::set_client(&nrf52::qdec::QDEC, qdec); + let platform = Platform { button: button, ble_radio: ble_radio, @@ -463,13 +465,16 @@ pub unsafe fn setup_board( alarm: alarm, analog_comparator: analog_comparator, nonvolatile_storage: nonvolatile_storage, - qdec: qdec, + //qdec: qdec, ipc: kernel::ipc::IPC::new(board_kernel, &memory_allocation_capability), }; platform.pconsole.start(); debug!("Initialization complete. Entering main loop\r"); - //qdec_test.start(); + debug!("Start of QDEC Janky Test 1"); + debug!("Accumulation value: {}", kernel::hil::qdec::QdecDriver::get_acc(&nrf52::qdec::QDEC)); + qdec_test.start(); + debug!("End of QDEC Janky Test 1"); debug!("{}", &nrf52::ficr::FICR_INSTANCE); extern "C" { diff --git a/boards/nordic/nrf52dk_base/src/qdec_test.rs b/boards/nordic/nrf52dk_base/src/qdec_test.rs index 0d76672fdc9..4f5b8a68da8 100644 --- a/boards/nordic/nrf52dk_base/src/qdec_test.rs +++ b/boards/nordic/nrf52dk_base/src/qdec_test.rs @@ -2,6 +2,9 @@ use capsules::virtual_alarm::{MuxAlarm, VirtualMuxAlarm}; use kernel::hil::time; use kernel::hil::time::{Alarm, Frequency}; +use kernel::{debug, static_init}; +use nrf52::qdec::Qdec; +use kernel::hil::qdec::QdecDriver; pub const TEST_DELAY_MS: u32 = 1000; @@ -37,7 +40,7 @@ impl<'a, A: time::Alarm<'a>> QdecTest<'a, A> { pub fn start(&self) { self.qdec.enable_qdec(); debug!("Is enabled?"); - self.qdec.enable_interrupts_qdec(); + self.qdec.enable_interrupts(); debug!("Is interruptable?"); self.schedule_next(); } @@ -61,7 +64,7 @@ impl<'a, A: time::Alarm<'a>> time::AlarmClient for QdecTest<'a, A> { } impl<'a, A: time::Alarm<'a>> kernel::hil::qdec::QdecClient for QdecTest<'a, A> { - fn sample_ready (&self, acc:u32) { //TODO go back and change name - debug!("Val:{:?}", acc); + fn sample_ready (&self) { //TODO go back and change name + debug!("Val:{:?}", 0); } } diff --git a/capsules/src/qdec.rs b/capsules/src/qdec.rs index 698cddbf59e..f1c2f642128 100644 --- a/capsules/src/qdec.rs +++ b/capsules/src/qdec.rs @@ -40,7 +40,6 @@ impl QdecInterface<'a> { driver: &'a dyn hil::qdec::QdecDriver, grant: Grant, ) -> QdecInterface<'a> { - driver.enable_interrupts(); QdecInterface { driver: driver, apps: grant, @@ -49,7 +48,6 @@ impl QdecInterface<'a> { fn configure_callback(&self, callback: Option, app_id: AppId) -> ReturnCode { - self.driver.enable_interrupts(); self.apps .enter(app_id, |app, _| { app.callback = callback; @@ -63,30 +61,27 @@ impl hil::qdec::QdecClient for QdecInterface<'a> { /// Goes through all the apps and if the app is /// subscribed then it sends back the acc value fn sample_ready (&self) { - debug!("HELLO"); + debug!("Client"); for cntr in self.apps.iter() { cntr.enter(|app, _| { if app.subscribed { app.subscribed = false; - //TODO: FIGURE OUT self.driver.get_acc() ->u32 app.callback.map(|mut cb| cb.schedule(self.driver.get_acc() as usize,0,0)); } }); } } - /// - fn overflow (&self) { + /*fn overflow (&self) { for cntr in self.apps.iter() { cntr.enter(|app, _| { if app.subscribed { app.subscribed = false; - //TODO: FIGURE OUT self.driver.get_acc() ->u32 app.callback.map(|mut cb| cb.schedule(self.driver.get_acc() as usize,0,0)); } }); } - } + }*/ } impl Driver for QdecInterface<'a> { @@ -109,7 +104,7 @@ impl Driver for QdecInterface<'a> { 0 => ReturnCode::SUCCESS, 1 => self.driver.enable_qdec(), 2 => self.driver.enabled(), - 3 => ReturnCode::SUCCESS,//self.driver.enable_interrupts(), + 3 => self.driver.enable_interrupts(), 4 => ReturnCode::SuccessWithValue { value: self.driver.get_acc() as usize, diff --git a/chips/nrf52/src/qdec.rs b/chips/nrf52/src/qdec.rs index c4ccfedbefc..0085486b508 100644 --- a/chips/nrf52/src/qdec.rs +++ b/chips/nrf52/src/qdec.rs @@ -203,6 +203,7 @@ impl Qdec { /// of the interrupt register bits are set. If it /// is, then put it in the client's bitmask pub fn handle_interrupt(&self) { + debug!("Entering Interrupt Handler!"); self.disable_samplerdy_interrupts(); let regs = &*self.registers; self.client.map(|client| { @@ -220,7 +221,8 @@ impl Qdec { client.sample_ready (); }, 2 => { - client.overflow (); + //client.overflow (); + debug!("Overflow!"); }, 4 => { if self.state == 1 { @@ -239,8 +241,14 @@ impl Qdec { fn enable_samplerdy_interrupts(&self) { let regs = &*self.registers; - regs.intenset.write(Inte::SAMPLERDY::SET); /*SET SAMPLE READY*/ - regs.intenset.write(Inte::ACCOF::SET); /*SET ACCOF READY*/ + regs.intenset.write(Inte::SAMPLERDY::SET); + regs.intenset.write(Inte::REPORTRDY::SET); + regs.intenset.write(Inte::ACCOF::SET); + regs.intenset.write(Inte::DBLRDY::SET); + regs.intenset.write(Inte::STOPPED::SET); + +// regs.intenset.write(Inte::SAMPLERDY::SET); /*SET SAMPLE READY*/ +// regs.intenset.write(Inte::ACCOF::SET); /*SET ACCOF READY*/ } fn disable_samplerdy_interrupts(&self) { @@ -274,13 +282,13 @@ impl kernel::hil::qdec::QdecDriver for Qdec { fn enable_interrupts (&self) -> ReturnCode { self.enable_samplerdy_interrupts(); - debug!("HALLO"); ReturnCode::SUCCESS } fn enable_qdec (&self) -> ReturnCode { if self.is_enabled() != ReturnCode::SUCCESS { - self.enable() + debug!("Enabled!"); + self.enable(); } self.is_enabled() } @@ -292,7 +300,9 @@ impl kernel::hil::qdec::QdecDriver for Qdec { fn get_acc(&self) -> u32 { let regs = &*self.registers; regs.tasks_readclracc.write(Task::ENABLE::SET); - regs.acc_read.read(Acc::ACC) + let val = regs.acc_read.read(Acc::ACC); + debug!("{}", val); + val } fn set_client(&self, client: &'static dyn kernel::hil::qdec::QdecClient) { diff --git a/kernel/src/hil/qdec.rs b/kernel/src/hil/qdec.rs index 3c321dcfd45..e6a24051c82 100644 --- a/kernel/src/hil/qdec.rs +++ b/kernel/src/hil/qdec.rs @@ -26,6 +26,6 @@ pub trait QdecDriver { pub trait QdecClient { /// Callback function 1 fn sample_ready (&self); - /// Callback function 2 - fn overflow (&self); + // Callback function 2 + //fn overflow (&self); } From 8dbc97fd8ae765437f651f6a1497962d30adb4f7 Mon Sep 17 00:00:00 2001 From: tock Date: Fri, 29 May 2020 02:44:08 +0800 Subject: [PATCH 28/39] Qdec interrupts are maybe on their way to working again? --- boards/nordic/nrf52dk_base/src/lib.rs | 17 ++++++++--------- boards/nordic/nrf52dk_base/src/qdec_test.rs | 4 ++-- chips/nrf52/src/interrupt_service.rs | 2 ++ chips/nrf52/src/qdec.rs | 11 ++++++----- 4 files changed, 18 insertions(+), 16 deletions(-) diff --git a/boards/nordic/nrf52dk_base/src/lib.rs b/boards/nordic/nrf52dk_base/src/lib.rs index 4608115dae5..7498e48d7c7 100644 --- a/boards/nordic/nrf52dk_base/src/lib.rs +++ b/boards/nordic/nrf52dk_base/src/lib.rs @@ -111,7 +111,7 @@ pub struct Platform { 'static, capsules::virtual_alarm::VirtualMuxAlarm<'static, nrf52::rtc::Rtc<'static>>, >, - //qdec: &'static capsules::qdec::QdecInterface<'static>, + qdec: &'static capsules::qdec::QdecInterface<'static>, // The nRF52dk does not have the flash chip on it, so we make this optional. nonvolatile_storage: Option<&'static capsules::nonvolatile_storage_driver::NonvolatileStorage<'static>>, @@ -130,7 +130,7 @@ impl kernel::Platform for Platform { capsules::led::DRIVER_NUM => f(Some(self.led)), capsules::button::DRIVER_NUM => f(Some(self.button)), capsules::rng::DRIVER_NUM => f(Some(self.rng)), - //capsules::qdec::DRIVER_NUM => f(Some(self.qdec)), + capsules::qdec::DRIVER_NUM => f(Some(self.qdec)), capsules::ble_advertising_driver::DRIVER_NUM => f(Some(self.ble_radio)), capsules::ieee802154::DRIVER_NUM => match self.ieee802154_radio { Some(radio) => f(Some(radio)), @@ -442,15 +442,15 @@ pub unsafe fn setup_board( nrf52::pinmux::Pinmux::new(qdec_pins.pin_a as u32), nrf52::pinmux::Pinmux::new(qdec_pins.pin_b as u32), ); - let qdec_test = qdec_test::initialize_all(mux_alarm, qdec_nrf52); - /*let qdec = static_init!( + //let qdec_test = qdec_test::initialize_all(mux_alarm, qdec_nrf52); + let qdec = static_init!( capsules::qdec::QdecInterface<'static>, capsules::qdec::QdecInterface::new( qdec_nrf52, board_kernel.create_grant(&memory_allocation_capability) ) - );*/ - //kernel::hil::qdec::QdecDriver::set_client(&nrf52::qdec::QDEC, qdec); + ); + kernel::hil::qdec::QdecDriver::set_client(&nrf52::qdec::QDEC, qdec); let platform = Platform { button: button, @@ -465,15 +465,14 @@ pub unsafe fn setup_board( alarm: alarm, analog_comparator: analog_comparator, nonvolatile_storage: nonvolatile_storage, - //qdec: qdec, + qdec: qdec, ipc: kernel::ipc::IPC::new(board_kernel, &memory_allocation_capability), }; platform.pconsole.start(); debug!("Initialization complete. Entering main loop\r"); debug!("Start of QDEC Janky Test 1"); - debug!("Accumulation value: {}", kernel::hil::qdec::QdecDriver::get_acc(&nrf52::qdec::QDEC)); - qdec_test.start(); + //qdec_test.start(); debug!("End of QDEC Janky Test 1"); debug!("{}", &nrf52::ficr::FICR_INSTANCE); diff --git a/boards/nordic/nrf52dk_base/src/qdec_test.rs b/boards/nordic/nrf52dk_base/src/qdec_test.rs index 4f5b8a68da8..cf985571db8 100644 --- a/boards/nordic/nrf52dk_base/src/qdec_test.rs +++ b/boards/nordic/nrf52dk_base/src/qdec_test.rs @@ -39,9 +39,9 @@ pub unsafe fn initialize_all( impl<'a, A: time::Alarm<'a>> QdecTest<'a, A> { pub fn start(&self) { self.qdec.enable_qdec(); - debug!("Is enabled?"); + //debug!("Is enabled?"); self.qdec.enable_interrupts(); - debug!("Is interruptable?"); + //debug!("Is interruptable?"); self.schedule_next(); } diff --git a/chips/nrf52/src/interrupt_service.rs b/chips/nrf52/src/interrupt_service.rs index 5bc9d5fd12d..70a99c82264 100644 --- a/chips/nrf52/src/interrupt_service.rs +++ b/chips/nrf52/src/interrupt_service.rs @@ -6,6 +6,7 @@ use crate::ieee802154_radio; use crate::power; use crate::spi; use crate::uart; +use crate::qdec; use kernel::debug; use nrf5x::peripheral_interrupts; @@ -123,6 +124,7 @@ impl InterruptService for Nrf52InterruptService { } peripheral_interrupts::SPIM2_SPIS2_SPI2 => spi::SPIM2.handle_interrupt(), peripheral_interrupts::ADC => adc::ADC.handle_interrupt(), + peripheral_interrupts::QDEC => qdec::QDEC.handle_interrupt(), _ => return false, } true diff --git a/chips/nrf52/src/qdec.rs b/chips/nrf52/src/qdec.rs index 0085486b508..b8783540d0b 100644 --- a/chips/nrf52/src/qdec.rs +++ b/chips/nrf52/src/qdec.rs @@ -241,14 +241,14 @@ impl Qdec { fn enable_samplerdy_interrupts(&self) { let regs = &*self.registers; - regs.intenset.write(Inte::SAMPLERDY::SET); + /* regs.intenset.write(Inte::REPORTRDY::SET); - regs.intenset.write(Inte::ACCOF::SET); regs.intenset.write(Inte::DBLRDY::SET); regs.intenset.write(Inte::STOPPED::SET); + */ -// regs.intenset.write(Inte::SAMPLERDY::SET); /*SET SAMPLE READY*/ -// regs.intenset.write(Inte::ACCOF::SET); /*SET ACCOF READY*/ + regs.intenset.write(Inte::SAMPLERDY::SET); /*SET SAMPLE READY*/ + regs.intenset.write(Inte::ACCOF::SET); /*SET ACCOF READY*/ } fn disable_samplerdy_interrupts(&self) { @@ -263,7 +263,7 @@ impl Qdec { //set_sample_rate //regs.tasks_stop.write(Task::ENABLE::SET); /*induce stop*/ - //regs.tasks_start.write(Task::ENABLE::SET); + regs.tasks_start.write(Task::ENABLE::SET); } fn is_enabled(&self) -> ReturnCode { @@ -282,6 +282,7 @@ impl kernel::hil::qdec::QdecDriver for Qdec { fn enable_interrupts (&self) -> ReturnCode { self.enable_samplerdy_interrupts(); + debug!("SUCCESS!"); ReturnCode::SUCCESS } From 8c7ed3ad5ef58d003921d788836f13d7edd1c02d Mon Sep 17 00:00:00 2001 From: tock Date: Tue, 2 Jun 2020 04:30:40 +0800 Subject: [PATCH 29/39] Changes to the kernel-interrupts not fully working --- boards/nordic/nrf52dk_base/src/lib.rs | 3 ++- capsules/src/qdec.rs | 4 ++-- chips/nrf52/src/qdec.rs | 3 ++- 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/boards/nordic/nrf52dk_base/src/lib.rs b/boards/nordic/nrf52dk_base/src/lib.rs index 7498e48d7c7..ebd2f01b91f 100644 --- a/boards/nordic/nrf52dk_base/src/lib.rs +++ b/boards/nordic/nrf52dk_base/src/lib.rs @@ -15,7 +15,7 @@ use kernel::hil::gpio::{Configure, FloatingState}; use nrf52::gpio::Pin; use nrf52::rtc::Rtc; use nrf52::uicr::Regulator0Output; - +use kernel::hil::qdec::QdecDriver; //TODO is this temporary? //use kernel::common::dynamic_deferred_call::{DynamicDeferredCall, DynamicDeferredCallClientState}; pub mod qdec_test; pub mod nrf52_components; @@ -442,6 +442,7 @@ pub unsafe fn setup_board( nrf52::pinmux::Pinmux::new(qdec_pins.pin_a as u32), nrf52::pinmux::Pinmux::new(qdec_pins.pin_b as u32), ); + //qdec_nrf52.enable_interrupts(); //let qdec_test = qdec_test::initialize_all(mux_alarm, qdec_nrf52); let qdec = static_init!( capsules::qdec::QdecInterface<'static>, diff --git a/capsules/src/qdec.rs b/capsules/src/qdec.rs index f1c2f642128..5b3626647f0 100644 --- a/capsules/src/qdec.rs +++ b/capsules/src/qdec.rs @@ -61,11 +61,11 @@ impl hil::qdec::QdecClient for QdecInterface<'a> { /// Goes through all the apps and if the app is /// subscribed then it sends back the acc value fn sample_ready (&self) { - debug!("Client"); + debug!("Client Ready!"); for cntr in self.apps.iter() { cntr.enter(|app, _| { if app.subscribed { - app.subscribed = false; + //app.subscribed = false; app.callback.map(|mut cb| cb.schedule(self.driver.get_acc() as usize,0,0)); } }); diff --git a/chips/nrf52/src/qdec.rs b/chips/nrf52/src/qdec.rs index b8783540d0b..be42fdb7c50 100644 --- a/chips/nrf52/src/qdec.rs +++ b/chips/nrf52/src/qdec.rs @@ -217,7 +217,7 @@ impl Qdec { // Disable corresponding interrupt let _interrupt_bit = match i { 0 => { - debug!("Interrupt handler!"); + debug!("Sample Ready interrupt!"); client.sample_ready (); }, 2 => { @@ -236,6 +236,7 @@ impl Qdec { } } }); + debug!("Finished!"); self.enable_samplerdy_interrupts(); } From b1f0fa522d5f711e3a094d2b29350d4d1ce3c604 Mon Sep 17 00:00:00 2001 From: Hudson Ayers Date: Mon, 1 Jun 2020 14:53:56 -0700 Subject: [PATCH 30/39] cleanup --- boards/nordic/nrf52dk_base/src/lib.rs | 17 +++--- boards/nordic/nrf52dk_base/src/qdec_test.rs | 12 ++-- capsules/src/qdec.rs | 27 ++++----- chips/nrf52/src/chip.rs | 62 --------------------- chips/nrf52/src/qdec.rs | 59 +++++++++----------- kernel/src/hil/mod.rs | 3 +- 6 files changed, 50 insertions(+), 130 deletions(-) diff --git a/boards/nordic/nrf52dk_base/src/lib.rs b/boards/nordic/nrf52dk_base/src/lib.rs index ebd2f01b91f..7be089af721 100644 --- a/boards/nordic/nrf52dk_base/src/lib.rs +++ b/boards/nordic/nrf52dk_base/src/lib.rs @@ -12,13 +12,13 @@ use kernel::common::dynamic_deferred_call::{DynamicDeferredCall, DynamicDeferred use kernel::component::Component; use kernel::hil; use kernel::hil::gpio::{Configure, FloatingState}; +use kernel::hil::qdec::QdecDriver; use nrf52::gpio::Pin; use nrf52::rtc::Rtc; -use nrf52::uicr::Regulator0Output; -use kernel::hil::qdec::QdecDriver; //TODO is this temporary? -//use kernel::common::dynamic_deferred_call::{DynamicDeferredCall, DynamicDeferredCallClientState}; -pub mod qdec_test; +use nrf52::uicr::Regulator0Output; //TODO is this temporary? + //use kernel::common::dynamic_deferred_call::{DynamicDeferredCall, DynamicDeferredCallClientState}; pub mod nrf52_components; +pub mod qdec_test; use nrf52_components::ble::BLEComponent; use nrf52_components::ieee802154::Ieee802154Component; @@ -439,10 +439,9 @@ pub unsafe fn setup_board( let qdec_nrf52 = &mut nrf52::qdec::QDEC; qdec_nrf52.set_pins( - nrf52::pinmux::Pinmux::new(qdec_pins.pin_a as u32), - nrf52::pinmux::Pinmux::new(qdec_pins.pin_b as u32), - ); - //qdec_nrf52.enable_interrupts(); + nrf52::pinmux::Pinmux::new(qdec_pins.pin_a as u32), + nrf52::pinmux::Pinmux::new(qdec_pins.pin_b as u32), + ); //let qdec_test = qdec_test::initialize_all(mux_alarm, qdec_nrf52); let qdec = static_init!( capsules::qdec::QdecInterface<'static>, @@ -472,9 +471,7 @@ pub unsafe fn setup_board( platform.pconsole.start(); debug!("Initialization complete. Entering main loop\r"); - debug!("Start of QDEC Janky Test 1"); //qdec_test.start(); - debug!("End of QDEC Janky Test 1"); debug!("{}", &nrf52::ficr::FICR_INSTANCE); extern "C" { diff --git a/boards/nordic/nrf52dk_base/src/qdec_test.rs b/boards/nordic/nrf52dk_base/src/qdec_test.rs index cf985571db8..749b8eda961 100644 --- a/boards/nordic/nrf52dk_base/src/qdec_test.rs +++ b/boards/nordic/nrf52dk_base/src/qdec_test.rs @@ -1,10 +1,10 @@ #[allow(unused_imports)] use capsules::virtual_alarm::{MuxAlarm, VirtualMuxAlarm}; +use kernel::hil::qdec::QdecDriver; use kernel::hil::time; use kernel::hil::time::{Alarm, Frequency}; use kernel::{debug, static_init}; use nrf52::qdec::Qdec; -use kernel::hil::qdec::QdecDriver; pub const TEST_DELAY_MS: u32 = 1000; @@ -39,9 +39,7 @@ pub unsafe fn initialize_all( impl<'a, A: time::Alarm<'a>> QdecTest<'a, A> { pub fn start(&self) { self.qdec.enable_qdec(); - //debug!("Is enabled?"); self.qdec.enable_interrupts(); - //debug!("Is interruptable?"); self.schedule_next(); } @@ -54,8 +52,6 @@ impl<'a, A: time::Alarm<'a>> QdecTest<'a, A> { impl<'a, A: time::Alarm<'a>> time::AlarmClient for QdecTest<'a, A> { fn fired(&self) { - self.qdec.enable_qdec(); - //self.qdec.enable_interrupts_qdec(); let acc = self.qdec.get_acc(); debug!("Is enabled?"); debug!("Acc: {:?}", acc); @@ -64,7 +60,7 @@ impl<'a, A: time::Alarm<'a>> time::AlarmClient for QdecTest<'a, A> { } impl<'a, A: time::Alarm<'a>> kernel::hil::qdec::QdecClient for QdecTest<'a, A> { - fn sample_ready (&self) { //TODO go back and change name - debug!("Val:{:?}", 0); - } + fn sample_ready(&self) { + debug!("sample ready qdec test"); + } } diff --git a/capsules/src/qdec.rs b/capsules/src/qdec.rs index 5b3626647f0..b99a3fe22f4 100644 --- a/capsules/src/qdec.rs +++ b/capsules/src/qdec.rs @@ -17,7 +17,7 @@ use crate::driver; use kernel::hil; -use kernel::{AppId, Callback, ReturnCode, Driver, Grant, debug}; +use kernel::{debug, AppId, Callback, Driver, Grant, ReturnCode}; pub const DRIVER_NUM: usize = driver::NUM::Qdec as usize; @@ -36,18 +36,14 @@ pub struct App { impl QdecInterface<'a> { /// Create a new instance of the QdecInterface - pub fn new ( - driver: &'a dyn hil::qdec::QdecDriver, - grant: Grant, - ) -> QdecInterface<'a> { + pub fn new(driver: &'a dyn hil::qdec::QdecDriver, grant: Grant) -> QdecInterface<'a> { QdecInterface { driver: driver, apps: grant, } } - fn configure_callback(&self, callback: Option, app_id: AppId) - -> ReturnCode { + fn configure_callback(&self, callback: Option, app_id: AppId) -> ReturnCode { self.apps .enter(app_id, |app, _| { app.callback = callback; @@ -60,13 +56,13 @@ impl QdecInterface<'a> { impl hil::qdec::QdecClient for QdecInterface<'a> { /// Goes through all the apps and if the app is /// subscribed then it sends back the acc value - fn sample_ready (&self) { + fn sample_ready(&self) { debug!("Client Ready!"); for cntr in self.apps.iter() { cntr.enter(|app, _| { if app.subscribed { - //app.subscribed = false; - app.callback.map(|mut cb| cb.schedule(self.driver.get_acc() as usize,0,0)); + app.callback + .map(|mut cb| cb.schedule(self.driver.get_acc() as usize, 0, 0)); } }); } @@ -77,7 +73,7 @@ impl hil::qdec::QdecClient for QdecInterface<'a> { cntr.enter(|app, _| { if app.subscribed { app.subscribed = false; - app.callback.map(|mut cb| cb.schedule(self.driver.get_acc() as usize,0,0)); + app.callback.map(|mut cb| cb.schedule(self.driver.get_acc() as usize,0,0)); } }); } @@ -99,17 +95,16 @@ impl Driver for QdecInterface<'a> { } /// Command switch statement for various essential processes - fn command (&self, command_num: usize, _: usize, _: usize, _app_id: AppId) -> ReturnCode { + fn command(&self, command_num: usize, _: usize, _: usize, _app_id: AppId) -> ReturnCode { match command_num { 0 => ReturnCode::SUCCESS, 1 => self.driver.enable_qdec(), 2 => self.driver.enabled(), 3 => self.driver.enable_interrupts(), - 4 => - ReturnCode::SuccessWithValue { + 4 => ReturnCode::SuccessWithValue { value: self.driver.get_acc() as usize, - }, - _ => ReturnCode::ENOSUPPORT + }, + _ => ReturnCode::ENOSUPPORT, } } } diff --git a/chips/nrf52/src/chip.rs b/chips/nrf52/src/chip.rs index 612a79bdf03..0366a683e9f 100644 --- a/chips/nrf52/src/chip.rs +++ b/chips/nrf52/src/chip.rs @@ -1,10 +1,6 @@ use crate::deferred_call_tasks::DeferredCallTask; use crate::interrupt_service::InterruptService; use crate::nvmc; -// use crate::power; -// use crate::spi; -// use crate::uart; -// use crate::qdec; use cortexm4::{self, nvic}; use kernel::common::deferred_call; use kernel::debug; @@ -54,66 +50,8 @@ impl kernel::Chip for NRF52 { DeferredCallTask::Nvmc => nvmc::NVMC.handle_interrupt(), } } else if let Some(interrupt) = nvic::next_pending() { -// match interrupt { -// peripheral_interrupts::ECB => nrf5x::aes::AESECB.handle_interrupt(), -// peripheral_interrupts::GPIOTE => self.gpio_port.handle_interrupt(), -// peripheral_interrupts::POWER_CLOCK => power::POWER.handle_interrupt(), -// peripheral_interrupts::RADIO => { -// match ( -// ieee802154_radio::RADIO.is_enabled(), -// ble_radio::RADIO.is_enabled(), -// ) { -// (false, false) => (), -// (true, false) => ieee802154_radio::RADIO.handle_interrupt(), -// (false, true) => ble_radio::RADIO.handle_interrupt(), -// (true, true) => debug!( -// "nRF 802.15.4 and BLE radios cannot be simultaneously enabled!" -// ), -// } -// } -// peripheral_interrupts::RNG => nrf5x::trng::TRNG.handle_interrupt(), -// peripheral_interrupts::RTC1 => nrf5x::rtc::RTC.handle_interrupt(), -// peripheral_interrupts::TEMP => nrf5x::temperature::TEMP.handle_interrupt(), -// peripheral_interrupts::TIMER0 => nrf5x::timer::TIMER0.handle_interrupt(), -// peripheral_interrupts::TIMER1 => nrf5x::timer::ALARM1.handle_interrupt(), -// peripheral_interrupts::TIMER2 => nrf5x::timer::TIMER2.handle_interrupt(), -// peripheral_interrupts::UART0 => uart::UARTE0.handle_interrupt(), -// peripheral_interrupts::SPI0_TWI0 => { -// // SPI0 and TWI0 share interrupts. -// // Dispatch the correct handler. -// match (spi::SPIM0.is_enabled(), i2c::TWIM0.is_enabled()) { -// (false, false) => (), -// (true, false) => spi::SPIM0.handle_interrupt(), -// (false, true) => i2c::TWIM0.handle_interrupt(), -// (true, true) => debug_assert!( -// false, -// "SPIM0 and TWIM0 cannot be \ -// enabled at the same time." -// ), -// } -// } -// peripheral_interrupts::SPI1_TWI1 => { -// // SPI1 and TWI1 share interrupts. -// // Dispatch the correct handler. -// match (spi::SPIM1.is_enabled(), i2c::TWIM1.is_enabled()) { -// (false, false) => (), -// (true, false) => spi::SPIM1.handle_interrupt(), -// (false, true) => i2c::TWIM1.handle_interrupt(), -// (true, true) => debug_assert!( -// false, -// "SPIM1 and TWIM1 cannot be \ -// enabled at the same time." -// ), -// } -// } -// peripheral_interrupts::SPIM2_SPIS2_SPI2 => spi::SPIM2.handle_interrupt(), -// peripheral_interrupts::ADC => adc::ADC.handle_interrupt(), -// peripheral_interrupts::QDEC => qdec::QDEC.handle_interrupt(), -// _ => debug!("NvicIdx not supported by Tock"), - if !self.interrupt_service.service_interrupt(interrupt) { debug!("NvicIdx not supported by Tock: {}", interrupt); - } let n = nvic::Nvic::new(interrupt); n.clear_pending(); diff --git a/chips/nrf52/src/qdec.rs b/chips/nrf52/src/qdec.rs index be42fdb7c50..3da0ab2fc14 100644 --- a/chips/nrf52/src/qdec.rs +++ b/chips/nrf52/src/qdec.rs @@ -8,9 +8,9 @@ use kernel::common::cells::OptionalCell; use kernel::common::registers::{ register_bitfields, register_structs, ReadOnly, ReadWrite, WriteOnly, }; -use kernel::ReturnCode; use kernel::common::StaticRef; use kernel::debug; +use kernel::ReturnCode; use nrf5x::pinmux; // In this section I declare a struct called QdecRegisters, which contains all the // relevant registers as outlined in the Nordic 5x specification of the Qdec. @@ -73,7 +73,7 @@ register_structs! { } // In this section, I initialize all the bitfields associated with the type -// of register assigned to each member of the struct above. +// of register assigned to each member of the struct above. register_bitfields![u32, Task [ ENABLE 0 @@ -186,7 +186,7 @@ impl Qdec { /// sets pins_a and pins_b to be the output pins for whatever the encoding device is pub fn set_pins(&self, pin_a: pinmux::Pinmux, pin_b: pinmux::Pinmux) { - let regs = self.registers; + let regs = self.registers; regs.psel_a.write( PinSelect::Pin.val(pin_a.into()) + PinSelect::Port.val(0) + PinSelect::Connect.val(0), ); @@ -202,42 +202,39 @@ impl Qdec { /// When an interrupt occurs, check to see if any /// of the interrupt register bits are set. If it /// is, then put it in the client's bitmask - pub fn handle_interrupt(&self) { + pub(crate) fn handle_interrupt(&self) { debug!("Entering Interrupt Handler!"); - self.disable_samplerdy_interrupts(); let regs = &*self.registers; self.client.map(|client| { - let mut val = 0; // For each of 4 possible compare events, if it's happened, // clear it and sort its bit in val to pass in callback for i in 0..regs.events_arr.len() { if self.registers.events_arr[i].is_set(Event::READY) { - val = val | 1 << i; - self.registers.events_arr[i].write(Event::READY::CLEAR); + self.registers.events_arr[i].set(0); // Disable corresponding interrupt - let _interrupt_bit = match i { + match i { 0 => { debug!("Sample Ready interrupt!"); - client.sample_ready (); - }, + client.sample_ready(); + } 2 => { //client.overflow (); debug!("Overflow!"); - }, + } 4 => { if self.state == 1 { - self.registers.sample_per.write(SampPer::SAMPLEPER.val(5)); - self.registers.tasks_start.write(Task::ENABLE::SET); - //self.state = 0; + self.registers.sample_per.write(SampPer::SAMPLEPER.val(5)); + self.registers.tasks_start.write(Task::ENABLE::SET); + debug!("BADDDD"); + //self.state = 0; } - }, + } _ => panic!("Unsupported interrupt value!"), - }; + } } } }); debug!("Finished!"); - self.enable_samplerdy_interrupts(); } fn enable_samplerdy_interrupts(&self) { @@ -270,32 +267,28 @@ impl Qdec { fn is_enabled(&self) -> ReturnCode { let regs = &*self.registers; let result = if regs.enable.is_set(Task::ENABLE) { - ReturnCode::SUCCESS - } else { - ReturnCode::FAIL - }; + ReturnCode::SUCCESS + } else { + ReturnCode::FAIL + }; result } - } -impl kernel::hil::qdec::QdecDriver for Qdec { - - fn enable_interrupts (&self) -> ReturnCode { - self.enable_samplerdy_interrupts(); - debug!("SUCCESS!"); - ReturnCode::SUCCESS +impl kernel::hil::qdec::QdecDriver for Qdec { + fn enable_interrupts(&self) -> ReturnCode { + self.enable_samplerdy_interrupts(); + ReturnCode::SUCCESS } - fn enable_qdec (&self) -> ReturnCode { + fn enable_qdec(&self) -> ReturnCode { if self.is_enabled() != ReturnCode::SUCCESS { - debug!("Enabled!"); self.enable(); } self.is_enabled() } - fn enabled (&self) -> ReturnCode { + fn enabled(&self) -> ReturnCode { self.is_enabled() } @@ -306,7 +299,7 @@ impl kernel::hil::qdec::QdecDriver for Qdec { debug!("{}", val); val } - + fn set_client(&self, client: &'static dyn kernel::hil::qdec::QdecClient) { self.client.set(client); } diff --git a/kernel/src/hil/mod.rs b/kernel/src/hil/mod.rs index c78c39cbbea..6bf395a12e4 100644 --- a/kernel/src/hil/mod.rs +++ b/kernel/src/hil/mod.rs @@ -14,6 +14,7 @@ pub mod i2c; pub mod led; pub mod nonvolatile_storage; pub mod pwm; +pub mod qdec; pub mod radio; pub mod rng; pub mod sensors; @@ -23,7 +24,7 @@ pub mod time; pub mod uart; pub mod usb; pub mod watchdog; -pub mod qdec; + /// Shared interface for configuring components. pub trait Controller { type Config; From 9576f6cb211925af9c47229069119449bfd5a7e2 Mon Sep 17 00:00:00 2001 From: tock Date: Mon, 17 Aug 2020 06:01:04 +0800 Subject: [PATCH 31/39] Takes away debug statements filling debug buffer --- capsules/src/qdec.rs | 2 +- chips/nrf52/src/qdec.rs | 26 ++++++++++++++------------ 2 files changed, 15 insertions(+), 13 deletions(-) diff --git a/capsules/src/qdec.rs b/capsules/src/qdec.rs index b99a3fe22f4..17bdeda9dd3 100644 --- a/capsules/src/qdec.rs +++ b/capsules/src/qdec.rs @@ -57,7 +57,7 @@ impl hil::qdec::QdecClient for QdecInterface<'a> { /// Goes through all the apps and if the app is /// subscribed then it sends back the acc value fn sample_ready(&self) { - debug!("Client Ready!"); + //debug!("Client Ready!"); for cntr in self.apps.iter() { cntr.enter(|app, _| { if app.subscribed { diff --git a/chips/nrf52/src/qdec.rs b/chips/nrf52/src/qdec.rs index 3da0ab2fc14..0b43e24b21f 100644 --- a/chips/nrf52/src/qdec.rs +++ b/chips/nrf52/src/qdec.rs @@ -203,23 +203,26 @@ impl Qdec { /// of the interrupt register bits are set. If it /// is, then put it in the client's bitmask pub(crate) fn handle_interrupt(&self) { - debug!("Entering Interrupt Handler!"); let regs = &*self.registers; self.client.map(|client| { // For each of 4 possible compare events, if it's happened, // clear it and sort its bit in val to pass in callback for i in 0..regs.events_arr.len() { - if self.registers.events_arr[i].is_set(Event::READY) { - self.registers.events_arr[i].set(0); - // Disable corresponding interrupt + if regs.events_arr[i].is_set(Event::READY) { + regs.events_arr[i].set(0); match i { 0 => { - debug!("Sample Ready interrupt!"); client.sample_ready(); } + 1 => { + //debug!("Report Ready interrupt!"); + } 2 => { - //client.overflow (); - debug!("Overflow!"); + //client.overflow(); + //debug!("ACCOF Overflow!"); + } + 3 => { + debug!("DBLRDY Interrupt!"); } 4 => { if self.state == 1 { @@ -229,29 +232,28 @@ impl Qdec { //self.state = 0; } } - _ => panic!("Unsupported interrupt value!"), + _ => panic!("Unsupported interrupt value {}!", i), } } } }); - debug!("Finished!"); } fn enable_samplerdy_interrupts(&self) { let regs = &*self.registers; /* - regs.intenset.write(Inte::REPORTRDY::SET); + regs.intenset.write(Inte::SAMPLERDY::SET); regs.intenset.write(Inte::DBLRDY::SET); regs.intenset.write(Inte::STOPPED::SET); */ - regs.intenset.write(Inte::SAMPLERDY::SET); /*SET SAMPLE READY*/ + regs.intenset.write(Inte::REPORTRDY::SET); /*SET SAMPLE READY*/ regs.intenset.write(Inte::ACCOF::SET); /*SET ACCOF READY*/ } fn disable_samplerdy_interrupts(&self) { let regs = &*self.registers; - regs.intenclr.write(Inte::SAMPLERDY::SET); + regs.intenclr.write(Inte::REPORTRDY::SET); regs.intenclr.write(Inte::ACCOF::SET); } From 50e2e44af55771d05e73626050156204d4345e1e Mon Sep 17 00:00:00 2001 From: tock Date: Tue, 15 Sep 2020 10:26:25 +0800 Subject: [PATCH 32/39] Callbacks are fully functional! --- boards/nordic/nrf52dk_base/src/lib.rs | 2 +- capsules/src/qdec.rs | 20 +++++++++----------- chips/nrf52/src/qdec.rs | 10 +++++----- kernel/src/hil/qdec.rs | 8 ++++---- 4 files changed, 19 insertions(+), 21 deletions(-) diff --git a/boards/nordic/nrf52dk_base/src/lib.rs b/boards/nordic/nrf52dk_base/src/lib.rs index 7be089af721..c98717517f1 100644 --- a/boards/nordic/nrf52dk_base/src/lib.rs +++ b/boards/nordic/nrf52dk_base/src/lib.rs @@ -18,7 +18,7 @@ use nrf52::rtc::Rtc; use nrf52::uicr::Regulator0Output; //TODO is this temporary? //use kernel::common::dynamic_deferred_call::{DynamicDeferredCall, DynamicDeferredCallClientState}; pub mod nrf52_components; -pub mod qdec_test; +//pub mod qdec_test; use nrf52_components::ble::BLEComponent; use nrf52_components::ieee802154::Ieee802154Component; diff --git a/capsules/src/qdec.rs b/capsules/src/qdec.rs index 17bdeda9dd3..4f9bd59c833 100644 --- a/capsules/src/qdec.rs +++ b/capsules/src/qdec.rs @@ -31,7 +31,7 @@ pub struct QdecInterface<'a> { /// This struct contains the necessary fields for an app pub struct App { callback: Option, - subscribed: bool, + pos: u32, } impl QdecInterface<'a> { @@ -60,24 +60,22 @@ impl hil::qdec::QdecClient for QdecInterface<'a> { //debug!("Client Ready!"); for cntr in self.apps.iter() { cntr.enter(|app, _| { - if app.subscribed { - app.callback - .map(|mut cb| cb.schedule(self.driver.get_acc() as usize, 0, 0)); - } + app.pos = app.pos + self.driver.get_acc(); + app.callback + .map(|mut cb| cb.schedule(app.pos as usize, 0, 0)); }); } } - /*fn overflow (&self) { + fn overflow (&self) { + //debug!("Overflow!"); for cntr in self.apps.iter() { cntr.enter(|app, _| { - if app.subscribed { - app.subscribed = false; - app.callback.map(|mut cb| cb.schedule(self.driver.get_acc() as usize,0,0)); - } + app.pos = app.pos + self.driver.get_acc(); + app.callback.map(|mut cb| cb.schedule(self.driver.get_acc() as usize, 0, 0)); }); } - }*/ + } } impl Driver for QdecInterface<'a> { diff --git a/chips/nrf52/src/qdec.rs b/chips/nrf52/src/qdec.rs index 0b43e24b21f..4844f499e68 100644 --- a/chips/nrf52/src/qdec.rs +++ b/chips/nrf52/src/qdec.rs @@ -218,11 +218,11 @@ impl Qdec { //debug!("Report Ready interrupt!"); } 2 => { - //client.overflow(); - //debug!("ACCOF Overflow!"); + client.overflow(); + debug!("ACCOF Overflow!"); } 3 => { - debug!("DBLRDY Interrupt!"); + //debug!("DBLRDY Interrupt!"); } 4 => { if self.state == 1 { @@ -298,8 +298,8 @@ impl kernel::hil::qdec::QdecDriver for Qdec { let regs = &*self.registers; regs.tasks_readclracc.write(Task::ENABLE::SET); let val = regs.acc_read.read(Acc::ACC); - debug!("{}", val); - val + //debug!("{}", val); + val /*as i32*/ } fn set_client(&self, client: &'static dyn kernel::hil::qdec::QdecClient) { diff --git a/kernel/src/hil/qdec.rs b/kernel/src/hil/qdec.rs index e6a24051c82..fc4cf8d415f 100644 --- a/kernel/src/hil/qdec.rs +++ b/kernel/src/hil/qdec.rs @@ -24,8 +24,8 @@ pub trait QdecDriver { } pub trait QdecClient { - /// Callback function 1 - fn sample_ready (&self); - // Callback function 2 - //fn overflow (&self); + /// Callback obtaining offset + fn sample_ready (&self); + /// Callback dealing with overflows + fn overflow (&self); } From d78dd940b10f2da8af7e5e9e45959b5646cb0055 Mon Sep 17 00:00:00 2001 From: tock Date: Tue, 15 Sep 2020 11:12:07 +0800 Subject: [PATCH 33/39] Cleans up part of the qdec codebase --- boards/nordic/nrf52dk_base/src/lib.rs | 4 -- boards/nordic/nrf52dk_base/src/qdec_test.rs | 66 --------------------- capsules/src/qdec.rs | 8 +-- chips/nrf52/src/qdec.rs | 25 +------- 4 files changed, 6 insertions(+), 97 deletions(-) delete mode 100644 boards/nordic/nrf52dk_base/src/qdec_test.rs diff --git a/boards/nordic/nrf52dk_base/src/lib.rs b/boards/nordic/nrf52dk_base/src/lib.rs index c98717517f1..8f37542d976 100644 --- a/boards/nordic/nrf52dk_base/src/lib.rs +++ b/boards/nordic/nrf52dk_base/src/lib.rs @@ -12,13 +12,11 @@ use kernel::common::dynamic_deferred_call::{DynamicDeferredCall, DynamicDeferred use kernel::component::Component; use kernel::hil; use kernel::hil::gpio::{Configure, FloatingState}; -use kernel::hil::qdec::QdecDriver; use nrf52::gpio::Pin; use nrf52::rtc::Rtc; use nrf52::uicr::Regulator0Output; //TODO is this temporary? //use kernel::common::dynamic_deferred_call::{DynamicDeferredCall, DynamicDeferredCallClientState}; pub mod nrf52_components; -//pub mod qdec_test; use nrf52_components::ble::BLEComponent; use nrf52_components::ieee802154::Ieee802154Component; @@ -442,7 +440,6 @@ pub unsafe fn setup_board( nrf52::pinmux::Pinmux::new(qdec_pins.pin_a as u32), nrf52::pinmux::Pinmux::new(qdec_pins.pin_b as u32), ); - //let qdec_test = qdec_test::initialize_all(mux_alarm, qdec_nrf52); let qdec = static_init!( capsules::qdec::QdecInterface<'static>, capsules::qdec::QdecInterface::new( @@ -471,7 +468,6 @@ pub unsafe fn setup_board( platform.pconsole.start(); debug!("Initialization complete. Entering main loop\r"); - //qdec_test.start(); debug!("{}", &nrf52::ficr::FICR_INSTANCE); extern "C" { diff --git a/boards/nordic/nrf52dk_base/src/qdec_test.rs b/boards/nordic/nrf52dk_base/src/qdec_test.rs deleted file mode 100644 index 749b8eda961..00000000000 --- a/boards/nordic/nrf52dk_base/src/qdec_test.rs +++ /dev/null @@ -1,66 +0,0 @@ -#[allow(unused_imports)] -use capsules::virtual_alarm::{MuxAlarm, VirtualMuxAlarm}; -use kernel::hil::qdec::QdecDriver; -use kernel::hil::time; -use kernel::hil::time::{Alarm, Frequency}; -use kernel::{debug, static_init}; -use nrf52::qdec::Qdec; - -pub const TEST_DELAY_MS: u32 = 1000; - -pub struct QdecTest<'a, A: time::Alarm<'a>> { - alarm: &'a A, - pub qdec: &'a mut Qdec, -} - -pub unsafe fn initialize_all( - mux_alarm: &'static MuxAlarm<'static, nrf52::rtc::Rtc<'static>>, - qdec: &'static mut Qdec, -) -> &'static QdecTest< - 'static, - capsules::virtual_alarm::VirtualMuxAlarm<'static, nrf52::rtc::Rtc<'static>>, -> { - let qdec_alarm = static_init!( - VirtualMuxAlarm<'static, nrf52::rtc::Rtc>, - VirtualMuxAlarm::new(mux_alarm) - ); - let qdec_test = static_init!( - QdecTest>>, - QdecTest { - alarm: qdec_alarm, - qdec: qdec, - } - ); - qdec_alarm.set_client(qdec_test); - qdec_test.qdec.set_client(qdec_test); - qdec_test -} - -impl<'a, A: time::Alarm<'a>> QdecTest<'a, A> { - pub fn start(&self) { - self.qdec.enable_qdec(); - self.qdec.enable_interrupts(); - self.schedule_next(); - } - - fn schedule_next(&self) { - let delta = (A::Frequency::frequency() * TEST_DELAY_MS) / 1000; - let next = self.alarm.now().wrapping_add(delta); - self.alarm.set_alarm(next); - } -} - -impl<'a, A: time::Alarm<'a>> time::AlarmClient for QdecTest<'a, A> { - fn fired(&self) { - let acc = self.qdec.get_acc(); - debug!("Is enabled?"); - debug!("Acc: {:?}", acc); - self.schedule_next(); - } -} - -impl<'a, A: time::Alarm<'a>> kernel::hil::qdec::QdecClient for QdecTest<'a, A> { - fn sample_ready(&self) { - debug!("sample ready qdec test"); - } -} diff --git a/capsules/src/qdec.rs b/capsules/src/qdec.rs index 4f9bd59c833..5b38c619465 100644 --- a/capsules/src/qdec.rs +++ b/capsules/src/qdec.rs @@ -17,7 +17,7 @@ use crate::driver; use kernel::hil; -use kernel::{debug, AppId, Callback, Driver, Grant, ReturnCode}; +use kernel::{AppId, Callback, Driver, Grant, ReturnCode}; pub const DRIVER_NUM: usize = driver::NUM::Qdec as usize; @@ -57,7 +57,6 @@ impl hil::qdec::QdecClient for QdecInterface<'a> { /// Goes through all the apps and if the app is /// subscribed then it sends back the acc value fn sample_ready(&self) { - //debug!("Client Ready!"); for cntr in self.apps.iter() { cntr.enter(|app, _| { app.pos = app.pos + self.driver.get_acc(); @@ -66,9 +65,10 @@ impl hil::qdec::QdecClient for QdecInterface<'a> { }); } } - + + /// Goes through all the apps and if the app recently + /// had an overflow, it records the occurance fn overflow (&self) { - //debug!("Overflow!"); for cntr in self.apps.iter() { cntr.enter(|app, _| { app.pos = app.pos + self.driver.get_acc(); diff --git a/chips/nrf52/src/qdec.rs b/chips/nrf52/src/qdec.rs index 4844f499e68..65e81029ebb 100644 --- a/chips/nrf52/src/qdec.rs +++ b/chips/nrf52/src/qdec.rs @@ -9,7 +9,6 @@ use kernel::common::registers::{ register_bitfields, register_structs, ReadOnly, ReadWrite, WriteOnly, }; use kernel::common::StaticRef; -use kernel::debug; use kernel::ReturnCode; use nrf5x::pinmux; // In this section I declare a struct called QdecRegisters, which contains all the @@ -215,20 +214,16 @@ impl Qdec { client.sample_ready(); } 1 => { - //debug!("Report Ready interrupt!"); } 2 => { - client.overflow(); - debug!("ACCOF Overflow!"); + //client.overflow(); } 3 => { - //debug!("DBLRDY Interrupt!"); } 4 => { if self.state == 1 { self.registers.sample_per.write(SampPer::SAMPLEPER.val(5)); self.registers.tasks_start.write(Task::ENABLE::SET); - debug!("BADDDD"); //self.state = 0; } } @@ -241,28 +236,13 @@ impl Qdec { fn enable_samplerdy_interrupts(&self) { let regs = &*self.registers; - /* - regs.intenset.write(Inte::SAMPLERDY::SET); - regs.intenset.write(Inte::DBLRDY::SET); - regs.intenset.write(Inte::STOPPED::SET); - */ - regs.intenset.write(Inte::REPORTRDY::SET); /*SET SAMPLE READY*/ regs.intenset.write(Inte::ACCOF::SET); /*SET ACCOF READY*/ } - fn disable_samplerdy_interrupts(&self) { - let regs = &*self.registers; - regs.intenclr.write(Inte::REPORTRDY::SET); - regs.intenclr.write(Inte::ACCOF::SET); - } - fn enable(&self) { let regs = &*self.registers; regs.enable.write(Task::ENABLE::SET); - - //set_sample_rate - //regs.tasks_stop.write(Task::ENABLE::SET); /*induce stop*/ regs.tasks_start.write(Task::ENABLE::SET); } @@ -298,8 +278,7 @@ impl kernel::hil::qdec::QdecDriver for Qdec { let regs = &*self.registers; regs.tasks_readclracc.write(Task::ENABLE::SET); let val = regs.acc_read.read(Acc::ACC); - //debug!("{}", val); - val /*as i32*/ + val } fn set_client(&self, client: &'static dyn kernel::hil::qdec::QdecClient) { From dcd14d76c9324daef00d04ef809ad6de501a490a Mon Sep 17 00:00:00 2001 From: tock Date: Tue, 15 Sep 2020 11:56:04 +0800 Subject: [PATCH 34/39] Cleans up qdec code further --- capsules/src/qdec.rs | 5 ++--- chips/nrf52/src/qdec.rs | 4 +++- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/capsules/src/qdec.rs b/capsules/src/qdec.rs index 5b38c619465..5b44c214c6c 100644 --- a/capsules/src/qdec.rs +++ b/capsules/src/qdec.rs @@ -70,9 +70,8 @@ impl hil::qdec::QdecClient for QdecInterface<'a> { /// had an overflow, it records the occurance fn overflow (&self) { for cntr in self.apps.iter() { - cntr.enter(|app, _| { - app.pos = app.pos + self.driver.get_acc(); - app.callback.map(|mut cb| cb.schedule(self.driver.get_acc() as usize, 0, 0)); + cntr.enter(|_app, _| { + /*for now, we do not handle overflows!*/ }); } } diff --git a/chips/nrf52/src/qdec.rs b/chips/nrf52/src/qdec.rs index 65e81029ebb..d6431a51737 100644 --- a/chips/nrf52/src/qdec.rs +++ b/chips/nrf52/src/qdec.rs @@ -214,11 +214,13 @@ impl Qdec { client.sample_ready(); } 1 => { + /*No handling for REPORTRDY*/ } 2 => { - //client.overflow(); + client.overflow(); } 3 => { + /*No handling for DBLRDY*/ } 4 => { if self.state == 1 { From 575ee3bf38490042de4187cdae5c818d04cc30cc Mon Sep 17 00:00:00 2001 From: tock Date: Tue, 15 Sep 2020 12:03:28 +0800 Subject: [PATCH 35/39] Formats all the files --- boards/nordic/nrf52840dk/src/main.rs | 1 - capsules/src/lib.rs | 2 +- capsules/src/qdec.rs | 8 +++---- chips/nrf52/src/interrupt_service.rs | 2 +- chips/nrf52/src/qdec.rs | 8 ++----- kernel/src/hil/qdec.rs | 36 ++++++++++++++-------------- 6 files changed, 25 insertions(+), 32 deletions(-) diff --git a/boards/nordic/nrf52840dk/src/main.rs b/boards/nordic/nrf52840dk/src/main.rs index 50b41db2d6f..8cfb2664736 100644 --- a/boards/nordic/nrf52840dk/src/main.rs +++ b/boards/nordic/nrf52840dk/src/main.rs @@ -71,7 +71,6 @@ use nrf52840::gpio::Pin; use nrf52dk_base::{QdecPins, SpiMX25R6435FPins, SpiPins, UartPins}; - // The nRF52840DK LEDs (see back of board) const LED1_PIN: Pin = Pin::P0_13; const LED2_PIN: Pin = Pin::P0_14; diff --git a/capsules/src/lib.rs b/capsules/src/lib.rs index d32ab4db1a3..7b010c36d83 100644 --- a/capsules/src/lib.rs +++ b/capsules/src/lib.rs @@ -44,6 +44,7 @@ pub mod nonvolatile_to_pages; pub mod nrf51822_serialization; pub mod pca9544a; pub mod process_console; +pub mod qdec; pub mod rf233; pub mod rf233_const; pub mod rng; @@ -61,4 +62,3 @@ pub mod virtual_i2c; pub mod virtual_pwm; pub mod virtual_spi; pub mod virtual_uart; -pub mod qdec; diff --git a/capsules/src/qdec.rs b/capsules/src/qdec.rs index 5b44c214c6c..f7643ee2831 100644 --- a/capsules/src/qdec.rs +++ b/capsules/src/qdec.rs @@ -65,14 +65,12 @@ impl hil::qdec::QdecClient for QdecInterface<'a> { }); } } - + /// Goes through all the apps and if the app recently /// had an overflow, it records the occurance - fn overflow (&self) { + fn overflow(&self) { for cntr in self.apps.iter() { - cntr.enter(|_app, _| { - /*for now, we do not handle overflows!*/ - }); + cntr.enter(|_app, _| { /*for now, we do not handle overflows!*/ }); } } } diff --git a/chips/nrf52/src/interrupt_service.rs b/chips/nrf52/src/interrupt_service.rs index 70a99c82264..430740d4fb1 100644 --- a/chips/nrf52/src/interrupt_service.rs +++ b/chips/nrf52/src/interrupt_service.rs @@ -4,9 +4,9 @@ use crate::ble_radio; use crate::i2c; use crate::ieee802154_radio; use crate::power; +use crate::qdec; use crate::spi; use crate::uart; -use crate::qdec; use kernel::debug; use nrf5x::peripheral_interrupts; diff --git a/chips/nrf52/src/qdec.rs b/chips/nrf52/src/qdec.rs index d6431a51737..d84cf14e138 100644 --- a/chips/nrf52/src/qdec.rs +++ b/chips/nrf52/src/qdec.rs @@ -213,15 +213,11 @@ impl Qdec { 0 => { client.sample_ready(); } - 1 => { - /*No handling for REPORTRDY*/ - } + 1 => { /*No handling for REPORTRDY*/ } 2 => { client.overflow(); } - 3 => { - /*No handling for DBLRDY*/ - } + 3 => { /*No handling for DBLRDY*/ } 4 => { if self.state == 1 { self.registers.sample_per.write(SampPer::SAMPLEPER.val(5)); diff --git a/kernel/src/hil/qdec.rs b/kernel/src/hil/qdec.rs index fc4cf8d415f..ca092f7fc36 100644 --- a/kernel/src/hil/qdec.rs +++ b/kernel/src/hil/qdec.rs @@ -1,31 +1,31 @@ //! Interface for a Qdec compatible chip //! -//! This trait provides a stanfard interface for chips with a +//! This trait provides a stanfard interface for chips with a //! quadrature decoder. Any interface functions that -//! a chip cannot implement can be ignored by the chip capsule +//! a chip cannot implement can be ignored by the chip capsule use crate::returncode::ReturnCode; pub trait QdecDriver { - /// Sets the client which will receive interrupts - fn set_client(&self, client: &'static dyn QdecClient); - - /// Enables the SAMPLERDY interrupt - fn enable_interrupts (&self) -> ReturnCode; - - /// Enables the Qdec, returning error if Qdec does not exist - fn enable_qdec (&self) -> ReturnCode; + /// Sets the client which will receive interrupts + fn set_client(&self, client: &'static dyn QdecClient); - /// Checks if the qdec has been enabled - fn enabled (&self) -> ReturnCode; + /// Enables the SAMPLERDY interrupt + fn enable_interrupts(&self) -> ReturnCode; - /// Reads the accumulator value and resets it - fn get_acc (&self) -> u32; + /// Enables the Qdec, returning error if Qdec does not exist + fn enable_qdec(&self) -> ReturnCode; + + /// Checks if the qdec has been enabled + fn enabled(&self) -> ReturnCode; + + /// Reads the accumulator value and resets it + fn get_acc(&self) -> u32; } pub trait QdecClient { - /// Callback obtaining offset - fn sample_ready (&self); - /// Callback dealing with overflows - fn overflow (&self); + /// Callback obtaining offset + fn sample_ready(&self); + /// Callback dealing with overflows + fn overflow(&self); } From 91624dbfcfeff6189b0f0b6618fef969973a7637 Mon Sep 17 00:00:00 2001 From: mmurray22 <36782608+mmurray22@users.noreply.github.com> Date: Tue, 15 Sep 2020 11:07:30 -0700 Subject: [PATCH 36/39] Update kernel/src/hil/qdec.rs Co-authored-by: Hudson Ayers <32688905+hudson-ayers@users.noreply.github.com> --- kernel/src/hil/qdec.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kernel/src/hil/qdec.rs b/kernel/src/hil/qdec.rs index ca092f7fc36..eddf68e8923 100644 --- a/kernel/src/hil/qdec.rs +++ b/kernel/src/hil/qdec.rs @@ -24,7 +24,7 @@ pub trait QdecDriver { } pub trait QdecClient { - /// Callback obtaining offset + /// Indicate to the client that the status of the accumulator has changed fn sample_ready(&self); /// Callback dealing with overflows fn overflow(&self); From a302da0c186ae9f3649c7e8955c9281d06b5c61e Mon Sep 17 00:00:00 2001 From: tock Date: Wed, 16 Sep 2020 02:49:09 +0800 Subject: [PATCH 37/39] Repsonds to PR comments --- boards/nordic/nrf52dk_base/src/lib.rs | 4 +-- capsules/src/qdec.rs | 9 ++++-- chips/nrf52/src/qdec.rs | 25 +++++++++++------ kernel/src/hil/qdec.rs | 40 ++++++++++++++------------- 4 files changed, 44 insertions(+), 34 deletions(-) diff --git a/boards/nordic/nrf52dk_base/src/lib.rs b/boards/nordic/nrf52dk_base/src/lib.rs index 8f37542d976..88bf7e39640 100644 --- a/boards/nordic/nrf52dk_base/src/lib.rs +++ b/boards/nordic/nrf52dk_base/src/lib.rs @@ -14,8 +14,7 @@ use kernel::hil; use kernel::hil::gpio::{Configure, FloatingState}; use nrf52::gpio::Pin; use nrf52::rtc::Rtc; -use nrf52::uicr::Regulator0Output; //TODO is this temporary? - //use kernel::common::dynamic_deferred_call::{DynamicDeferredCall, DynamicDeferredCallClientState}; +use nrf52::uicr::Regulator0Output; pub mod nrf52_components; use nrf52_components::ble::BLEComponent; use nrf52_components::ieee802154::Ieee802154Component; @@ -113,7 +112,6 @@ pub struct Platform { // The nRF52dk does not have the flash chip on it, so we make this optional. nonvolatile_storage: Option<&'static capsules::nonvolatile_storage_driver::NonvolatileStorage<'static>>, - //_ => f(None), } impl kernel::Platform for Platform { diff --git a/capsules/src/qdec.rs b/capsules/src/qdec.rs index f7643ee2831..4a93701d302 100644 --- a/capsules/src/qdec.rs +++ b/capsules/src/qdec.rs @@ -69,9 +69,7 @@ impl hil::qdec::QdecClient for QdecInterface<'a> { /// Goes through all the apps and if the app recently /// had an overflow, it records the occurance fn overflow(&self) { - for cntr in self.apps.iter() { - cntr.enter(|_app, _| { /*for now, we do not handle overflows!*/ }); - } + /*for now, we do not handle overflows*/ } } @@ -90,6 +88,11 @@ impl Driver for QdecInterface<'a> { } /// Command switch statement for various essential processes + /// 0 is a sanity check for the switch statement + /// 1 enables the qdec + /// 2 checks that the qdec is enabled + /// 3 enables inerrupts + /// 4 gets the current displacement stored in the QDEC fn command(&self, command_num: usize, _: usize, _: usize, _app_id: AppId) -> ReturnCode { match command_num { 0 => ReturnCode::SUCCESS, diff --git a/chips/nrf52/src/qdec.rs b/chips/nrf52/src/qdec.rs index d84cf14e138..85762cbc982 100644 --- a/chips/nrf52/src/qdec.rs +++ b/chips/nrf52/src/qdec.rs @@ -71,8 +71,6 @@ register_structs! { } } -// In this section, I initialize all the bitfields associated with the type -// of register assigned to each member of the struct above. register_bitfields![u32, Task [ ENABLE 0 @@ -165,11 +163,16 @@ const QDEC_BASE: StaticRef = pub static mut QDEC: Qdec = Qdec::new(); +#[derive(PartialEq, Eq)] +enum QdecState { + Start, + Stop, +} /// Qdec type declaration: gives the Qdec instance registers and a client pub struct Qdec { registers: StaticRef, client: OptionalCell<&'static dyn kernel::hil::qdec::QdecClient>, - state: usize, + state: QdecState, } /// Qdec impl: provides the Qdec type with vital functionality including: @@ -178,7 +181,7 @@ impl Qdec { let qdec = Qdec { registers: QDEC_BASE, client: OptionalCell::empty(), - state: 0, //Start + state: QdecState::Start, }; qdec } @@ -213,16 +216,19 @@ impl Qdec { 0 => { client.sample_ready(); } - 1 => { /*No handling for REPORTRDY*/ } + 1 => { + /*No handling for REPORTRDY*/ + } 2 => { client.overflow(); } - 3 => { /*No handling for DBLRDY*/ } + 3 => { + /*No handling for DBLRDY*/ + } 4 => { - if self.state == 1 { + if self.state == QdecState::Stop { self.registers.sample_per.write(SampPer::SAMPLEPER.val(5)); self.registers.tasks_start.write(Task::ENABLE::SET); - //self.state = 0; } } _ => panic!("Unsupported interrupt value {}!", i), @@ -234,7 +240,8 @@ impl Qdec { fn enable_samplerdy_interrupts(&self) { let regs = &*self.registers; - regs.intenset.write(Inte::REPORTRDY::SET); /*SET SAMPLE READY*/ + + regs.intenset.write(Inte::REPORTRDY::SET); /*SET REPORT READY*/ regs.intenset.write(Inte::ACCOF::SET); /*SET ACCOF READY*/ } diff --git a/kernel/src/hil/qdec.rs b/kernel/src/hil/qdec.rs index ca092f7fc36..67b2a15496c 100644 --- a/kernel/src/hil/qdec.rs +++ b/kernel/src/hil/qdec.rs @@ -1,31 +1,33 @@ //! Interface for a Qdec compatible chip //! -//! This trait provides a stanfard interface for chips with a -//! quadrature decoder. Any interface functions that -//! a chip cannot implement can be ignored by the chip capsule +//! This trait provides a stanfard interface for chips with a +//! quadrature decoder. Note this interface is experimental and +//! may need further updates once implemented on additional chips use crate::returncode::ReturnCode; pub trait QdecDriver { - /// Sets the client which will receive interrupts - fn set_client(&self, client: &'static dyn QdecClient); + /// Sets the client which will receive interrupts + fn set_client(&self, client: &'static dyn QdecClient); + + /// Enables the SAMPLERDY interrupt + fn enable_interrupts (&self) -> ReturnCode; + + /// Enables the Qdec, returning error if Qdec does not exist + fn enable_qdec (&self) -> ReturnCode; - /// Enables the SAMPLERDY interrupt - fn enable_interrupts(&self) -> ReturnCode; + /// Checks if the qdec has been enabled + fn enabled (&self) -> ReturnCode; - /// Enables the Qdec, returning error if Qdec does not exist - fn enable_qdec(&self) -> ReturnCode; - - /// Checks if the qdec has been enabled - fn enabled(&self) -> ReturnCode; - - /// Reads the accumulator value and resets it - fn get_acc(&self) -> u32; + /// Reads the accumulator value and resets it + /// Note accumulator means the measure of how many ticks the + /// QDEC has moved since the last time the function was called + fn get_acc (&self) -> u32; } pub trait QdecClient { - /// Callback obtaining offset - fn sample_ready(&self); - /// Callback dealing with overflows - fn overflow(&self); + /// Callback obtaining offset + fn sample_ready (&self); + /// Indicate to the client that an overflow has occurred + fn overflow (&self); } From 55612aaeda8e5b4c5b4fcc7f4a5a2db51cf66753 Mon Sep 17 00:00:00 2001 From: tock Date: Wed, 16 Sep 2020 02:52:25 +0800 Subject: [PATCH 38/39] Removes unneeded comments in chips --- chips/nrf52/src/qdec.rs | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/chips/nrf52/src/qdec.rs b/chips/nrf52/src/qdec.rs index 85762cbc982..8a9f51db66b 100644 --- a/chips/nrf52/src/qdec.rs +++ b/chips/nrf52/src/qdec.rs @@ -29,16 +29,6 @@ register_structs! { (0x0014 => _reserved), /// All the events which have interrupts! (0x100 => events_arr: [ReadWrite; 5]), - /// Event being generated for every new sample - ///(0x100 => events_samplerdy: Write), - /// Non-null report ready - ///(0x104 => events_reportrdy: Write), - /// ACC or ACCDBL register overflow - ///(0x108 => events_accof: Write), - /// Double displacement detected - ///(0x10C => events_dblrdy: Read), - /// events stopped - ///(0x110 => events_stopped: Read), (0x0114 => _reserved2), /// Shortcut register (0x200 => shorts: ReadWrite), From 2ca257ff6c8b669ebcf9cdc33e28bac22e851859 Mon Sep 17 00:00:00 2001 From: tock Date: Wed, 16 Sep 2020 02:54:32 +0800 Subject: [PATCH 39/39] Reformatted some files --- chips/nrf52/src/qdec.rs | 8 ++------ kernel/src/hil/qdec.rs | 30 +++++++++++++++--------------- 2 files changed, 17 insertions(+), 21 deletions(-) diff --git a/chips/nrf52/src/qdec.rs b/chips/nrf52/src/qdec.rs index 8a9f51db66b..5ee59f9c5a5 100644 --- a/chips/nrf52/src/qdec.rs +++ b/chips/nrf52/src/qdec.rs @@ -206,15 +206,11 @@ impl Qdec { 0 => { client.sample_ready(); } - 1 => { - /*No handling for REPORTRDY*/ - } + 1 => { /*No handling for REPORTRDY*/ } 2 => { client.overflow(); } - 3 => { - /*No handling for DBLRDY*/ - } + 3 => { /*No handling for DBLRDY*/ } 4 => { if self.state == QdecState::Stop { self.registers.sample_per.write(SampPer::SAMPLEPER.val(5)); diff --git a/kernel/src/hil/qdec.rs b/kernel/src/hil/qdec.rs index 733034f70e7..22a58a2c283 100644 --- a/kernel/src/hil/qdec.rs +++ b/kernel/src/hil/qdec.rs @@ -1,28 +1,28 @@ //! Interface for a Qdec compatible chip //! -//! This trait provides a stanfard interface for chips with a +//! This trait provides a stanfard interface for chips with a //! quadrature decoder. Note this interface is experimental and //! may need further updates once implemented on additional chips use crate::returncode::ReturnCode; pub trait QdecDriver { - /// Sets the client which will receive interrupts - fn set_client(&self, client: &'static dyn QdecClient); - - /// Enables the SAMPLERDY interrupt - fn enable_interrupts (&self) -> ReturnCode; - - /// Enables the Qdec, returning error if Qdec does not exist - fn enable_qdec (&self) -> ReturnCode; + /// Sets the client which will receive interrupts + fn set_client(&self, client: &'static dyn QdecClient); - /// Checks if the qdec has been enabled - fn enabled (&self) -> ReturnCode; + /// Enables the SAMPLERDY interrupt + fn enable_interrupts(&self) -> ReturnCode; - /// Reads the accumulator value and resets it - /// Note accumulator means the measure of how many ticks the - /// QDEC has moved since the last time the function was called - fn get_acc (&self) -> u32; + /// Enables the Qdec, returning error if Qdec does not exist + fn enable_qdec(&self) -> ReturnCode; + + /// Checks if the qdec has been enabled + fn enabled(&self) -> ReturnCode; + + /// Reads the accumulator value and resets it + /// Note accumulator means the measure of how many ticks the + /// QDEC has moved since the last time the function was called + fn get_acc(&self) -> u32; } pub trait QdecClient {