74 lines
2.3 KiB
Rust
74 lines
2.3 KiB
Rust
|
|
use hcl::platform::usart;
|
|
use hcl::platform::dma;
|
|
use hcl::platform::PeripheralRef;
|
|
use hcl::platform::Location;
|
|
use hcl::dma::*;
|
|
|
|
use alloc::vec::Vec;
|
|
|
|
|
|
type UsartDRRef<Addr> = PeripheralRef<usart::USARTdr, usart::USART_part_offsets::dr<Addr>>;
|
|
type UsartDMAResult<'a, Addr, Chan> = Result<'a, Vec<u8>, UsartDRRef<Addr>, Chan, SetupError>;
|
|
|
|
|
|
pub struct UsartPrinter<'a, Addr, Chan : 'a, ChanAddr> where
|
|
Addr : hcl::platform::Location,
|
|
Chan: hcl::dma::PeripheralChannel,
|
|
ChanAddr: hcl::platform::Location {
|
|
usart_dr: Option<UsartDRRef<Addr>>,
|
|
dma_result : Option<UsartDMAResult<'a, Addr, Chan>>,
|
|
|
|
dma_channel_idx: u32,
|
|
dma_channel: PeripheralRef<Chan,ChanAddr>,
|
|
}
|
|
|
|
impl<'a, Addr, Chan, ChanAddr> UsartPrinter<'a, Addr, Chan, ChanAddr> where
|
|
Addr : hcl::platform::Location,
|
|
Chan: hcl::dma::PeripheralChannel,
|
|
ChanAddr: hcl::platform::Location {
|
|
|
|
pub fn init(usart: usart::USARTParts<Addr>,
|
|
dma_channel_idx: u32,
|
|
dma_channel: PeripheralRef<Chan,ChanAddr>) -> UsartPrinter<'a, Addr, Chan, ChanAddr> {
|
|
UsartPrinter {
|
|
usart_dr: Some(usart.dr),
|
|
dma_result: None,
|
|
dma_channel_idx: dma_channel_idx,
|
|
dma_channel: dma_channel,
|
|
}
|
|
}
|
|
|
|
pub fn wait_for_completion(&mut self, dma_control: &mut dma::DMA1control) -> () {
|
|
match self.dma_result.take() {
|
|
Some(res) => {
|
|
let dr = match res {
|
|
Ok(tx) => {
|
|
while !dma_control.transfer_complete(self.dma_channel_idx) {
|
|
}
|
|
tx.retrieve().1
|
|
},
|
|
Err((_, sink, _)) => sink
|
|
};
|
|
self.usart_dr = Some(dr)
|
|
}
|
|
None => {}
|
|
}
|
|
}
|
|
|
|
pub fn print(&'a mut self, data: Vec<u8>, dma_control: & mut dma::DMA1control) -> () {
|
|
let dr = match self.usart_dr.take() {
|
|
Some(dr) => dr,
|
|
None => {
|
|
self.wait_for_completion(dma_control);
|
|
self.usart_dr.take().unwrap()
|
|
}
|
|
};
|
|
|
|
let foo = &self.dma_channel;
|
|
|
|
dma_control.clear_transfer_complete(self.dma_channel_idx);
|
|
self.dma_result = Some(self.dma_channel.begin_source(data, dr));
|
|
}
|
|
}
|