use crate::Error;
pub const DEVICE_ID: u16 = 0x0424;
pub const MAX_ADDRESS: u8 = 0x73;
pub const REG_DEVICE_ID: u8 = 0x00;
pub const REG_INTERRUPT: u8 = 0x01;
pub const REG_GPI_STATUS: u8 = 0x06;
pub const REG_GPO_DATA: u8 = 0x0D;
pub const REG_DEVICE_CTRL: u8 = 0x10;
pub const REG_INTERRUPT_MASK: u8 = 0x11;
pub const REG_IRQ_MODE: u8 = 0x12;
pub const REG_PORT_CONFIG: u8 = 0x20;
pub const REG_ADC_DATA: u8 = 0x40;
pub const REG_DAC_DATA: u8 = 0x60;
#[repr(u8)]
#[derive(Clone, Copy, PartialEq, Eq)]
pub enum Port {
P0,
P1,
P2,
P3,
P4,
P5,
P6,
P7,
P8,
P9,
P10,
P11,
P12,
P13,
P14,
P15,
P16,
P17,
P18,
P19,
}
impl Port {
pub fn as_config_addr(&self) -> u8 {
REG_PORT_CONFIG + *self as u8
}
pub fn as_u16(&self) -> u16 {
*self as u16
}
pub fn as_usize(&self) -> usize {
*self as usize
}
}
impl TryFrom<usize> for Port {
type Error = Error<(), ()>;
fn try_from(value: usize) -> Result<Self, Self::Error> {
match value {
0 => Ok(Port::P0),
1 => Ok(Port::P1),
2 => Ok(Port::P2),
3 => Ok(Port::P3),
4 => Ok(Port::P4),
5 => Ok(Port::P5),
6 => Ok(Port::P6),
7 => Ok(Port::P7),
8 => Ok(Port::P8),
9 => Ok(Port::P9),
10 => Ok(Port::P10),
11 => Ok(Port::P11),
12 => Ok(Port::P12),
13 => Ok(Port::P13),
14 => Ok(Port::P14),
15 => Ok(Port::P15),
16 => Ok(Port::P16),
17 => Ok(Port::P17),
18 => Ok(Port::P18),
19 => Ok(Port::P19),
_ => Err(Error::Port),
}
}
}
#[repr(u8)]
#[derive(Clone, Copy)]
pub enum ADCCTL {
IdleMode,
SingleSweep,
SingleConversion,
ContinuousSweep,
}
#[repr(u8)]
#[derive(Clone, Copy)]
pub enum DACCTL {
Sequential,
Immediate,
PresetData1,
PresetData2,
}
#[repr(u8)]
#[derive(Clone, Copy)]
pub enum ADCCONV {
Rate200,
Rate250,
Rate333,
Rate400,
}
#[repr(u8)]
#[derive(Clone, Copy)]
pub enum DACREF {
ExternalRef,
InternalRef,
}
#[repr(u8)]
#[derive(Clone, Copy)]
pub enum THSHDN {
Disabled,
Enabled,
}
#[derive(Clone, Copy)]
pub struct TMPCTL(u8, u8, u8);
impl From<TMPCTL> for u16 {
fn from(tmpctl: TMPCTL) -> Self {
((tmpctl.2 as u16) << 2) | ((tmpctl.1 as u16) << 1) | tmpctl.0 as u16
}
}
#[repr(u8)]
#[derive(Clone, Copy)]
pub enum TMPPER {
Default,
Extended,
}
#[repr(u8)]
#[derive(Clone, Copy)]
pub enum RSCANCEL {
Disabled,
Enabled,
}
#[repr(u8)]
#[derive(Clone, Copy)]
pub enum LPEN {
Default,
LowPower,
}
#[repr(u8)]
#[derive(Clone, Copy)]
pub enum BRST {
Default,
Contextual,
}
#[derive(Clone, Copy)]
pub struct DeviceConfig {
pub adcctl: ADCCTL,
pub dacctl: DACCTL,
pub adcconv: ADCCONV,
pub dacref: DACREF,
pub thshdn: THSHDN,
pub tmpctl: TMPCTL,
pub tmpper: TMPPER,
pub rscancel: RSCANCEL,
pub lpen: LPEN,
pub brst: BRST,
}
impl DeviceConfig {
pub fn as_u16(&self) -> u16 {
((self.brst as u16) << 14)
| ((self.lpen as u16) << 13)
| ((self.rscancel as u16) << 12)
| ((self.tmpper as u16) << 11)
| (u16::from(self.tmpctl) << 8)
| ((self.thshdn as u16) << 7)
| ((self.dacref as u16) << 6)
| ((self.adcconv as u16) << 4)
| ((self.dacctl as u16) << 2)
| self.adcctl as u16
}
}
impl Default for DeviceConfig {
fn default() -> Self {
Self {
adcctl: ADCCTL::IdleMode,
dacctl: DACCTL::Sequential,
adcconv: ADCCONV::Rate200,
dacref: DACREF::ExternalRef,
thshdn: THSHDN::Disabled,
tmpctl: TMPCTL(0, 0, 0),
tmpper: TMPPER::Default,
rscancel: RSCANCEL::Disabled,
lpen: LPEN::Default,
brst: BRST::Default,
}
}
}
pub struct Interrupts {
pub adcflag: bool,
pub adcdr: bool,
pub adcdm: bool,
pub gpidr: bool,
pub gpidm: bool,
pub dacoi: bool,
pub tmpint: (bool, bool, bool),
pub tmpext1: (bool, bool, bool),
pub tmpext2: (bool, bool, bool),
pub vmon: bool,
}
impl From<u16> for Interrupts {
fn from(int: u16) -> Self {
Self {
adcflag: int & (1 << 0) != 0,
adcdr: int & (1 << 1) != 0,
adcdm: int & (1 << 2) != 0,
gpidr: int & (1 << 3) != 0,
gpidm: int & (1 << 4) != 0,
dacoi: int & (1 << 5) != 0,
tmpint: (
int & (1 << 6) != 0,
int & (1 << 7) != 0,
int & (1 << 8) != 0,
),
tmpext1: (
int & (1 << 9) != 0,
int & (1 << 10) != 0,
int & (1 << 11) != 0,
),
tmpext2: (
int & (1 << 12) != 0,
int & (1 << 13) != 0,
int & (1 << 14) != 0,
),
vmon: int & (1 << 15) != 0,
}
}
}
#[repr(u8)]
#[derive(Clone, Copy)]
pub enum INV {
NotInverted,
Inverted,
}
impl INV {
pub fn mask() -> u16 {
0xf7ff
}
pub fn as_u16(&self) -> u16 {
(*self as u16) << 11
}
}
#[repr(u8)]
#[derive(Clone, Copy)]
pub enum AVR {
InternalRef,
ExternalRef,
}
impl AVR {
pub fn mask() -> u16 {
0xf7ff
}
pub fn as_u16(&self) -> u16 {
(*self as u16) << 11
}
}
#[repr(u8)]
#[derive(Clone, Copy)]
pub enum ADCRANGE {
Rg0_10v = 1,
RgNeg5_5v,
RgNeg10_0v,
Rg0_2v5,
Rg0_2v5_1 = 6,
}
impl ADCRANGE {
pub fn mask() -> u16 {
0xf8ff
}
pub fn as_u16(&self) -> u16 {
(*self as u16) << 8
}
}
#[repr(u8)]
#[derive(Clone, Copy)]
pub enum DACRANGE {
Rg0_10v = 1,
RgNeg5_5v,
RgNeg10_0v,
RgNeg5_5v1,
Rg0_10v1 = 6,
}
impl DACRANGE {
pub fn mask() -> u16 {
0xf8ff
}
pub fn as_u16(&self) -> u16 {
(*self as u16) << 8
}
}
#[repr(u8)]
#[derive(Clone, Copy)]
pub enum NSAMPLES {
Samples1,
Samples2,
Samples4,
Samples8,
Samples16,
Samples32,
Samples64,
Samples128,
}
impl NSAMPLES {
pub fn mask() -> u16 {
0xff1f
}
pub fn as_u16(&self) -> u16 {
(*self as u16) << 5
}
}
#[repr(u8)]
#[derive(Clone, Copy)]
pub enum GPIMD {
Never,
PositiveEdge,
NegativeEdge,
BothEdges,
}
#[derive(Clone, Copy)]
pub struct ConfigMode0;
impl ConfigMode0 {
pub(crate) fn as_u16(&self) -> u16 {
0x0
}
}
#[derive(Clone, Copy)]
pub struct ConfigMode1;
impl ConfigMode1 {
pub(crate) fn as_u16(&self) -> u16 {
0x1 << 12
}
}
#[derive(Clone, Copy)]
pub struct ConfigMode2;
impl ConfigMode2 {
pub(crate) fn as_u16(&self) -> u16 {
0x2 << 12
}
}
#[derive(Clone, Copy)]
pub struct ConfigMode3;
impl ConfigMode3 {
pub(crate) fn as_u16(&self) -> u16 {
0x3 << 12
}
}
#[derive(Clone, Copy)]
pub struct ConfigMode4(pub INV, pub Port);
impl ConfigMode4 {
pub(crate) fn as_u16(&self) -> u16 {
(0x4 << 12) | self.0.as_u16() | self.1 as u16
}
}
#[derive(Clone, Copy)]
pub struct ConfigMode5(pub DACRANGE);
impl ConfigMode5 {
pub(crate) fn as_u16(&self) -> u16 {
(0x5 << 12) | self.0.as_u16()
}
}
#[derive(Clone, Copy)]
pub struct ConfigMode6(pub AVR, pub DACRANGE);
impl ConfigMode6 {
pub(crate) fn as_u16(&self) -> u16 {
(0x6 << 12) | self.0.as_u16() | self.1.as_u16()
}
}
#[derive(Clone, Copy)]
pub struct ConfigMode7(pub AVR, pub ADCRANGE, pub NSAMPLES);
impl ConfigMode7 {
pub(crate) fn as_u16(&self) -> u16 {
(0x7 << 12) | self.0.as_u16() | self.1.as_u16() | self.2.as_u16()
}
}
#[derive(Clone, Copy)]
pub struct ConfigMode8(pub AVR, pub ADCRANGE, pub NSAMPLES, pub Port);
impl ConfigMode8 {
pub(crate) fn as_u16(&self) -> u16 {
(0x8 << 12) | self.0.as_u16() | self.1.as_u16() | self.2.as_u16() | self.3.as_u16()
}
}
#[derive(Clone, Copy)]
pub struct ConfigMode9(pub AVR, pub ADCRANGE);
impl ConfigMode9 {
pub(crate) fn as_u16(&self) -> u16 {
(0x9 << 12) | self.0.as_u16() | self.1.as_u16()
}
}
#[derive(Clone, Copy)]
pub struct ConfigMode10(pub AVR, pub DACRANGE);
impl ConfigMode10 {
pub(crate) fn as_u16(&self) -> u16 {
(0xa << 12) | self.0.as_u16() | self.1.as_u16()
}
}
#[derive(Clone, Copy)]
pub struct ConfigMode11(pub INV, pub Port);
impl ConfigMode11 {
pub(crate) fn as_u16(&self) -> u16 {
(0xb << 12) | self.0.as_u16() | self.1.as_u16()
}
}
#[derive(Clone, Copy)]
pub struct ConfigMode12(pub INV, pub Port);
impl ConfigMode12 {
pub(crate) fn as_u16(&self) -> u16 {
0xc << 12
}
}
#[derive(Clone, Copy)]
pub enum Mode {
Mode0(ConfigMode0),
Mode1(ConfigMode1),
Mode2(ConfigMode2),
Mode3(ConfigMode3),
Mode4(ConfigMode4),
Mode5(ConfigMode5),
Mode6(ConfigMode6),
Mode7(ConfigMode7),
Mode8(ConfigMode8),
Mode9(ConfigMode9),
Mode10(ConfigMode10),
Mode11(ConfigMode11),
Mode12(ConfigMode12),
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn default_config() {
let config = DeviceConfig::default();
assert_eq!(config.as_u16(), 0);
}
}