serial clock @ 8khz

This commit is contained in:
Alex Janka 2023-03-16 18:42:23 +11:00
parent 7fb8b06ff9
commit 8dc01b59c2

View file

@ -5,7 +5,7 @@ use std::{
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use crate::util::get_bit; use crate::{constants::CLOCK_SPEED, util::get_bit};
#[derive(Copy, Clone, Serialize, Deserialize, Debug, PartialEq)] #[derive(Copy, Clone, Serialize, Deserialize, Debug, PartialEq)]
enum ClockSource { enum ClockSource {
@ -58,6 +58,7 @@ struct InputByte {
} }
const BYTE_DELAY: usize = 2000; const BYTE_DELAY: usize = 2000;
const CLOCK_DIV: usize = CLOCK_SPEED / 8192;
impl InputByte { impl InputByte {
fn advance(&mut self, rx: &Option<Receiver<u8>>) -> u8 { fn advance(&mut self, rx: &Option<Receiver<u8>>) -> u8 {
@ -104,6 +105,7 @@ pub struct Serial {
bits_remaining: u8, bits_remaining: u8,
control: SerialControl, control: SerialControl,
target: SerialTarget, target: SerialTarget,
clock_inc: usize,
} }
#[derive(Serialize, Deserialize)] #[derive(Serialize, Deserialize)]
@ -113,6 +115,7 @@ pub struct SerialSaveState {
input_byte: InputByte, input_byte: InputByte,
bits_remaining: u8, bits_remaining: u8,
control: SerialControl, control: SerialControl,
clock_inc: usize,
} }
impl SerialSaveState { impl SerialSaveState {
@ -123,6 +126,7 @@ impl SerialSaveState {
input_byte: serial.input_byte, input_byte: serial.input_byte,
bits_remaining: serial.bits_remaining, bits_remaining: serial.bits_remaining,
control: serial.control, control: serial.control,
clock_inc: serial.clock_inc,
} }
} }
} }
@ -136,6 +140,7 @@ impl Serial {
bits_remaining: 7, bits_remaining: 7,
control: SerialControl::default(), control: SerialControl::default(),
target, target,
clock_inc: 0,
} }
} }
@ -147,6 +152,7 @@ impl Serial {
bits_remaining: state.bits_remaining, bits_remaining: state.bits_remaining,
control: state.control, control: state.control,
target, target,
clock_inc: state.clock_inc,
} }
} }
@ -165,36 +171,40 @@ impl Serial {
&None &None
}; };
for _ in 0..steps { for _ in 0..steps {
if ime { self.clock_inc += 1;
self.input_byte.input_delay = self.input_byte.input_delay.saturating_sub(1); if self.clock_inc >= CLOCK_DIV {
} self.clock_inc %= CLOCK_DIV;
if (self.control.transfer_in_progress if ime {
&& self.control.clock_source == ClockSource::Internal) self.input_byte.input_delay = self.input_byte.input_delay.saturating_sub(1);
|| (self.control.clock_source == ClockSource::External }
&& self.input_byte.is_ready(rx) if (self.control.transfer_in_progress
&& ime) && self.control.clock_source == ClockSource::Internal)
{ || (self.control.clock_source == ClockSource::External
self.output_byte = self.output_byte << 1 | self.byte >> 7; && self.input_byte.is_ready(rx)
self.byte = (self.byte << 1) | self.input_byte.advance(rx); && ime)
let (remainder, finished) = self.bits_remaining.overflowing_sub(1); {
self.bits_remaining = if finished { self.output_byte = self.output_byte << 1 | self.byte >> 7;
self.control.transfer_in_progress = false; self.byte = (self.byte << 1) | self.input_byte.advance(rx);
will_interrupt = true; let (remainder, finished) = self.bits_remaining.overflowing_sub(1);
match &self.target { self.bits_remaining = if finished {
SerialTarget::Stdout => { self.control.transfer_in_progress = false;
print!("{}", self.output_byte as char); will_interrupt = true;
stdout().flush().unwrap(); match &self.target {
} SerialTarget::Stdout => {
SerialTarget::Custom { rx: _, tx } => { print!("{}", self.output_byte as char);
if let Some(tx) = tx { stdout().flush().unwrap();
tx.send(self.output_byte).unwrap();
} }
SerialTarget::Custom { rx: _, tx } => {
if let Some(tx) = tx {
tx.send(self.output_byte).unwrap();
}
}
SerialTarget::None => {}
} }
SerialTarget::None => {} 7
} else {
remainder
} }
7
} else {
remainder
} }
} }
} }