mirror of
https://github.com/italicsjenga/agb.git
synced 2025-01-10 00:51:34 +11:00
almost implemented normal link port function
This commit is contained in:
parent
e1ac328ce6
commit
6be8f02fd3
|
@ -10,6 +10,8 @@
|
||||||
any(test, feature = "testing"),
|
any(test, feature = "testing"),
|
||||||
reexport_test_harness_main = "test_main"
|
reexport_test_harness_main = "test_main"
|
||||||
)]
|
)]
|
||||||
|
#![allow(incomplete_features)]
|
||||||
|
#![feature(adt_const_params)]
|
||||||
#![feature(alloc_error_handler)]
|
#![feature(alloc_error_handler)]
|
||||||
#![feature(allocator_api)]
|
#![feature(allocator_api)]
|
||||||
#![feature(asm_const)]
|
#![feature(asm_const)]
|
||||||
|
|
|
@ -1,9 +1,16 @@
|
||||||
|
use self::uart::UartSioControl;
|
||||||
|
pub use self::{
|
||||||
|
normal::{ClockSource, LinkPortNormal},
|
||||||
|
uart::{BaudRate, LinkPortUart},
|
||||||
|
};
|
||||||
|
use crate::memory_mapped::MemoryMapped;
|
||||||
use core::ops::{Deref, DerefMut};
|
use core::ops::{Deref, DerefMut};
|
||||||
|
|
||||||
use embedded_hal::serial::{Read, Write};
|
mod normal;
|
||||||
|
mod uart;
|
||||||
use crate::{memory_mapped::MemoryMapped, println};
|
|
||||||
|
|
||||||
|
// const SIODATA32LOW: MemoryMapped<u16> = unsafe { MemoryMapped::new(0x0400_0120) };
|
||||||
|
// const SIODATA32HIGH: MemoryMapped<u16> = unsafe { MemoryMapped::new(0x0400_0122) };
|
||||||
const SIODATA8: MemoryMapped<u16> = unsafe { MemoryMapped::new(0x0400_012A) };
|
const SIODATA8: MemoryMapped<u16> = unsafe { MemoryMapped::new(0x0400_012A) };
|
||||||
const SIOCNT: MemoryMapped<u16> = unsafe { MemoryMapped::new(0x0400_0128) };
|
const SIOCNT: MemoryMapped<u16> = unsafe { MemoryMapped::new(0x0400_0128) };
|
||||||
const RCNT: MemoryMapped<u16> = unsafe { MemoryMapped::new(0x0400_0134) };
|
const RCNT: MemoryMapped<u16> = unsafe { MemoryMapped::new(0x0400_0134) };
|
||||||
|
@ -13,76 +20,11 @@ pub enum LinkPortError {
|
||||||
GbaErrorBit,
|
GbaErrorBit,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct LinkPortUart;
|
#[allow(dead_code)]
|
||||||
|
enum SioControlReg {
|
||||||
impl LinkPortUart {
|
Normal,
|
||||||
pub fn init(rate: BaudRate, with_interrupts: bool, clear_to_send: bool) -> Self {
|
Multi,
|
||||||
println!("begin init");
|
Uart(UartSioControl),
|
||||||
RCNT.set(0x0);
|
|
||||||
println!("have set rcnt");
|
|
||||||
SIOCNT.set(0x0);
|
|
||||||
let reg: u16 = SioControlReg::default_uart()
|
|
||||||
.with_baud(rate)
|
|
||||||
.with_interrupts(with_interrupts)
|
|
||||||
.with_cts(clear_to_send)
|
|
||||||
.into();
|
|
||||||
SIOCNT.set(reg);
|
|
||||||
println!("have set siocnt to {reg:#X}/{reg:#b}");
|
|
||||||
Self
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Read<u8> for LinkPortUart {
|
|
||||||
type Error = LinkPortError;
|
|
||||||
|
|
||||||
fn read(&mut self) -> Result<u8, nb::Error<LinkPortError>> {
|
|
||||||
match SioControlReg::from(SIOCNT.get()) {
|
|
||||||
v if *v.error => Err(nb::Error::Other(LinkPortError::GbaErrorBit)),
|
|
||||||
v if *v.recv_empty => Err(nb::Error::WouldBlock),
|
|
||||||
_ => Ok((SIODATA8.get() & 0xFF) as u8),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Write<u8> for LinkPortUart {
|
|
||||||
type Error = LinkPortError;
|
|
||||||
|
|
||||||
fn write(&mut self, word: u8) -> nb::Result<(), Self::Error> {
|
|
||||||
match self.flush() {
|
|
||||||
Ok(_) => {
|
|
||||||
SIODATA8.set(word as u16);
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
Err(e) => Err(e),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn flush(&mut self) -> nb::Result<(), Self::Error> {
|
|
||||||
match SioControlReg::from(SIOCNT.get()) {
|
|
||||||
v if *v.error => Err(nb::Error::Other(LinkPortError::GbaErrorBit)),
|
|
||||||
v if *v.send_full => Err(nb::Error::WouldBlock),
|
|
||||||
_ => Ok(()),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub enum BaudRate {
|
|
||||||
B9600 = 0b00,
|
|
||||||
B38400 = 0b01,
|
|
||||||
B57600 = 0b10,
|
|
||||||
B115200 = 0b11,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<u16> for BaudRate {
|
|
||||||
fn from(value: u16) -> Self {
|
|
||||||
match value {
|
|
||||||
0b00 => Self::B9600,
|
|
||||||
0b01 => Self::B38400,
|
|
||||||
0b10 => Self::B57600,
|
|
||||||
0b11 => Self::B115200,
|
|
||||||
_ => panic!("passed invalid value"),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub enum SioMode {
|
pub enum SioMode {
|
||||||
|
@ -104,96 +46,6 @@ impl From<u16> for SioMode {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct SioControlReg {
|
|
||||||
baud_rate: BaudRate, // 0-1
|
|
||||||
flow_control: BoolField, // 2
|
|
||||||
parity_odd: BoolField, // 3
|
|
||||||
send_full: BoolField, // 4
|
|
||||||
recv_empty: BoolField, // 5
|
|
||||||
error: BoolField, // 6
|
|
||||||
data_8bit: BoolField, // 7
|
|
||||||
fifo_enabled: BoolField, // 8
|
|
||||||
parity_enabled: BoolField, // 9
|
|
||||||
tx_enabled: BoolField, // 10
|
|
||||||
rx_enabled: BoolField, // 11
|
|
||||||
mode: SioMode, // 12-13
|
|
||||||
irq_enable: BoolField, // 14
|
|
||||||
}
|
|
||||||
|
|
||||||
impl SioControlReg {
|
|
||||||
fn default_uart() -> Self {
|
|
||||||
Self {
|
|
||||||
baud_rate: BaudRate::B9600,
|
|
||||||
flow_control: BoolField(false),
|
|
||||||
parity_odd: BoolField(false),
|
|
||||||
send_full: BoolField(false),
|
|
||||||
recv_empty: BoolField(false),
|
|
||||||
error: BoolField(false),
|
|
||||||
data_8bit: BoolField(true),
|
|
||||||
// fifo_enabled: BoolField(true),
|
|
||||||
fifo_enabled: BoolField(true),
|
|
||||||
parity_enabled: BoolField(false),
|
|
||||||
tx_enabled: BoolField(true),
|
|
||||||
rx_enabled: BoolField(true),
|
|
||||||
mode: SioMode::Uart,
|
|
||||||
irq_enable: BoolField(false),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn with_baud(mut self, rate: BaudRate) -> Self {
|
|
||||||
self.baud_rate = rate;
|
|
||||||
self
|
|
||||||
}
|
|
||||||
|
|
||||||
fn with_interrupts(mut self, interrupts: bool) -> Self {
|
|
||||||
*self.irq_enable = interrupts;
|
|
||||||
self
|
|
||||||
}
|
|
||||||
|
|
||||||
fn with_cts(mut self, clear_to_send: bool) -> Self {
|
|
||||||
*self.flow_control = clear_to_send;
|
|
||||||
self
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<SioControlReg> for u16 {
|
|
||||||
fn from(value: SioControlReg) -> Self {
|
|
||||||
value.baud_rate as u16
|
|
||||||
| u16::from(value.flow_control) << 2
|
|
||||||
| u16::from(value.parity_odd) << 3
|
|
||||||
| u16::from(value.send_full) << 4
|
|
||||||
| u16::from(value.recv_empty) << 5
|
|
||||||
| u16::from(value.error) << 6
|
|
||||||
| u16::from(value.data_8bit) << 7 // bit start
|
|
||||||
| u16::from(value.fifo_enabled) << 8
|
|
||||||
| u16::from(value.parity_enabled) << 9
|
|
||||||
| u16::from(value.tx_enabled) << 10
|
|
||||||
| u16::from(value.rx_enabled) << 11
|
|
||||||
| (value.mode as u16) << 12
|
|
||||||
| u16::from(value.irq_enable) << 14
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<u16> for SioControlReg {
|
|
||||||
fn from(value: u16) -> Self {
|
|
||||||
Self {
|
|
||||||
baud_rate: BaudRate::from(value & 0b11),
|
|
||||||
flow_control: (value & (1 << 2)).into(),
|
|
||||||
parity_odd: (value & (1 << 3)).into(),
|
|
||||||
send_full: (value & (1 << 4)).into(),
|
|
||||||
recv_empty: (value & (1 << 5)).into(),
|
|
||||||
error: (value & (1 << 6)).into(),
|
|
||||||
data_8bit: (value & (1 << 7)).into(),
|
|
||||||
fifo_enabled: (value & (1 << 8)).into(),
|
|
||||||
parity_enabled: (value & (1 << 9)).into(),
|
|
||||||
tx_enabled: (value & (1 << 10)).into(),
|
|
||||||
rx_enabled: (value & (1 << 11)).into(),
|
|
||||||
mode: ((value & (0b11 << 12)) >> 12).into(),
|
|
||||||
irq_enable: (value & (1 << 14)).into(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct BoolField(bool);
|
pub struct BoolField(bool);
|
||||||
|
|
||||||
impl Deref for BoolField {
|
impl Deref for BoolField {
|
||||||
|
@ -222,7 +74,7 @@ impl From<BoolField> for u16 {
|
||||||
|
|
||||||
impl From<u16> for BoolField {
|
impl From<u16> for BoolField {
|
||||||
fn from(value: u16) -> Self {
|
fn from(value: u16) -> Self {
|
||||||
Self(value != 0)
|
Self((value % 2) != 0)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
148
agb/src/serial_link/normal.rs
Normal file
148
agb/src/serial_link/normal.rs
Normal file
|
@ -0,0 +1,148 @@
|
||||||
|
use crate::println;
|
||||||
|
|
||||||
|
use super::{BoolField, RCNT, SIOCNT};
|
||||||
|
|
||||||
|
pub struct LinkPortNormal<const S: TransferLength>;
|
||||||
|
|
||||||
|
impl<const S: TransferLength> LinkPortNormal<S> {
|
||||||
|
pub fn init(clock_source: ClockSource) -> Self {
|
||||||
|
println!("begin uart init");
|
||||||
|
RCNT.set(0x0);
|
||||||
|
println!("have set rcnt");
|
||||||
|
SIOCNT.set(0x0);
|
||||||
|
let reg: u16 = NormalSioControl::default()
|
||||||
|
.with_clock_source(clock_source)
|
||||||
|
.with_transfer_length(S)
|
||||||
|
.into();
|
||||||
|
SIOCNT.set(reg);
|
||||||
|
println!("have set siocnt to {reg:#X}/{reg:#b}");
|
||||||
|
Self
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(super) struct NormalSioControl {
|
||||||
|
clock_source: ClockSource, // 0
|
||||||
|
clock_rate: InternalClock, // 1
|
||||||
|
si_state: BoolField, // 2
|
||||||
|
so_inactive: BoolField, // 3
|
||||||
|
// 4-6 empty
|
||||||
|
start_bit: StartBit, // 7
|
||||||
|
// 8-11 empty
|
||||||
|
transfer_length: TransferLength, // 12
|
||||||
|
// 13 must be 0
|
||||||
|
irq_enable: BoolField, // 14
|
||||||
|
}
|
||||||
|
|
||||||
|
impl NormalSioControl {
|
||||||
|
fn with_clock_source(mut self, source: ClockSource) -> Self {
|
||||||
|
self.clock_source = source;
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
fn with_transfer_length(mut self, length: TransferLength) -> Self {
|
||||||
|
self.transfer_length = length;
|
||||||
|
self
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for NormalSioControl {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self {
|
||||||
|
clock_source: ClockSource::Internal,
|
||||||
|
clock_rate: InternalClock::Khz256,
|
||||||
|
si_state: BoolField(false),
|
||||||
|
so_inactive: BoolField(false),
|
||||||
|
start_bit: StartBit::Inactive,
|
||||||
|
transfer_length: TransferLength::Bits32,
|
||||||
|
irq_enable: BoolField(false),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<NormalSioControl> for u16 {
|
||||||
|
fn from(value: NormalSioControl) -> Self {
|
||||||
|
value.clock_source as u16
|
||||||
|
| (value.clock_rate as u16) << 1
|
||||||
|
| u16::from(value.si_state) << 2
|
||||||
|
| u16::from(value.so_inactive) << 3
|
||||||
|
| (value.start_bit as u16) << 7
|
||||||
|
| (value.transfer_length as u16) << 12
|
||||||
|
| u16::from(value.irq_enable) << 14
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<u16> for NormalSioControl {
|
||||||
|
fn from(value: u16) -> Self {
|
||||||
|
Self {
|
||||||
|
clock_source: (value & 1).into(),
|
||||||
|
clock_rate: (value & (1 << 1)).into(),
|
||||||
|
si_state: (value & (1 << 2)).into(),
|
||||||
|
so_inactive: (value & (1 << 3)).into(),
|
||||||
|
start_bit: (value & (1 << 7)).into(),
|
||||||
|
transfer_length: (value & (1 << 12)).into(),
|
||||||
|
irq_enable: (value & (1 << 14)).into(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub enum ClockSource {
|
||||||
|
External = 0,
|
||||||
|
Internal = 1,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<u16> for ClockSource {
|
||||||
|
fn from(value: u16) -> Self {
|
||||||
|
match value % 2 {
|
||||||
|
0 => ClockSource::External,
|
||||||
|
1 => ClockSource::Internal,
|
||||||
|
_ => panic!(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub enum InternalClock {
|
||||||
|
Khz256 = 0,
|
||||||
|
Mhz2 = 1,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<u16> for InternalClock {
|
||||||
|
fn from(value: u16) -> Self {
|
||||||
|
match value % 2 {
|
||||||
|
0 => InternalClock::Khz256,
|
||||||
|
1 => InternalClock::Mhz2,
|
||||||
|
_ => panic!(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// automatically reset when transfer complete
|
||||||
|
pub enum StartBit {
|
||||||
|
Inactive = 0,
|
||||||
|
Active = 1,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<u16> for StartBit {
|
||||||
|
fn from(value: u16) -> Self {
|
||||||
|
match value % 2 {
|
||||||
|
0 => StartBit::Inactive,
|
||||||
|
1 => StartBit::Active,
|
||||||
|
_ => panic!(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(PartialEq, Eq)]
|
||||||
|
pub enum TransferLength {
|
||||||
|
Bits8 = 0,
|
||||||
|
Bits32 = 1,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<u16> for TransferLength {
|
||||||
|
fn from(value: u16) -> Self {
|
||||||
|
match value % 2 {
|
||||||
|
0 => TransferLength::Bits8,
|
||||||
|
1 => TransferLength::Bits32,
|
||||||
|
_ => panic!(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
168
agb/src/serial_link/uart.rs
Normal file
168
agb/src/serial_link/uart.rs
Normal file
|
@ -0,0 +1,168 @@
|
||||||
|
use embedded_hal::serial::{Read, Write};
|
||||||
|
|
||||||
|
use crate::println;
|
||||||
|
|
||||||
|
use super::{BoolField, LinkPortError, SioMode, RCNT, SIOCNT, SIODATA8};
|
||||||
|
|
||||||
|
pub struct LinkPortUart;
|
||||||
|
|
||||||
|
impl LinkPortUart {
|
||||||
|
pub fn init(rate: BaudRate, with_interrupts: bool, clear_to_send: bool) -> Self {
|
||||||
|
println!("begin uart init");
|
||||||
|
RCNT.set(0x0);
|
||||||
|
println!("have set rcnt");
|
||||||
|
SIOCNT.set(0x0);
|
||||||
|
let reg: u16 = UartSioControl::default()
|
||||||
|
.with_baud(rate)
|
||||||
|
.with_interrupts(with_interrupts)
|
||||||
|
.with_cts(clear_to_send)
|
||||||
|
.into();
|
||||||
|
SIOCNT.set(reg);
|
||||||
|
println!("have set siocnt to {reg:#X}/{reg:#b}");
|
||||||
|
Self
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Read<u8> for LinkPortUart {
|
||||||
|
type Error = LinkPortError;
|
||||||
|
|
||||||
|
fn read(&mut self) -> Result<u8, nb::Error<LinkPortError>> {
|
||||||
|
match UartSioControl::from(SIOCNT.get()) {
|
||||||
|
v if *v.error => Err(nb::Error::Other(LinkPortError::GbaErrorBit)),
|
||||||
|
v if *v.recv_empty => Err(nb::Error::WouldBlock),
|
||||||
|
_ => Ok((SIODATA8.get() & 0xFF) as u8),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Write<u8> for LinkPortUart {
|
||||||
|
type Error = LinkPortError;
|
||||||
|
|
||||||
|
fn write(&mut self, word: u8) -> nb::Result<(), Self::Error> {
|
||||||
|
match self.flush() {
|
||||||
|
Ok(_) => {
|
||||||
|
SIODATA8.set(word as u16);
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
Err(e) => Err(e),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn flush(&mut self) -> nb::Result<(), Self::Error> {
|
||||||
|
match UartSioControl::from(SIOCNT.get()) {
|
||||||
|
v if *v.error => Err(nb::Error::Other(LinkPortError::GbaErrorBit)),
|
||||||
|
v if *v.send_full => Err(nb::Error::WouldBlock),
|
||||||
|
_ => Ok(()),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(super) struct UartSioControl {
|
||||||
|
baud_rate: BaudRate, // 0-1
|
||||||
|
flow_control: BoolField, // 2
|
||||||
|
parity_odd: BoolField, // 3
|
||||||
|
send_full: BoolField, // 4
|
||||||
|
recv_empty: BoolField, // 5
|
||||||
|
error: BoolField, // 6
|
||||||
|
data_8bit: BoolField, // 7
|
||||||
|
fifo_enabled: BoolField, // 8
|
||||||
|
parity_enabled: BoolField, // 9
|
||||||
|
tx_enabled: BoolField, // 10
|
||||||
|
rx_enabled: BoolField, // 11
|
||||||
|
mode: SioMode, // 12-13
|
||||||
|
irq_enable: BoolField, // 14
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for UartSioControl {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self {
|
||||||
|
baud_rate: BaudRate::B9600,
|
||||||
|
flow_control: BoolField(false),
|
||||||
|
parity_odd: BoolField(false),
|
||||||
|
send_full: BoolField(false),
|
||||||
|
recv_empty: BoolField(false),
|
||||||
|
error: BoolField(false),
|
||||||
|
data_8bit: BoolField(true),
|
||||||
|
fifo_enabled: BoolField(true),
|
||||||
|
parity_enabled: BoolField(false),
|
||||||
|
tx_enabled: BoolField(true),
|
||||||
|
rx_enabled: BoolField(true),
|
||||||
|
mode: SioMode::Uart,
|
||||||
|
irq_enable: BoolField(false),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl UartSioControl {
|
||||||
|
fn with_baud(mut self, rate: BaudRate) -> Self {
|
||||||
|
self.baud_rate = rate;
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
fn with_interrupts(mut self, interrupts: bool) -> Self {
|
||||||
|
*self.irq_enable = interrupts;
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
fn with_cts(mut self, clear_to_send: bool) -> Self {
|
||||||
|
*self.flow_control = clear_to_send;
|
||||||
|
self
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<UartSioControl> for u16 {
|
||||||
|
fn from(value: UartSioControl) -> Self {
|
||||||
|
value.baud_rate as u16
|
||||||
|
| u16::from(value.flow_control) << 2
|
||||||
|
| u16::from(value.parity_odd) << 3
|
||||||
|
| u16::from(value.send_full) << 4
|
||||||
|
| u16::from(value.recv_empty) << 5
|
||||||
|
| u16::from(value.error) << 6
|
||||||
|
| u16::from(value.data_8bit) << 7 // bit start
|
||||||
|
| u16::from(value.fifo_enabled) << 8
|
||||||
|
| u16::from(value.parity_enabled) << 9
|
||||||
|
| u16::from(value.tx_enabled) << 10
|
||||||
|
| u16::from(value.rx_enabled) << 11
|
||||||
|
| (value.mode as u16) << 12
|
||||||
|
| u16::from(value.irq_enable) << 14
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<u16> for UartSioControl {
|
||||||
|
fn from(value: u16) -> Self {
|
||||||
|
Self {
|
||||||
|
baud_rate: BaudRate::from(value & 0b11),
|
||||||
|
flow_control: (value & (1 << 2)).into(),
|
||||||
|
parity_odd: (value & (1 << 3)).into(),
|
||||||
|
send_full: (value & (1 << 4)).into(),
|
||||||
|
recv_empty: (value & (1 << 5)).into(),
|
||||||
|
error: (value & (1 << 6)).into(),
|
||||||
|
data_8bit: (value & (1 << 7)).into(),
|
||||||
|
fifo_enabled: (value & (1 << 8)).into(),
|
||||||
|
parity_enabled: (value & (1 << 9)).into(),
|
||||||
|
tx_enabled: (value & (1 << 10)).into(),
|
||||||
|
rx_enabled: (value & (1 << 11)).into(),
|
||||||
|
mode: ((value & (0b11 << 12)) >> 12).into(),
|
||||||
|
irq_enable: (value & (1 << 14)).into(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub enum BaudRate {
|
||||||
|
B9600 = 0b00,
|
||||||
|
B38400 = 0b01,
|
||||||
|
B57600 = 0b10,
|
||||||
|
B115200 = 0b11,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<u16> for BaudRate {
|
||||||
|
fn from(value: u16) -> Self {
|
||||||
|
match value {
|
||||||
|
0b00 => Self::B9600,
|
||||||
|
0b01 => Self::B38400,
|
||||||
|
0b10 => Self::B57600,
|
||||||
|
0b11 => Self::B115200,
|
||||||
|
_ => panic!("passed invalid value"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue