Skip to content

Commit a342024

Browse files
committed
Add support for UART4/5
1 parent 97ff2ef commit a342024

File tree

11 files changed

+411
-40
lines changed

11 files changed

+411
-40
lines changed

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ vcell = "0.1.3"
3636

3737
[dependencies.stm32f1]
3838
package = "stm32f1-staging"
39-
version = "0.17.1"
39+
version = "0.19.0"
4040
features = ["atomics"]
4141

4242
[dependencies.embedded-hal-02]

examples/can-echo.rs

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -29,11 +29,10 @@ fn main() -> ! {
2929
let rx = gpioa.pa11;
3030
let tx = gpioa.pa12;
3131

32-
let can = dp.CAN1.can(
33-
#[cfg(not(feature = "connectivity"))]
34-
dp.USB,
35-
(tx, rx),
36-
);
32+
#[cfg(not(feature = "connectivity"))]
33+
let can = dp.CAN.can(dp.USB, (tx, rx));
34+
#[cfg(feature = "connectivity")]
35+
let can = dp.CAN1.can((tx, rx));
3736

3837
// APB1 (PCLK1): 8MHz, Bit rate: 125kBit/s, Sample Point 87.5%
3938
// Value was calculated with http://www.bittiming.can-wiki.info/

examples/can-loopback.rs

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -25,11 +25,10 @@ fn main() -> ! {
2525
// resonator must be used.
2626
rcc.cfgr.use_hse(8.MHz()).freeze(&mut flash.acr);
2727

28-
let can = Can::<_, Floating>::new_loopback(
29-
dp.CAN1,
30-
#[cfg(not(feature = "connectivity"))]
31-
dp.USB,
32-
);
28+
#[cfg(not(feature = "connectivity"))]
29+
let can = Can::<_, Floating>::new_loopback(dp.CAN, dp.USB);
30+
#[cfg(feature = "connectivity")]
31+
let can = Can::<_, Floating>::new_loopback(dp.CAN1);
3332

3433
// Use loopback mode: No pins need to be assigned to peripheral.
3534
// APB1 (PCLK1): 8MHz, Bit rate: 500Bit/s, Sample Point 87.5%

examples/can-rtic.rs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,11 @@ mod app {
5555
use super::{enqueue_frame, PriorityFrame};
5656
use bxcan::{filter::Mask32, ExtendedId, Fifo, Frame, Interrupts, Rx0, StandardId, Tx};
5757
use heapless::binary_heap::{BinaryHeap, Max};
58-
use stm32f1xx_hal::{can::Can, pac::CAN1, prelude::*};
58+
#[cfg(not(feature = "connectivity"))]
59+
use stm32f1xx_hal::pac::CAN as CAN1;
60+
#[cfg(feature = "connectivity")]
61+
use stm32f1xx_hal::pac::CAN1;
62+
use stm32f1xx_hal::{can::Can, prelude::*};
5963

6064
#[local]
6165
struct Local {
@@ -88,7 +92,7 @@ mod app {
8892
let can_tx_pin = gpioa.pa12;
8993

9094
#[cfg(not(feature = "connectivity"))]
91-
let can = Can::new(cx.device.CAN1, cx.device.USB, (can_tx_pin, can_rx_pin));
95+
let can = Can::new(cx.device.CAN, cx.device.USB, (can_tx_pin, can_rx_pin));
9296

9397
#[cfg(feature = "connectivity")]
9498
let can = Can::new(cx.device.CAN1, (can_tx_pin, can_rx_pin));

src/afio.rs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -215,7 +215,7 @@ remap! {
215215

216216
#[cfg(feature = "stm32f103")]
217217
remap! {
218-
pac::CAN1: MAPR, u8: can_remap, { 0 | 2 | 3 };
218+
pac::CAN: MAPR, u8: can_remap, { 0 | 2 | 3 };
219219
}
220220

221221
#[cfg(feature = "connectivity")]
@@ -303,7 +303,11 @@ pub mod can1 {
303303
],
304304
}
305305

306-
impl CanCommon for pac::CAN1 {
306+
#[cfg(not(feature = "connectivity"))]
307+
use pac::CAN as CAN1;
308+
#[cfg(feature = "connectivity")]
309+
use pac::CAN1;
310+
impl CanCommon for CAN1 {
307311
type Tx = Tx;
308312
type Rx<PULL> = Rx<PULL>;
309313
}

src/can.rs

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,12 @@ impl<CAN: Instance> CanExt for CAN {
5858
}
5959

6060
pub trait Instance: crate::rcc::Enable + afio::CanCommon {}
61-
impl Instance for pac::CAN1 {}
61+
#[cfg(not(feature = "connectivity"))]
62+
use pac::CAN as CAN1;
63+
#[cfg(feature = "connectivity")]
64+
use pac::CAN1;
65+
66+
impl Instance for CAN1 {}
6267
#[cfg(feature = "connectivity")]
6368
impl Instance for pac::CAN2 {}
6469

@@ -125,18 +130,18 @@ impl<CAN: Instance, PULL: UpMode> Can<CAN, PULL> {
125130
}
126131
}
127132

128-
unsafe impl<PULL> bxcan::Instance for Can<pac::CAN1, PULL> {
129-
const REGISTERS: *mut bxcan::RegisterBlock = pac::CAN1::ptr() as *mut _;
133+
unsafe impl<PULL> bxcan::Instance for Can<CAN1, PULL> {
134+
const REGISTERS: *mut bxcan::RegisterBlock = CAN1::ptr() as *mut _;
130135
}
131136

132137
#[cfg(feature = "connectivity")]
133138
unsafe impl<PULL> bxcan::Instance for Can<pac::CAN2, PULL> {
134139
const REGISTERS: *mut bxcan::RegisterBlock = pac::CAN2::ptr() as *mut _;
135140
}
136141

137-
unsafe impl<PULL> bxcan::FilterOwner for Can<pac::CAN1, PULL> {
142+
unsafe impl<PULL> bxcan::FilterOwner for Can<CAN1, PULL> {
138143
const NUM_FILTER_BANKS: u8 = 28;
139144
}
140145

141146
#[cfg(feature = "connectivity")]
142-
unsafe impl<PULL> bxcan::MasterInstance for Can<pac::CAN1, PULL> {}
147+
unsafe impl<PULL> bxcan::MasterInstance for Can<CAN1, PULL> {}

src/gpio.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -223,7 +223,7 @@ mod sealed {
223223
}
224224
}
225225

226-
use crate::pac::gpioa::crl::{CNF0 as Cnf, MODE0 as Mode};
226+
use crate::pac::gpioa::crl::{CONFIG as Cnf, MODE as Mode};
227227

228228
use sealed::Interruptable;
229229
pub(crate) use sealed::PinMode;

src/lib.rs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -157,3 +157,18 @@ mod sealed {
157157
pub trait Sealed {}
158158
}
159159
use sealed::Sealed;
160+
use stm32f1::Periph;
161+
162+
pub trait Ptr {
163+
/// RegisterBlock structure
164+
type RB;
165+
/// Return the pointer to the register block
166+
fn ptr() -> *const Self::RB;
167+
}
168+
169+
impl<RB, const ADDR: usize> Ptr for Periph<RB, ADDR> {
170+
type RB = RB;
171+
fn ptr() -> *const Self::RB {
172+
Self::ptr()
173+
}
174+
}

src/rcc/enable.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ macro_rules! ahb_bus {
6565
#[cfg(feature = "stm32f103")]
6666
bus! {
6767
ADC2 => (APB2, 10),
68-
CAN1 => (APB1, 25),
68+
CAN => (APB1, 25),
6969
}
7070
#[cfg(feature = "connectivity")]
7171
bus! {

src/serial.rs

Lines changed: 48 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -102,9 +102,12 @@ use crate::pac::{self, RCC};
102102
use crate::rcc::{BusClock, Clocks, Enable, Reset};
103103
use crate::time::{Bps, U32Ext};
104104

105+
pub mod ext;
105106
mod hal_02;
106107
mod hal_1;
107108

109+
use ext::{SrR, UartExt};
110+
108111
pub trait SerialExt: Sized + Instance {
109112
fn serial<Otype, PULL: UpMode>(
110113
self,
@@ -159,28 +162,56 @@ impl<USART: Instance> SerialExt for USART {
159162
}
160163
}
161164

162-
use crate::pac::usart1 as uart_base;
165+
pub trait RBExt: UartExt {
166+
fn set_stopbits(&self, bits: StopBits);
167+
}
168+
169+
impl RBExt for pac::usart1::RegisterBlock {
170+
fn set_stopbits(&self, bits: StopBits) {
171+
use crate::pac::usart1::cr2::STOP;
172+
173+
self.cr2().write(|w| {
174+
w.stop().variant(match bits {
175+
StopBits::STOP0P5 => STOP::Stop0p5,
176+
StopBits::STOP1 => STOP::Stop1,
177+
StopBits::STOP1P5 => STOP::Stop1p5,
178+
StopBits::STOP2 => STOP::Stop2,
179+
})
180+
});
181+
}
182+
}
183+
184+
#[cfg(any(all(feature = "stm32f103", feature = "high"), feature = "connectivity"))]
185+
impl RBExt for pac::uart4::RegisterBlock {
186+
fn set_stopbits(&self, bits: StopBits) {
187+
use crate::pac::uart4::cr2::STOP;
188+
189+
// StopBits::STOP0P5 and StopBits::STOP1P5 aren't supported when using UART
190+
// STOP_A::STOP1 and STOP_A::STOP2 will be used, respectively
191+
self.cr2().write(|w| {
192+
w.stop().variant(match bits {
193+
StopBits::STOP0P5 | StopBits::STOP1 => STOP::Stop1,
194+
StopBits::STOP1P5 | StopBits::STOP2 => STOP::Stop2,
195+
})
196+
});
197+
}
198+
}
163199

164200
pub trait Instance:
165201
crate::Sealed
166-
+ Deref<Target = uart_base::RegisterBlock>
202+
+ crate::Ptr<RB: RBExt>
203+
+ Deref<Target = Self::RB>
167204
+ Enable
168205
+ Reset
169206
+ BusClock
170207
+ afio::SerialAsync
171208
{
172-
#[doc(hidden)]
173-
fn ptr() -> *const uart_base::RegisterBlock;
174209
}
175210

176211
macro_rules! inst {
177212
($($USARTX:ty;)+) => {
178213
$(
179-
impl Instance for $USARTX {
180-
fn ptr() -> *const uart_base::RegisterBlock {
181-
<$USARTX>::ptr()
182-
}
183-
}
214+
impl Instance for $USARTX { }
184215
)+
185216
};
186217
}
@@ -190,6 +221,11 @@ inst! {
190221
pac::USART2;
191222
pac::USART3;
192223
}
224+
#[cfg(any(all(feature = "stm32f103", feature = "high"), feature = "connectivity"))]
225+
inst! {
226+
pac::UART4;
227+
pac::UART5;
228+
}
193229

194230
/// Serial error
195231
#[derive(Debug)]
@@ -519,7 +555,7 @@ fn apply_config<USART: Instance>(config: Config, clocks: &Clocks) {
519555
// Configure baud rate
520556
let brr = USART::clock(clocks).raw() / config.baudrate.0;
521557
assert!(brr >= 16, "impossible baud rate");
522-
usart.brr().write(|w| unsafe { w.bits(brr) });
558+
usart.brr().write(|w| unsafe { w.bits(brr as u16) });
523559

524560
// Configure word
525561
usart.cr1().modify(|_r, w| {
@@ -537,13 +573,7 @@ fn apply_config<USART: Instance>(config: Config, clocks: &Clocks) {
537573
});
538574

539575
// Configure stop bits
540-
let stop_bits = match config.stopbits {
541-
StopBits::STOP1 => 0b00,
542-
StopBits::STOP0P5 => 0b01,
543-
StopBits::STOP2 => 0b10,
544-
StopBits::STOP1P5 => 0b11,
545-
};
546-
usart.cr2().modify(|_r, w| w.stop().set(stop_bits));
576+
usart.set_stopbits(config.stopbits);
547577
}
548578

549579
/// Reconfigure the USART instance.
@@ -657,7 +687,7 @@ impl<USART: Instance> Rx<USART> {
657687
Some(Error::Parity)
658688
} else if sr.fe().bit_is_set() {
659689
Some(Error::FrameFormat)
660-
} else if sr.ne().bit_is_set() {
690+
} else if sr.nf().bit_is_set() {
661691
Some(Error::Noise)
662692
} else if sr.ore().bit_is_set() {
663693
Some(Error::Overrun)

0 commit comments

Comments
 (0)