Skip to content

Commit ffba652

Browse files
committed
Usart Instance
1 parent 8cf2bfc commit ffba652

File tree

1 file changed

+110
-93
lines changed

1 file changed

+110
-93
lines changed

src/serial.rs

Lines changed: 110 additions & 93 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ use crate::gpio::gpiob::{PB10, PB11, PB6, PB7};
5454
use crate::gpio::gpioc::{PC10, PC11};
5555
use crate::gpio::gpiod::{PD5, PD6, PD8, PD9};
5656
use crate::gpio::{Alternate, Floating, Input, PushPull};
57-
use crate::rcc::{Clocks, Enable, GetBusFreq, RccBus, Reset};
57+
use crate::rcc::{Clocks, Enable, GetBusFreq, Reset};
5858
use crate::time::{Bps, U32Ext};
5959

6060
/// Interrupt event
@@ -182,6 +182,15 @@ pub struct Serial<USART, PINS> {
182182
pins: PINS,
183183
}
184184

185+
pub trait Instance:
186+
crate::Sealed + Deref<Target = crate::pac::usart1::RegisterBlock> + Enable + Reset + GetBusFreq
187+
{
188+
}
189+
190+
impl Instance for USART1 {}
191+
impl Instance for USART2 {}
192+
impl Instance for USART3 {}
193+
185194
/// Serial receiver
186195
pub struct Rx<USART> {
187196
_usart: PhantomData<USART>,
@@ -257,6 +266,101 @@ trait UsartReadWrite: Deref<Target = crate::pac::usart1::RegisterBlock> {
257266
}
258267
impl UsartReadWrite for &crate::pac::usart1::RegisterBlock {}
259268

269+
impl<USART, PINS> Serial<USART, PINS>
270+
where
271+
USART: Instance,
272+
{
273+
fn init(self, config: Config, clocks: Clocks, remap: impl FnOnce()) -> Self {
274+
// enable and reset $USARTX
275+
let rcc = unsafe { &(*RCC::ptr()) };
276+
USART::enable(rcc);
277+
USART::reset(rcc);
278+
279+
remap();
280+
// Configure baud rate
281+
let brr = USART::get_frequency(&clocks).0 / config.baudrate.0;
282+
assert!(brr >= 16, "impossible baud rate");
283+
self.usart.brr.write(|w| unsafe { w.bits(brr) });
284+
285+
// Configure parity and word length
286+
// Unlike most uart devices, the "word length" of this usart device refers to
287+
// the size of the data plus the parity bit. I.e. "word length"=8, parity=even
288+
// results in 7 bits of data. Therefore, in order to get 8 bits and one parity
289+
// bit, we need to set the "word" length to 9 when using parity bits.
290+
let (word_length, parity_control_enable, parity) = match config.parity {
291+
Parity::ParityNone => (false, false, false),
292+
Parity::ParityEven => (true, true, false),
293+
Parity::ParityOdd => (true, true, true),
294+
};
295+
self.usart.cr1.modify(|_r, w| {
296+
w.m()
297+
.bit(word_length)
298+
.ps()
299+
.bit(parity)
300+
.pce()
301+
.bit(parity_control_enable)
302+
});
303+
304+
// Configure stop bits
305+
let stop_bits = match config.stopbits {
306+
StopBits::STOP1 => 0b00,
307+
StopBits::STOP0P5 => 0b01,
308+
StopBits::STOP2 => 0b10,
309+
StopBits::STOP1P5 => 0b11,
310+
};
311+
self.usart.cr2.modify(|_r, w| w.stop().bits(stop_bits));
312+
313+
// UE: enable USART
314+
// RE: enable receiver
315+
// TE: enable transceiver
316+
self.usart
317+
.cr1
318+
.modify(|_r, w| w.ue().set_bit().re().set_bit().te().set_bit());
319+
320+
self
321+
}
322+
323+
/// Starts listening to the USART by enabling the _Received data
324+
/// ready to be read (RXNE)_ interrupt and _Transmit data
325+
/// register empty (TXE)_ interrupt
326+
pub fn listen(&mut self, event: Event) {
327+
match event {
328+
Event::Rxne => self.usart.cr1.modify(|_, w| w.rxneie().set_bit()),
329+
Event::Txe => self.usart.cr1.modify(|_, w| w.txeie().set_bit()),
330+
Event::Idle => self.usart.cr1.modify(|_, w| w.idleie().set_bit()),
331+
}
332+
}
333+
334+
/// Stops listening to the USART by disabling the _Received data
335+
/// ready to be read (RXNE)_ interrupt and _Transmit data
336+
/// register empty (TXE)_ interrupt
337+
pub fn unlisten(&mut self, event: Event) {
338+
match event {
339+
Event::Rxne => self.usart.cr1.modify(|_, w| w.rxneie().clear_bit()),
340+
Event::Txe => self.usart.cr1.modify(|_, w| w.txeie().clear_bit()),
341+
Event::Idle => self.usart.cr1.modify(|_, w| w.idleie().clear_bit()),
342+
}
343+
}
344+
345+
/// Returns ownership of the borrowed register handles
346+
pub fn release(self) -> (USART, PINS) {
347+
(self.usart, self.pins)
348+
}
349+
350+
/// Separates the serial struct into separate channel objects for sending (Tx) and
351+
/// receiving (Rx)
352+
pub fn split(self) -> (Tx<USART>, Rx<USART>) {
353+
(
354+
Tx {
355+
_usart: PhantomData,
356+
},
357+
Rx {
358+
_usart: PhantomData,
359+
},
360+
)
361+
}
362+
}
363+
260364
macro_rules! hal {
261365
($(
262366
$(#[$meta:meta])*
@@ -265,7 +369,6 @@ macro_rules! hal {
265369
$usartX_remap:ident,
266370
$bit:ident,
267371
$closure:expr,
268-
$APBx:ident,
269372
),
270373
)+) => {
271374
$(
@@ -299,99 +402,16 @@ macro_rules! hal {
299402
where
300403
PINS: Pins<$USARTX>,
301404
{
302-
// enable and reset $USARTX
303-
let rcc = unsafe { &(*RCC::ptr()) };
304-
$USARTX::enable(rcc);
305-
$USARTX::reset(rcc);
306-
307405
#[allow(unused_unsafe)]
308-
mapr.modify_mapr(|_, w| unsafe{
406+
Serial { usart, pins }.init(
407+
config,
408+
clocks,
409+
|| mapr.modify_mapr(|_, w| unsafe{
309410
#[allow(clippy::redundant_closure_call)]
310411
w.$usartX_remap().$bit(($closure)(PINS::REMAP))
311-
});
312-
313-
// Configure baud rate
314-
let brr = <$USARTX as RccBus>::Bus::get_frequency(&clocks).0 / config.baudrate.0;
315-
assert!(brr >= 16, "impossible baud rate");
316-
usart.brr.write(|w| unsafe { w.bits(brr) });
317-
318-
// Configure parity and word length
319-
// Unlike most uart devices, the "word length" of this usart device refers to
320-
// the size of the data plus the parity bit. I.e. "word length"=8, parity=even
321-
// results in 7 bits of data. Therefore, in order to get 8 bits and one parity
322-
// bit, we need to set the "word" length to 9 when using parity bits.
323-
let (word_length, parity_control_enable, parity) = match config.parity {
324-
Parity::ParityNone => (false, false, false),
325-
Parity::ParityEven => (true, true, false),
326-
Parity::ParityOdd => (true, true, true),
327-
};
328-
usart.cr1.modify(|_r, w| {
329-
w
330-
.m().bit(word_length)
331-
.ps().bit(parity)
332-
.pce().bit(parity_control_enable)
333-
});
334-
335-
// Configure stop bits
336-
let stop_bits = match config.stopbits {
337-
StopBits::STOP1 => 0b00,
338-
StopBits::STOP0P5 => 0b01,
339-
StopBits::STOP2 => 0b10,
340-
StopBits::STOP1P5 => 0b11,
341-
};
342-
usart.cr2.modify(|_r, w| {
343-
w.stop().bits(stop_bits)
344-
});
345-
346-
// UE: enable USART
347-
// RE: enable receiver
348-
// TE: enable transceiver
349-
usart
350-
.cr1
351-
.modify(|_r, w| w.ue().set_bit().re().set_bit().te().set_bit());
352-
353-
Serial { usart, pins }
354-
}
355-
356-
/// Starts listening to the USART by enabling the _Received data
357-
/// ready to be read (RXNE)_ interrupt and _Transmit data
358-
/// register empty (TXE)_ interrupt
359-
pub fn listen(&mut self, event: Event) {
360-
match event {
361-
Event::Rxne => self.usart.cr1.modify(|_, w| w.rxneie().set_bit()),
362-
Event::Txe => self.usart.cr1.modify(|_, w| w.txeie().set_bit()),
363-
Event::Idle => self.usart.cr1.modify(|_, w| w.idleie().set_bit()),
364-
}
365-
}
366-
367-
/// Stops listening to the USART by disabling the _Received data
368-
/// ready to be read (RXNE)_ interrupt and _Transmit data
369-
/// register empty (TXE)_ interrupt
370-
pub fn unlisten(&mut self, event: Event) {
371-
match event {
372-
Event::Rxne => self.usart.cr1.modify(|_, w| w.rxneie().clear_bit()),
373-
Event::Txe => self.usart.cr1.modify(|_, w| w.txeie().clear_bit()),
374-
Event::Idle => self.usart.cr1.modify(|_, w| w.idleie().clear_bit()),
375-
}
412+
}))
376413
}
377414

378-
/// Returns ownership of the borrowed register handles
379-
pub fn release(self) -> ($USARTX, PINS) {
380-
(self.usart, self.pins)
381-
}
382-
383-
/// Separates the serial struct into separate channel objects for sending (Tx) and
384-
/// receiving (Rx)
385-
pub fn split(self) -> (Tx<$USARTX>, Rx<$USARTX>) {
386-
(
387-
Tx {
388-
_usart: PhantomData,
389-
},
390-
Rx {
391-
_usart: PhantomData,
392-
},
393-
)
394-
}
395415
}
396416

397417
impl Tx<$USARTX> {
@@ -476,23 +496,20 @@ hal! {
476496
usart1_remap,
477497
bit,
478498
|remap| remap == 1,
479-
APB2,
480499
),
481500
/// # USART2 functions
482501
USART2: (
483502
usart2,
484503
usart2_remap,
485504
bit,
486505
|remap| remap == 1,
487-
APB1,
488506
),
489507
/// # USART3 functions
490508
USART3: (
491509
usart3,
492510
usart3_remap,
493511
bits,
494512
|remap| remap,
495-
APB1,
496513
),
497514
}
498515

0 commit comments

Comments
 (0)