Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

FDCAN support using the fdcan crate #277

Merged
merged 5 commits into from
Mar 21, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ jobs:
- stm32h7b0
- stm32h735
env: # Peripheral Feature flags
FLAGS: rt,xspi,sdmmc,sdmmc-fatfs,fmc,usb_hs,rtc,ethernet,ltdc,crc,rand,defmt
FLAGS: rt,xspi,sdmmc,sdmmc-fatfs,fmc,usb_hs,rtc,ethernet,ltdc,crc,rand,can,defmt

steps:
- uses: actions/checkout@v2
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/nightly.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ jobs:
- log-semihost
- log-rtt
env: # Peripheral Feature flags
FLAGS: rt,xspi,sdmmc,sdmmc-fatfs,fmc,usb_hs,rtc,ethernet,ltdc,crc,rand
FLAGS: rt,xspi,sdmmc,sdmmc-fatfs,fmc,usb_hs,rtc,ethernet,ltdc,crc,rand,can

steps:
- uses: actions/checkout@v2
Expand Down
6 changes: 6 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ stm32-fmc = { version = "0.2", optional = true }
synopsys-usb-otg = { version = "^0.3.0", features = ["cortex-m"], optional = true }
embedded-display-controller = { version = "^0.1.0", optional = true }
log = { version = "0.4.14", optional = true} # see also the dev-dependencies section
fdcan = { version = "0.1", optional = true }

[dependencies.smoltcp]
version = "0.8.0"
Expand Down Expand Up @@ -99,6 +100,7 @@ sdmmc = ["sdio-host"]
sdmmc-fatfs = ["embedded-sdmmc", "sdmmc"]
ethernet = ["smoltcp"]
rtc = ["chrono"]
can = ["fdcan/fdcan_h7"]
crc = []
rand = ["rand_core"]
rt = ["stm32h7/rt"]
Expand Down Expand Up @@ -151,6 +153,10 @@ required-features = ["revision_v", "rm0433"]
name = "fmc"
required-features = ["fmc", "rm0399"]

[[example]]
name = "can-echo"
required-features = ["can"]

[[example]]
name = "qspi"
required-features = ["xspi", "rm0433"]
Expand Down
136 changes: 136 additions & 0 deletions examples/can-echo.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
#![no_main]
#![no_std]

use crate::hal::{
gpio::{GpioExt as _, Speed},
nb::block,
pac,
prelude::*,
rcc,
rcc::rec,
time::U32Ext,
};
use fdcan::{
config::NominalBitTiming,
filter::{StandardFilter, StandardFilterSlot},
frame::{FrameFormat, TxFrameHeader},
id::StandardId,
};
use stm32h7xx_hal as hal;

use core::num::{NonZeroU16, NonZeroU8};

use cortex_m_rt::entry;

use log::info;

#[macro_use]
mod utilities;

#[entry]
fn main() -> ! {
utilities::logger::init();

// Kernel Clock 24MHz, Bit rate: 125kBit/s, Sample Point 87.5%
// Value was calculated with http://www.bittiming.can-wiki.info/
// TODO: use the can_bit_timings crate
let btr = NominalBitTiming {
prescaler: NonZeroU16::new(12).unwrap(),
seg1: NonZeroU8::new(13).unwrap(),
seg2: NonZeroU8::new(2).unwrap(),
sync_jump_width: NonZeroU8::new(1).unwrap(),
};

let dp = pac::Peripherals::take().unwrap();
let cp =
cortex_m::Peripherals::take().expect("cannot take core peripherals");

// Constrain and Freeze power
info!("Setup PWR... ");
let pwr = dp.PWR.constrain();
let pwrcfg = example_power!(pwr).freeze();

// Constrain and Freeze clock
info!("Setup RCC... ");
let rcc = dp.RCC.constrain();
let ccdr = rcc
.sys_ck(192.mhz())
.pll1_strategy(rcc::PllConfigStrategy::Iterative)
.pll1_q_ck(24.mhz())
.freeze(pwrcfg, &dp.SYSCFG);

// Setup fdcan_tq_ck = 24MHz
assert_eq!(ccdr.clocks.pll1_q_ck().unwrap().0, 24_000_000);
let fdcan_prec = ccdr
.peripheral
.FDCAN
.kernel_clk_mux(rec::FdcanClkSel::PLL1_Q);

let mut delay = cp.SYST.delay(ccdr.clocks);

let can1 = {
info!("Init CAN 1");
let gpioh = dp.GPIOH.split(ccdr.peripheral.GPIOH);
let rx = gpioh.ph14.into_alternate_af9().set_speed(Speed::VeryHigh);
let tx = gpioh.ph13.into_alternate_af9().set_speed(Speed::VeryHigh);

info!("-- Create CAN 1 instance");
dp.FDCAN1.fdcan(tx, rx, fdcan_prec)
};

// let can2 = {
// info!("Init CAN 2");
// let gpiob = dp.GPIOB.split(ccdr.peripheral.GPIOB);
// let rx = gpiob.pb5.into_alternate_af9().set_speed(Speed::VeryHigh);
// let tx = gpiob.pb6.into_alternate_af9().set_speed(Speed::VeryHigh);

// info!("-- Create CAN 2 instance");
// dp.FDCAN2.fdcan(tx, rx, fdcan_prec)
// };

let mut can = can1;
can.set_protocol_exception_handling(false);

info!("-- Configure nominal timing");
can.set_nominal_bit_timing(btr);

info!("-- Configure Filters");
can.set_standard_filter(
StandardFilterSlot::_0,
StandardFilter::accept_all_into_fifo0(),
);

info!("-- Set CAN into normal mode");
let mut can = can.into_external_loopback();
//let mut can = can.into_normal();

info!("Create Message Data");
let mut buffer = [
0xAA, 0xAA, 0xAA, 0xAA, 0xFF, 0xFF, 0xFF, 0xFF, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
];
info!("Create Message Header");
let header = TxFrameHeader {
len: 2 * 4,
id: StandardId::new(0x1).unwrap().into(),
frame_format: FrameFormat::Standard,
bit_rate_switching: false,
marker: None,
};
info!("Initial Header: {:#X?}", &header);

info!("Transmit initial message");
block!(can.transmit(header, &buffer)).unwrap();

loop {
if let Ok(rxheader) = block!(can.receive0(&mut buffer)) {
info!("Received Header: {:#X?}", rxheader);
info!("received data: {:X?}", &buffer);

delay.delay_ms(1_u16);
block!(can.transmit(rxheader.unwrap().to_tx_header(None), &buffer))
.unwrap();
info!("Transmit: {:X?}", buffer);
}
}
}
Loading