// Oscillator use devices::DeviceImpl; use slog::Logger; const OSC_CTRL: u32 = 0; const OSC_STATUS: u32 = 1; const OSC_XOSCCTRL: u32 = 2; const OSC_XOSCFAIL: u32 = 3; /* const OSC_RC32KCAL: u32 = 4; const OSC_PLLCTRL: u32 = 5; const OSC_DFLLCTRL: u32 = 6; */ /* enum PllSrc { RC2M, RC32M, XOSC, } */ pub struct Oscillator { log: Logger, reg_values: [u8; 7], // Real attributes: ctrl: u8, status: u8, xoscctrl: u8, /* xoscfail: u8, rs32kcal: u8, pllsrc: PllSrc, pllfac: u8, dfllctrl: u8, */ } impl Oscillator { pub fn new(log: Logger) -> Self { Self { log, reg_values: [0u8; 7], ctrl: 0, status: 0, xoscctrl: 0, /* xoscfail: 0, rs32kcal: 0, pllsrc: PllSrc::RC2M, pllfac: 0, dfllctrl: 0, */ } } } impl DeviceImpl for Oscillator { fn read(&mut self, addr: u32) -> u8 { match addr { OSC_CTRL => { // PLL and clock ready. return self.ctrl | 0x30; } OSC_STATUS => { return self.status | 0x30; } _ => {} } self.reg_values[addr as usize] } fn write(&mut self, addr: u32, value: u8) { match addr { OSC_CTRL => { info!(self.log, "OSC_CTRL <= {:02X}", value); self.ctrl = value & 0x1F; self.status = value & 0x1F; } OSC_XOSCCTRL => { self.xoscctrl = value & 0xEF; } OSC_XOSCFAIL => {} _ => {} } self.reg_values[addr as usize] = value; } /* } else if(addr == 0x03) { // XOSCFAIL XOSCFAIL vreg; vreg.data = v & 0x03; // XOSCFDEN if(!xoscfail_.xoscfden && vreg.xoscfden) { if(device_->ccpState() & Device::CCP_IOREG) { xoscfail_.xoscfden = 1; } else { LOGF(ERROR, "cannot set XOSCFAIL.XOSCFDEN: protected by CCP"); } } else if(xoscfail_.xoscfden && !vreg.xoscfden) { LOGF(ERROR, "XOSCFAIL.XOSCFDEN cannot be cleared"); } // XOSCFDIF if(vreg.xoscfdif) { xoscfail_.xoscfdif = 0; } } else if(addr == 0x04) { // RC32KCAL rc32kcal_ = v; } else if(addr == 0x05) { // PLLCTRL if((v >> 6) == 1) { LOGF(ERROR, "invalid PLLSRC value"); } else { pllsrc_ = static_cast(v >> 6); } pllfac_ = v & 0x1F; } else if(addr == 0x06) { // DFLLCTRL //TODO no check nor handling is made here dfllctrl_.data = v & 0x03; } else { LOGF(ERROR, "I/O write %s + 0x%02X: not writable") % name() % addr; } */ }