diff options
| author | Corey Schuhen <[email protected]> | 2024-02-03 09:44:00 +1000 |
|---|---|---|
| committer | Corey Schuhen <[email protected]> | 2024-02-17 18:25:58 +1000 |
| commit | 70b3c4374d57ab638e0cb76013b725e1ea229546 (patch) | |
| tree | 0c0f13b68c6e67d1f2ae49fafb62e5c38754c8c6 /examples | |
| parent | 377e58e408f830f79171a470ba602b7d8bc525e4 (diff) | |
Port FDCAN HAL to use PAC directly instead of fdcan crate.
- Provide separate FDCAN capable and Classic CAN API's
- Don't use fdcan crate dep anymore
- Provide embedded-can traits.
Diffstat (limited to 'examples')
| -rw-r--r-- | examples/stm32g4/Cargo.toml | 1 | ||||
| -rw-r--r-- | examples/stm32g4/src/bin/can.rs | 96 | ||||
| -rw-r--r-- | examples/stm32h5/src/bin/can.rs | 89 | ||||
| -rw-r--r-- | examples/stm32h7/src/bin/can.rs | 89 |
4 files changed, 195 insertions, 80 deletions
diff --git a/examples/stm32g4/Cargo.toml b/examples/stm32g4/Cargo.toml index 895ad3e7c..fdb325f06 100644 --- a/examples/stm32g4/Cargo.toml +++ b/examples/stm32g4/Cargo.toml | |||
| @@ -20,6 +20,7 @@ defmt-rtt = "0.4" | |||
| 20 | cortex-m = { version = "0.7.6", features = ["critical-section-single-core"] } | 20 | cortex-m = { version = "0.7.6", features = ["critical-section-single-core"] } |
| 21 | cortex-m-rt = "0.7.0" | 21 | cortex-m-rt = "0.7.0" |
| 22 | embedded-hal = "0.2.6" | 22 | embedded-hal = "0.2.6" |
| 23 | embedded-can = { version = "0.4" } | ||
| 23 | panic-probe = { version = "0.3", features = ["print-defmt"] } | 24 | panic-probe = { version = "0.3", features = ["print-defmt"] } |
| 24 | futures = { version = "0.3.17", default-features = false, features = ["async-await"] } | 25 | futures = { version = "0.3.17", default-features = false, features = ["async-await"] } |
| 25 | heapless = { version = "0.8", default-features = false } | 26 | heapless = { version = "0.8", default-features = false } |
diff --git a/examples/stm32g4/src/bin/can.rs b/examples/stm32g4/src/bin/can.rs index 727921fba..5ff4f0ef0 100644 --- a/examples/stm32g4/src/bin/can.rs +++ b/examples/stm32g4/src/bin/can.rs | |||
| @@ -20,32 +20,100 @@ async fn main(_spawner: Spawner) { | |||
| 20 | 20 | ||
| 21 | let mut can = can::Fdcan::new(peripherals.FDCAN1, peripherals.PA11, peripherals.PA12, Irqs); | 21 | let mut can = can::Fdcan::new(peripherals.FDCAN1, peripherals.PA11, peripherals.PA12, Irqs); |
| 22 | 22 | ||
| 23 | can.set_extended_filter( | ||
| 24 | can::fd::filter::ExtendedFilterSlot::_0, | ||
| 25 | can::fd::filter::ExtendedFilter::accept_all_into_fifo1(), | ||
| 26 | ); | ||
| 27 | |||
| 23 | // 250k bps | 28 | // 250k bps |
| 24 | can.set_bitrate(250_000); | 29 | can.set_bitrate(250_000); |
| 25 | 30 | ||
| 31 | // 1M bps | ||
| 32 | can.set_fd_data_bitrate(1_000_000, false); | ||
| 33 | |||
| 26 | info!("Configured"); | 34 | info!("Configured"); |
| 27 | 35 | ||
| 28 | //let mut can = can.into_external_loopback_mode(); | 36 | //let mut can = can.into_normal_mode(); |
| 29 | let mut can = can.into_normal_mode(); | 37 | let mut can = can.into_internal_loopback_mode(); |
| 30 | 38 | ||
| 31 | let mut i = 0; | 39 | let mut i = 0; |
| 40 | let mut last_read_ts = embassy_time::Instant::now(); | ||
| 41 | |||
| 32 | loop { | 42 | loop { |
| 33 | let frame = can::TxFrame::new( | 43 | let frame = can::frame::ClassicFrame::new_extended(0x123456F, &[i; 8]).unwrap(); |
| 34 | can::TxFrameHeader { | ||
| 35 | len: 1, | ||
| 36 | frame_format: can::FrameFormat::Standard, | ||
| 37 | id: can::StandardId::new(0x123).unwrap().into(), | ||
| 38 | bit_rate_switching: false, | ||
| 39 | marker: None, | ||
| 40 | }, | ||
| 41 | &[i], | ||
| 42 | ) | ||
| 43 | .unwrap(); | ||
| 44 | info!("Writing frame"); | 44 | info!("Writing frame"); |
| 45 | |||
| 45 | _ = can.write(&frame).await; | 46 | _ = can.write(&frame).await; |
| 46 | 47 | ||
| 47 | match can.read().await { | 48 | match can.read().await { |
| 48 | Ok(rx_frame) => info!("Rx: {}", rx_frame.data()[0]), | 49 | Ok((rx_frame, ts)) => { |
| 50 | let delta = (ts - last_read_ts).as_millis(); | ||
| 51 | last_read_ts = ts; | ||
| 52 | info!( | ||
| 53 | "Rx: {} {:02x} --- {}ms", | ||
| 54 | rx_frame.header().len(), | ||
| 55 | rx_frame.data()[0..rx_frame.header().len() as usize], | ||
| 56 | delta, | ||
| 57 | ) | ||
| 58 | } | ||
| 59 | Err(_err) => error!("Error in frame"), | ||
| 60 | } | ||
| 61 | |||
| 62 | Timer::after_millis(250).await; | ||
| 63 | |||
| 64 | i += 1; | ||
| 65 | if i > 2 { | ||
| 66 | break; | ||
| 67 | } | ||
| 68 | } | ||
| 69 | |||
| 70 | // Use the FD API's even if we don't get FD packets. | ||
| 71 | loop { | ||
| 72 | let frame = can::frame::FdFrame::new_extended(0x123456F, &[i; 16]).unwrap(); | ||
| 73 | info!("Writing frame using FD API"); | ||
| 74 | |||
| 75 | _ = can.write_fd(&frame).await; | ||
| 76 | |||
| 77 | match can.read_fd().await { | ||
| 78 | Ok((rx_frame, ts)) => { | ||
| 79 | let delta = (ts - last_read_ts).as_millis(); | ||
| 80 | last_read_ts = ts; | ||
| 81 | info!( | ||
| 82 | "Rx: {} {:02x} --- using FD API {}ms", | ||
| 83 | rx_frame.header().len(), | ||
| 84 | rx_frame.data()[0..rx_frame.header().len() as usize], | ||
| 85 | delta, | ||
| 86 | ) | ||
| 87 | } | ||
| 88 | Err(_err) => error!("Error in frame"), | ||
| 89 | } | ||
| 90 | |||
| 91 | Timer::after_millis(250).await; | ||
| 92 | |||
| 93 | i += 1; | ||
| 94 | if i > 4 { | ||
| 95 | break; | ||
| 96 | } | ||
| 97 | } | ||
| 98 | |||
| 99 | let (mut tx, mut rx) = can.split(); | ||
| 100 | // With split | ||
| 101 | loop { | ||
| 102 | let frame = can::frame::ClassicFrame::new_extended(0x123456F, &[i; 8]).unwrap(); | ||
| 103 | info!("Writing frame"); | ||
| 104 | _ = tx.write(&frame).await; | ||
| 105 | |||
| 106 | match rx.read().await { | ||
| 107 | Ok((rx_frame, ts)) => { | ||
| 108 | let delta = (ts - last_read_ts).as_millis(); | ||
| 109 | last_read_ts = ts; | ||
| 110 | info!( | ||
| 111 | "Rx: {} {:02x} --- {}ms", | ||
| 112 | rx_frame.header().len(), | ||
| 113 | rx_frame.data()[0..rx_frame.header().len() as usize], | ||
| 114 | delta, | ||
| 115 | ) | ||
| 116 | } | ||
| 49 | Err(_err) => error!("Error in frame"), | 117 | Err(_err) => error!("Error in frame"), |
| 50 | } | 118 | } |
| 51 | 119 | ||
diff --git a/examples/stm32h5/src/bin/can.rs b/examples/stm32h5/src/bin/can.rs index 2906d1576..4b29a0d21 100644 --- a/examples/stm32h5/src/bin/can.rs +++ b/examples/stm32h5/src/bin/can.rs | |||
| @@ -16,54 +16,77 @@ bind_interrupts!(struct Irqs { | |||
| 16 | #[embassy_executor::main] | 16 | #[embassy_executor::main] |
| 17 | async fn main(_spawner: Spawner) { | 17 | async fn main(_spawner: Spawner) { |
| 18 | let mut config = Config::default(); | 18 | let mut config = Config::default(); |
| 19 | 19 | config.rcc.hse = Some(rcc::Hse { | |
| 20 | // configure FDCAN to use PLL1_Q at 64 MHz | 20 | freq: embassy_stm32::time::Hertz(25_000_000), |
| 21 | config.rcc.pll1 = Some(rcc::Pll { | 21 | mode: rcc::HseMode::Oscillator, |
| 22 | source: rcc::PllSource::HSI, | ||
| 23 | prediv: rcc::PllPreDiv::DIV4, | ||
| 24 | mul: rcc::PllMul::MUL8, | ||
| 25 | divp: None, | ||
| 26 | divq: Some(rcc::PllDiv::DIV2), | ||
| 27 | divr: None, | ||
| 28 | }); | 22 | }); |
| 29 | config.rcc.fdcan_clock_source = rcc::FdCanClockSource::PLL1_Q; | 23 | config.rcc.fdcan_clock_source = rcc::FdCanClockSource::HSE; |
| 30 | 24 | ||
| 31 | let peripherals = embassy_stm32::init(config); | 25 | let peripherals = embassy_stm32::init(config); |
| 32 | 26 | ||
| 27 | //let mut can = can::Fdcan::new(peripherals.FDCAN1, peripherals.PB8, peripherals.PB9, Irqs); | ||
| 33 | let mut can = can::Fdcan::new(peripherals.FDCAN1, peripherals.PA11, peripherals.PA12, Irqs); | 28 | let mut can = can::Fdcan::new(peripherals.FDCAN1, peripherals.PA11, peripherals.PA12, Irqs); |
| 34 | 29 | ||
| 35 | can.can.apply_config( | 30 | // 250k bps |
| 36 | can::config::FdCanConfig::default().set_nominal_bit_timing(can::config::NominalBitTiming { | 31 | can.set_bitrate(250_000); |
| 37 | sync_jump_width: 1.try_into().unwrap(), | ||
| 38 | prescaler: 8.try_into().unwrap(), | ||
| 39 | seg1: 13.try_into().unwrap(), | ||
| 40 | seg2: 2.try_into().unwrap(), | ||
| 41 | }), | ||
| 42 | ); | ||
| 43 | 32 | ||
| 44 | info!("Configured"); | 33 | //let mut can = can.into_internal_loopback_mode(); |
| 34 | let mut can = can.into_normal_mode(); | ||
| 45 | 35 | ||
| 46 | let mut can = can.into_external_loopback_mode(); | 36 | info!("CAN Configured"); |
| 47 | //let mut can = can.into_normal_mode(); | ||
| 48 | 37 | ||
| 49 | let mut i = 0; | 38 | let mut i = 0; |
| 39 | let mut last_read_ts = embassy_time::Instant::now(); | ||
| 40 | |||
| 50 | loop { | 41 | loop { |
| 51 | let frame = can::TxFrame::new( | 42 | let frame = can::frame::ClassicFrame::new_extended(0x123456F, &[i; 8]).unwrap(); |
| 52 | can::TxFrameHeader { | ||
| 53 | len: 1, | ||
| 54 | frame_format: can::FrameFormat::Standard, | ||
| 55 | id: can::StandardId::new(0x123).unwrap().into(), | ||
| 56 | bit_rate_switching: false, | ||
| 57 | marker: None, | ||
| 58 | }, | ||
| 59 | &[i], | ||
| 60 | ) | ||
| 61 | .unwrap(); | ||
| 62 | info!("Writing frame"); | 43 | info!("Writing frame"); |
| 63 | _ = can.write(&frame).await; | 44 | _ = can.write(&frame).await; |
| 64 | 45 | ||
| 65 | match can.read().await { | 46 | match can.read().await { |
| 66 | Ok(rx_frame) => info!("Rx: {}", rx_frame.data()[0]), | 47 | Ok((rx_frame, ts)) => { |
| 48 | let delta = (ts - last_read_ts).as_millis(); | ||
| 49 | last_read_ts = ts; | ||
| 50 | info!( | ||
| 51 | "Rx: {:x} {:x} {:x} {:x} --- NEW {}", | ||
| 52 | rx_frame.data()[0], | ||
| 53 | rx_frame.data()[1], | ||
| 54 | rx_frame.data()[2], | ||
| 55 | rx_frame.data()[3], | ||
| 56 | delta, | ||
| 57 | ) | ||
| 58 | } | ||
| 59 | Err(_err) => error!("Error in frame"), | ||
| 60 | } | ||
| 61 | |||
| 62 | Timer::after_millis(250).await; | ||
| 63 | |||
| 64 | i += 1; | ||
| 65 | if i > 3 { | ||
| 66 | break; | ||
| 67 | } | ||
| 68 | } | ||
| 69 | |||
| 70 | let (mut tx, mut rx) = can.split(); | ||
| 71 | // With split | ||
| 72 | loop { | ||
| 73 | let frame = can::frame::ClassicFrame::new_extended(0x123456F, &[i; 8]).unwrap(); | ||
| 74 | info!("Writing frame"); | ||
| 75 | _ = tx.write(&frame).await; | ||
| 76 | |||
| 77 | match rx.read().await { | ||
| 78 | Ok((rx_frame, ts)) => { | ||
| 79 | let delta = (ts - last_read_ts).as_millis(); | ||
| 80 | last_read_ts = ts; | ||
| 81 | info!( | ||
| 82 | "Rx: {:x} {:x} {:x} {:x} --- NEW {}", | ||
| 83 | rx_frame.data()[0], | ||
| 84 | rx_frame.data()[1], | ||
| 85 | rx_frame.data()[2], | ||
| 86 | rx_frame.data()[3], | ||
| 87 | delta, | ||
| 88 | ) | ||
| 89 | } | ||
| 67 | Err(_err) => error!("Error in frame"), | 90 | Err(_err) => error!("Error in frame"), |
| 68 | } | 91 | } |
| 69 | 92 | ||
diff --git a/examples/stm32h7/src/bin/can.rs b/examples/stm32h7/src/bin/can.rs index 2906d1576..4b29a0d21 100644 --- a/examples/stm32h7/src/bin/can.rs +++ b/examples/stm32h7/src/bin/can.rs | |||
| @@ -16,54 +16,77 @@ bind_interrupts!(struct Irqs { | |||
| 16 | #[embassy_executor::main] | 16 | #[embassy_executor::main] |
| 17 | async fn main(_spawner: Spawner) { | 17 | async fn main(_spawner: Spawner) { |
| 18 | let mut config = Config::default(); | 18 | let mut config = Config::default(); |
| 19 | 19 | config.rcc.hse = Some(rcc::Hse { | |
| 20 | // configure FDCAN to use PLL1_Q at 64 MHz | 20 | freq: embassy_stm32::time::Hertz(25_000_000), |
| 21 | config.rcc.pll1 = Some(rcc::Pll { | 21 | mode: rcc::HseMode::Oscillator, |
| 22 | source: rcc::PllSource::HSI, | ||
| 23 | prediv: rcc::PllPreDiv::DIV4, | ||
| 24 | mul: rcc::PllMul::MUL8, | ||
| 25 | divp: None, | ||
| 26 | divq: Some(rcc::PllDiv::DIV2), | ||
| 27 | divr: None, | ||
| 28 | }); | 22 | }); |
| 29 | config.rcc.fdcan_clock_source = rcc::FdCanClockSource::PLL1_Q; | 23 | config.rcc.fdcan_clock_source = rcc::FdCanClockSource::HSE; |
| 30 | 24 | ||
| 31 | let peripherals = embassy_stm32::init(config); | 25 | let peripherals = embassy_stm32::init(config); |
| 32 | 26 | ||
| 27 | //let mut can = can::Fdcan::new(peripherals.FDCAN1, peripherals.PB8, peripherals.PB9, Irqs); | ||
| 33 | let mut can = can::Fdcan::new(peripherals.FDCAN1, peripherals.PA11, peripherals.PA12, Irqs); | 28 | let mut can = can::Fdcan::new(peripherals.FDCAN1, peripherals.PA11, peripherals.PA12, Irqs); |
| 34 | 29 | ||
| 35 | can.can.apply_config( | 30 | // 250k bps |
| 36 | can::config::FdCanConfig::default().set_nominal_bit_timing(can::config::NominalBitTiming { | 31 | can.set_bitrate(250_000); |
| 37 | sync_jump_width: 1.try_into().unwrap(), | ||
| 38 | prescaler: 8.try_into().unwrap(), | ||
| 39 | seg1: 13.try_into().unwrap(), | ||
| 40 | seg2: 2.try_into().unwrap(), | ||
| 41 | }), | ||
| 42 | ); | ||
| 43 | 32 | ||
| 44 | info!("Configured"); | 33 | //let mut can = can.into_internal_loopback_mode(); |
| 34 | let mut can = can.into_normal_mode(); | ||
| 45 | 35 | ||
| 46 | let mut can = can.into_external_loopback_mode(); | 36 | info!("CAN Configured"); |
| 47 | //let mut can = can.into_normal_mode(); | ||
| 48 | 37 | ||
| 49 | let mut i = 0; | 38 | let mut i = 0; |
| 39 | let mut last_read_ts = embassy_time::Instant::now(); | ||
| 40 | |||
| 50 | loop { | 41 | loop { |
| 51 | let frame = can::TxFrame::new( | 42 | let frame = can::frame::ClassicFrame::new_extended(0x123456F, &[i; 8]).unwrap(); |
| 52 | can::TxFrameHeader { | ||
| 53 | len: 1, | ||
| 54 | frame_format: can::FrameFormat::Standard, | ||
| 55 | id: can::StandardId::new(0x123).unwrap().into(), | ||
| 56 | bit_rate_switching: false, | ||
| 57 | marker: None, | ||
| 58 | }, | ||
| 59 | &[i], | ||
| 60 | ) | ||
| 61 | .unwrap(); | ||
| 62 | info!("Writing frame"); | 43 | info!("Writing frame"); |
| 63 | _ = can.write(&frame).await; | 44 | _ = can.write(&frame).await; |
| 64 | 45 | ||
| 65 | match can.read().await { | 46 | match can.read().await { |
| 66 | Ok(rx_frame) => info!("Rx: {}", rx_frame.data()[0]), | 47 | Ok((rx_frame, ts)) => { |
| 48 | let delta = (ts - last_read_ts).as_millis(); | ||
| 49 | last_read_ts = ts; | ||
| 50 | info!( | ||
| 51 | "Rx: {:x} {:x} {:x} {:x} --- NEW {}", | ||
| 52 | rx_frame.data()[0], | ||
| 53 | rx_frame.data()[1], | ||
| 54 | rx_frame.data()[2], | ||
| 55 | rx_frame.data()[3], | ||
| 56 | delta, | ||
| 57 | ) | ||
| 58 | } | ||
| 59 | Err(_err) => error!("Error in frame"), | ||
| 60 | } | ||
| 61 | |||
| 62 | Timer::after_millis(250).await; | ||
| 63 | |||
| 64 | i += 1; | ||
| 65 | if i > 3 { | ||
| 66 | break; | ||
| 67 | } | ||
| 68 | } | ||
| 69 | |||
| 70 | let (mut tx, mut rx) = can.split(); | ||
| 71 | // With split | ||
| 72 | loop { | ||
| 73 | let frame = can::frame::ClassicFrame::new_extended(0x123456F, &[i; 8]).unwrap(); | ||
| 74 | info!("Writing frame"); | ||
| 75 | _ = tx.write(&frame).await; | ||
| 76 | |||
| 77 | match rx.read().await { | ||
| 78 | Ok((rx_frame, ts)) => { | ||
| 79 | let delta = (ts - last_read_ts).as_millis(); | ||
| 80 | last_read_ts = ts; | ||
| 81 | info!( | ||
| 82 | "Rx: {:x} {:x} {:x} {:x} --- NEW {}", | ||
| 83 | rx_frame.data()[0], | ||
| 84 | rx_frame.data()[1], | ||
| 85 | rx_frame.data()[2], | ||
| 86 | rx_frame.data()[3], | ||
| 87 | delta, | ||
| 88 | ) | ||
| 89 | } | ||
| 67 | Err(_err) => error!("Error in frame"), | 90 | Err(_err) => error!("Error in frame"), |
| 68 | } | 91 | } |
| 69 | 92 | ||
