Skip to content

Commit

Permalink
Add solenoid settings
Browse files Browse the repository at this point in the history
  • Loading branch information
rnd-ash committed Apr 26, 2023
1 parent fd99ed2 commit f27f549
Show file tree
Hide file tree
Showing 7 changed files with 300 additions and 195 deletions.
49 changes: 27 additions & 22 deletions backend/src/diag/flash.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
use ecu_diagnostics::{DiagServerResult, DiagError, kwp2000::{self, KwpSessionTypeByte}};
use ecu_diagnostics::{
kwp2000::{self, KwpSessionTypeByte},
DiagError, DiagServerResult,
};
use packed_struct::{prelude::PackedStruct, PackedStructSlice};

use crate::hw::firmware::FirmwareHeader;
Expand All @@ -7,46 +10,42 @@ use super::Nag52Diag;

#[derive(PackedStruct, Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
pub struct PartitionInfo {
#[packed_field(endian="lsb")]
#[packed_field(endian = "lsb")]
pub address: u32,
#[packed_field(endian="lsb")]
pub size: u32
#[packed_field(endian = "lsb")]
pub size: u32,
}

pub const OTA_FORMAT: u8 = 0xF0;

impl Nag52Diag {

pub fn get_total_flash_size(&self) -> PartitionInfo {
PartitionInfo {
address: 0x0,
size: 0x400000
size: 0x400000,
}
}

pub fn get_coredump_flash_info(&mut self) -> DiagServerResult<PartitionInfo> {
self.with_kwp(|server| {
server.kwp_read_custom_local_identifier(0x29).map(|res| {
PartitionInfo::unpack_from_slice(&res).map_err(|_|
DiagError::InvalidResponseLength)
PartitionInfo::unpack_from_slice(&res).map_err(|_| DiagError::InvalidResponseLength)
})?
})
}

pub fn get_running_partition_flash_info(&mut self) -> DiagServerResult<PartitionInfo> {
self.with_kwp(|server| {
server.kwp_read_custom_local_identifier(0x2A).map(|res| {
PartitionInfo::unpack_from_slice(&res).map_err(|_|
DiagError::InvalidResponseLength)
PartitionInfo::unpack_from_slice(&res).map_err(|_| DiagError::InvalidResponseLength)
})?
})
}

pub fn get_next_ota_partition_flash_info(&mut self) -> DiagServerResult<PartitionInfo> {
self.with_kwp(|server| {
server.kwp_read_custom_local_identifier(0x2B).map(|res| {
PartitionInfo::unpack_from_slice(&res).map_err(|_|
DiagError::InvalidResponseLength)
PartitionInfo::unpack_from_slice(&res).map_err(|_| DiagError::InvalidResponseLength)
})?
})
}
Expand All @@ -55,18 +54,21 @@ impl Nag52Diag {
self.with_kwp(|server| {
server.kwp_read_custom_local_identifier(0x28).map(|res| {
println!("{:02X?}", res);
FirmwareHeader::unpack_from_slice(&res).map_err(|_|
DiagError::InvalidResponseLength)
FirmwareHeader::unpack_from_slice(&res)
.map_err(|_| DiagError::InvalidResponseLength)
})?
})
}

pub fn begin_ota(&mut self, image_len: u32) -> DiagServerResult<(u32, u16)> {
let part_info_next = self.get_next_ota_partition_flash_info()?;
let res = self.with_kwp(|server| {
server.kwp_set_session(KwpSessionTypeByte::Standard(kwp2000::KwpSessionType::Reprogramming))?;
server.kwp_set_session(KwpSessionTypeByte::Standard(
kwp2000::KwpSessionType::Reprogramming,
))?;
let x = part_info_next.address;
let mut req: Vec<u8> = vec![0x34, (x >> 16) as u8, (x >> 8) as u8, (x) as u8, OTA_FORMAT];
let mut req: Vec<u8> =
vec![0x34, (x >> 16) as u8, (x >> 8) as u8, (x) as u8, OTA_FORMAT];
req.push((image_len >> 16) as u8);
req.push((image_len >> 8) as u8);
req.push((image_len) as u8);
Expand All @@ -79,7 +81,9 @@ impl Nag52Diag {

pub fn begin_download(&mut self, partition_info: &PartitionInfo) -> DiagServerResult<u16> {
let res = self.with_kwp(|server| {
server.kwp_set_session(KwpSessionTypeByte::Standard(kwp2000::KwpSessionType::Reprogramming))?;
server.kwp_set_session(KwpSessionTypeByte::Standard(
kwp2000::KwpSessionType::Reprogramming,
))?;
let x = partition_info.address;
let mut req: Vec<u8> = vec![0x35, (x >> 16) as u8, (x >> 8) as u8, (x) as u8, 0x00];
req.push((partition_info.size >> 16) as u8);
Expand All @@ -96,13 +100,15 @@ impl Nag52Diag {
self.with_kwp(|server| {
let mut req = vec![0x36, blk_id];
req.extend_from_slice(data);
server.send_byte_array_with_response(&req).map(|_|())
server.send_byte_array_with_response(&req).map(|_| ())
})
}

pub fn read_data(&mut self, blk_id: u8) -> DiagServerResult<Vec<u8>> {
self.with_kwp(|server| {
server.send_byte_array_with_response(&[0x36, blk_id]).map(|x| x[2..].to_vec())
server
.send_byte_array_with_response(&[0x36, blk_id])
.map(|x| x[2..].to_vec())
})
}

Expand All @@ -112,7 +118,7 @@ impl Nag52Diag {
let status = server.send_byte_array_with_response(&[0x31, 0xE1])?;
if status[2] == 0x00 {
eprintln!("ECU Flash check OK! Rebooting");
if reboot {
if reboot {
server.kwp_reset_ecu(kwp2000::ResetType::PowerOnReset)?;
}
Ok(())
Expand All @@ -122,5 +128,4 @@ impl Nag52Diag {
}
})
}

}
}
10 changes: 4 additions & 6 deletions backend/src/diag/ident.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
use std::fmt::{Display};
use std::fmt::Display;

use ecu_diagnostics::{DiagServerResult, bcd_decode_slice};
use ecu_diagnostics::{bcd_decode_slice, DiagServerResult};

use super::{Nag52Diag};
use super::Nag52Diag;

#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
pub enum EgsMode {
Expand Down Expand Up @@ -109,8 +109,6 @@ impl Nag52Diag {
}

pub fn get_ecu_sn(&mut self) -> DiagServerResult<String> {
self.with_kwp(|k| {
Ok(String::from_utf8(k.kwp_read_ecu_serial_number()?).unwrap())
})
self.with_kwp(|k| Ok(String::from_utf8(k.kwp_read_ecu_serial_number()?).unwrap()))
}
}
24 changes: 14 additions & 10 deletions backend/src/diag/mod.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,19 @@
use core::fmt;
use std::{
borrow::{BorrowMut, Borrow},
borrow::{Borrow, BorrowMut},
sync::{Arc, Mutex, RwLock},
};

use ecu_diagnostics::{channel::*, dynamic_diag::{DynamicDiagSession, DiagServerBasicOptions, TimeoutConfig, DiagServerAdvancedOptions, DiagProtocol, DiagSessionMode}};
use ecu_diagnostics::hardware::{
passthru::*, Hardware, HardwareError, HardwareInfo, HardwareResult, HardwareScanner,
};
use ecu_diagnostics::{
channel::*,
dynamic_diag::{
DiagProtocol, DiagServerAdvancedOptions, DiagServerBasicOptions, DiagSessionMode,
DynamicDiagSession, TimeoutConfig,
},
};
use ecu_diagnostics::{kwp2000::*, DiagServerResult};

#[cfg(unix)]
Expand All @@ -18,8 +24,8 @@ use crate::hw::{
usb_scanner::Nag52UsbScanner,
};

pub mod ident;
pub mod flash;
pub mod ident;
pub mod settings;

#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
Expand Down Expand Up @@ -175,9 +181,9 @@ impl Nag52Diag {
send_id: 0x07E1,
recv_id: 0x07E9,
timeout_cfg: TimeoutConfig {
read_timeout_ms: 5000,
write_timeout_ms: 5000,
}
read_timeout_ms: 5000,
write_timeout_ms: 5000,
},
};

let adv_opts = DiagServerAdvancedOptions {
Expand All @@ -201,7 +207,7 @@ impl Nag52Diag {
hw.create_isotp_channel()?,
channel_cfg,
basic_opts,
Some(adv_opts)
Some(adv_opts),
)?;

Ok(Self {
Expand Down Expand Up @@ -230,9 +236,7 @@ impl Nag52Diag {
{
match self.server.borrow() {
None => Err(HardwareError::DeviceNotOpen.into()),
Some(s) => {
kwp_fn(&s)
}
Some(s) => kwp_fn(&s),
}
}
}
Expand Down
105 changes: 73 additions & 32 deletions backend/src/diag/settings.rs
Original file line number Diff line number Diff line change
@@ -1,19 +1,13 @@
use std::{ptr::slice_from_raw_parts};
use std::ptr::slice_from_raw_parts;

use serde::{Deserialize, Serialize};
use serde::{Deserialize, Serialize, de::DeserializeOwned};

pub type UnpackResult<T> = std::result::Result<T, UnPackError>;

#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
pub enum UnPackError {
WrongId {
wanted: u8,
real: u8
},
InvalidLen {
wanted: usize,
len: usize
}
WrongId { wanted: u8, real: u8 },
InvalidLen { wanted: usize, len: usize },
}

impl ToString for UnPackError {
Expand All @@ -26,47 +20,64 @@ impl ToString for UnPackError {
}

pub fn unpack_settings<T>(settings_id: u8, raw: &[u8]) -> UnpackResult<T>
where T: Copy {
where
T: Copy,
{
if settings_id != raw[0] {
Err(UnPackError::WrongId { wanted: settings_id, real: raw[0] })
} else if raw.len()-1 != std::mem::size_of::<T>() {
Err(UnPackError::InvalidLen { wanted: std::mem::size_of::<T>(), len: raw.len()-1 })
Err(UnPackError::WrongId {
wanted: settings_id,
real: raw[0],
})
} else if raw.len() - 1 != std::mem::size_of::<T>() {
Err(UnPackError::InvalidLen {
wanted: std::mem::size_of::<T>(),
len: raw.len() - 1,
})
} else {
let ptr: *const T = raw[1..].as_ptr() as *const T;
Ok(unsafe { *ptr })
}
}

pub fn pack_settings<T>(settings_id: u8, settings: T) -> Vec<u8>
where T: Copy {
where
T: Copy,
{
let mut ret = vec![settings_id];
let ptr= slice_from_raw_parts((&settings as *const T) as *const u8, std::mem::size_of::<T>());
let ptr = slice_from_raw_parts(
(&settings as *const T) as *const u8,
std::mem::size_of::<T>(),
);
ret.extend_from_slice(unsafe { &*ptr });
ret
}

pub trait TcuSettings<'de> : Serialize + Deserialize<'de> where Self: Sized {
fn wiki_url(&self) -> Option<&'static str>;
fn setting_name(&self) -> &'static str;
fn get_revision_name(&self) -> &'static str;
fn get_scn_id(&self) -> u8;
pub trait TcuSettings: Serialize + DeserializeOwned
where
Self: Sized,
{
fn wiki_url() -> Option<&'static str>;
fn setting_name() -> &'static str;
fn get_revision_name() -> &'static str;
fn get_scn_id() -> u8;
}


#[derive(Default, Debug, Copy, Clone, PartialEq, PartialOrd, Serialize, Deserialize)]
#[repr(C, packed)]
pub struct LinearInterpSettings {
pub new_min: f32,
pub new_max: f32,
pub raw_min: f32,
pub raw_max: f32
pub raw_max: f32,
}

impl LinearInterpSettings {
// Copied from TCU source lib/core/tcu_maths.cpp - Function scale_number()
pub fn calc_with_value(&self, input: f32) -> f32 {
let raw_limited = self.raw_min.max(input.min( self.raw_max));
return (((self.new_max - self.new_min) * (raw_limited - self.raw_min)) / (self.raw_max - self.raw_min)) + self.new_min;
let raw_limited = self.raw_min.max(input.min(self.raw_max));
return (((self.new_max - self.new_min) * (raw_limited - self.raw_min))
/ (self.raw_max - self.raw_min))
+ self.new_min;
}
}

Expand Down Expand Up @@ -101,20 +112,50 @@ pub struct TccSettings {
pub max_allowed_pressure_longterm: u16,
}

impl TcuSettings<'_> for TccSettings {
fn wiki_url(&self) -> Option<&'static str> {
impl TcuSettings for TccSettings {
fn wiki_url() -> Option<&'static str> {
Some("https://docs.ultimate-nag52.net/en/gettingstarted/configuration/settings/tcc#revision-a2-240423")
}

fn setting_name(&self) -> &'static str {
fn setting_name() -> &'static str {
"TCC Settings"
}

fn get_revision_name(&self) -> &'static str {
"A2 (24/03/23)"
fn get_revision_name() -> &'static str {
"A2 (24/04/23)"
}

fn get_scn_id(&self) -> u8 {
fn get_scn_id() -> u8 {
0x01
}
}
}

#[derive(Default, Debug, Copy, Clone, PartialEq, PartialOrd, Serialize, Deserialize)]
#[repr(C, packed)]
pub struct SolSettings {
min_batt_power_on_test: u16,
current_threshold_error: u16,
cc_vref_solenoid: u16,
cc_temp_coefficient_wires: f32,
cc_reference_resistance: f32,
cc_reference_temp: f32,
cc_max_adjust_per_step: f32,
}

impl TcuSettings for SolSettings {
fn wiki_url() -> Option<&'static str> {
Some("https://docs.ultimate-nag52.net/en/gettingstarted/configuration/settings/SolenoidControlProgramSettings#revision-a0-260423")
}

fn setting_name() -> &'static str {
"Solenoid subsystem Settings"
}

fn get_revision_name() -> &'static str {
"A0 (26/04/23)"
}

fn get_scn_id() -> u8 {
0x02
}
}
Loading

0 comments on commit f27f549

Please sign in to comment.