Skip to content

Commit 306aa0a

Browse files
authored
Serial/USART improvements (#122)
* serial: add 7-bit support * serial: support inverting Tx and Rx pins * serial: add listen_idle and co * serial: correct DE handling
1 parent e272a8f commit 306aa0a

File tree

2 files changed

+73
-3
lines changed

2 files changed

+73
-3
lines changed

src/serial/config.rs

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,8 @@ pub struct BasicConfig {
6060
pub(crate) wordlength: WordLength,
6161
pub(crate) parity: Parity,
6262
pub(crate) stopbits: StopBits,
63+
pub(crate) inverted_tx: bool,
64+
pub(crate) inverted_rx: bool,
6365
pub(crate) swap: bool,
6466
}
6567

@@ -69,6 +71,8 @@ pub struct FullConfig {
6971
pub(crate) wordlength: WordLength,
7072
pub(crate) parity: Parity,
7173
pub(crate) stopbits: StopBits,
74+
pub(crate) inverted_tx: bool,
75+
pub(crate) inverted_rx: bool,
7276
pub(crate) swap: bool,
7377
pub(crate) fifo_enable: bool,
7478
pub(crate) tx_fifo_threshold: FifoThreshold,
@@ -100,6 +104,11 @@ impl BasicConfig {
100104
self
101105
}
102106

107+
pub fn wordlength_7(mut self) -> Self {
108+
self.wordlength = WordLength::DataBits7;
109+
self
110+
}
111+
103112
pub fn wordlength_8(mut self) -> Self {
104113
self.wordlength = WordLength::DataBits8;
105114
self
@@ -115,6 +124,16 @@ impl BasicConfig {
115124
self
116125
}
117126

127+
pub fn invert_tx(mut self) -> Self {
128+
self.inverted_tx = true;
129+
self
130+
}
131+
132+
pub fn invert_rx(mut self) -> Self {
133+
self.inverted_rx = true;
134+
self
135+
}
136+
118137
/// Swap the Tx/Rx pins
119138
///
120139
/// The peripheral will transmit on the pin given as the `rx` argument.
@@ -145,6 +164,11 @@ impl FullConfig {
145164
self
146165
}
147166

167+
pub fn wordlength_7(mut self) -> Self {
168+
self.wordlength = WordLength::DataBits7;
169+
self
170+
}
171+
148172
pub fn wordlength_8(mut self) -> Self {
149173
self.wordlength = WordLength::DataBits8;
150174
self
@@ -160,6 +184,16 @@ impl FullConfig {
160184
self
161185
}
162186

187+
pub fn invert_tx(mut self) -> Self {
188+
self.inverted_tx = true;
189+
self
190+
}
191+
192+
pub fn invert_rx(mut self) -> Self {
193+
self.inverted_rx = true;
194+
self
195+
}
196+
163197
/// Swap the Tx/Rx pins
164198
///
165199
/// The peripheral will transmit on the pin given as the `rx` argument.
@@ -212,6 +246,8 @@ impl Default for BasicConfig {
212246
wordlength: WordLength::DataBits8,
213247
parity: Parity::ParityNone,
214248
stopbits: StopBits::STOP1,
249+
inverted_tx: false,
250+
inverted_rx: false,
215251
swap: false,
216252
}
217253
}
@@ -225,6 +261,8 @@ impl Default for FullConfig {
225261
wordlength: WordLength::DataBits8,
226262
parity: Parity::ParityNone,
227263
stopbits: StopBits::STOP1,
264+
inverted_tx: false,
265+
inverted_rx: false,
228266
swap: false,
229267
fifo_enable: false,
230268
tx_fifo_threshold: FifoThreshold::FIFO_8_BYTES,

src/serial/usart.rs

Lines changed: 35 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -247,12 +247,13 @@ macro_rules! uart_shared {
247247
)+
248248

249249
impl<Config> Rx<$USARTX, Config> {
250+
/// Listen for a data interrupt event
250251
pub fn listen(&mut self) {
251252
let usart = unsafe { &(*$USARTX::ptr()) };
252253
usart.cr1.modify(|_, w| w.rxneie().set_bit());
253254
}
254255

255-
/// Stop listening for an interrupt event
256+
/// Stop listening for a data interrupt event
256257
pub fn unlisten(&mut self) {
257258
let usart = unsafe { &(*$USARTX::ptr()) };
258259
usart.cr1.modify(|_, w| w.rxneie().clear_bit());
@@ -264,6 +265,29 @@ macro_rules! uart_shared {
264265
usart.isr.read().rxne().bit_is_set()
265266
}
266267

268+
/// Listen for an idle interrupt event
269+
pub fn listen_idle(&mut self) {
270+
let usart = unsafe { &(*$USARTX::ptr()) };
271+
usart.cr1.modify(|_, w| w.idleie().set_bit());
272+
}
273+
274+
/// Stop listening for an idle interrupt event
275+
pub fn unlisten_idle(&mut self) {
276+
let usart = unsafe { &(*$USARTX::ptr()) };
277+
usart.cr1.modify(|_, w| w.idleie().clear_bit());
278+
}
279+
280+
/// Return true if the idle event occured
281+
pub fn is_idle(&self) -> bool {
282+
let usart = unsafe { &(*$USARTX::ptr()) };
283+
usart.isr.read().idle().bit_is_set()
284+
}
285+
286+
/// Clear the idle event flag
287+
pub fn clear_idle(&mut self) {
288+
let usart = unsafe { &(*$USARTX::ptr()) };
289+
usart.icr.write(|w| w.idlecf().set_bit());
290+
}
267291
}
268292

269293
impl<Config> hal::serial::Read<u8> for Rx<$USARTX, Config> {
@@ -477,6 +501,10 @@ macro_rules! uart_basic {
477501
StopBits::STOP2 => 0b10,
478502
StopBits::STOP1P5 => 0b11,
479503
})
504+
.txinv()
505+
.bit(config.inverted_tx)
506+
.rxinv()
507+
.bit(config.inverted_rx)
480508
.swap()
481509
.bit(config.swap)
482510
});
@@ -578,6 +606,10 @@ macro_rules! uart_full {
578606
usart.cr2.write(|w| unsafe {
579607
w.stop()
580608
.bits(config.stopbits.bits())
609+
.txinv()
610+
.bit(config.inverted_tx)
611+
.rxinv()
612+
.bit(config.inverted_rx)
581613
.swap()
582614
.bit(config.swap)
583615
});
@@ -597,6 +629,8 @@ macro_rules! uart_full {
597629
.bit(config.tx_fifo_interrupt)
598630
.rxftie()
599631
.bit(config.rx_fifo_interrupt)
632+
.dem()
633+
.bit(PINS::DRIVER_ENABLE)
600634
});
601635

602636
usart.cr1.modify(|_, w| {
@@ -618,8 +652,6 @@ macro_rules! uart_full {
618652
.bit(config.fifo_enable)
619653
});
620654

621-
usart.cr3.write(|w| w.dem().bit(PINS::DRIVER_ENABLE));
622-
623655
// Enable pins
624656
pins.setup();
625657

0 commit comments

Comments
 (0)