Merge pull request #3089 from qwerty19106/stm32_uart_half_fix_sequential_read_write
WIP: STM32 Half-Duplex: fix sequential reads and writes
This commit is contained in:
commit
d6e4086a15
1 changed files with 31 additions and 14 deletions
|
@ -371,9 +371,12 @@ impl<'d> UartTx<'d, Async> {
|
||||||
pub async fn write(&mut self, buffer: &[u8]) -> Result<(), Error> {
|
pub async fn write(&mut self, buffer: &[u8]) -> Result<(), Error> {
|
||||||
let r = self.info.regs;
|
let r = self.info.regs;
|
||||||
|
|
||||||
// Disable Receiver for Half-Duplex mode
|
// Enable Transmitter and disable Receiver for Half-Duplex mode
|
||||||
if r.cr3().read().hdsel() {
|
let mut cr1 = r.cr1().read();
|
||||||
r.cr1().modify(|reg| reg.set_re(false));
|
if r.cr3().read().hdsel() && !cr1.te() {
|
||||||
|
cr1.set_te(true);
|
||||||
|
cr1.set_re(false);
|
||||||
|
r.cr1().write_value(cr1);
|
||||||
}
|
}
|
||||||
|
|
||||||
let ch = self.tx_dma.as_mut().unwrap();
|
let ch = self.tx_dma.as_mut().unwrap();
|
||||||
|
@ -474,9 +477,12 @@ impl<'d, M: Mode> UartTx<'d, M> {
|
||||||
pub fn blocking_write(&mut self, buffer: &[u8]) -> Result<(), Error> {
|
pub fn blocking_write(&mut self, buffer: &[u8]) -> Result<(), Error> {
|
||||||
let r = self.info.regs;
|
let r = self.info.regs;
|
||||||
|
|
||||||
// Disable Receiver for Half-Duplex mode
|
// Enable Transmitter and disable Receiver for Half-Duplex mode
|
||||||
if r.cr3().read().hdsel() {
|
let mut cr1 = r.cr1().read();
|
||||||
r.cr1().modify(|reg| reg.set_re(false));
|
if r.cr3().read().hdsel() && !cr1.te() {
|
||||||
|
cr1.set_te(true);
|
||||||
|
cr1.set_re(false);
|
||||||
|
r.cr1().write_value(cr1);
|
||||||
}
|
}
|
||||||
|
|
||||||
for &b in buffer {
|
for &b in buffer {
|
||||||
|
@ -561,8 +567,9 @@ impl<'d> UartRx<'d, Async> {
|
||||||
) -> Result<ReadCompletionEvent, Error> {
|
) -> Result<ReadCompletionEvent, Error> {
|
||||||
let r = self.info.regs;
|
let r = self.info.regs;
|
||||||
|
|
||||||
// Call flush for Half-Duplex mode. It prevents reading of bytes which have just been written.
|
// Call flush for Half-Duplex mode if some bytes were written and flush was not called.
|
||||||
if r.cr3().read().hdsel() {
|
// It prevents reading of bytes which have just been written.
|
||||||
|
if r.cr3().read().hdsel() && r.cr1().read().te() {
|
||||||
blocking_flush(self.info)?;
|
blocking_flush(self.info)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -898,8 +905,9 @@ impl<'d, M: Mode> UartRx<'d, M> {
|
||||||
pub fn blocking_read(&mut self, buffer: &mut [u8]) -> Result<(), Error> {
|
pub fn blocking_read(&mut self, buffer: &mut [u8]) -> Result<(), Error> {
|
||||||
let r = self.info.regs;
|
let r = self.info.regs;
|
||||||
|
|
||||||
// Call flush for Half-Duplex mode. It prevents reading of bytes which have just been written.
|
// Call flush for Half-Duplex mode if some bytes were written and flush was not called.
|
||||||
if r.cr3().read().hdsel() {
|
// It prevents reading of bytes which have just been written.
|
||||||
|
if r.cr3().read().hdsel() && r.cr1().read().te() {
|
||||||
blocking_flush(self.info)?;
|
blocking_flush(self.info)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1481,10 +1489,19 @@ fn configure(
|
||||||
r.cr1().write(|w| {
|
r.cr1().write(|w| {
|
||||||
// enable uart
|
// enable uart
|
||||||
w.set_ue(true);
|
w.set_ue(true);
|
||||||
// enable transceiver
|
|
||||||
w.set_te(enable_tx);
|
if config.half_duplex {
|
||||||
// enable receiver
|
// The te and re bits will be set by write, read and flush methods.
|
||||||
w.set_re(enable_rx);
|
// Receiver should be enabled by default for Half-Duplex.
|
||||||
|
w.set_te(false);
|
||||||
|
w.set_re(true);
|
||||||
|
} else {
|
||||||
|
// enable transceiver
|
||||||
|
w.set_te(enable_tx);
|
||||||
|
// enable receiver
|
||||||
|
w.set_re(enable_rx);
|
||||||
|
}
|
||||||
|
|
||||||
// configure word size
|
// configure word size
|
||||||
// if using odd or even parity it must be configured to 9bits
|
// if using odd or even parity it must be configured to 9bits
|
||||||
w.set_m0(if config.parity != Parity::ParityNone {
|
w.set_m0(if config.parity != Parity::ParityNone {
|
||||||
|
|
Loading…
Add table
Reference in a new issue