Skip to content

Commit 9beafbb

Browse files
authored
vector-xl: switch to new bitrate API (#103)
1 parent 10db4a9 commit 9beafbb

5 files changed

Lines changed: 76 additions & 27 deletions

File tree

examples/configure_bitrate.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ pub async fn run() -> automotive::Result<()> {
1414
.build()
1515
.unwrap();
1616

17-
let adapter = VectorCan::new_async(0, &Some(bitrate_cfg.into()))?;
17+
let adapter = VectorCan::new_async(0, Some(bitrate_cfg))?;
1818
let mut stream = adapter.recv();
1919

2020
while let Some(frame) = stream.next().await {

src/can/adapter.rs

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,15 @@ pub fn get_adapter() -> Result<crate::can::AsyncCanAdapter, crate::error::Error>
2121

2222
#[cfg(all(target_os = "windows", feature = "vector-xl"))]
2323
{
24-
if let Ok(adapter) =
25-
crate::vector::VectorCan::new_async(0, &Some(crate::vector::CONFIG_500K_2M_80))
26-
{
24+
let bitrate_cfg = crate::can::bitrate::BitrateBuilder::new::<crate::vector::VectorCan>()
25+
.bitrate(500_000)
26+
.sample_point(0.8)
27+
.data_bitrate(2_000_000)
28+
.data_sample_point(0.8)
29+
.build()
30+
.unwrap();
31+
32+
if let Ok(adapter) = crate::vector::VectorCan::new_async(0, Some(bitrate_cfg)) {
2733
return Ok(adapter);
2834
};
2935
}

src/error.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ pub enum Error {
1111
NotSupported,
1212
#[error("Malformed Frame")]
1313
MalformedFrame,
14+
#[error("Invalid bitrate: {0}")]
15+
InvalidBitrate(String),
1416
#[error("Timeout")]
1517
Timeout,
1618
#[error("Disconnected")]

src/vector/mod.rs

Lines changed: 48 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -8,30 +8,14 @@ pub use error::Error;
88

99
use std::collections::VecDeque;
1010

11-
use crate::can::bitrate::{AdapterTimingConst, BitTimingConst};
11+
use crate::can::bitrate::{AdapterTimingConst, BitTimingConst, BitrateConfig};
1212
use crate::can::{AsyncCanAdapter, CanAdapter, Frame};
13-
pub use crate::vector::types::XLcanFdConf;
13+
use crate::vector::bindings::XLcanFdConf;
1414
use crate::vector::types::{PortHandle, XLaccess, XLcanTxEvent};
1515
use crate::vector::vxlapi::*;
1616
use crate::Result;
1717
use tracing::info;
1818

19-
/// Predefined configuration for 500 kbps arbitration bitrate and 2 Mbps data bitrate
20-
pub const CONFIG_500K_2M_80: XLcanFdConf = XLcanFdConf {
21-
arbitrationBitRate: 500_000,
22-
sjwAbr: 1,
23-
tseg1Abr: 127,
24-
tseg2Abr: 32,
25-
dataBitRate: 2_000_000,
26-
sjwDbr: 1,
27-
tseg1Dbr: 31,
28-
tseg2Dbr: 8,
29-
reserved: 0,
30-
options: 0,
31-
reserved1: [0, 0],
32-
reserved2: 0,
33-
};
34-
3519
/// Vector XL timing capabilities used for bitrate helper calculations.
3620
pub const VECTOR_TIMING_CONST: AdapterTimingConst = AdapterTimingConst {
3721
nominal: BitTimingConst {
@@ -66,7 +50,7 @@ pub struct VectorCan {
6650

6751
impl VectorCan {
6852
/// Convenience function to create a new adapter and wrap in an [`AsyncCanAdapter`]
69-
pub fn new_async(channel_idx: usize, conf: &Option<XLcanFdConf>) -> Result<AsyncCanAdapter> {
53+
pub fn new_async(channel_idx: usize, conf: Option<BitrateConfig>) -> Result<AsyncCanAdapter> {
7054
let vector = VectorCan::new(channel_idx, conf)?;
7155
Ok(AsyncCanAdapter::new(vector))
7256
}
@@ -75,7 +59,13 @@ impl VectorCan {
7559
/// If conf is provided, the channel will be initialized with the provided configuration.
7660
/// If not, the channel will be opened without requesting init (exclusive) access,
7761
/// and can be configured using other tools (e.g. Vector's CANalyzer).
78-
pub fn new(channel_idx: usize, conf: &Option<XLcanFdConf>) -> Result<VectorCan> {
62+
pub fn new(channel_idx: usize, conf: Option<BitrateConfig>) -> Result<VectorCan> {
63+
if conf.as_ref().is_some_and(|conf| conf.data.is_none()) {
64+
return Err(crate::Error::InvalidBitrate(
65+
"Vector bitrate configuration requires a CAN-FD data phase".to_string(),
66+
));
67+
}
68+
7969
xl_open_driver()?;
8070

8171
// Get config based on global channel number
@@ -92,7 +82,8 @@ impl VectorCan {
9282

9383
// Configure bitrate
9484
if let Some(conf) = conf {
95-
xl_can_fd_set_configuration(&port_handle, channel_mask, conf)?;
85+
let conf: XLcanFdConf = conf.into();
86+
xl_can_fd_set_configuration(&port_handle, channel_mask, &conf)?;
9687
}
9788

9889
xl_activate_channel(&port_handle, channel_mask)?;
@@ -158,6 +149,21 @@ mod tests {
158149
use super::*;
159150
use crate::can::bitrate::BitrateBuilder;
160151

152+
const CONFIG_500K_2M_80: XLcanFdConf = XLcanFdConf {
153+
arbitrationBitRate: 500_000,
154+
sjwAbr: 1,
155+
tseg1Abr: 127,
156+
tseg2Abr: 32,
157+
dataBitRate: 2_000_000,
158+
sjwDbr: 1,
159+
tseg1Dbr: 31,
160+
tseg2Dbr: 8,
161+
reserved: 0,
162+
options: 0,
163+
reserved1: [0, 0],
164+
reserved2: 0,
165+
};
166+
161167
#[test]
162168
fn bitrate_builder_matches_predefined_config() {
163169
let bitrate_cfg = BitrateBuilder::new::<VectorCan>()
@@ -173,4 +179,25 @@ mod tests {
173179
let conf: XLcanFdConf = bitrate_cfg.into();
174180
assert_eq!(conf, CONFIG_500K_2M_80);
175181
}
182+
183+
#[test]
184+
fn rejects_nominal_only_bitrate_config() {
185+
let bitrate_cfg = BitrateBuilder::new::<VectorCan>()
186+
.bitrate(500_000)
187+
.sample_point(0.8)
188+
.sjw(1)
189+
.build()
190+
.unwrap();
191+
192+
match VectorCan::new(0, Some(bitrate_cfg)) {
193+
Err(crate::Error::InvalidBitrate(msg)) => {
194+
assert_eq!(
195+
msg,
196+
"Vector bitrate configuration requires a CAN-FD data phase"
197+
);
198+
}
199+
Err(err) => panic!("unexpected error: {err}"),
200+
Ok(_) => panic!("expected invalid bitrate error"),
201+
}
202+
}
176203
}

tests/adapter_tests.rs

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,19 @@ static BULK_NUM_FRAMES_ASYNC: usize = 0x1000;
1010
static BULK_SYNC_TIMEOUT_MS: u64 = 1000;
1111
static BULK_ASYNC_TIMEOUT_MS: u64 = 5000;
1212

13+
#[cfg(feature = "test-vector")]
14+
fn vector_bitrate_config() -> automotive::can::bitrate::BitrateConfig {
15+
automotive::can::bitrate::BitrateBuilder::new::<automotive::vector::VectorCan>()
16+
.bitrate(500_000)
17+
.sample_point(0.8)
18+
.sjw(1)
19+
.data_bitrate(2_000_000)
20+
.data_sample_point(0.8)
21+
.data_sjw(1)
22+
.build()
23+
.unwrap()
24+
}
25+
1326
fn get_test_frames(amount: usize) -> Vec<Frame> {
1427
let mut frames = vec![];
1528

@@ -110,15 +123,16 @@ async fn panda_bulk_send_async() {
110123
#[test]
111124
#[serial_test::serial]
112125
fn vector_bulk_send_sync() {
113-
let mut vector = automotive::vector::VectorCan::new(0).unwrap();
126+
let mut vector = automotive::vector::VectorCan::new(0, Some(vector_bitrate_config())).unwrap();
114127
bulk_send_sync(&mut vector);
115128
}
116129

117130
#[cfg(feature = "test-vector")]
118131
#[tokio::test]
119132
#[serial_test::serial]
120133
async fn vector_bulk_send_async() {
121-
let vector = automotive::vector::VectorCan::new_async(0).unwrap();
134+
let vector =
135+
automotive::vector::VectorCan::new_async(0, Some(vector_bitrate_config())).unwrap();
122136
bulk_send(&vector).await;
123137
}
124138

0 commit comments

Comments
 (0)