aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--embassy-stm32/src/can/fdcan.rs413
-rw-r--r--tests/stm32/src/bin/can.rs8
-rw-r--r--tests/stm32/src/bin/can_common.rs9
-rw-r--r--tests/stm32/src/bin/fdcan.rs4
4 files changed, 258 insertions, 176 deletions
diff --git a/embassy-stm32/src/can/fdcan.rs b/embassy-stm32/src/can/fdcan.rs
index 81ceb06aa..b772a3ca0 100644
--- a/embassy-stm32/src/can/fdcan.rs
+++ b/embassy-stm32/src/can/fdcan.rs
@@ -3,6 +3,7 @@ use core::future::poll_fn;
3use core::marker::PhantomData; 3use core::marker::PhantomData;
4use core::task::Poll; 4use core::task::Poll;
5 5
6use embassy_hal_internal::interrupt::InterruptExt;
6use embassy_hal_internal::{into_ref, PeripheralRef}; 7use embassy_hal_internal::{into_ref, PeripheralRef};
7use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex; 8use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex;
8use embassy_sync::channel::{Channel, DynamicReceiver, DynamicSender}; 9use embassy_sync::channel::{Channel, DynamicReceiver, DynamicSender};
@@ -40,7 +41,7 @@ pub struct IT0InterruptHandler<T: Instance> {
40// We use IT0 for everything currently 41// We use IT0 for everything currently
41impl<T: Instance> interrupt::typelevel::Handler<T::IT0Interrupt> for IT0InterruptHandler<T> { 42impl<T: Instance> interrupt::typelevel::Handler<T::IT0Interrupt> for IT0InterruptHandler<T> {
42 unsafe fn on_interrupt() { 43 unsafe fn on_interrupt() {
43 let regs = T::regs(); 44 let regs = T::registers().regs;
44 45
45 let ir = regs.ir().read(); 46 let ir = regs.ir().read();
46 47
@@ -140,22 +141,13 @@ pub enum OperatingMode {
140 //TestMode, 141 //TestMode,
141} 142}
142 143
143/// FDCAN Configuration instance instance
144/// Create instance of this first
145pub struct CanConfigurator<'d, T: Instance> {
146 config: crate::can::fd::config::FdCanConfig,
147 /// Reference to internals.
148 instance: FdcanInstance<'d, T>,
149 properties: Properties<T>,
150}
151
152fn calc_ns_per_timer_tick<T: Instance>(mode: crate::can::fd::config::FrameTransmissionConfig) -> u64 { 144fn calc_ns_per_timer_tick<T: Instance>(mode: crate::can::fd::config::FrameTransmissionConfig) -> u64 {
153 match mode { 145 match mode {
154 // Use timestamp from Rx FIFO to adjust timestamp reported to user 146 // Use timestamp from Rx FIFO to adjust timestamp reported to user
155 crate::can::fd::config::FrameTransmissionConfig::ClassicCanOnly => { 147 crate::can::fd::config::FrameTransmissionConfig::ClassicCanOnly => {
156 let freq = T::frequency(); 148 let freq = T::frequency();
157 let prescale: u64 = 149 let prescale: u64 = ({ T::registers().regs.nbtp().read().nbrp() } + 1) as u64
158 ({ T::regs().nbtp().read().nbrp() } + 1) as u64 * ({ T::regs().tscc().read().tcp() } + 1) as u64; 150 * ({ T::registers().regs.tscc().read().tcp() } + 1) as u64;
159 1_000_000_000 as u64 / (freq.0 as u64 * prescale) 151 1_000_000_000 as u64 / (freq.0 as u64 * prescale)
160 } 152 }
161 // For VBR this is too hard because the FDCAN timer switches clock rate you need to configure to use 153 // For VBR this is too hard because the FDCAN timer switches clock rate you need to configure to use
@@ -164,6 +156,18 @@ fn calc_ns_per_timer_tick<T: Instance>(mode: crate::can::fd::config::FrameTransm
164 } 156 }
165} 157}
166 158
159/// FDCAN Configuration instance instance
160/// Create instance of this first
161pub struct CanConfigurator<'d, T: Instance> {
162 config: crate::can::fd::config::FdCanConfig,
163 info: &'static Info,
164 state: &'static State,
165 /// Reference to internals.
166 _instance: FdcanInstance<'d, T>,
167 properties: Properties,
168 periph_clock: crate::time::Hertz,
169}
170
167impl<'d, T: Instance> CanConfigurator<'d, T> { 171impl<'d, T: Instance> CanConfigurator<'d, T> {
168 /// Creates a new Fdcan instance, keeping the peripheral in sleep mode. 172 /// Creates a new Fdcan instance, keeping the peripheral in sleep mode.
169 /// You must call [Fdcan::enable_non_blocking] to use the peripheral. 173 /// You must call [Fdcan::enable_non_blocking] to use the peripheral.
@@ -196,16 +200,18 @@ impl<'d, T: Instance> CanConfigurator<'d, T> {
196 T::IT1Interrupt::unpend(); // Not unsafe 200 T::IT1Interrupt::unpend(); // Not unsafe
197 T::IT1Interrupt::enable(); 201 T::IT1Interrupt::enable();
198 } 202 }
199
200 Self { 203 Self {
201 config, 204 config,
202 instance: FdcanInstance(peri), 205 info: T::info(),
203 properties: Properties::new(), 206 state: T::state(),
207 _instance: FdcanInstance(peri),
208 properties: Properties::new(T::info()),
209 periph_clock: T::frequency(),
204 } 210 }
205 } 211 }
206 212
207 /// Get driver properties 213 /// Get driver properties
208 pub fn properties(&self) -> &Properties<T> { 214 pub fn properties(&self) -> &Properties {
209 &self.properties 215 &self.properties
210 } 216 }
211 217
@@ -221,7 +227,7 @@ impl<'d, T: Instance> CanConfigurator<'d, T> {
221 227
222 /// Configures the bit timings calculated from supplied bitrate. 228 /// Configures the bit timings calculated from supplied bitrate.
223 pub fn set_bitrate(&mut self, bitrate: u32) { 229 pub fn set_bitrate(&mut self, bitrate: u32) {
224 let bit_timing = util::calc_can_timings(T::frequency(), bitrate).unwrap(); 230 let bit_timing = util::calc_can_timings(self.periph_clock, bitrate).unwrap();
225 231
226 let nbtr = crate::can::fd::config::NominalBitTiming { 232 let nbtr = crate::can::fd::config::NominalBitTiming {
227 sync_jump_width: bit_timing.sync_jump_width, 233 sync_jump_width: bit_timing.sync_jump_width,
@@ -234,7 +240,7 @@ impl<'d, T: Instance> CanConfigurator<'d, T> {
234 240
235 /// Configures the bit timings for VBR data calculated from supplied bitrate. This also sets confit to allow can FD and VBR 241 /// Configures the bit timings for VBR data calculated from supplied bitrate. This also sets confit to allow can FD and VBR
236 pub fn set_fd_data_bitrate(&mut self, bitrate: u32, transceiver_delay_compensation: bool) { 242 pub fn set_fd_data_bitrate(&mut self, bitrate: u32, transceiver_delay_compensation: bool) {
237 let bit_timing = util::calc_can_timings(T::frequency(), bitrate).unwrap(); 243 let bit_timing = util::calc_can_timings(self.periph_clock, bitrate).unwrap();
238 // Note, used existing calcluation for normal(non-VBR) bitrate, appears to work for 250k/1M 244 // Note, used existing calcluation for normal(non-VBR) bitrate, appears to work for 250k/1M
239 let nbtr = crate::can::fd::config::DataBitTiming { 245 let nbtr = crate::can::fd::config::DataBitTiming {
240 transceiver_delay_compensation, 246 transceiver_delay_compensation,
@@ -248,62 +254,68 @@ impl<'d, T: Instance> CanConfigurator<'d, T> {
248 } 254 }
249 255
250 /// Start in mode. 256 /// Start in mode.
251 pub fn start(self, mode: OperatingMode) -> Can<'d, T> { 257 pub fn start(self, mode: OperatingMode) -> Can<'d> {
252 let ns_per_timer_tick = calc_ns_per_timer_tick::<T>(self.config.frame_transmit); 258 let ns_per_timer_tick = calc_ns_per_timer_tick::<T>(self.config.frame_transmit);
253 critical_section::with(|_| unsafe { 259 critical_section::with(|_| {
254 T::mut_state().ns_per_timer_tick = ns_per_timer_tick; 260 let state = self.state as *const State;
261 unsafe {
262 let mut_state = state as *mut State;
263 (*mut_state).ns_per_timer_tick = ns_per_timer_tick;
264 }
255 }); 265 });
256 T::registers().into_mode(self.config, mode); 266 T::registers().into_mode(self.config, mode);
257 let ret = Can { 267 Can {
258 config: self.config, 268 config: self.config,
259 instance: self.instance, 269 info: self.info,
270 state: self.state,
271 instance: T::info().regs.regs,
260 _mode: mode, 272 _mode: mode,
261 properties: self.properties, 273 properties: Properties::new(T::info()),
262 }; 274 }
263 ret
264 } 275 }
265 276
266 /// Start, entering mode. Does same as start(mode) 277 /// Start, entering mode. Does same as start(mode)
267 pub fn into_normal_mode(self) -> Can<'d, T> { 278 pub fn into_normal_mode(self) -> Can<'d> {
268 self.start(OperatingMode::NormalOperationMode) 279 self.start(OperatingMode::NormalOperationMode)
269 } 280 }
270 281
271 /// Start, entering mode. Does same as start(mode) 282 /// Start, entering mode. Does same as start(mode)
272 pub fn into_internal_loopback_mode(self) -> Can<'d, T> { 283 pub fn into_internal_loopback_mode(self) -> Can<'d> {
273 self.start(OperatingMode::InternalLoopbackMode) 284 self.start(OperatingMode::InternalLoopbackMode)
274 } 285 }
275 286
276 /// Start, entering mode. Does same as start(mode) 287 /// Start, entering mode. Does same as start(mode)
277 pub fn into_external_loopback_mode(self) -> Can<'d, T> { 288 pub fn into_external_loopback_mode(self) -> Can<'d> {
278 self.start(OperatingMode::ExternalLoopbackMode) 289 self.start(OperatingMode::ExternalLoopbackMode)
279 } 290 }
280} 291}
281 292
282/// FDCAN Instance 293/// FDCAN Instance
283pub struct Can<'d, T: Instance> { 294pub struct Can<'d> {
284 config: crate::can::fd::config::FdCanConfig, 295 config: crate::can::fd::config::FdCanConfig,
285 /// Reference to internals. 296 info: &'static Info,
286 instance: FdcanInstance<'d, T>, 297 state: &'static State,
298 instance: &'d crate::pac::can::Fdcan,
287 _mode: OperatingMode, 299 _mode: OperatingMode,
288 properties: Properties<T>, 300 properties: Properties,
289} 301}
290 302
291impl<'d, T: Instance> Can<'d, T> { 303impl<'d> Can<'d> {
292 /// Get driver properties 304 /// Get driver properties
293 pub fn properties(&self) -> &Properties<T> { 305 pub fn properties(&self) -> &Properties {
294 &self.properties 306 &self.properties
295 } 307 }
296 308
297 /// Flush one of the TX mailboxes. 309 /// Flush one of the TX mailboxes.
298 pub async fn flush(&self, idx: usize) { 310 pub async fn flush(&self, idx: usize) {
299 poll_fn(|cx| { 311 poll_fn(|cx| {
300 T::state().tx_mode.register(cx.waker()); 312 self.state.tx_mode.register(cx.waker());
301 313
302 if idx > 3 { 314 if idx > 3 {
303 panic!("Bad mailbox"); 315 panic!("Bad mailbox");
304 } 316 }
305 let idx = 1 << idx; 317 let idx = 1 << idx;
306 if !T::regs().txbrp().read().trp(idx) { 318 if !self.info.regs.regs.txbrp().read().trp(idx) {
307 return Poll::Ready(()); 319 return Poll::Ready(());
308 } 320 }
309 321
@@ -317,12 +329,12 @@ impl<'d, T: Instance> Can<'d, T> {
317 /// can be replaced, this call asynchronously waits for a frame to be successfully 329 /// can be replaced, this call asynchronously waits for a frame to be successfully
318 /// transmitted, then tries again. 330 /// transmitted, then tries again.
319 pub async fn write(&mut self, frame: &Frame) -> Option<Frame> { 331 pub async fn write(&mut self, frame: &Frame) -> Option<Frame> {
320 T::state().tx_mode.write::<T>(frame).await 332 self.state.tx_mode.write(self.info, frame).await
321 } 333 }
322 334
323 /// Returns the next received message frame 335 /// Returns the next received message frame
324 pub async fn read(&mut self) -> Result<Envelope, BusError> { 336 pub async fn read(&mut self) -> Result<Envelope, BusError> {
325 T::state().rx_mode.read_classic::<T>().await 337 self.state.rx_mode.read_classic(self.info, self.state).await
326 } 338 }
327 339
328 /// Queues the message to be sent but exerts backpressure. If a lower-priority 340 /// Queues the message to be sent but exerts backpressure. If a lower-priority
@@ -330,58 +342,61 @@ impl<'d, T: Instance> Can<'d, T> {
330 /// can be replaced, this call asynchronously waits for a frame to be successfully 342 /// can be replaced, this call asynchronously waits for a frame to be successfully
331 /// transmitted, then tries again. 343 /// transmitted, then tries again.
332 pub async fn write_fd(&mut self, frame: &FdFrame) -> Option<FdFrame> { 344 pub async fn write_fd(&mut self, frame: &FdFrame) -> Option<FdFrame> {
333 T::state().tx_mode.write_fd::<T>(frame).await 345 self.state.tx_mode.write_fd(self.info, frame).await
334 } 346 }
335 347
336 /// Returns the next received message frame 348 /// Returns the next received message frame
337 pub async fn read_fd(&mut self) -> Result<FdEnvelope, BusError> { 349 pub async fn read_fd(&mut self) -> Result<FdEnvelope, BusError> {
338 T::state().rx_mode.read_fd::<T>().await 350 self.state.rx_mode.read_fd(self.info, self.state).await
339 } 351 }
340 352
341 /// Split instance into separate portions: Tx(write), Rx(read), common properties 353 /// Split instance into separate portions: Tx(write), Rx(read), common properties
342 pub fn split(self) -> (CanTx<'d, T>, CanRx<'d, T>, Properties<T>) { 354 pub fn split(self) -> (CanTx<'d>, CanRx<'d>, Properties) {
343 ( 355 (
344 CanTx { 356 CanTx {
357 info: self.info,
358 state: self.state,
345 config: self.config, 359 config: self.config,
346 _instance: self.instance, 360 _instance: self.instance,
347 _mode: self._mode, 361 _mode: self._mode,
348 }, 362 },
349 CanRx { 363 CanRx {
350 _instance1: PhantomData::<T>, 364 info: self.info,
351 _instance2: T::regs(), 365 state: self.state,
366 _instance: self.instance,
352 _mode: self._mode, 367 _mode: self._mode,
353 }, 368 },
354 self.properties, 369 self.properties,
355 ) 370 )
356 } 371 }
357
358 /// Join split rx and tx portions back together 372 /// Join split rx and tx portions back together
359 pub fn join(tx: CanTx<'d, T>, rx: CanRx<'d, T>) -> Self { 373 pub fn join(tx: CanTx<'d>, rx: CanRx<'d>) -> Self {
360 Can { 374 Can {
361 config: tx.config, 375 config: tx.config,
362 //_instance2: T::regs(), 376 info: tx.info,
377 state: tx.state,
363 instance: tx._instance, 378 instance: tx._instance,
364 _mode: rx._mode, 379 _mode: rx._mode,
365 properties: Properties::new(), 380 properties: Properties::new(tx.info),
366 } 381 }
367 } 382 }
368 383
369 /// Return a buffered instance of driver without CAN FD support. User must supply Buffers 384 /// Return a buffered instance of driver without CAN FD support. User must supply Buffers
370 pub fn buffered<const TX_BUF_SIZE: usize, const RX_BUF_SIZE: usize>( 385 pub fn buffered<const TX_BUF_SIZE: usize, const RX_BUF_SIZE: usize>(
371 &self, 386 self,
372 tx_buf: &'static mut TxBuf<TX_BUF_SIZE>, 387 tx_buf: &'static mut TxBuf<TX_BUF_SIZE>,
373 rxb: &'static mut RxBuf<RX_BUF_SIZE>, 388 rxb: &'static mut RxBuf<RX_BUF_SIZE>,
374 ) -> BufferedCan<'d, T, TX_BUF_SIZE, RX_BUF_SIZE> { 389 ) -> BufferedCan<'d, TX_BUF_SIZE, RX_BUF_SIZE> {
375 BufferedCan::new(PhantomData::<T>, T::regs(), self._mode, tx_buf, rxb) 390 BufferedCan::new(self.info, self.state, self.info.regs.regs, self._mode, tx_buf, rxb)
376 } 391 }
377 392
378 /// Return a buffered instance of driver with CAN FD support. User must supply Buffers 393 /// Return a buffered instance of driver with CAN FD support. User must supply Buffers
379 pub fn buffered_fd<const TX_BUF_SIZE: usize, const RX_BUF_SIZE: usize>( 394 pub fn buffered_fd<const TX_BUF_SIZE: usize, const RX_BUF_SIZE: usize>(
380 &self, 395 self,
381 tx_buf: &'static mut TxFdBuf<TX_BUF_SIZE>, 396 tx_buf: &'static mut TxFdBuf<TX_BUF_SIZE>,
382 rxb: &'static mut RxFdBuf<RX_BUF_SIZE>, 397 rxb: &'static mut RxFdBuf<RX_BUF_SIZE>,
383 ) -> BufferedCanFd<'d, T, TX_BUF_SIZE, RX_BUF_SIZE> { 398 ) -> BufferedCanFd<'d, TX_BUF_SIZE, RX_BUF_SIZE> {
384 BufferedCanFd::new(PhantomData::<T>, T::regs(), self._mode, tx_buf, rxb) 399 BufferedCanFd::new(self.info, self.state, self.info.regs.regs, self._mode, tx_buf, rxb)
385 } 400 }
386} 401}
387 402
@@ -392,52 +407,57 @@ pub type RxBuf<const BUF_SIZE: usize> = Channel<CriticalSectionRawMutex, Result<
392pub type TxBuf<const BUF_SIZE: usize> = Channel<CriticalSectionRawMutex, Frame, BUF_SIZE>; 407pub type TxBuf<const BUF_SIZE: usize> = Channel<CriticalSectionRawMutex, Frame, BUF_SIZE>;
393 408
394/// Buffered FDCAN Instance 409/// Buffered FDCAN Instance
395pub struct BufferedCan<'d, T: Instance, const TX_BUF_SIZE: usize, const RX_BUF_SIZE: usize> { 410pub struct BufferedCan<'d, const TX_BUF_SIZE: usize, const RX_BUF_SIZE: usize> {
396 _instance1: PhantomData<T>, 411 info: &'static Info,
397 _instance2: &'d crate::pac::can::Fdcan, 412 state: &'static State,
413 _instance: &'d crate::pac::can::Fdcan,
398 _mode: OperatingMode, 414 _mode: OperatingMode,
399 tx_buf: &'static TxBuf<TX_BUF_SIZE>, 415 tx_buf: &'static TxBuf<TX_BUF_SIZE>,
400 rx_buf: &'static RxBuf<RX_BUF_SIZE>, 416 rx_buf: &'static RxBuf<RX_BUF_SIZE>,
401 properties: Properties<T>, 417 properties: Properties,
402} 418}
403 419
404impl<'c, 'd, T: Instance, const TX_BUF_SIZE: usize, const RX_BUF_SIZE: usize> 420impl<'c, 'd, const TX_BUF_SIZE: usize, const RX_BUF_SIZE: usize> BufferedCan<'d, TX_BUF_SIZE, RX_BUF_SIZE> {
405 BufferedCan<'d, T, TX_BUF_SIZE, RX_BUF_SIZE>
406{
407 fn new( 421 fn new(
408 _instance1: PhantomData<T>, 422 info: &'static Info,
409 _instance2: &'d crate::pac::can::Fdcan, 423 state: &'static State,
424 _instance: &'d crate::pac::can::Fdcan,
410 _mode: OperatingMode, 425 _mode: OperatingMode,
411 tx_buf: &'static TxBuf<TX_BUF_SIZE>, 426 tx_buf: &'static TxBuf<TX_BUF_SIZE>,
412 rx_buf: &'static RxBuf<RX_BUF_SIZE>, 427 rx_buf: &'static RxBuf<RX_BUF_SIZE>,
413 ) -> Self { 428 ) -> Self {
414 BufferedCan { 429 BufferedCan {
415 _instance1, 430 info,
416 _instance2, 431 state,
432 _instance,
417 _mode, 433 _mode,
418 tx_buf, 434 tx_buf,
419 rx_buf, 435 rx_buf,
420 properties: Properties::new(), 436 properties: Properties::new(info),
421 } 437 }
422 .setup() 438 .setup()
423 } 439 }
424 440
425 /// Get driver properties 441 /// Get driver properties
426 pub fn properties(&self) -> &Properties<T> { 442 pub fn properties(&self) -> &Properties {
427 &self.properties 443 &self.properties
428 } 444 }
429 445
430 fn setup(self) -> Self { 446 fn setup(self) -> Self {
431 // We don't want interrupts being processed while we change modes. 447 // We don't want interrupts being processed while we change modes.
432 critical_section::with(|_| unsafe { 448 critical_section::with(|_| {
433 let rx_inner = super::common::ClassicBufferedRxInner { 449 let rx_inner = super::common::ClassicBufferedRxInner {
434 rx_sender: self.rx_buf.sender().into(), 450 rx_sender: self.rx_buf.sender().into(),
435 }; 451 };
436 let tx_inner = super::common::ClassicBufferedTxInner { 452 let tx_inner = super::common::ClassicBufferedTxInner {
437 tx_receiver: self.tx_buf.receiver().into(), 453 tx_receiver: self.tx_buf.receiver().into(),
438 }; 454 };
439 T::mut_state().rx_mode = RxMode::ClassicBuffered(rx_inner); 455 let state = self.state as *const State;
440 T::mut_state().tx_mode = TxMode::ClassicBuffered(tx_inner); 456 unsafe {
457 let mut_state = state as *mut State;
458 (*mut_state).rx_mode = RxMode::ClassicBuffered(rx_inner);
459 (*mut_state).tx_mode = TxMode::ClassicBuffered(tx_inner);
460 }
441 }); 461 });
442 self 462 self
443 } 463 }
@@ -445,7 +465,8 @@ impl<'c, 'd, T: Instance, const TX_BUF_SIZE: usize, const RX_BUF_SIZE: usize>
445 /// Async write frame to TX buffer. 465 /// Async write frame to TX buffer.
446 pub async fn write(&mut self, frame: Frame) { 466 pub async fn write(&mut self, frame: Frame) {
447 self.tx_buf.send(frame).await; 467 self.tx_buf.send(frame).await;
448 T::IT0Interrupt::pend(); // Wake for Tx 468 self.info.interrupt0.pend(); // Wake for Tx
469 //T::IT0Interrupt::pend(); // Wake for Tx
449 } 470 }
450 471
451 /// Async read frame from RX buffer. 472 /// Async read frame from RX buffer.
@@ -457,7 +478,7 @@ impl<'c, 'd, T: Instance, const TX_BUF_SIZE: usize, const RX_BUF_SIZE: usize>
457 pub fn writer(&self) -> BufferedCanSender { 478 pub fn writer(&self) -> BufferedCanSender {
458 BufferedCanSender { 479 BufferedCanSender {
459 tx_buf: self.tx_buf.sender().into(), 480 tx_buf: self.tx_buf.sender().into(),
460 waker: T::IT0Interrupt::pend, 481 waker: self.info.tx_waker,
461 } 482 }
462 } 483 }
463 484
@@ -467,13 +488,15 @@ impl<'c, 'd, T: Instance, const TX_BUF_SIZE: usize, const RX_BUF_SIZE: usize>
467 } 488 }
468} 489}
469 490
470impl<'c, 'd, T: Instance, const TX_BUF_SIZE: usize, const RX_BUF_SIZE: usize> Drop 491impl<'c, 'd, const TX_BUF_SIZE: usize, const RX_BUF_SIZE: usize> Drop for BufferedCan<'d, TX_BUF_SIZE, RX_BUF_SIZE> {
471 for BufferedCan<'d, T, TX_BUF_SIZE, RX_BUF_SIZE>
472{
473 fn drop(&mut self) { 492 fn drop(&mut self) {
474 critical_section::with(|_| unsafe { 493 critical_section::with(|_| {
475 T::mut_state().rx_mode = RxMode::NonBuffered(embassy_sync::waitqueue::AtomicWaker::new()); 494 let state = self.state as *const State;
476 T::mut_state().tx_mode = TxMode::NonBuffered(embassy_sync::waitqueue::AtomicWaker::new()); 495 unsafe {
496 let mut_state = state as *mut State;
497 (*mut_state).rx_mode = RxMode::NonBuffered(embassy_sync::waitqueue::AtomicWaker::new());
498 (*mut_state).tx_mode = TxMode::NonBuffered(embassy_sync::waitqueue::AtomicWaker::new());
499 }
477 }); 500 });
478 } 501 }
479} 502}
@@ -484,16 +507,6 @@ pub type RxFdBuf<const BUF_SIZE: usize> = Channel<CriticalSectionRawMutex, Resul
484/// User supplied buffer for TX buffering 507/// User supplied buffer for TX buffering
485pub type TxFdBuf<const BUF_SIZE: usize> = Channel<CriticalSectionRawMutex, FdFrame, BUF_SIZE>; 508pub type TxFdBuf<const BUF_SIZE: usize> = Channel<CriticalSectionRawMutex, FdFrame, BUF_SIZE>;
486 509
487/// Buffered FDCAN Instance
488pub struct BufferedCanFd<'d, T: Instance, const TX_BUF_SIZE: usize, const RX_BUF_SIZE: usize> {
489 _instance1: PhantomData<T>,
490 _instance2: &'d crate::pac::can::Fdcan,
491 _mode: OperatingMode,
492 tx_buf: &'static TxFdBuf<TX_BUF_SIZE>,
493 rx_buf: &'static RxFdBuf<RX_BUF_SIZE>,
494 properties: Properties<T>,
495}
496
497/// Sender that can be used for sending CAN frames. 510/// Sender that can be used for sending CAN frames.
498#[derive(Copy, Clone)] 511#[derive(Copy, Clone)]
499pub struct BufferedFdCanSender { 512pub struct BufferedFdCanSender {
@@ -524,43 +537,58 @@ impl BufferedFdCanSender {
524/// Receiver that can be used for receiving CAN frames. Note, each CAN frame will only be received by one receiver. 537/// Receiver that can be used for receiving CAN frames. Note, each CAN frame will only be received by one receiver.
525pub type BufferedFdCanReceiver = DynamicReceiver<'static, Result<FdEnvelope, BusError>>; 538pub type BufferedFdCanReceiver = DynamicReceiver<'static, Result<FdEnvelope, BusError>>;
526 539
527impl<'c, 'd, T: Instance, const TX_BUF_SIZE: usize, const RX_BUF_SIZE: usize> 540/// Buffered FDCAN Instance
528 BufferedCanFd<'d, T, TX_BUF_SIZE, RX_BUF_SIZE> 541pub struct BufferedCanFd<'d, const TX_BUF_SIZE: usize, const RX_BUF_SIZE: usize> {
529{ 542 info: &'static Info,
543 state: &'static State,
544 _instance: &'d crate::pac::can::Fdcan,
545 _mode: OperatingMode,
546 tx_buf: &'static TxFdBuf<TX_BUF_SIZE>,
547 rx_buf: &'static RxFdBuf<RX_BUF_SIZE>,
548 properties: Properties,
549}
550
551impl<'c, 'd, const TX_BUF_SIZE: usize, const RX_BUF_SIZE: usize> BufferedCanFd<'d, TX_BUF_SIZE, RX_BUF_SIZE> {
530 fn new( 552 fn new(
531 _instance1: PhantomData<T>, 553 info: &'static Info,
532 _instance2: &'d crate::pac::can::Fdcan, 554 state: &'static State,
555 _instance: &'d crate::pac::can::Fdcan,
533 _mode: OperatingMode, 556 _mode: OperatingMode,
534 tx_buf: &'static TxFdBuf<TX_BUF_SIZE>, 557 tx_buf: &'static TxFdBuf<TX_BUF_SIZE>,
535 rx_buf: &'static RxFdBuf<RX_BUF_SIZE>, 558 rx_buf: &'static RxFdBuf<RX_BUF_SIZE>,
536 ) -> Self { 559 ) -> Self {
537 BufferedCanFd { 560 BufferedCanFd {
538 _instance1, 561 info,
539 _instance2, 562 state,
563 _instance,
540 _mode, 564 _mode,
541 tx_buf, 565 tx_buf,
542 rx_buf, 566 rx_buf,
543 properties: Properties::new(), 567 properties: Properties::new(info),
544 } 568 }
545 .setup() 569 .setup()
546 } 570 }
547 571
548 /// Get driver properties 572 /// Get driver properties
549 pub fn properties(&self) -> &Properties<T> { 573 pub fn properties(&self) -> &Properties {
550 &self.properties 574 &self.properties
551 } 575 }
552 576
553 fn setup(self) -> Self { 577 fn setup(self) -> Self {
554 // We don't want interrupts being processed while we change modes. 578 // We don't want interrupts being processed while we change modes.
555 critical_section::with(|_| unsafe { 579 critical_section::with(|_| {
556 let rx_inner = super::common::FdBufferedRxInner { 580 let rx_inner = super::common::FdBufferedRxInner {
557 rx_sender: self.rx_buf.sender().into(), 581 rx_sender: self.rx_buf.sender().into(),
558 }; 582 };
559 let tx_inner = super::common::FdBufferedTxInner { 583 let tx_inner = super::common::FdBufferedTxInner {
560 tx_receiver: self.tx_buf.receiver().into(), 584 tx_receiver: self.tx_buf.receiver().into(),
561 }; 585 };
562 T::mut_state().rx_mode = RxMode::FdBuffered(rx_inner); 586 let state = self.state as *const State;
563 T::mut_state().tx_mode = TxMode::FdBuffered(tx_inner); 587 unsafe {
588 let mut_state = state as *mut State;
589 (*mut_state).rx_mode = RxMode::FdBuffered(rx_inner);
590 (*mut_state).tx_mode = TxMode::FdBuffered(tx_inner);
591 }
564 }); 592 });
565 self 593 self
566 } 594 }
@@ -568,7 +596,8 @@ impl<'c, 'd, T: Instance, const TX_BUF_SIZE: usize, const RX_BUF_SIZE: usize>
568 /// Async write frame to TX buffer. 596 /// Async write frame to TX buffer.
569 pub async fn write(&mut self, frame: FdFrame) { 597 pub async fn write(&mut self, frame: FdFrame) {
570 self.tx_buf.send(frame).await; 598 self.tx_buf.send(frame).await;
571 T::IT0Interrupt::pend(); // Wake for Tx 599 self.info.interrupt0.pend(); // Wake for Tx
600 //T::IT0Interrupt::pend(); // Wake for Tx
572 } 601 }
573 602
574 /// Async read frame from RX buffer. 603 /// Async read frame from RX buffer.
@@ -580,7 +609,7 @@ impl<'c, 'd, T: Instance, const TX_BUF_SIZE: usize, const RX_BUF_SIZE: usize>
580 pub fn writer(&self) -> BufferedFdCanSender { 609 pub fn writer(&self) -> BufferedFdCanSender {
581 BufferedFdCanSender { 610 BufferedFdCanSender {
582 tx_buf: self.tx_buf.sender().into(), 611 tx_buf: self.tx_buf.sender().into(),
583 waker: T::IT0Interrupt::pend, 612 waker: self.info.tx_waker,
584 } 613 }
585 } 614 }
586 615
@@ -590,38 +619,55 @@ impl<'c, 'd, T: Instance, const TX_BUF_SIZE: usize, const RX_BUF_SIZE: usize>
590 } 619 }
591} 620}
592 621
593impl<'c, 'd, T: Instance, const TX_BUF_SIZE: usize, const RX_BUF_SIZE: usize> Drop 622impl<'c, 'd, const TX_BUF_SIZE: usize, const RX_BUF_SIZE: usize> Drop for BufferedCanFd<'d, TX_BUF_SIZE, RX_BUF_SIZE> {
594 for BufferedCanFd<'d, T, TX_BUF_SIZE, RX_BUF_SIZE>
595{
596 fn drop(&mut self) { 623 fn drop(&mut self) {
597 critical_section::with(|_| unsafe { 624 critical_section::with(|_| {
598 T::mut_state().rx_mode = RxMode::NonBuffered(embassy_sync::waitqueue::AtomicWaker::new()); 625 let state = self.state as *const State;
599 T::mut_state().tx_mode = TxMode::NonBuffered(embassy_sync::waitqueue::AtomicWaker::new()); 626 unsafe {
627 let mut_state = state as *mut State;
628 (*mut_state).rx_mode = RxMode::NonBuffered(embassy_sync::waitqueue::AtomicWaker::new());
629 (*mut_state).tx_mode = TxMode::NonBuffered(embassy_sync::waitqueue::AtomicWaker::new());
630 }
600 }); 631 });
601 } 632 }
602} 633}
603 634
604/// FDCAN Rx only Instance 635/// FDCAN Rx only Instance
605pub struct CanRx<'d, T: Instance> { 636pub struct CanRx<'d> {
606 _instance1: PhantomData<T>, 637 info: &'static Info,
607 _instance2: &'d crate::pac::can::Fdcan, 638 state: &'static State,
639 _instance: &'d crate::pac::can::Fdcan,
608 _mode: OperatingMode, 640 _mode: OperatingMode,
609} 641}
610 642
643impl<'d> CanRx<'d> {
644 /// Returns the next received message frame
645 pub async fn read(&mut self) -> Result<Envelope, BusError> {
646 self.state.rx_mode.read_classic(&self.info, &self.state).await
647 }
648
649 /// Returns the next received message frame
650 pub async fn read_fd(&mut self) -> Result<FdEnvelope, BusError> {
651 self.state.rx_mode.read_fd(&self.info, &self.state).await
652 }
653}
654
611/// FDCAN Tx only Instance 655/// FDCAN Tx only Instance
612pub struct CanTx<'d, T: Instance> { 656pub struct CanTx<'d> {
657 info: &'static Info,
658 state: &'static State,
613 config: crate::can::fd::config::FdCanConfig, 659 config: crate::can::fd::config::FdCanConfig,
614 _instance: FdcanInstance<'d, T>, //(PeripheralRef<'a, T>); 660 _instance: &'d crate::pac::can::Fdcan,
615 _mode: OperatingMode, 661 _mode: OperatingMode,
616} 662}
617 663
618impl<'c, 'd, T: Instance> CanTx<'d, T> { 664impl<'c, 'd> CanTx<'d> {
619 /// Queues the message to be sent but exerts backpressure. If a lower-priority 665 /// Queues the message to be sent but exerts backpressure. If a lower-priority
620 /// frame is dropped from the mailbox, it is returned. If no lower-priority frames 666 /// frame is dropped from the mailbox, it is returned. If no lower-priority frames
621 /// can be replaced, this call asynchronously waits for a frame to be successfully 667 /// can be replaced, this call asynchronously waits for a frame to be successfully
622 /// transmitted, then tries again. 668 /// transmitted, then tries again.
623 pub async fn write(&mut self, frame: &Frame) -> Option<Frame> { 669 pub async fn write(&mut self, frame: &Frame) -> Option<Frame> {
624 T::state().tx_mode.write::<T>(frame).await 670 self.state.tx_mode.write(self.info, frame).await
625 } 671 }
626 672
627 /// Queues the message to be sent but exerts backpressure. If a lower-priority 673 /// Queues the message to be sent but exerts backpressure. If a lower-priority
@@ -629,19 +675,7 @@ impl<'c, 'd, T: Instance> CanTx<'d, T> {
629 /// can be replaced, this call asynchronously waits for a frame to be successfully 675 /// can be replaced, this call asynchronously waits for a frame to be successfully
630 /// transmitted, then tries again. 676 /// transmitted, then tries again.
631 pub async fn write_fd(&mut self, frame: &FdFrame) -> Option<FdFrame> { 677 pub async fn write_fd(&mut self, frame: &FdFrame) -> Option<FdFrame> {
632 T::state().tx_mode.write_fd::<T>(frame).await 678 self.state.tx_mode.write_fd(self.info, frame).await
633 }
634}
635
636impl<'c, 'd, T: Instance> CanRx<'d, T> {
637 /// Returns the next received message frame
638 pub async fn read(&mut self) -> Result<Envelope, BusError> {
639 T::state().rx_mode.read_classic::<T>().await
640 }
641
642 /// Returns the next received message frame
643 pub async fn read_fd(&mut self) -> Result<FdEnvelope, BusError> {
644 T::state().rx_mode.read_fd::<T>().await
645 } 679 }
646} 680}
647 681
@@ -662,7 +696,7 @@ impl RxMode {
662 } 696 }
663 697
664 fn on_interrupt<T: Instance>(&self, fifonr: usize) { 698 fn on_interrupt<T: Instance>(&self, fifonr: usize) {
665 T::regs().ir().write(|w| w.set_rfn(fifonr, true)); 699 T::registers().regs.ir().write(|w| w.set_rfn(fifonr, true));
666 match self { 700 match self {
667 RxMode::NonBuffered(waker) => { 701 RxMode::NonBuffered(waker) => {
668 waker.wake(); 702 waker.wake();
@@ -696,7 +730,6 @@ impl RxMode {
696 } 730 }
697 } 731 }
698 732
699 //async fn read_classic<T: Instance>(&self) -> Result<Envelope, BusError> {
700 fn try_read_fd<T: Instance>(&self) -> Option<Result<FdEnvelope, BusError>> { 733 fn try_read_fd<T: Instance>(&self) -> Option<Result<FdEnvelope, BusError>> {
701 if let Some((frame, ts)) = T::registers().read(0) { 734 if let Some((frame, ts)) = T::registers().read(0) {
702 let ts = T::calc_timestamp(T::state().ns_per_timer_tick, ts); 735 let ts = T::calc_timestamp(T::state().ns_per_timer_tick, ts);
@@ -712,14 +745,18 @@ impl RxMode {
712 } 745 }
713 } 746 }
714 747
715 fn read<T: Instance, F: CanHeader>(&self) -> Option<Result<(F, Timestamp), BusError>> { 748 fn read<F: CanHeader>(
716 if let Some((msg, ts)) = T::registers().read(0) { 749 &self,
717 let ts = T::calc_timestamp(T::state().ns_per_timer_tick, ts); 750 info: &'static Info,
751 state: &'static State,
752 ) -> Option<Result<(F, Timestamp), BusError>> {
753 if let Some((msg, ts)) = info.regs.read(0) {
754 let ts = info.calc_timestamp(state.ns_per_timer_tick, ts);
718 Some(Ok((msg, ts))) 755 Some(Ok((msg, ts)))
719 } else if let Some((msg, ts)) = T::registers().read(1) { 756 } else if let Some((msg, ts)) = info.regs.read(1) {
720 let ts = T::calc_timestamp(T::state().ns_per_timer_tick, ts); 757 let ts = info.calc_timestamp(state.ns_per_timer_tick, ts);
721 Some(Ok((msg, ts))) 758 Some(Ok((msg, ts)))
722 } else if let Some(err) = T::registers().curr_error() { 759 } else if let Some(err) = info.regs.curr_error() {
723 // TODO: this is probably wrong 760 // TODO: this is probably wrong
724 Some(Err(err)) 761 Some(Err(err))
725 } else { 762 } else {
@@ -727,11 +764,16 @@ impl RxMode {
727 } 764 }
728 } 765 }
729 766
730 async fn read_async<T: Instance, F: CanHeader>(&self) -> Result<(F, Timestamp), BusError> { 767 async fn read_async<F: CanHeader>(
731 poll_fn(|cx| { 768 &self,
732 T::state().err_waker.register(cx.waker()); 769 info: &'static Info,
770 state: &'static State,
771 ) -> Result<(F, Timestamp), BusError> {
772 //let _ = self.read::<F>(info, state);
773 poll_fn(move |cx| {
774 state.err_waker.register(cx.waker());
733 self.register(cx.waker()); 775 self.register(cx.waker());
734 match self.read::<T, _>() { 776 match self.read::<_>(info, state) {
735 Some(result) => Poll::Ready(result), 777 Some(result) => Poll::Ready(result),
736 None => Poll::Pending, 778 None => Poll::Pending,
737 } 779 }
@@ -739,15 +781,15 @@ impl RxMode {
739 .await 781 .await
740 } 782 }
741 783
742 async fn read_classic<T: Instance>(&self) -> Result<Envelope, BusError> { 784 async fn read_classic(&self, info: &'static Info, state: &'static State) -> Result<Envelope, BusError> {
743 match self.read_async::<T, _>().await { 785 match self.read_async::<_>(info, state).await {
744 Ok((frame, ts)) => Ok(Envelope { ts, frame }), 786 Ok((frame, ts)) => Ok(Envelope { ts, frame }),
745 Err(e) => Err(e), 787 Err(e) => Err(e),
746 } 788 }
747 } 789 }
748 790
749 async fn read_fd<T: Instance>(&self) -> Result<FdEnvelope, BusError> { 791 async fn read_fd(&self, info: &'static Info, state: &'static State) -> Result<FdEnvelope, BusError> {
750 match self.read_async::<T, _>().await { 792 match self.read_async::<_>(info, state).await {
751 Ok((frame, ts)) => Ok(FdEnvelope { ts, frame }), 793 Ok((frame, ts)) => Ok(FdEnvelope { ts, frame }),
752 Err(e) => Err(e), 794 Err(e) => Err(e),
753 } 795 }
@@ -776,11 +818,11 @@ impl TxMode {
776 /// frame is dropped from the mailbox, it is returned. If no lower-priority frames 818 /// frame is dropped from the mailbox, it is returned. If no lower-priority frames
777 /// can be replaced, this call asynchronously waits for a frame to be successfully 819 /// can be replaced, this call asynchronously waits for a frame to be successfully
778 /// transmitted, then tries again. 820 /// transmitted, then tries again.
779 async fn write_generic<T: Instance, F: embedded_can::Frame + CanHeader>(&self, frame: &F) -> Option<F> { 821 async fn write_generic<F: embedded_can::Frame + CanHeader>(&self, info: &'static Info, frame: &F) -> Option<F> {
780 poll_fn(|cx| { 822 poll_fn(|cx| {
781 self.register(cx.waker()); 823 self.register(cx.waker());
782 824
783 if let Ok(dropped) = T::registers().write(frame) { 825 if let Ok(dropped) = info.regs.write(frame) {
784 return Poll::Ready(dropped); 826 return Poll::Ready(dropped);
785 } 827 }
786 828
@@ -795,68 +837,70 @@ impl TxMode {
795 /// frame is dropped from the mailbox, it is returned. If no lower-priority frames 837 /// frame is dropped from the mailbox, it is returned. If no lower-priority frames
796 /// can be replaced, this call asynchronously waits for a frame to be successfully 838 /// can be replaced, this call asynchronously waits for a frame to be successfully
797 /// transmitted, then tries again. 839 /// transmitted, then tries again.
798 async fn write<T: Instance>(&self, frame: &Frame) -> Option<Frame> { 840 async fn write(&self, info: &'static Info, frame: &Frame) -> Option<Frame> {
799 self.write_generic::<T, _>(frame).await 841 self.write_generic::<_>(info, frame).await
800 } 842 }
801 843
802 /// Queues the message to be sent but exerts backpressure. If a lower-priority 844 /// Queues the message to be sent but exerts backpressure. If a lower-priority
803 /// frame is dropped from the mailbox, it is returned. If no lower-priority frames 845 /// frame is dropped from the mailbox, it is returned. If no lower-priority frames
804 /// can be replaced, this call asynchronously waits for a frame to be successfully 846 /// can be replaced, this call asynchronously waits for a frame to be successfully
805 /// transmitted, then tries again. 847 /// transmitted, then tries again.
806 async fn write_fd<T: Instance>(&self, frame: &FdFrame) -> Option<FdFrame> { 848 async fn write_fd(&self, info: &'static Info, frame: &FdFrame) -> Option<FdFrame> {
807 self.write_generic::<T, _>(frame).await 849 self.write_generic::<_>(info, frame).await
808 } 850 }
809} 851}
810 852
811/// Common driver properties, including filters and error counters 853/// Common driver properties, including filters and error counters
812pub struct Properties<T> { 854pub struct Properties {
855 info: &'static Info,
813 // phantom pointer to ensure !Sync 856 // phantom pointer to ensure !Sync
814 instance: PhantomData<*const T>, 857 //instance: PhantomData<*const T>,
815} 858}
816 859
817impl<T: Instance> Properties<T> { 860impl Properties {
818 fn new() -> Self { 861 fn new(info: &'static Info) -> Self {
819 Self { 862 Self {
820 instance: Default::default(), 863 info,
864 //instance: Default::default(),
821 } 865 }
822 } 866 }
823 867
824 /// Set a standard address CAN filter in the specified slot in FDCAN memory. 868 /// Set a standard address CAN filter in the specified slot in FDCAN memory.
825 #[inline] 869 #[inline]
826 pub fn set_standard_filter(&self, slot: StandardFilterSlot, filter: StandardFilter) { 870 pub fn set_standard_filter(&self, slot: StandardFilterSlot, filter: StandardFilter) {
827 T::registers().msg_ram_mut().filters.flssa[slot as usize].activate(filter); 871 self.info.regs.msg_ram_mut().filters.flssa[slot as usize].activate(filter);
828 } 872 }
829 873
830 /// Set the full array of standard address CAN filters in FDCAN memory. 874 /// Set the full array of standard address CAN filters in FDCAN memory.
831 /// Overwrites all standard address filters in memory. 875 /// Overwrites all standard address filters in memory.
832 pub fn set_standard_filters(&self, filters: &[StandardFilter; STANDARD_FILTER_MAX as usize]) { 876 pub fn set_standard_filters(&self, filters: &[StandardFilter; STANDARD_FILTER_MAX as usize]) {
833 for (i, f) in filters.iter().enumerate() { 877 for (i, f) in filters.iter().enumerate() {
834 T::registers().msg_ram_mut().filters.flssa[i].activate(*f); 878 self.info.regs.msg_ram_mut().filters.flssa[i].activate(*f);
835 } 879 }
836 } 880 }
837 881
838 /// Set an extended address CAN filter in the specified slot in FDCAN memory. 882 /// Set an extended address CAN filter in the specified slot in FDCAN memory.
839 #[inline] 883 #[inline]
840 pub fn set_extended_filter(&self, slot: ExtendedFilterSlot, filter: ExtendedFilter) { 884 pub fn set_extended_filter(&self, slot: ExtendedFilterSlot, filter: ExtendedFilter) {
841 T::registers().msg_ram_mut().filters.flesa[slot as usize].activate(filter); 885 self.info.regs.msg_ram_mut().filters.flesa[slot as usize].activate(filter);
842 } 886 }
843 887
844 /// Set the full array of extended address CAN filters in FDCAN memory. 888 /// Set the full array of extended address CAN filters in FDCAN memory.
845 /// Overwrites all extended address filters in memory. 889 /// Overwrites all extended address filters in memory.
846 pub fn set_extended_filters(&self, filters: &[ExtendedFilter; EXTENDED_FILTER_MAX as usize]) { 890 pub fn set_extended_filters(&self, filters: &[ExtendedFilter; EXTENDED_FILTER_MAX as usize]) {
847 for (i, f) in filters.iter().enumerate() { 891 for (i, f) in filters.iter().enumerate() {
848 T::registers().msg_ram_mut().filters.flesa[i].activate(*f); 892 self.info.regs.msg_ram_mut().filters.flesa[i].activate(*f);
849 } 893 }
850 } 894 }
851 895
852 /// Get the CAN RX error counter 896 /// Get the CAN RX error counter
853 pub fn rx_error_count(&self) -> u8 { 897 pub fn rx_error_count(&self) -> u8 {
854 T::regs().ecr().read().rec() 898 self.info.regs.regs.ecr().read().rec()
855 } 899 }
856 900
857 /// Get the CAN TX error counter 901 /// Get the CAN TX error counter
858 pub fn tx_error_count(&self) -> u8 { 902 pub fn tx_error_count(&self) -> u8 {
859 T::regs().ecr().read().tec() 903 self.info.regs.regs.ecr().read().tec()
860 } 904 }
861 905
862 /// Get the current bus error mode 906 /// Get the current bus error mode
@@ -864,7 +908,7 @@ impl<T: Instance> Properties<T> {
864 // This read will clear LEC and DLEC. This is not ideal, but protocol 908 // This read will clear LEC and DLEC. This is not ideal, but protocol
865 // error reporting in this driver should have a big ol' FIXME on it 909 // error reporting in this driver should have a big ol' FIXME on it
866 // anyway! 910 // anyway!
867 let psr = T::regs().psr().read(); 911 let psr = self.info.regs.regs.psr().read();
868 match (psr.bo(), psr.ep()) { 912 match (psr.bo(), psr.ep()) {
869 (false, false) => BusErrorMode::ErrorActive, 913 (false, false) => BusErrorMode::ErrorActive,
870 (false, true) => BusErrorMode::ErrorPassive, 914 (false, true) => BusErrorMode::ErrorPassive,
@@ -892,10 +936,37 @@ impl State {
892 } 936 }
893} 937}
894 938
939struct Info {
940 regs: Registers,
941 interrupt0: crate::interrupt::Interrupt,
942 _interrupt1: crate::interrupt::Interrupt,
943 tx_waker: fn(),
944}
945
946impl Info {
947 #[cfg(feature = "time")]
948 fn calc_timestamp(&self, ns_per_timer_tick: u64, ts_val: u16) -> Timestamp {
949 let now_embassy = embassy_time::Instant::now();
950 if ns_per_timer_tick == 0 {
951 return now_embassy;
952 }
953 let cantime = { self.regs.regs.tscv().read().tsc() };
954 let delta = cantime.overflowing_sub(ts_val).0 as u64;
955 let ns = ns_per_timer_tick * delta as u64;
956 now_embassy - embassy_time::Duration::from_nanos(ns)
957 }
958
959 #[cfg(not(feature = "time"))]
960 fn calc_timestamp(&self, _ns_per_timer_tick: u64, ts_val: u16) -> Timestamp {
961 ts_val
962 }
963}
964
895trait SealedInstance { 965trait SealedInstance {
896 const MSG_RAM_OFFSET: usize; 966 const MSG_RAM_OFFSET: usize;
897 967
898 fn regs() -> &'static crate::pac::can::Fdcan; 968 fn info() -> &'static Info;
969 //fn regs() -> &'static crate::pac::can::Fdcan;
899 fn registers() -> crate::can::fd::peripheral::Registers; 970 fn registers() -> crate::can::fd::peripheral::Registers;
900 fn state() -> &'static State; 971 fn state() -> &'static State;
901 unsafe fn mut_state() -> &'static mut State; 972 unsafe fn mut_state() -> &'static mut State;
@@ -915,12 +986,20 @@ pub trait Instance: SealedInstance + RccPeripheral + 'static {
915pub struct FdcanInstance<'a, T>(PeripheralRef<'a, T>); 986pub struct FdcanInstance<'a, T>(PeripheralRef<'a, T>);
916 987
917macro_rules! impl_fdcan { 988macro_rules! impl_fdcan {
918 ($inst:ident, $msg_ram_inst:ident, $msg_ram_offset:literal) => { 989 ($inst:ident,
990 //$irq0:ident, $irq1:ident,
991 $msg_ram_inst:ident, $msg_ram_offset:literal) => {
919 impl SealedInstance for peripherals::$inst { 992 impl SealedInstance for peripherals::$inst {
920 const MSG_RAM_OFFSET: usize = $msg_ram_offset; 993 const MSG_RAM_OFFSET: usize = $msg_ram_offset;
921 994
922 fn regs() -> &'static crate::pac::can::Fdcan { 995 fn info() -> &'static Info {
923 &crate::pac::$inst 996 static INFO: Info = Info {
997 regs: Registers{regs: &crate::pac::$inst, msgram: &crate::pac::$msg_ram_inst, msg_ram_offset: $msg_ram_offset},
998 interrupt0: crate::_generated::peripheral_interrupts::$inst::IT0::IRQ,
999 _interrupt1: crate::_generated::peripheral_interrupts::$inst::IT1::IRQ,
1000 tx_waker: crate::_generated::peripheral_interrupts::$inst::IT0::pend,
1001 };
1002 &INFO
924 } 1003 }
925 fn registers() -> Registers { 1004 fn registers() -> Registers {
926 Registers{regs: &crate::pac::$inst, msgram: &crate::pac::$msg_ram_inst, msg_ram_offset: Self::MSG_RAM_OFFSET} 1005 Registers{regs: &crate::pac::$inst, msgram: &crate::pac::$msg_ram_inst, msg_ram_offset: Self::MSG_RAM_OFFSET}
@@ -939,7 +1018,7 @@ macro_rules! impl_fdcan {
939 if ns_per_timer_tick == 0 { 1018 if ns_per_timer_tick == 0 {
940 return now_embassy; 1019 return now_embassy;
941 } 1020 }
942 let cantime = { Self::regs().tscv().read().tsc() }; 1021 let cantime = { Self::registers().regs.tscv().read().tsc() };
943 let delta = cantime.overflowing_sub(ts_val).0 as u64; 1022 let delta = cantime.overflowing_sub(ts_val).0 as u64;
944 let ns = ns_per_timer_tick * delta as u64; 1023 let ns = ns_per_timer_tick * delta as u64;
945 now_embassy - embassy_time::Duration::from_nanos(ns) 1024 now_embassy - embassy_time::Duration::from_nanos(ns)
diff --git a/tests/stm32/src/bin/can.rs b/tests/stm32/src/bin/can.rs
index 551764458..004b1a729 100644
--- a/tests/stm32/src/bin/can.rs
+++ b/tests/stm32/src/bin/can.rs
@@ -9,9 +9,7 @@ use common::*;
9use embassy_executor::Spawner; 9use embassy_executor::Spawner;
10use embassy_stm32::bind_interrupts; 10use embassy_stm32::bind_interrupts;
11use embassy_stm32::can::filter::Mask32; 11use embassy_stm32::can::filter::Mask32;
12use embassy_stm32::can::{ 12use embassy_stm32::can::{Fifo, Rx0InterruptHandler, Rx1InterruptHandler, SceInterruptHandler, TxInterruptHandler};
13 Can, Fifo, Rx0InterruptHandler, Rx1InterruptHandler, SceInterruptHandler, TxInterruptHandler,
14};
15use embassy_stm32::gpio::{Input, Pull}; 13use embassy_stm32::gpio::{Input, Pull};
16use embassy_stm32::peripherals::CAN1; 14use embassy_stm32::peripherals::CAN1;
17use embassy_time::Duration; 15use embassy_time::Duration;
@@ -20,6 +18,10 @@ use {defmt_rtt as _, panic_probe as _};
20mod can_common; 18mod can_common;
21use can_common::*; 19use can_common::*;
22 20
21type Can<'d> = embassy_stm32::can::Can<'d, embassy_stm32::peripherals::CAN1>;
22type CanTx<'d> = embassy_stm32::can::CanTx<'d, embassy_stm32::peripherals::CAN1>;
23type CanRx<'d> = embassy_stm32::can::CanRx<'d, embassy_stm32::peripherals::CAN1>;
24
23bind_interrupts!(struct Irqs { 25bind_interrupts!(struct Irqs {
24 CAN1_RX0 => Rx0InterruptHandler<CAN1>; 26 CAN1_RX0 => Rx0InterruptHandler<CAN1>;
25 CAN1_RX1 => Rx1InterruptHandler<CAN1>; 27 CAN1_RX1 => Rx1InterruptHandler<CAN1>;
diff --git a/tests/stm32/src/bin/can_common.rs b/tests/stm32/src/bin/can_common.rs
index 4b39269cc..fbfbcdc21 100644
--- a/tests/stm32/src/bin/can_common.rs
+++ b/tests/stm32/src/bin/can_common.rs
@@ -8,7 +8,8 @@ pub struct TestOptions {
8 pub max_buffered: u8, 8 pub max_buffered: u8,
9} 9}
10 10
11pub async fn run_can_tests<'d, T: can::Instance>(can: &mut can::Can<'d, T>, options: &TestOptions) { 11pub async fn run_can_tests<'d>(can: &mut crate::Can<'d>, options: &TestOptions) {
12 //pub async fn run_can_tests<'d, T: can::Instance>(can: &mut can::Can<'d, T>, options: &TestOptions) {
12 let mut i: u8 = 0; 13 let mut i: u8 = 0;
13 loop { 14 loop {
14 //let tx_frame = can::frame::Frame::new_standard(0x123, &[i, 0x12 as u8, 0x34 as u8, 0x56 as u8, 0x78 as u8, 0x9A as u8, 0xBC as u8 ]).unwrap(); 15 //let tx_frame = can::frame::Frame::new_standard(0x123, &[i, 0x12 as u8, 0x34 as u8, 0x56 as u8, 0x78 as u8, 0x9A as u8, 0xBC as u8 ]).unwrap();
@@ -79,11 +80,7 @@ pub async fn run_can_tests<'d, T: can::Instance>(can: &mut can::Can<'d, T>, opti
79 } 80 }
80} 81}
81 82
82pub async fn run_split_can_tests<'d, T: can::Instance>( 83pub async fn run_split_can_tests<'d>(tx: &mut crate::CanTx<'d>, rx: &mut crate::CanRx<'d>, options: &TestOptions) {
83 tx: &mut can::CanTx<'d, T>,
84 rx: &mut can::CanRx<'d, T>,
85 options: &TestOptions,
86) {
87 for i in 0..options.max_buffered { 84 for i in 0..options.max_buffered {
88 // Try filling up the RX FIFO0 buffers 85 // Try filling up the RX FIFO0 buffers
89 //let tx_frame = if 0 != (i & 0x01) { 86 //let tx_frame = if 0 != (i & 0x01) {
diff --git a/tests/stm32/src/bin/fdcan.rs b/tests/stm32/src/bin/fdcan.rs
index 20bd3f7e3..8534f92e8 100644
--- a/tests/stm32/src/bin/fdcan.rs
+++ b/tests/stm32/src/bin/fdcan.rs
@@ -15,6 +15,10 @@ use {defmt_rtt as _, panic_probe as _};
15mod can_common; 15mod can_common;
16use can_common::*; 16use can_common::*;
17 17
18type Can<'d> = can::Can<'d>;
19type CanTx<'d> = can::CanTx<'d>;
20type CanRx<'d> = can::CanRx<'d>;
21
18bind_interrupts!(struct Irqs2 { 22bind_interrupts!(struct Irqs2 {
19 FDCAN2_IT0 => can::IT0InterruptHandler<FDCAN2>; 23 FDCAN2_IT0 => can::IT0InterruptHandler<FDCAN2>;
20 FDCAN2_IT1 => can::IT1InterruptHandler<FDCAN2>; 24 FDCAN2_IT1 => can::IT1InterruptHandler<FDCAN2>;