Skip to content

Commit

Permalink
peripherals: change adc precision to 12-bits, add infra (todo 12)
Browse files Browse the repository at this point in the history
  • Loading branch information
rrbutani committed Aug 8, 2022
1 parent 2a371ed commit 74c92fb
Show file tree
Hide file tree
Showing 11 changed files with 76 additions and 22 deletions.
2 changes: 1 addition & 1 deletion baseline-sim/src/mem_mapped.rs
Original file line number Diff line number Diff line change
Expand Up @@ -879,7 +879,7 @@ macro_rules! adc_mem_mapped {
fn from<I: Ipa> (interp: &I) -> Result<Self, Acv> {

let word = match Adc::read(interp.get_adc(), $pin) {
Ok(val) => val as Word,
Ok(val) => val.val(),
Err(err) => {
interp.set_error(Error::from(err));
0x8000
Expand Down
4 changes: 2 additions & 2 deletions baseline-sim/src/sim.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ use lc3_traits::control::rpc::{
EventFutureSharedStatePorcelain, SimpleEventFutureSharedState, EventFuture
};
use lc3_traits::error::Error;
use lc3_traits::peripherals::adc::{Adc, AdcPinArr, AdcReadError, AdcState};
use lc3_traits::peripherals::adc::{Adc, AdcPinArr, AdcReadError, AdcState, AdcReading};
use lc3_traits::peripherals::clock::Clock;
use lc3_traits::peripherals::gpio::{Gpio, GpioPinArr, GpioReadError, GpioState, GpioBank};
use lc3_traits::peripherals::pwm::{Pwm, PwmPinArr, PwmState};
Expand Down Expand Up @@ -618,7 +618,7 @@ impl<'s, I: InstructionInterpreterPeripheralAccess, S: EventFutureSharedStatePor
Adc::get_states(self.interp.get_adc())
}

fn get_adc_readings(&self) -> AdcPinArr<Result<u8, AdcReadError>> {
fn get_adc_readings(&self) -> AdcPinArr<Result<AdcReading, AdcReadError>> {
Adc::read_all(self.interp.get_adc())
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -378,6 +378,8 @@ mod read {
//}

mod write {
use lc3_traits::peripherals::adc::AdcReading;

use super::*;


Expand Down Expand Up @@ -446,10 +448,11 @@ mod write {

match got {
Enabled => {
eq!(read_adc, Ok(0),
let exp = AdcReading::new_raw(0);
eq!(read_adc, Ok(exp),
"Adc Pin {}: expected val `{:?}`, got `{:?}`.\
\n\n[Test Case: {:?}]",
pin, 0, read_adc, states
pin, exp, read_adc, states
);
},
Disabled => {
Expand Down
11 changes: 11 additions & 0 deletions isa/src/isa.rs
Original file line number Diff line number Diff line change
Expand Up @@ -706,6 +706,17 @@ bits_impl!{
u8, i8, u16, i16, u32, i32, i64, u64, isize, usize,
}

#[cfg(test)]
mod test_bits {
use super::*;

#[test]
fn bits() {
assert_eq!(0xFFFF, u32::MAX.u16(0..15));
assert_eq!(0x0FFF, u32::MAX.u16(0..11));
}
}

impl TryFrom<Word> for Instruction {
type Error = Word;

Expand Down
4 changes: 2 additions & 2 deletions os/tests/trap_tests/traps/adc.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use super::*;

use lc3_traits::peripherals::{Peripherals, adc::{Adc, AdcPin, AdcState}};
use lc3_traits::peripherals::{Peripherals, adc::{Adc, AdcPin, AdcReading, AdcState}};
use lc3_shims::peripherals::AdcShim;

use AdcState::*;
Expand Down Expand Up @@ -75,7 +75,7 @@ single_test! {
],
pre: |p| {
Adc::set_state(p, A0, Enabled).unwrap();
AdcShim::set_value(&mut *p.get_adc().write().unwrap(), A0, 10).unwrap();
AdcShim::set_value(&mut *p.get_adc().write().unwrap(), A0, AdcReading::new_raw(10)).unwrap();
},
post: |i| { eq!(i.get_word_unchecked(0x3004), 10); },
with default os,
Expand Down
12 changes: 6 additions & 6 deletions shims/src/peripherals/adc.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use lc3_traits::peripherals::adc::{
Adc, AdcMiscError, AdcPin as Pin, AdcPinArr as PinArr, AdcReadError as ReadError, AdcState,
AdcStateMismatch as StateMismatch,
AdcStateMismatch as StateMismatch, AdcReading,
};

#[derive(Debug, Clone)]
Expand All @@ -10,7 +10,7 @@ pub struct AdcShim {

#[derive(Copy, Clone, Debug, PartialEq)]
pub enum State {
Enabled(u8),
Enabled(AdcReading),
Disabled,
}

Expand All @@ -24,7 +24,7 @@ impl From<State> for AdcState {
}
}

const INIT_VALUE: u8 = 0;
const INIT_VALUE: AdcReading = AdcReading::new_raw(0);

impl Default for AdcShim {
fn default() -> Self {
Expand All @@ -42,7 +42,7 @@ impl AdcShim {
Self::default()
}

pub fn set_value(&mut self, pin: Pin, value: u8) -> Result<(), SetError> {
pub fn set_value(&mut self, pin: Pin, value: AdcReading) -> Result<(), SetError> {
use State::*;
self.states[pin] = match self.states[pin] {
Enabled(_) => Enabled(value),
Expand All @@ -66,7 +66,7 @@ impl Adc for AdcShim {
self.states[pin].into()
}

fn read(&self, pin: Pin) -> Result<u8, ReadError> {
fn read(&self, pin: Pin) -> Result<AdcReading, ReadError> {
use State::*;
match self.states[pin] {
Enabled(value) => Ok(value),
Expand Down Expand Up @@ -99,7 +99,7 @@ mod tests {

#[test]
fn set_value() {
let new_val: u8 = 1;
let new_val = AdcReading::new::<12, _>(1024u32);
assert_ne!(
INIT_VALUE, new_val,
"TEST FAULTY: new_val must not equal INIT_VALUE"
Expand Down
4 changes: 2 additions & 2 deletions traits/src/control/control.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
//! TODO!
use crate::error::Error;
use crate::peripherals::adc::{AdcPinArr, AdcReadError, AdcState};
use crate::peripherals::adc::{AdcPinArr, AdcReadError, AdcState, AdcReading};
use crate::peripherals::gpio::{GpioPinArr, GpioReadError, GpioState, GpioBank};
use crate::peripherals::pwm::{PwmPinArr, PwmState};
use crate::peripherals::timers::{TimerArr, TimerState, TimerMode};
Expand Down Expand Up @@ -277,7 +277,7 @@ pub trait Control {
fn get_gpio_readings(&self, bank: GpioBank) -> Option<GpioPinArr<Result<bool, GpioReadError>>>;

fn get_adc_states(&self) -> AdcPinArr<AdcState>;
fn get_adc_readings(&self) -> AdcPinArr<Result<u8, AdcReadError>>;
fn get_adc_readings(&self) -> AdcPinArr<Result<AdcReading, AdcReadError>>;
fn get_timer_modes(&self) -> TimerArr<TimerMode>;
fn get_timer_states(&self) -> TimerArr<TimerState>;
fn get_pwm_states(&self) -> PwmPinArr<PwmState>;
Expand Down
3 changes: 2 additions & 1 deletion traits/src/control/rpc/controller.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ use crate::control::load::{
};
use crate::control::{ProgramMetadata, DeviceInfo, UnifiedRange};
use crate::error::Error as Lc3Error;
use crate::peripherals::adc::AdcReading;
use crate::peripherals::{
adc::{AdcPinArr, AdcState, AdcReadError},
gpio::{GpioPinArr, GpioState, GpioReadError, GpioBank},
Expand Down Expand Up @@ -492,7 +493,7 @@ where
fn get_gpio_states(&self, bank: GpioBank) -> Option<GpioPinArr<GpioState>> { ctrl!(self, GetGpioStates { bank }, R::GetGpioStates(r), r) }
fn get_gpio_readings(&self, bank: GpioBank) -> Option<GpioPinArr<Result<bool, GpioReadError>>> { ctrl!(self, GetGpioReadings { bank }, R::GetGpioReadings(r), r) }
fn get_adc_states(&self) -> AdcPinArr<AdcState> { ctrl!(self, GetAdcStates, R::GetAdcStates(r), r) }
fn get_adc_readings(&self) -> AdcPinArr<Result<u8, AdcReadError>> { ctrl!(self, GetAdcReadings, R::GetAdcReadings(r), r) }
fn get_adc_readings(&self) -> AdcPinArr<Result<AdcReading, AdcReadError>> { ctrl!(self, GetAdcReadings, R::GetAdcReadings(r), r) }
fn get_timer_modes(&self) -> TimerArr<TimerMode> { ctrl!(self, GetTimerModes, R::GetTimerModes(r), r) }
fn get_timer_states(&self) -> TimerArr<TimerState> { ctrl!(self, GetTimerStates, R::GetTimerStates(r), r) }
fn get_pwm_states(&self) -> PwmPinArr<PwmState> { ctrl!(self, GetPwmStates, R::GetPwmStates(r), r) }
Expand Down
3 changes: 2 additions & 1 deletion traits/src/control/rpc/messages.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ use crate::control::load::{
};
use crate::control::{ProgramMetadata, DeviceInfo, UnifiedRange, ProcessorMode, Idx};
use crate::error::Error as Lc3Error;
use crate::peripherals::adc::AdcReading;
use crate::peripherals::{
adc::{AdcPinArr, AdcState, AdcReadError},
gpio::{GpioPinArr, GpioState, GpioReadError, GpioBank},
Expand Down Expand Up @@ -173,7 +174,7 @@ pub enum ResponseMessage { // messages for everything but tick()
GetGpioStates(Option<GpioPinArr<GpioState>>),
GetGpioReadings(Option<GpioPinArr<Result<bool, GpioReadError>>>),
GetAdcStates(AdcPinArr<AdcState>),
GetAdcReadings(AdcPinArr<Result<u8, AdcReadError>>),
GetAdcReadings(AdcPinArr<Result<AdcReading, AdcReadError>>),
GetTimerModes(TimerArr<TimerMode>),
GetTimerStates(TimerArr<TimerState>),
GetPwmStates(PwmPinArr<PwmState>),
Expand Down
44 changes: 41 additions & 3 deletions traits/src/peripherals/adc.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
//! [`Adc` trait](Adc) and associated types.
use lc3_isa::{Word, Bits};
use lc3_macros::DisplayUsingDebug;

use core::convert::TryFrom;
Expand Down Expand Up @@ -76,6 +77,42 @@ impl<T> IndexMut<AdcPin> for AdcPinArr<T> {
}


// represents a 12-bit reading, currently
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)]
#[derive(DisplayUsingDebug)]
pub struct AdcReading(Word);

impl From<AdcReading> for Word {
fn from(r: AdcReading) -> Self {
r.0
}
}

impl AdcReading {
pub const WIDTH: u8 = 12;

pub const fn new_raw(reading: Word) -> Self {
let val = reading & 0x0FFFF;
Self(val)
}

#[inline(always)]
pub fn new<const WIDTH: u8, R: Into<u64>>(reading: R) -> Self {
let val = reading.into();
let val = if WIDTH >= Self::WIDTH {
val >> (WIDTH - Self::WIDTH)
} else {
val << (Self::WIDTH - WIDTH)
};

let val = val.u16(0..((Self::WIDTH - 1) as u32));

Self(val)
}

pub fn val(self) -> Word { self.0 }
}

/// Adc access for the interpreter.
#[ambassador::delegatable_trait]
pub trait Adc {
Expand All @@ -92,11 +129,12 @@ pub trait Adc {
states
}

fn read(&self, pin: AdcPin) -> Result<u8, AdcReadError>;
// TODO: remove the pin from these error types, like with GPIO!
fn read(&self, pin: AdcPin) -> Result<AdcReading, AdcReadError>;
#[inline]
fn read_all(&self) -> AdcPinArr<Result<u8, AdcReadError>> {
fn read_all(&self) -> AdcPinArr<Result<AdcReading, AdcReadError>> {
// TODO: Error conversion impl (see Gpio)
let mut readings = AdcPinArr([Ok(0u8); AdcPin::NUM_PINS]); // TODO: that we need a default value here is weird and bad...
let mut readings = AdcPinArr([Err(AdcReadError((AdcPin::A0, AdcState::Disabled))); AdcPin::NUM_PINS]); // TODO: that we need a default value here is weird and bad...

ADC_PINS
.iter()
Expand Down
4 changes: 2 additions & 2 deletions traits/src/peripherals/stubs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,12 +33,12 @@ impl Gpio for GpioStub {
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Default)]
pub struct AdcStub;

use super::adc::{AdcPin, AdcState, AdcReadError, AdcMiscError};
use super::adc::{AdcPin, AdcState, AdcReadError, AdcMiscError, AdcReading};
impl Adc for AdcStub {
fn set_state(&mut self, _pin: AdcPin, _: AdcState) -> Result<(), AdcMiscError> { Err(AdcMiscError) }
fn get_state(&self, _pin: AdcPin) -> AdcState { AdcState::Disabled }

fn read(&self, pin: AdcPin) -> Result<u8, AdcReadError> { Err(AdcReadError((pin, AdcState::Disabled)))}
fn read(&self, pin: AdcPin) -> Result<AdcReading, AdcReadError> { Err(AdcReadError((pin, AdcState::Disabled)))}
}

#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Default)]
Expand Down

0 comments on commit 74c92fb

Please sign in to comment.