|
3 | 3 | //! Based on STM32F4xx HAL. |
4 | 4 |
|
5 | 5 | use crate::pac::CAN1; |
| 6 | +use crate::rcc::APB1R1; |
6 | 7 |
|
7 | 8 | mod sealed { |
8 | 9 | pub trait Sealed {} |
@@ -57,55 +58,50 @@ mod pb13_pb12_af10 { |
57 | 58 | /// Enable/disable peripheral |
58 | 59 | pub trait Enable: sealed::Sealed { |
59 | 60 | /// Enables this peripheral by setting the associated enable bit in an RCC enable register |
60 | | - fn enable(); |
| 61 | + fn enable(apb: &mut APB1R1); |
61 | 62 | } |
62 | 63 |
|
63 | 64 | impl crate::can::sealed::Sealed for crate::pac::CAN1 {} |
64 | 65 |
|
65 | 66 | impl crate::can::Enable for crate::pac::CAN1 { |
66 | 67 | #[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()); |
76 | 73 | } |
77 | 74 | } |
78 | 75 |
|
79 | 76 | /// 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, |
82 | 80 | } |
83 | 81 |
|
84 | | -impl<Instance> Can<Instance> |
| 82 | +impl<Instance, P> Can<Instance, P> |
85 | 83 | where |
86 | 84 | Instance: Enable, |
| 85 | + P: Pins<Instance = Instance>, |
87 | 86 | { |
88 | 87 | /// 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 } |
95 | 91 | } |
96 | 92 |
|
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) |
100 | 96 | } |
101 | 97 | } |
102 | 98 |
|
103 | | -unsafe impl bxcan::Instance for Can<CAN1> { |
| 99 | +unsafe impl<Pins> bxcan::Instance for Can<CAN1, Pins> { |
104 | 100 | const REGISTERS: *mut bxcan::RegisterBlock = CAN1::ptr() as *mut _; |
105 | 101 | } |
106 | 102 |
|
107 | | -unsafe impl bxcan::FilterOwner for Can<CAN1> { |
| 103 | +unsafe impl<Pins> bxcan::FilterOwner for Can<CAN1, Pins> { |
108 | 104 | const NUM_FILTER_BANKS: u8 = 14; |
109 | 105 | } |
110 | 106 |
|
111 | | -unsafe impl bxcan::MasterInstance for Can<CAN1> {} |
| 107 | +unsafe impl<Pins> bxcan::MasterInstance for Can<CAN1, Pins> {} |
0 commit comments