An error occurred while loading the file. Please try again.
-
Mark Hakansson authored00df8a36
extern crate generic_array;
extern crate canlib_rs;
extern crate canlib_sys;
extern crate hex;
use crate::communication_interface::*;
use crate::protocol_interface::*;
use crate::ring_buffer::RingBuffer;
use crate::ring_buffer::RingBufferInterface;
use generic_array::ArrayLength;
use canlib_rs::*;
use canlib_sys::canStatus;
use std::u8;
/// # CAN struct
///
/// Struct for one connection over the CAN bus.
/// Currently this CAN implementation is focused for Kvaser hardware and CANlib.
///
/// * `send_buffer` - Internal send buffer. Use send() to add message to this buffer. Then tx() to transmit to CAN bus.
/// * `recieve_buffer` - Internal receive buffer. Use rx() to read the CAN bus to this buffer. Then receive() to get the message.
/// * `protocol_type` - Specifies what type of protocol to use. E.g. UartSimpleMessage<N>.
/// * `can_settings` - Stores the settings for this specific instance.
/// * `can_handle` - Handle Id for this instance. Used to seperate different instances of CAN. If only one is used, then can_handle = 0.
///
pub struct Can<N, T> where
N: ArrayLength<u8>,
T: ProtocolInterface<N>
{
// Hardware independent variables
send_buffer: RingBuffer<N>,
receive_buffer: RingBuffer<N>,
protocol_type: T,
// Hardware dependent variables
can_settings: CanBusSettings,
handle: CanHandle,
}
pub trait CanTrait {
/// Initializes the CAN channel with given settings.
/// * `settings` The CanBusSettings to initialize the current CAN instance with.
fn init(&mut self, settings: CanBusSettings);
/// Terminates this CAN instance by turning off and closing the CAN bus for this handle.
fn terminate(&mut self);
/// Read CAN channel and add message to recieve_buffer.
/// There are queues and buffers implemented in Kvaser's hardware. Each read will get the message
/// with the highest priority in the mailbox.
fn rx(&mut self);
/// TODO: Implementation to talk to light modules.
fn tx(&mut self);
}
/// Settings for all types of CAN buses. Check the CANlib documentation for information of these variables.
pub struct CanBusSettings {
// General
pub channel: i32,
pub flags: i32,
pub driver_type: CanDriver,
// For normal CAN
pub freq: CanBitrate,
pub tseg1: u32,
pub tseg2: u32,
pub sjw: u32,
pub no_samp: u32,
// For CAN-FD
pub can_fd: bool,
pub freq_brs: CanBitrate,
pub tseg1_brs: u32,
pub tseg2_brs: u32,
pub sjw_brs: u32,
7172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
}
impl<N, T> CommunicationInterface<N, T> for Can<N, T> where
N: ArrayLength<u8>,
T: ProtocolInterface<N> {
/// Initialize the CAN instance with 'empty' settings.
fn new() -> Self {
let settings = CanBusSettings
{
channel: 0,
flags: 0,
driver_type:
CanDriver::Off,
freq: CanBitrate::_1M,
tseg1: 0,
tseg2: 0,
sjw: 0,
no_samp: 0,
can_fd: false,
freq_brs: CanBitrate::Fd1M,
tseg1_brs: 0,
tseg2_brs: 0,
sjw_brs: 0,
};
let init_handle: CanHandle = 0;
Can {
send_buffer: RingBufferInterface::new(),
receive_buffer: RingBufferInterface::new(),
protocol_type: T::new(),
can_settings: settings,
handle: init_handle,
}
}
/// TODO: Not yet implemented.
fn send(& mut self, mut p: T) -> bool {
true
}
/// Returns the internal recieve buffer.
fn receive(& mut self) -> T {
let mut a : T = T::new();
a.deseralize(&mut self.receive_buffer);
a
}
}
impl<N, T> CanTrait for Can<N, T> where
N: ArrayLength<u8>,
T: ProtocolInterface<N> {
fn init(&mut self, settings: CanBusSettings) {
self.can_settings = settings;
let handle = can_open_channel(self.can_settings.channel, self.can_settings.flags);
self.handle = handle;
// For CAN FD
if self.can_settings.can_fd {
can_set_bus_params(
self.handle,
self.can_settings.freq,
self.can_settings.tseg1,
self.can_settings.tseg2,
self.can_settings.sjw,
141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210
self.can_settings.no_samp,
);
canfd_set_bus_params(
self.handle,
self.can_settings.freq_brs,
self.can_settings.tseg1_brs,
self.can_settings.tseg2_brs,
self.can_settings.sjw_brs,
);
can_set_bus_output_control(
self.handle,
self.can_settings.driver_type,
);
can_bus_on(self.handle);
// For Normal CAN
} else {
can_set_bus_params(
self.handle,
self.can_settings.freq,
self.can_settings.tseg1,
self.can_settings.tseg2,
self.can_settings.sjw,
self.can_settings.no_samp,
);
can_set_bus_output_control(
self.handle,
self.can_settings.driver_type,
);
can_bus_on(self.handle);
}
}
fn terminate(&mut self) {
can_bus_off(self.handle);
can_close(self.handle);
}
fn rx(&mut self) {
let mut buffer = [0; 64]; // 64 bytes; maximum message size CAN FD
//println!("CanHandle: {}", self.handle);
if self.handle < 0 {
println!("canOpenChannel failed!");
} else {
// Variables the CAN hardware will read to.
let mut id: i32 = 0;
let mut dlc: u32 = 0;
let mut flag: u32 = 0;
let mut time: u32 = 0;;
// Sync waits until a message is recieved.
let sync_stat = can_read_sync(self.handle, 0xFFFFFFFF); // 0xFFFFFFFF = infinte long time
if sync_stat as i32 != canStatus::canOK as i32 {
println!("canWriteSync Error.");
} else {
//println!("canWriteSync Ok");
}