aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDario Nieuwenhuis <[email protected]>2021-07-15 01:02:12 +0200
committerGitHub <[email protected]>2021-07-15 01:02:12 +0200
commit8a172ac12325ddc382e5ac0ffa637120a166d057 (patch)
tree690a49d9e7cac2c07946fc2bdee5f69bb7e1b7b8
parentd71be45a91c1e61f97fa3564f2fd6a56728da307 (diff)
parent4361cb15f18730b5b73171267e5d44fb244c8ec0 (diff)
Merge pull request #294 from embassy-rs/usart-merge
stm32/usart: merge v2 and v3 (they're identical)
-rw-r--r--embassy-stm32/src/usart/mod.rs1
-rw-r--r--embassy-stm32/src/usart/v2.rs51
-rw-r--r--embassy-stm32/src/usart/v3.rs149
m---------stm32-data0
4 files changed, 42 insertions, 159 deletions
diff --git a/embassy-stm32/src/usart/mod.rs b/embassy-stm32/src/usart/mod.rs
index ddaed5bb9..c3ac8bc59 100644
--- a/embassy-stm32/src/usart/mod.rs
+++ b/embassy-stm32/src/usart/mod.rs
@@ -2,7 +2,6 @@
2 2
3#[cfg_attr(usart_v1, path = "v1.rs")] 3#[cfg_attr(usart_v1, path = "v1.rs")]
4#[cfg_attr(usart_v2, path = "v2.rs")] 4#[cfg_attr(usart_v2, path = "v2.rs")]
5#[cfg_attr(usart_v3, path = "v3.rs")]
6mod _version; 5mod _version;
7use crate::peripherals; 6use crate::peripherals;
8pub use _version::*; 7pub use _version::*;
diff --git a/embassy-stm32/src/usart/v2.rs b/embassy-stm32/src/usart/v2.rs
index 22041b4aa..b958c0a0c 100644
--- a/embassy-stm32/src/usart/v2.rs
+++ b/embassy-stm32/src/usart/v2.rs
@@ -3,29 +3,38 @@ use core::marker::PhantomData;
3use embassy::util::Unborrow; 3use embassy::util::Unborrow;
4use embassy_extras::unborrow; 4use embassy_extras::unborrow;
5 5
6use crate::pac::usart::vals; 6use crate::pac::usart::{regs, vals};
7 7
8use super::*; 8use super::*;
9use core::future::Future;
10use futures::TryFutureExt;
9 11
10pub struct Uart<'d, T: Instance> { 12use crate::dma_traits::NoDma;
13
14#[allow(dead_code)]
15pub struct Uart<'d, T: Instance, TxDma = NoDma, RxDma = NoDma> {
11 inner: T, 16 inner: T,
12 phantom: PhantomData<&'d mut T>, 17 phantom: PhantomData<&'d mut T>,
18 tx_dma: TxDma,
19 rx_dma: RxDma,
13} 20}
14 21
15impl<'d, T: Instance> Uart<'d, T> { 22impl<'d, T: Instance, TxDma, RxDma> Uart<'d, T, TxDma, RxDma> {
16 pub fn new( 23 pub fn new(
17 inner: impl Unborrow<Target = T>, 24 inner: impl Unborrow<Target = T>,
18 rx: impl Unborrow<Target = impl RxPin<T>>, 25 rx: impl Unborrow<Target = impl RxPin<T>>,
19 tx: impl Unborrow<Target = impl TxPin<T>>, 26 tx: impl Unborrow<Target = impl TxPin<T>>,
27 tx_dma: impl Unborrow<Target = TxDma>,
28 rx_dma: impl Unborrow<Target = RxDma>,
20 config: Config, 29 config: Config,
21 ) -> Self { 30 ) -> Self {
22 unborrow!(inner, rx, tx); 31 unborrow!(inner, rx, tx, tx_dma, rx_dma);
23 32
24 T::enable(); 33 T::enable();
25 let pclk_freq = T::frequency(); 34 let pclk_freq = T::frequency();
26 35
27 // TODO: better calculation, including error checking and OVER8 if possible. 36 // TODO: better calculation, including error checking and OVER8 if possible.
28 let div = pclk_freq.0 / config.baudrate; 37 let div = (pclk_freq.0 + (config.baudrate / 2)) / config.baudrate;
29 38
30 let r = inner.regs(); 39 let r = inner.regs();
31 40
@@ -50,16 +59,23 @@ impl<'d, T: Instance> Uart<'d, T> {
50 _ => vals::Ps::EVEN, 59 _ => vals::Ps::EVEN,
51 }); 60 });
52 }); 61 });
62 r.cr2().write(|_w| {});
63 r.cr3().write(|_w| {});
53 } 64 }
54 65
55 Self { 66 Self {
56 inner, 67 inner,
57 phantom: PhantomData, 68 phantom: PhantomData,
69 tx_dma,
70 rx_dma,
58 } 71 }
59 } 72 }
60 73
61 #[cfg(bdma)] 74 async fn write_dma(&mut self, buffer: &[u8]) -> Result<(), Error>
62 pub async fn write_dma(&mut self, ch: &mut impl TxDma<T>, buffer: &[u8]) -> Result<(), Error> { 75 where
76 TxDma: crate::usart::TxDma<T>,
77 {
78 let ch = &mut self.tx_dma;
63 unsafe { 79 unsafe {
64 self.inner.regs().cr3().modify(|reg| { 80 self.inner.regs().cr3().modify(|reg| {
65 reg.set_dmat(true); 81 reg.set_dmat(true);
@@ -83,6 +99,9 @@ impl<'d, T: Instance> Uart<'d, T> {
83 } else if sr.fe() { 99 } else if sr.fe() {
84 r.rdr().read(); 100 r.rdr().read();
85 return Err(Error::Framing); 101 return Err(Error::Framing);
102 } else if sr.nf() {
103 r.rdr().read();
104 return Err(Error::Noise);
86 } else if sr.ore() { 105 } else if sr.ore() {
87 r.rdr().read(); 106 r.rdr().read();
88 return Err(Error::Overrun); 107 return Err(Error::Overrun);
@@ -97,14 +116,16 @@ impl<'d, T: Instance> Uart<'d, T> {
97 } 116 }
98} 117}
99 118
100impl<'d, T: Instance> embedded_hal::blocking::serial::Write<u8> for Uart<'d, T> { 119impl<'d, T: Instance, RxDma> embedded_hal::blocking::serial::Write<u8>
120 for Uart<'d, T, NoDma, RxDma>
121{
101 type Error = Error; 122 type Error = Error;
102 fn bwrite_all(&mut self, buffer: &[u8]) -> Result<(), Self::Error> { 123 fn bwrite_all(&mut self, buffer: &[u8]) -> Result<(), Self::Error> {
103 unsafe { 124 unsafe {
104 let r = self.inner.regs(); 125 let r = self.inner.regs();
105 for &b in buffer { 126 for &b in buffer {
106 while !r.isr().read().txe() {} 127 while !r.isr().read().txe() {}
107 r.tdr().write(|w| w.set_dr(b as u16)); 128 r.tdr().write_value(regs::Dr(b as u32))
108 } 129 }
109 } 130 }
110 Ok(()) 131 Ok(())
@@ -117,3 +138,15 @@ impl<'d, T: Instance> embedded_hal::blocking::serial::Write<u8> for Uart<'d, T>
117 Ok(()) 138 Ok(())
118 } 139 }
119} 140}
141
142// rustfmt::skip because intellij removes the 'where' claus on the associated type.
143#[rustfmt::skip]
144impl<'d, T: Instance, TxDma, RxDma> embassy_traits::uart::Write for Uart<'d, T, TxDma, RxDma>
145 where TxDma: crate::usart::TxDma<T>
146{
147 type WriteFuture<'a> where Self: 'a = impl Future<Output = Result<(), embassy_traits::uart::Error>>;
148
149 fn write<'a>(&'a mut self, buf: &'a [u8]) -> Self::WriteFuture<'a> {
150 self.write_dma(buf).map_err(|_| embassy_traits::uart::Error::Other)
151 }
152}
diff --git a/embassy-stm32/src/usart/v3.rs b/embassy-stm32/src/usart/v3.rs
deleted file mode 100644
index 4d78abb24..000000000
--- a/embassy-stm32/src/usart/v3.rs
+++ /dev/null
@@ -1,149 +0,0 @@
1use core::marker::PhantomData;
2
3use embassy::util::Unborrow;
4use embassy_extras::unborrow;
5
6use crate::pac::usart::{regs, vals};
7
8use super::*;
9use core::future::Future;
10use futures::TryFutureExt;
11
12use crate::dma_traits::NoDma;
13
14#[allow(dead_code)]
15pub struct Uart<'d, T: Instance, TxDma = NoDma, RxDma = NoDma> {
16 inner: T,
17 phantom: PhantomData<&'d mut T>,
18 tx_dma: TxDma,
19 rx_dma: RxDma,
20}
21
22impl<'d, T: Instance, TxDma, RxDma> Uart<'d, T, TxDma, RxDma> {
23 pub fn new(
24 inner: impl Unborrow<Target = T>,
25 rx: impl Unborrow<Target = impl RxPin<T>>,
26 tx: impl Unborrow<Target = impl TxPin<T>>,
27 tx_dma: impl Unborrow<Target = TxDma>,
28 rx_dma: impl Unborrow<Target = RxDma>,
29 config: Config,
30 ) -> Self {
31 unborrow!(inner, rx, tx, tx_dma, rx_dma);
32
33 // Uncomment once we find all of the H7's UART clocks.
34 T::enable();
35 let pclk_freq = T::frequency();
36
37 // TODO: better calculation, including error checking and OVER8 if possible.
38 let div = (pclk_freq.0 + (config.baudrate / 2)) / config.baudrate;
39
40 let r = inner.regs();
41
42 unsafe {
43 rx.set_as_af(rx.af_num());
44 tx.set_as_af(tx.af_num());
45
46 r.brr().write_value(regs::Brr(div));
47 r.cr1().write(|w| {
48 w.set_ue(true);
49 w.set_te(true);
50 w.set_re(true);
51 w.set_m(0, vals::M0::BIT8);
52 w.set_pce(config.parity != Parity::ParityNone);
53 w.set_ps(match config.parity {
54 Parity::ParityOdd => vals::Ps::ODD,
55 Parity::ParityEven => vals::Ps::EVEN,
56 _ => vals::Ps::EVEN,
57 });
58 });
59 r.cr2().write(|_w| {});
60 r.cr3().write(|_w| {});
61 }
62
63 Self {
64 inner,
65 phantom: PhantomData,
66 tx_dma,
67 rx_dma,
68 }
69 }
70
71 async fn write_dma(&mut self, buffer: &[u8]) -> Result<(), Error>
72 where
73 TxDma: crate::usart::TxDma<T>,
74 {
75 let ch = &mut self.tx_dma;
76 unsafe {
77 self.inner.regs().cr3().modify(|reg| {
78 reg.set_dmat(true);
79 });
80 }
81 let r = self.inner.regs();
82 let dst = r.tdr().ptr() as *mut u8;
83 ch.transfer(buffer, dst).await;
84 Ok(())
85 }
86
87 pub fn read(&mut self, buffer: &mut [u8]) -> Result<(), Error> {
88 unsafe {
89 let r = self.inner.regs();
90 for b in buffer {
91 loop {
92 let sr = r.isr().read();
93 if sr.pe() {
94 r.rdr().read();
95 return Err(Error::Parity);
96 } else if sr.fe() {
97 r.rdr().read();
98 return Err(Error::Framing);
99 } else if sr.ne() {
100 r.rdr().read();
101 return Err(Error::Noise);
102 } else if sr.ore() {
103 r.rdr().read();
104 return Err(Error::Overrun);
105 } else if sr.rxne() {
106 break;
107 }
108 }
109 *b = r.rdr().read().0 as u8;
110 }
111 }
112 Ok(())
113 }
114}
115
116impl<'d, T: Instance, RxDma> embedded_hal::blocking::serial::Write<u8>
117 for Uart<'d, T, NoDma, RxDma>
118{
119 type Error = Error;
120 fn bwrite_all(&mut self, buffer: &[u8]) -> Result<(), Self::Error> {
121 unsafe {
122 let r = self.inner.regs();
123 for &b in buffer {
124 while !r.isr().read().txe() {}
125 r.tdr().write_value(regs::Tdr(b as u32))
126 }
127 }
128 Ok(())
129 }
130 fn bflush(&mut self) -> Result<(), Self::Error> {
131 unsafe {
132 let r = self.inner.regs();
133 while !r.isr().read().tc() {}
134 }
135 Ok(())
136 }
137}
138
139// rustfmt::skip because intellij removes the 'where' claus on the associated type.
140#[rustfmt::skip]
141impl<'d, T: Instance, TxDma, RxDma> embassy_traits::uart::Write for Uart<'d, T, TxDma, RxDma>
142 where TxDma: crate::usart::TxDma<T>
143{
144 type WriteFuture<'a> where Self: 'a = impl Future<Output = Result<(), embassy_traits::uart::Error>>;
145
146 fn write<'a>(&'a mut self, buf: &'a [u8]) -> Self::WriteFuture<'a> {
147 self.write_dma(buf).map_err(|_| embassy_traits::uart::Error::Other)
148 }
149}
diff --git a/stm32-data b/stm32-data
Subproject 964bf38532aca5b8ecb274a38659b272db3d4d5 Subproject b10a0dd9101038d9f93402565e9b9675f15c087