1use deku::DekuError;
2
3use crate::{
4 messages::{AxisState, CanMessageWithId, ControlMode, InputMode, RebootAction},
5 sdo::ConfigValue,
6};
7
8pub mod messages;
9pub mod sdo;
10
11pub const UNADDRESSED_NODE_ID: u8 = 0x3f;
12
13pub fn parse_frame<F: embedded_can::Frame>(frame: &F) -> Result<CanMessageWithId, DekuError> {
14 CanMessageWithId::from_frame(frame)
15}
16
17pub fn estop<F: embedded_can::Frame>(node_id: u8) -> F {
18 CanMessageWithId::estop(node_id).to_frame()
19}
20
21pub fn reboot<F: embedded_can::Frame>(node_id: u8, reboot_action: RebootAction) -> F {
23 CanMessageWithId::reboot(node_id, reboot_action).to_frame()
24}
25
26pub fn clear_errors<F: embedded_can::Frame>(node_id: u8, identify: bool) -> F {
29 CanMessageWithId::clear_errors(node_id, identify).to_frame()
30}
31
32pub fn query_version<F: embedded_can::Frame>(node_id: u8) -> F {
33 CanMessageWithId::get_version(node_id).to_rtr_frame()
34}
35
36pub fn query_heartbeat<F: embedded_can::Frame>(node_id: u8) -> F {
37 CanMessageWithId::heartbeat(node_id).to_rtr_frame()
38}
39
40pub fn query_error<F: embedded_can::Frame>(node_id: u8) -> F {
41 CanMessageWithId::get_error(node_id).to_rtr_frame()
42}
43
44pub fn query_address<F: embedded_can::Frame>(node_id: u8) -> F {
45 CanMessageWithId::get_address(node_id).to_rtr_frame()
46}
47
48pub fn query_all_addresses<F: embedded_can::Frame>() -> F {
49 CanMessageWithId::get_all_addresses().to_rtr_frame()
50}
51
52pub fn query_encoder_estimates<F: embedded_can::Frame>(node_id: u8) -> F {
53 CanMessageWithId::get_encoder_estimates(node_id).to_rtr_frame()
54}
55
56pub fn query_iq<F: embedded_can::Frame>(node_id: u8) -> F {
57 CanMessageWithId::get_iq(node_id).to_rtr_frame()
58}
59
60pub fn query_temperature<F: embedded_can::Frame>(node_id: u8) -> F {
61 CanMessageWithId::get_temperature(node_id).to_rtr_frame()
62}
63
64pub fn query_bus_voltage_current<F: embedded_can::Frame>(node_id: u8) -> F {
65 CanMessageWithId::get_bus_voltage_current(node_id).to_rtr_frame()
66}
67
68pub fn query_torques<F: embedded_can::Frame>(node_id: u8) -> F {
69 CanMessageWithId::get_torques(node_id).to_rtr_frame()
70}
71
72pub fn query_powers<F: embedded_can::Frame>(node_id: u8) -> F {
73 CanMessageWithId::get_powers(node_id).to_rtr_frame()
74}
75
76pub fn set_address_by_serial_number<F: embedded_can::Frame>(
77 serial_number: [u8; 6],
78 new_address: u8,
79) -> F {
80 CanMessageWithId::set_address(UNADDRESSED_NODE_ID, new_address, serial_number, 0).to_frame()
81}
82
83pub fn set_axis_state<F: embedded_can::Frame>(node_id: u8, state: AxisState) -> F {
84 CanMessageWithId::set_axis_state(node_id, state).to_frame()
85}
86
87pub fn set_controller_mode<F: embedded_can::Frame>(
88 node_id: u8,
89 control_mode: ControlMode,
90 input_mode: InputMode,
91) -> F {
92 CanMessageWithId::set_controller_mode(node_id, control_mode, input_mode).to_frame()
93}
94
95pub fn set_input_pos<F: embedded_can::Frame>(
100 node_id: u8,
101 position: f32,
102 vel_feedforward: i16,
103 torque_feedforward: i16,
104) -> F {
105 CanMessageWithId::set_input_pos(node_id, position, vel_feedforward, torque_feedforward)
106 .to_frame()
107}
108
109pub fn set_input_vel<F: embedded_can::Frame>(
113 node_id: u8,
114 velocity: f32,
115 torque_feedforward: f32,
116) -> F {
117 CanMessageWithId::set_input_vel(node_id, velocity, torque_feedforward).to_frame()
118}
119
120pub fn set_input_torque<F: embedded_can::Frame>(node_id: u8, torque: f32) -> F {
123 CanMessageWithId::set_input_torque(node_id, torque).to_frame()
124}
125
126pub fn set_limits<F: embedded_can::Frame>(
130 node_id: u8,
131 velocity_limit: f32,
132 current_limit: f32,
133) -> F {
134 CanMessageWithId::set_limits(node_id, velocity_limit, current_limit).to_frame()
135}
136
137pub fn set_traj_vel_limit<F: embedded_can::Frame>(node_id: u8, traj_vel_limit: f32) -> F {
140 CanMessageWithId::set_traj_vel_limit(node_id, traj_vel_limit).to_frame()
141}
142
143pub fn set_traj_accel_limits<F: embedded_can::Frame>(
147 node_id: u8,
148 traj_accel_limit: f32,
149 traj_decel_limit: f32,
150) -> F {
151 CanMessageWithId::set_traj_accel_limits(node_id, traj_accel_limit, traj_decel_limit).to_frame()
152}
153
154pub fn set_traj_inertia<F: embedded_can::Frame>(node_id: u8, traj_inertia: f32) -> F {
157 CanMessageWithId::set_traj_inertia(node_id, traj_inertia).to_frame()
158}
159
160pub fn set_absolute_position<F: embedded_can::Frame>(node_id: u8, position: f32) -> F {
163 CanMessageWithId::set_absolute_position(node_id, position).to_frame()
164}
165
166pub fn set_pos_gain<F: embedded_can::Frame>(node_id: u8, pos_gain: f32) -> F {
169 CanMessageWithId::set_pos_gain(node_id, pos_gain).to_frame()
170}
171
172pub fn set_vel_gains<F: embedded_can::Frame>(
176 node_id: u8,
177 vel_gain: f32,
178 vel_integrator_gain: f32,
179) -> F {
180 CanMessageWithId::set_vel_gains(node_id, vel_gain, vel_integrator_gain).to_frame()
181}
182
183pub fn read_config<F: embedded_can::Frame>(node_id: u8, endpoint_id: u16) -> F {
184 CanMessageWithId::rx_sdo(
185 node_id,
186 messages::SdoOpcode::Read,
187 endpoint_id,
188 ConfigValue::Empty,
189 )
190 .to_frame()
191}
192
193pub fn write_config<F: embedded_can::Frame>(
194 node_id: u8,
195 endpoint_id: u16,
196 value: ConfigValue,
197) -> F {
198 CanMessageWithId::rx_sdo(node_id, messages::SdoOpcode::Write, endpoint_id, value).to_frame()
199}
200
201pub fn enter_dfu_mode<F: embedded_can::Frame>(node_id: u8) -> F {
203 CanMessageWithId::enter_dfu_mode(node_id).to_frame()
204}