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

Bitrate configuration support #80

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
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
7 changes: 7 additions & 0 deletions src/can/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,14 @@

pub mod adapter;
pub mod async_can;
pub mod timing;

use std::collections::VecDeque;
use std::fmt;

pub use adapter::get_adapter;
pub use async_can::AsyncCanAdapter;
pub use timing::{BitTiming, TimingConfig};

pub static DLC_TO_LEN: &[usize] = &[0, 1, 2, 3, 4, 5, 6, 7, 8, 12, 16, 20, 24, 32, 48, 64];

Expand Down Expand Up @@ -127,6 +129,11 @@ impl fmt::Debug for Frame {
pub trait CanAdapter {
fn send(&mut self, frames: &mut VecDeque<crate::can::Frame>) -> crate::Result<()>;
fn recv(&mut self) -> crate::Result<Vec<Frame>>;
fn config_timing(
&mut self,
bus: usize,
config: &crate::can::timing::TimingConfig,
) -> crate::Result<()>;
}

#[cfg(test)]
Expand Down
28 changes: 28 additions & 0 deletions src/can/timing.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
const DEFAULT_BITRATE: u32 = 500_000;
const DEFAULT_DBITRATE: u32 = 2_000_000; // SAE J2284-4
const DEFAULT_SAMPLE_POINT: f32 = 0.8; // SAE J2284-4 and SAE J2284-5

pub struct TimingConfig {
pub classic: BitTiming,
pub fd: Option<BitTiming>,
}

pub struct BitTiming {
pub bitrate: u32,
pub sample_point: f32,
}

impl Default for TimingConfig {
fn default() -> Self {
TimingConfig {
classic: BitTiming {
bitrate: DEFAULT_BITRATE,
sample_point: DEFAULT_SAMPLE_POINT,
},
fd: Some(BitTiming {
bitrate: DEFAULT_DBITRATE,
sample_point: DEFAULT_SAMPLE_POINT,
}),
}
}
}
9 changes: 9 additions & 0 deletions src/panda/constants.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ pub enum Endpoint {
CanWrite = 0x3,
HwType = 0xc1,
SafetyModel = 0xdc,
CanSpeed = 0xde,
CanDataSpeed = 0xf9,
CanResetCommunications = 0xc0,
CanRead = 0x81,
PacketsVersions = 0xdd,
Expand All @@ -35,3 +37,10 @@ pub enum SafetyModel {
Silent = 0,
AllOutput = 17,
}

pub const FD_PANDAS: [HwType; 4] = [
HwType::RedPanda,
HwType::RedPandaV2,
HwType::Tres,
HwType::Quatro,
];
42 changes: 40 additions & 2 deletions src/panda/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@ use std::collections::VecDeque;
use crate::can::AsyncCanAdapter;
use crate::can::CanAdapter;
use crate::can::Frame;
use crate::panda::constants::{Endpoint, HwType, SafetyModel};
use crate::can::TimingConfig;
use crate::panda::constants::{Endpoint, HwType, SafetyModel, FD_PANDAS};
use crate::Result;
use tracing::{info, warn};

Expand All @@ -19,6 +20,7 @@ const PRODUCT_ID: u16 = 0xddcc;
const EXPECTED_CAN_PACKET_VERSION: u8 = 4;
const MAX_BULK_SIZE: usize = 16384;
const PANDA_BUS_CNT: usize = 3;
const PANDA_DEFAULT_SAMPLE_POINT: f32 = 0.8; // SAE J2284-4 and SAE J2284-5

/// Blocking implementation of the panda CAN adapter
pub struct Panda {
Expand Down Expand Up @@ -55,7 +57,7 @@ impl Panda {
continue;
}

let panda = Panda {
let mut panda = Panda {
dat: vec![],
handle: device.open()?,
timeout: std::time::Duration::from_millis(100),
Expand All @@ -74,8 +76,11 @@ impl Panda {
panda.set_heartbeat_disabled()?;
panda.can_reset_communications()?;

let config = TimingConfig::default();

for i in 0..PANDA_BUS_CNT {
panda.set_canfd_auto(i, false)?;
panda.config_timing(i, &config)?;
}

// can_reset_communications() doesn't work properly, flush manually
Expand Down Expand Up @@ -125,6 +130,19 @@ impl Panda {
self.usb_write_control(Endpoint::CanFDAuto, bus as u16, auto as u16)
}

fn set_can_speed_kbps(&self, bus: usize, speed_kbps: u32) -> Result<()> {
self.usb_write_control(Endpoint::CanSpeed, bus as u16, (speed_kbps * 10) as u16)
}

fn set_can_data_speed_kbps(&self, bus: usize, speed_kbps: u32) -> Result<()> {
self.usb_write_control(Endpoint::CanDataSpeed, bus as u16, (speed_kbps * 10) as u16)
}

fn supports_fd(&self) -> Result<bool> {
let hw_type = self.get_hw_type()?;
Ok(FD_PANDAS.contains(&hw_type))
}

/// Get the hardware type of the panda. Usefull to detect if it supports CAN-FD.
pub fn get_hw_type(&self) -> Result<HwType> {
let hw_type = self.usb_read_control(Endpoint::HwType, 1)?;
Expand Down Expand Up @@ -217,4 +235,24 @@ impl CanAdapter for Panda {
}
}
}

fn config_timing(&mut self, bus: usize, config: &TimingConfig) -> Result<()> {
self.set_can_speed_kbps(bus, config.classic.bitrate / 1000)?;
if config.classic.sample_point != PANDA_DEFAULT_SAMPLE_POINT {
warn!("Setting sample point is not supported on Panda, ignoring");
}

if let Some(fd) = &config.fd {
if !self.supports_fd()? {
warn!("CAN-FD not supported by adapter");
} else {
self.set_can_data_speed_kbps(bus, fd.bitrate / 1000)?;
if fd.sample_point != PANDA_DEFAULT_SAMPLE_POINT {
warn!("Setting sample point is not supported on Panda, ignoring");
}
}
}

Ok(())
}
}
12 changes: 12 additions & 0 deletions src/socketcan/mod.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
//! This module provides a [`CanAdapter`] implementation for SocketCAN interfaces
use tracing::warn;

use crate::can::{AsyncCanAdapter, CanAdapter, Frame};
use crate::socketcan::socket::CanFdSocket;
use crate::Result;
Expand Down Expand Up @@ -121,4 +123,14 @@ impl CanAdapter for SocketCan {

Ok(frames)
}

fn config_timing(
&mut self,
_bus: usize,
_config: &crate::can::TimingConfig,
) -> crate::Result<()> {
warn!("Ignoring timing config. Set using ip link");
// TODO: Report error instead?
Ok(())
}
}
9 changes: 9 additions & 0 deletions src/vector/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -91,4 +91,13 @@ impl CanAdapter for VectorCan {

Ok(frames)
}

fn config_timing(
&mut self,
_bus: usize,
_config: &crate::can::TimingConfig,
) -> crate::Result<()> {
todo!("No yet implemented");
Ok(())
}
}
Loading