Skip to content

Commit 21f60ce

Browse files
committed
Now type safe
1 parent 575b7fc commit 21f60ce

File tree

2 files changed

+22
-26
lines changed

2 files changed

+22
-26
lines changed

examples/can-loopback.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ const APP: () = {
3636
let rx = gpioa.pa11.into_af9(&mut gpioa.moder, &mut gpioa.afrh);
3737
let tx = gpioa.pa12.into_af9(&mut gpioa.moder, &mut gpioa.afrh);
3838

39-
let can = Can::new(dp.CAN1, (tx, rx));
39+
let can = Can::new(&mut rcc.apb1r1, dp.CAN1, (tx, rx));
4040

4141
bxcan::Can::new(can)
4242
};

src/can.rs

Lines changed: 21 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
//! Based on STM32F4xx HAL.
44
55
use crate::pac::CAN1;
6+
use crate::rcc::APB1R1;
67

78
mod sealed {
89
pub trait Sealed {}
@@ -57,55 +58,50 @@ mod pb13_pb12_af10 {
5758
/// Enable/disable peripheral
5859
pub trait Enable: sealed::Sealed {
5960
/// Enables this peripheral by setting the associated enable bit in an RCC enable register
60-
fn enable();
61+
fn enable(apb: &mut APB1R1);
6162
}
6263

6364
impl crate::can::sealed::Sealed for crate::pac::CAN1 {}
6465

6566
impl crate::can::Enable for crate::pac::CAN1 {
6667
#[inline(always)]
67-
fn enable() {
68-
unsafe {
69-
// NOTE(unsafe) this reference will only be used for atomic writes with no side effects.
70-
let rcc = &(*crate::pac::RCC::ptr());
71-
// Enable peripheral clock
72-
rcc.apb1enr1.modify(|_, w| w.can1en().set_bit());
73-
rcc.apb1rstr1.modify(|_, w| w.can1rst().set_bit());
74-
rcc.apb1rstr1.modify(|_, w| w.can1rst().clear_bit());
75-
};
68+
fn enable(apb: &mut APB1R1) {
69+
// Enable peripheral clock
70+
apb.enr().modify(|_, w| w.can1en().set_bit());
71+
apb.rstr().modify(|_, w| w.can1rst().set_bit());
72+
apb.rstr().modify(|_, w| w.can1rst().clear_bit());
7673
}
7774
}
7875

7976
/// Interface to the CAN peripheral.
80-
pub struct Can<Instance> {
81-
_peripheral: Instance,
77+
pub struct Can<Instance, Pins> {
78+
can: Instance,
79+
pins: Pins,
8280
}
8381

84-
impl<Instance> Can<Instance>
82+
impl<Instance, P> Can<Instance, P>
8583
where
8684
Instance: Enable,
85+
P: Pins<Instance = Instance>,
8786
{
8887
/// Creates a CAN interface.
89-
pub fn new<P>(can: Instance, _pins: P) -> Can<Instance>
90-
where
91-
P: Pins<Instance = Instance>,
92-
{
93-
Instance::enable();
94-
Can { _peripheral: can }
88+
pub fn new(apb: &mut APB1R1, can: Instance, pins: P) -> Can<Instance, P> {
89+
Instance::enable(apb);
90+
Can { can, pins }
9591
}
9692

97-
pub fn new_unchecked(can: Instance) -> Can<Instance> {
98-
Instance::enable();
99-
Can { _peripheral: can }
93+
// Split the peripheral back into its components.
94+
pub fn split(self) -> (Instance, P) {
95+
(self.can, self.pins)
10096
}
10197
}
10298

103-
unsafe impl bxcan::Instance for Can<CAN1> {
99+
unsafe impl<Pins> bxcan::Instance for Can<CAN1, Pins> {
104100
const REGISTERS: *mut bxcan::RegisterBlock = CAN1::ptr() as *mut _;
105101
}
106102

107-
unsafe impl bxcan::FilterOwner for Can<CAN1> {
103+
unsafe impl<Pins> bxcan::FilterOwner for Can<CAN1, Pins> {
108104
const NUM_FILTER_BANKS: u8 = 14;
109105
}
110106

111-
unsafe impl bxcan::MasterInstance for Can<CAN1> {}
107+
unsafe impl<Pins> bxcan::MasterInstance for Can<CAN1, Pins> {}

0 commit comments

Comments
 (0)