use embedded_hal::i2c::I2c;
use rusty_esp_core::error::{Error, Result};
use super::{Bits, CodecChip, I2cRegs, I2sFormat, Module};
pub const ADDR: u8 = 0x10;
pub const REG_PGA1: u8 = 0x20;
pub const REG_PGA2: u8 = 0x21;
pub const INIT: &[(u8, u8)] = &[
(0x01, 0x3A),
(0x00, 0x80),
(0xF9, 0x00),
(0x04, 0x02),
(0x04, 0x01),
(0xF9, 0x01),
(0x00, 0x1E),
(0x01, 0x00),
(0x02, 0x00),
(0x03, 0x20),
(0x04, 0x01),
(0x0D, 0x00),
(0x05, 0x00),
(0x06, 0x03), (0x07, 0x00), (0x08, 0xFF), (0x09, 0xCA),
(0x0A, 0x85),
(0x0B, 0x00),
(0x0E, 0xBF),
(0x0F, 0x80),
(0x14, 0x0C),
(0x15, 0x0C),
(0x17, 0x02),
(0x18, 0x26),
(0x19, 0x77),
(0x1A, 0xF4),
(0x1B, 0x66),
(0x1C, 0x44),
(0x1E, 0x00),
(0x1F, 0x0C),
(REG_PGA1, 0x1A), (REG_PGA2, 0x1A), (0x00, 0x80), (0x01, 0x3A),
(0x16, 0x3F),
(0x16, 0x00),
];
pub const START: &[(u8, u8)] = &[
(0xF9, 0x00),
(0x04, 0x01),
(0x17, 0x01),
(REG_PGA1, 0x10),
(REG_PGA2, 0x10),
(0x00, 0x80),
(0x01, 0x3A),
(0x16, 0x3F),
(0x16, 0x00),
];
pub const STOP: &[(u8, u8)] = &[
(0x04, 0x02),
(0x04, 0x01),
(0xF7, 0x30),
(0xF9, 0x01),
(0x16, 0xFF),
(0x17, 0x00),
(0x01, 0x38),
(REG_PGA1, 0x00),
(REG_PGA2, 0x00),
(0x00, 0x00),
(0x00, 0x1E),
(0x01, 0x30),
(0x01, 0x00),
];
#[derive(Debug)]
pub struct Es7243e<I> {
regs: I2cRegs<I>,
}
impl<I: I2c> Es7243e<I> {
pub fn new(i2c: I, addr: u8) -> Self {
Es7243e {
regs: I2cRegs::new(i2c, addr),
}
}
pub fn release(self) -> I {
self.regs.release()
}
pub fn regs(&mut self) -> &mut I2cRegs<I> {
&mut self.regs
}
pub fn init(&mut self) -> Result<()> {
self.write_all(INIT)
}
pub fn set_pga_code(&mut self, code: u8) -> Result<()> {
self.regs.write(REG_PGA1, code)?;
self.regs.write(REG_PGA2, code)
}
fn write_all(&mut self, table: &[(u8, u8)]) -> Result<()> {
for &(r, v) in table {
self.regs.write(r, v)?;
}
Ok(())
}
}
impl<I: I2c> CodecChip for Es7243e<I> {
fn set_sample_rate(&mut self, _sample_rate_hz: u32, _mclk_hz: u32) -> Result<()> {
Ok(())
}
fn set_format(&mut self, fmt: I2sFormat, bits: Bits) -> Result<()> {
match (fmt, bits) {
(I2sFormat::Standard, Bits::B16) => Ok(()),
_ => Err(Error::Unsupported),
}
}
fn start(&mut self, module: Module) -> Result<()> {
if module == Module::Dac {
return Err(Error::Unsupported);
}
self.write_all(START)
}
fn stop(&mut self) -> Result<()> {
self.write_all(STOP)
}
fn set_mute(&mut self, _mute: bool) -> Result<()> {
Err(Error::Unsupported)
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::chip::fake::FakeCodec;
#[test]
fn init_start_stop_are_the_vendor_tables_in_order() {
let mut chip = Es7243e::new(FakeCodec::default(), ADDR);
chip.init().unwrap();
chip.start(Module::Adc).unwrap();
chip.stop().unwrap();
let bus = chip.release();
assert_eq!(bus.addr_seen, Some(0x10));
let expected: Vec<(u8, u8)> = INIT.iter().chain(START).chain(STOP).copied().collect();
assert_eq!(bus.writes, expected);
assert_eq!((INIT.len(), START.len(), STOP.len()), (37, 9, 13));
assert_eq!(bus.reg(REG_PGA1), 0x00, "stop leaves the PGAs off");
}
#[test]
fn pga_and_the_refusals() {
let mut chip = Es7243e::new(FakeCodec::default(), ADDR);
chip.init().unwrap();
assert_eq!(chip.regs().bus().reg(REG_PGA1), 0x1A);
chip.set_pga_code(0x10).unwrap();
assert_eq!(chip.regs().bus().reg(REG_PGA2), 0x10);
let writes = chip.regs().bus().writes.len();
assert_eq!(chip.start(Module::Dac), Err(Error::Unsupported));
assert_eq!(chip.set_mute(true), Err(Error::Unsupported));
assert_eq!(
chip.set_format(I2sFormat::LeftJustified, Bits::B16),
Err(Error::Unsupported)
);
chip.set_format(I2sFormat::Standard, Bits::B16).unwrap();
chip.set_sample_rate(16_000, 4_096_000).unwrap();
assert_eq!(
chip.regs().bus().writes.len(),
writes,
"nothing written by any of those"
);
}
}