use std::sync::{Arc, Mutex, LazyLock};
use crate::error::{Error, Result};
use bitvec::prelude::*;
struct KBusState {
input_data: BitVec<u8>,
output_data: BitVec<u8>,
}
impl Default for KBusState {
fn default() -> Self {
Self {
input_data: bitvec![u8, LocalBits; 0; 90],
output_data: bitvec![u8, LocalBits; 0; 90],
}
}
}
static KBUS_STATE: LazyLock<Arc<Mutex<KBusState>>> =
LazyLock::new(|| Arc::new(Mutex::new(KBusState::default())));
pub struct Writer<'a> {
_dev: &'a mut KBus,
_task_id: u32,
}
impl<'a> Writer<'a> {
fn new(_dev: &'a mut KBus, _task_id: u32) -> Result<Writer<'a>> {
Ok(Writer {
_dev,
_task_id,
})
}
pub fn write_bit(&mut self, bit_offset: u32, data: &mut u8) -> Result<()> {
let mut state = KBUS_STATE.lock().unwrap();
let bit_offset = bit_offset as usize;
if bit_offset >= state.output_data.len() {
return Err(Error::OperationFailed("Offset out of range".to_string()));
}
state.output_data.set(bit_offset, *data & 1 != 0);
Ok(())
}
pub fn write_bool(&mut self, bit_offset: u32, value: bool) -> Result<()> {
let mut state = KBUS_STATE.lock().unwrap();
let bit_offset = bit_offset as usize;
if bit_offset >= state.output_data.len() {
return Err(Error::OperationFailed("Offset out of range".to_string()));
}
state.output_data.set(bit_offset, value);
Ok(())
}
pub fn write_bytes(&mut self, offset: u32, data: &mut [u8]) -> Result<()> {
let mut state = KBUS_STATE.lock().unwrap();
let bit_offset = offset as usize;
if bit_offset + (data.len() * 8) > state.output_data.len() {
return Err(Error::OperationFailed(
"Write exceeds buffer size".to_string(),
));
}
for (i, byte) in data.iter().enumerate() {
let byte_start = bit_offset + (i * 8);
for j in 0..8 {
let bit_value = (*byte >> j) & 1 != 0;
state.output_data.set(byte_start + j, bit_value);
}
}
Ok(())
}
}
pub struct Reader<'a> {
_dev: &'a mut KBus,
_task_id: u32,
}
impl<'a> Reader<'a> {
fn new(_dev: &'a mut KBus, _task_id: u32) -> Result<Reader<'a>> {
Ok(Reader {
_dev,
_task_id,
})
}
pub fn read_bit(&mut self, bit_offset: u32, data: &mut u8) -> Result<()> {
let state = KBUS_STATE.lock().unwrap();
let bit_offset = bit_offset as usize;
if bit_offset >= state.input_data.len() {
return Err(Error::OperationFailed("Offset out of range".to_string()));
}
*data = state.input_data[bit_offset] as u8;
Ok(())
}
pub fn read_bool(&mut self, bit_offset: u32, value: &mut bool) -> Result<()> {
let state = KBUS_STATE.lock().unwrap();
let bit_offset = bit_offset as usize;
if bit_offset >= state.input_data.len() {
return Err(Error::OperationFailed("Offset out of range".to_string()));
}
*value = state.input_data[bit_offset];
Ok(())
}
pub fn read_bytes(&mut self, offset: u32, data: &mut [u8]) -> Result<()> {
let state = KBUS_STATE.lock().unwrap();
let bit_offset = offset as usize;
if bit_offset > state.input_data.len() {
return Err(Error::OperationFailed(
"Read exceeds buffer size".to_string(),
));
}
for (i, byte) in data.iter_mut().enumerate() {
*byte = 0; let byte_start = bit_offset + (i * 8);
for j in 0..8 {
if byte_start + j >= state.input_data.len() {
break;
}
if state.input_data[byte_start + j] {
*byte |= 1 << j;
}
}
}
Ok(())
}
}
pub struct KBus {
is_open: bool,
}
impl KBus {
pub fn new() -> Result<KBus> {
Ok(KBus { is_open: true })
}
pub fn start(&mut self) -> Result<()> {
Ok(())
}
pub fn stop(&mut self) -> Result<()> {
Ok(())
}
pub fn reset(&mut self) -> Result<()> {
Ok(())
}
pub fn trigger_bus_cycle(&mut self) -> Result<()> {
Ok(())
}
pub fn io_sizes(&mut self) -> Result<(u32, u32)> {
Ok((90, 90))
}
pub fn writer(&mut self) -> Result<Writer> {
let task_id = 0;
Writer::new(self, task_id)
}
pub fn reader(&mut self) -> Result<Reader> {
let task_id = 0;
Reader::new(self, task_id)
}
}
impl Drop for KBus {
fn drop(&mut self) {
self.is_open = false;
}
}
pub fn set_input_bit(bit_offset: u32, value: bool) -> Result<()> {
let mut state = KBUS_STATE.lock().unwrap();
let bit_offset = bit_offset as usize;
if bit_offset >= state.input_data.len() {
return Err(Error::OperationFailed("Offset out of range".to_string()));
}
state.input_data.set(bit_offset, value);
Ok(())
}
pub fn get_output_bit(bit_offset: u32) -> Result<bool> {
let state = KBUS_STATE.lock().unwrap();
let bit_offset = bit_offset as usize;
if bit_offset >= state.output_data.len() {
return Err(Error::OperationFailed("Offset out of range".to_string()));
}
Ok(state.output_data[bit_offset])
}
pub fn reset_state() {
let mut state = KBUS_STATE.lock().unwrap();
state.input_data.fill(false);
state.output_data.fill(false);
}