///|
/// PROFIdrive record index for parameter access base.
pub let record_index_base : Int = 0xB02E
///|
/// PROFIdrive profile identification.
pub let profile_id : Int = 0x3A00
///|
/// Parameter request ID: Read.
pub let param_request_read : Byte = 1
///|
/// Parameter request ID: Write.
pub let param_request_write : Byte = 2
///|
/// Standard PROFIdrive parameters.
pub let pnu_control_word_1 : Int = 967
///|
pub let pnu_status_word_1 : Int = 968
///|
pub let pnu_speed_setpoint : Int = 1
///|
pub let pnu_speed_actual : Int = 2
///|
pub let pnu_station_name : Int = 924
///|
pub let pnu_vendor_id : Int = 964
///|
pub let pnu_device_id : Int = 965
///|
fn push_u16_be(output : Array[Byte], value : Int) -> Unit {
output.push(((value >> 8) & 0xFF).to_byte())
output.push((value & 0xFF).to_byte())
}
///|
fn read_u16_be(data : Bytes, offset : Int) -> Int {
(data[offset].to_int() << 8) + data[offset + 1].to_int()
}
///|
/// PROFIdrive parameter request (single parameter).
pub(all) struct ParamRequest {
request_id : Byte
axis : Int
pnu : Int
subindex : Int
num_elements : Int
} derive(Eq, Debug)
///|
/// Encode a PROFIdrive parameter request block.
pub fn encode_param_request(req : ParamRequest) -> Bytes {
let output : Array[Byte] = []
output.push(req.request_id)
output.push(req.axis.to_byte())
push_u16_be(output, req.pnu)
push_u16_be(output, req.subindex)
push_u16_be(output, req.num_elements)
Bytes::from_array(output)
}
///|
/// PROFIdrive parameter response (single parameter).
pub(all) struct ParamResponse {
format : Byte
num_values : Int
values : Bytes
} derive(Eq, Debug)
///|
/// Parse a PROFIdrive parameter response.
pub fn parse_param_response(
data : Bytes,
offset : Int,
) -> ParamResponse raise @frame.FrameError {
guard data.length() >= offset + 4 else {
raise @frame.FrameError::InvalidMacLength(data.length())
}
let format = data[offset]
let num_values = read_u16_be(data, offset + 1)
let value_start = offset + 4
let value_bytes : Array[Byte] = []
for i = value_start; i < data.length(); i = i + 1 {
value_bytes.push(data[i])
}
ParamResponse::{ format, num_values, values: Bytes::from_array(value_bytes) }
}
///|
pub fn pnu_label(pnu : Int) -> String {
match pnu {
967 => "ControlWord1"
968 => "StatusWord1"
1 => "SpeedSetpoint"
2 => "SpeedActual"
924 => "StationName"
964 => "VendorID"
965 => "DeviceID"
_ => "PNU(" + pnu.to_string() + ")"
}
}
///|
/// Format parameter request summary.
pub fn format_param_request(req : ParamRequest) -> String {
let lines : Array[String] = []
let req_label = if req.request_id == param_request_read {
"Read"
} else {
"Write"
}
lines.push("request=" + req_label)
lines.push("axis=" + req.axis.to_string())
lines.push("pnu=" + pnu_label(req.pnu))
lines.push("subindex=" + req.subindex.to_string())
lines.push("num_elements=" + req.num_elements.to_string())
lines.join("\n")
}