1
- use super :: pac ;
2
- use super :: pac :: can :: TX ;
1
+ use bxcan :: { FilterOwner , Instance , RegisterBlock } ;
2
+
3
3
use crate :: gpio:: gpioa:: { PA11 , PA12 } ;
4
4
use crate :: gpio:: gpiob:: { PB8 , PB9 } ;
5
5
use crate :: gpio:: { Alternate , AF4 } ;
6
+ use crate :: pac:: CAN ;
6
7
use crate :: rcc:: Rcc ;
7
8
8
- pub trait RxPin { }
9
- pub trait TxPin { }
9
+ mod sealed {
10
+ pub trait Sealed { }
11
+ }
12
+
13
+ use self :: sealed:: Sealed ;
14
+
15
+ pub use bxcan;
16
+
17
+ pub trait RxPin : Sealed { }
18
+ pub trait TxPin : Sealed { }
10
19
11
20
macro_rules! can_pins {
12
21
(
13
22
rx => [ $( $rx: ty) ,+ $( , ) * ] ,
14
23
tx => [ $( $tx: ty) ,+ $( , ) * ] ,
15
24
) => {
16
25
$(
26
+ impl Sealed for $rx { }
17
27
impl RxPin for $rx { }
18
28
) +
19
29
$(
30
+ impl Sealed for $tx { }
20
31
impl TxPin for $tx { }
21
32
) +
22
33
} ;
@@ -28,198 +39,48 @@ can_pins! {
28
39
tx => [ PA12 <Alternate <AF4 >>, PB9 <Alternate <AF4 >>] ,
29
40
}
30
41
31
- pub struct CANBus < RX_PIN , TX_PIN > {
32
- can : pac:: CAN ,
33
- _rx : RX_PIN ,
34
- _tx : TX_PIN ,
42
+ #[ cfg( any( feature = "stm32f072" , feature = "stm32f091" ) ) ]
43
+ use crate :: gpio:: {
44
+ gpiod:: { PD0 , PD1 } ,
45
+ AF0 ,
46
+ } ;
47
+
48
+ #[ cfg( any( feature = "stm32f072" , feature = "stm32f091" ) ) ]
49
+ can_pins ! {
50
+ rx => [ PD0 <Alternate <AF0 >>] ,
51
+ tx => [ PD1 <Alternate <AF0 >>] ,
35
52
}
36
53
37
- pub enum Event {
38
- RxMessagePending ,
54
+ /// Resources used by the CAN peripheral.
55
+ pub struct CanInstance < T : TxPin , R : RxPin > {
56
+ peripheral : CAN ,
57
+ tx : T ,
58
+ rx : R ,
39
59
}
40
60
41
- impl < RX_PIN , TX_PIN > CANBus < RX_PIN , TX_PIN >
42
- where
43
- RX_PIN : RxPin ,
44
- TX_PIN : TxPin ,
45
- {
46
- pub fn new ( can : pac:: CAN , rx : RX_PIN , tx : TX_PIN , rcc : & mut Rcc ) -> Self {
61
+ impl < T : TxPin , R : RxPin > CanInstance < T , R > {
62
+ pub fn new ( peripheral : CAN , tx : T , rx : R , rcc : & mut Rcc ) -> Self {
47
63
rcc. regs . apb1enr . modify ( |_, w| w. canen ( ) . enabled ( ) ) ;
48
64
rcc. regs . apb1rstr . modify ( |_, w| w. canrst ( ) . reset ( ) ) ;
49
65
rcc. regs . apb1rstr . modify ( |_, w| w. canrst ( ) . clear_bit ( ) ) ;
50
66
51
- can. mcr . write ( |w| w. sleep ( ) . clear_bit ( ) ) ;
52
- can. mcr . modify ( |_, w| w. inrq ( ) . set_bit ( ) ) ;
53
- while !can. msr . read ( ) . inak ( ) . bit ( ) { }
54
-
55
- can. mcr . modify ( |_, w| {
56
- w. ttcm ( )
57
- . clear_bit ( ) // no time triggered communication
58
- . abom ( )
59
- . set_bit ( ) // bus automatically recovers itself after error state
60
- . awum ( )
61
- . set_bit ( ) // bus is automatically waken up on message RX
62
- . nart ( )
63
- . clear_bit ( ) // automatic message retransmission enabled
64
- . rflm ( )
65
- . clear_bit ( ) // new RX message overwrite unread older ones
66
- . txfp ( )
67
- . clear_bit ( ) // TX message priority driven by the message identifier
68
- . sleep ( )
69
- . clear_bit ( ) // do not sleep
70
- } ) ;
71
- // calculated using http://www.bittiming.can-wiki.info/ for STMicroelectronics bxCAN 48 MHz clock, 87.6% sample point, SJW = 1, bitrate 250 kHz
72
- const TIME_SEGMENT1 : u8 = 13 ;
73
- const TIME_SEGMENT2 : u8 = 2 ;
74
- const RESYNC_WIDTH : u8 = 1 ;
75
- const PRESCALER : u16 = 12 ;
76
- can. btr . modify ( |_, w| unsafe {
77
- w. silm ( )
78
- . clear_bit ( ) // disable silent mode
79
- . lbkm ( )
80
- . clear_bit ( ) // disable loopback mode
81
- . sjw ( )
82
- . bits ( RESYNC_WIDTH - 1 )
83
- . ts2 ( )
84
- . bits ( TIME_SEGMENT2 - 1 )
85
- . ts1 ( )
86
- . bits ( TIME_SEGMENT1 - 1 )
87
- . brp ( )
88
- . bits ( PRESCALER - 1 )
89
- } ) ;
90
-
91
- can. mcr . modify ( |_, w| w. inrq ( ) . clear_bit ( ) ) ;
92
- while !can. msr . read ( ) . inak ( ) . bit ( ) { }
93
-
94
- can. fmr . modify ( |_, w| w. finit ( ) . set_bit ( ) ) ; // filter init enabled
95
- can. fa1r . write ( |w| w. fact0 ( ) . clear_bit ( ) ) ; // filter is inactive
96
-
97
- can. fm1r . write ( |w| w. fbm0 ( ) . clear_bit ( ) ) ; // identifier mask mode for fbm0
98
- can. fs1r . write ( |w| w. fsc0 ( ) . set_bit ( ) ) ; // 32 bit scale configuration
99
-
100
- // const FILTER0_ID: u16 = 0x0;
101
- // const FILTER0_MASK: u16 = 0x00;
102
- // const FILTER1_ID: u16 = 0x00;
103
- // const FILTER1_MASK: u16 = 0x00;
104
- can. fb [ 0 ] . fr1 . write ( |w| unsafe { w. bits ( 0 ) } ) ;
105
- can. fb [ 0 ] . fr2 . write ( |w| unsafe { w. bits ( 0 ) } ) ;
106
-
107
- can. fa1r . write ( |w| w. fact0 ( ) . set_bit ( ) ) ; // filter is active
108
- can. fmr . modify ( |_, w| w. finit ( ) . clear_bit ( ) ) ; // filter init disabled
109
-
110
- Self {
111
- can,
112
- _rx : rx,
113
- _tx : tx,
114
- }
115
- }
116
-
117
- pub fn write ( & self , frame : & CANFrame ) -> nb:: Result < ( ) , CANError > {
118
- if self . can . tsr . read ( ) . tme0 ( ) . bit_is_set ( ) {
119
- self . write_to_mailbox ( & self . can . tx [ 0 ] , frame) ;
120
- Ok ( ( ) )
121
- } else if self . can . tsr . read ( ) . tme1 ( ) . bit_is_set ( ) {
122
- self . write_to_mailbox ( & self . can . tx [ 1 ] , frame) ;
123
- Ok ( ( ) )
124
- } else if self . can . tsr . read ( ) . tme2 ( ) . bit_is_set ( ) {
125
- self . write_to_mailbox ( & self . can . tx [ 2 ] , frame) ;
126
- Ok ( ( ) )
127
- } else {
128
- Err ( nb:: Error :: WouldBlock )
129
- }
67
+ Self { peripheral, tx, rx }
130
68
}
131
69
132
- fn write_to_mailbox ( & self , tx : & TX , frame : & CANFrame ) {
133
- tx. tdtr . write ( |w| unsafe { w. dlc ( ) . bits ( frame. dlc ) } ) ;
134
- tx. tdlr . write ( |w| unsafe {
135
- w. data0 ( )
136
- . bits ( frame. data [ 0 ] )
137
- . data1 ( )
138
- . bits ( frame. data [ 1 ] )
139
- . data2 ( )
140
- . bits ( frame. data [ 2 ] )
141
- . data3 ( )
142
- . bits ( frame. data [ 3 ] )
143
- } ) ;
144
- tx. tdhr . write ( |w| unsafe {
145
- w. data4 ( )
146
- . bits ( frame. data [ 4 ] )
147
- . data5 ( )
148
- . bits ( frame. data [ 5 ] )
149
- . data6 ( )
150
- . bits ( frame. data [ 6 ] )
151
- . data7 ( )
152
- . bits ( frame. data [ 7 ] )
153
- } ) ;
154
-
155
- tx. tir . write ( |w| unsafe {
156
- w. stid ( )
157
- . bits ( frame. id )
158
- . ide ( )
159
- . standard ( )
160
- . rtr ( )
161
- . bit ( frame. rtr )
162
- . txrq ( )
163
- . set_bit ( )
164
- } ) ;
70
+ pub fn into_raw ( self ) -> ( CAN , T , R ) {
71
+ ( self . peripheral , self . tx , self . rx )
165
72
}
166
73
167
- pub fn read ( & self ) -> nb:: Result < CANFrame , CANError > {
168
- for ( i, rfr) in self . can . rfr . iter ( ) . enumerate ( ) {
169
- let pending = rfr. read ( ) . fmp ( ) . bits ( ) ;
170
- if pending > 0 {
171
- let rx = & self . can . rx [ i] ;
172
- let id = rx. rir . read ( ) . stid ( ) . bits ( ) ;
173
- let rtr = rx. rir . read ( ) . rtr ( ) . bit_is_set ( ) ;
174
- let dlc = rx. rdtr . read ( ) . dlc ( ) . bits ( ) ;
175
-
176
- let data0 = rx. rdlr . read ( ) . data0 ( ) . bits ( ) ;
177
- let data1 = rx. rdlr . read ( ) . data1 ( ) . bits ( ) ;
178
- let data2 = rx. rdlr . read ( ) . data2 ( ) . bits ( ) ;
179
- let data3 = rx. rdlr . read ( ) . data3 ( ) . bits ( ) ;
180
- let data4 = rx. rdhr . read ( ) . data4 ( ) . bits ( ) ;
181
- let data5 = rx. rdhr . read ( ) . data5 ( ) . bits ( ) ;
182
- let data6 = rx. rdhr . read ( ) . data6 ( ) . bits ( ) ;
183
- let data7 = rx. rdhr . read ( ) . data7 ( ) . bits ( ) ;
184
-
185
- rfr. modify ( |_, w| w. rfom ( ) . release ( ) ) ; // release
186
- if rfr. read ( ) . fovr ( ) . bit_is_set ( ) {
187
- rfr. modify ( |_, w| w. fovr ( ) . clear ( ) ) ;
188
- }
189
-
190
- if rfr. read ( ) . full ( ) . bit_is_set ( ) {
191
- rfr. modify ( |_, w| w. full ( ) . clear ( ) ) ;
192
- }
193
-
194
- let frame = CANFrame {
195
- id,
196
- rtr,
197
- dlc,
198
- data : [ data0, data1, data2, data3, data4, data5, data6, data7] ,
199
- } ;
200
- return Ok ( frame) ;
201
- }
202
- }
203
- Err ( nb:: Error :: WouldBlock )
204
- }
205
-
206
- pub fn listen ( & self , event : Event ) {
207
- match event {
208
- Event :: RxMessagePending => {
209
- self . can
210
- . ier
211
- . modify ( |_, w| w. fmpie0 ( ) . set_bit ( ) . fmpie1 ( ) . set_bit ( ) ) ;
212
- }
213
- }
74
+ /// Returns a reference to the raw CAN peripheral.
75
+ pub unsafe fn peripheral ( & mut self ) -> & mut CAN {
76
+ & mut self . peripheral
214
77
}
215
78
}
216
79
217
- pub enum CANError { }
80
+ unsafe impl < T : TxPin , R : RxPin > Instance for CanInstance < T , R > {
81
+ const REGISTERS : * mut RegisterBlock = CAN :: ptr ( ) as * mut _ ;
82
+ }
218
83
219
- #[ derive( Copy , Clone , Default ) ]
220
- pub struct CANFrame {
221
- pub id : u16 ,
222
- pub rtr : bool ,
223
- pub dlc : u8 ,
224
- pub data : [ u8 ; 8 ] ,
84
+ unsafe impl < T : TxPin , R : RxPin > FilterOwner for CanInstance < T , R > {
85
+ const NUM_FILTER_BANKS : u8 = 14 ;
225
86
}
0 commit comments