Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
9bd0264
Initial current sensing reworking
joe-spall Mar 7, 2025
c0c9c7b
WIP gets building and testable
joe-spall Mar 10, 2025
5eb1ae1
Merge branch 'dev/will/generation3' into joe/adc-fixes
guyfleeman Mar 12, 2025
080b6a9
local adc testing tweaks
guyfleeman Mar 12, 2025
85d49ed
WIP Current control fixes
joe-spall May 6, 2025
8197671
WIP update software communication
joe-spall May 6, 2025
4d4db06
Add timing register, redo functions
joe-spall May 28, 2025
024bbc2
First pass of current control
joe-spall May 30, 2025
3558bbc
Cleanup and adds opamp offset
joe-spall Jun 4, 2025
35da67b
WIP adding ADC current calibration
joe-spall Jun 15, 2025
f553d4f
Updated software-communication
joe-spall Jun 15, 2025
f3b943d
Confirmed page erase works
joe-spall Jun 18, 2025
42a9aac
Update software-communication
joe-spall Jun 19, 2025
09357ae
Merge branch 'dev/will/generation3' into joe/adc-fixes
joe-spall Jun 19, 2025
df8cf40
WIP Motor flash
joe-spall Jul 5, 2025
5c0263a
Merge branch 'dev/will/generation3' into joe/adc-fixes
joe-spall Jul 5, 2025
907e558
WIP current offset finished???
joe-spall Jul 6, 2025
2a0f1f5
Add additional for calibrate
joe-spall Jul 7, 2025
d20f6ac
Merge branch 'comp/2025' into joe/adc-fixes
joe-spall Jul 18, 2025
eafd768
Update software-communication
joe-spall Jul 18, 2025
a5d32f7
Update software-communication again
joe-spall Jul 18, 2025
0f1f547
Merge branch 'main' into joe/adc-fixes
guyfleeman Aug 31, 2025
99b8587
uart test cleanup
guyfleeman Sep 3, 2025
13ee0d3
clean up IOQ len defs
guyfleeman Sep 3, 2025
a95f079
more uart header cleanup
guyfleeman Sep 3, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion control-board/.cargo/config.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,4 @@ runner = 'probe-rs run --preverify --chip STM32H723ZGTx'

[env]
# DEFMT_LOG = "error,ateam-control-board::tasks::control_task=trace"
DEFMT_LOG="info"
DEFMT_LOG="trace"
8 changes: 6 additions & 2 deletions control-board/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ embassy-time = { version = "0.4.0", features = [
embassy-stm32 = { version = "0.3.0", features = [
"defmt",
"stm32h723zg",
"unstable-pac",
"unstable-pac",
"time-driver-tim1",
"exti",
"chrono"
Expand Down Expand Up @@ -124,6 +124,11 @@ name = "hwtest-radio"
test = false
harness = false

[[bin]]
name = "calibrate-motor"
test = false
harness = false

[[test]]
name = "basic-test"
harness = false
Expand All @@ -140,4 +145,3 @@ embassy-sync = { git = "https://github.com/embassy-rs/embassy"}
embassy-time = { git = "https://github.com/embassy-rs/embassy"}
embassy-stm32 = { git = "https://github.com/embassy-rs/embassy"}
embassy-futures = { git = "https://github.com/embassy-rs/embassy"}

127 changes: 127 additions & 0 deletions control-board/src/bin/calibrate-motor/main.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
#![no_std]
#![no_main]

use embassy_executor::InterruptExecutor;
use embassy_stm32::{
interrupt, pac::Interrupt
};
use embassy_sync::pubsub::PubSubChannel;

use defmt_rtt as _;

use ateam_control_board::{create_motor_calibrate_task, create_imu_task, create_io_task, create_kicker_task, create_power_task, get_system_config, pins::{AccelDataPubSub, CommandsPubSub, GyroDataPubSub, KickerTelemetryPubSub, LedCommandPubSub, PowerTelemetryPubSub, TelemetryPubSub}, robot_state::SharedRobotState};

use embassy_time::Timer;
// provide embedded panic probe
use panic_probe as _;
use static_cell::ConstStaticCell;

static ROBOT_STATE: ConstStaticCell<SharedRobotState> = ConstStaticCell::new(SharedRobotState::new());

static RADIO_C2_CHANNEL: CommandsPubSub = PubSubChannel::new();
static RADIO_TELEMETRY_CHANNEL: TelemetryPubSub = PubSubChannel::new();
static GYRO_DATA_CHANNEL: GyroDataPubSub = PubSubChannel::new();
static ACCEL_DATA_CHANNEL: AccelDataPubSub = PubSubChannel::new();
static POWER_DATA_CHANNEL: PowerTelemetryPubSub = PubSubChannel::new();
static KICKER_DATA_CHANNEL: KickerTelemetryPubSub = PubSubChannel::new();
static LED_COMMAND_PUBSUB: LedCommandPubSub = PubSubChannel::new();

static RADIO_UART_QUEUE_EXECUTOR: InterruptExecutor = InterruptExecutor::new();
static UART_QUEUE_EXECUTOR: InterruptExecutor = InterruptExecutor::new();

#[allow(non_snake_case)]
#[interrupt]
unsafe fn CEC() {
UART_QUEUE_EXECUTOR.on_interrupt();
}

#[allow(non_snake_case)]
#[interrupt]
unsafe fn CORDIC() {
RADIO_UART_QUEUE_EXECUTOR.on_interrupt();
}

#[embassy_executor::main]
async fn main(main_spawner: embassy_executor::Spawner) {
// init system
let sys_config = get_system_config();
let p = embassy_stm32::init(sys_config);

defmt::info!("embassy HAL configured.");

let robot_state = ROBOT_STATE.take();

////////////////////////
// setup task pools //
////////////////////////

// uart queue executor should be highest priority
// NOTE: maybe this should be all DMA tasks? No computation tasks here
interrupt::InterruptExt::set_priority(embassy_stm32::interrupt::CEC, embassy_stm32::interrupt::Priority::P7);
let uart_queue_spawner = UART_QUEUE_EXECUTOR.start(Interrupt::CEC);

//////////////////////////////////////
// setup inter-task coms channels //
//////////////////////////////////////

// commands channel
let control_command_subscriber = RADIO_C2_CHANNEL.subscriber().unwrap();
let kicker_command_subscriber = RADIO_C2_CHANNEL.subscriber().unwrap();

// telemetry channel
let control_telemetry_publisher = RADIO_TELEMETRY_CHANNEL.publisher().unwrap();

// IMU channels
let imu_gyro_data_publisher = GYRO_DATA_CHANNEL.publisher().unwrap();
let control_gyro_data_subscriber = GYRO_DATA_CHANNEL.subscriber().unwrap();
let imu_led_cmd_publisher = LED_COMMAND_PUBSUB.publisher().unwrap();

let imu_accel_data_publisher = ACCEL_DATA_CHANNEL.publisher().unwrap();
let control_accel_data_subscriber = ACCEL_DATA_CHANNEL.subscriber().unwrap();

// power channel
let power_board_telemetry_publisher = POWER_DATA_CHANNEL.publisher().unwrap();
let control_task_power_telemetry_subscriber = POWER_DATA_CHANNEL.subscriber().unwrap();

// kicker channel
let kicker_board_telemetry_publisher = KICKER_DATA_CHANNEL.publisher().unwrap();
let control_task_kicker_telemetry_subscriber = KICKER_DATA_CHANNEL.subscriber().unwrap();

// power board
let power_led_cmd_publisher = LED_COMMAND_PUBSUB.publisher().unwrap();

///////////////////
// start tasks //
///////////////////

create_io_task!(main_spawner,
robot_state,
p);

create_power_task!(main_spawner, uart_queue_spawner,
robot_state, power_board_telemetry_publisher, power_led_cmd_publisher,
p);

create_imu_task!(main_spawner,
robot_state,
imu_gyro_data_publisher, imu_accel_data_publisher, imu_led_cmd_publisher,
p);

create_motor_calibrate_task!(main_spawner, uart_queue_spawner,
robot_state,
control_command_subscriber, control_telemetry_publisher,
control_task_power_telemetry_subscriber, control_task_kicker_telemetry_subscriber,
control_gyro_data_subscriber, control_accel_data_subscriber,
p);

create_kicker_task!(
main_spawner, uart_queue_spawner,
robot_state,
kicker_command_subscriber,
kicker_board_telemetry_publisher,
p);

loop {
Timer::after_millis(10).await;
}
}
26 changes: 12 additions & 14 deletions control-board/src/bin/hwtest-motor/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -124,19 +124,17 @@ async fn main(main_spawner: embassy_executor::Spawner) {
);

loop {
Timer::after_millis(100).await;

test_command_publisher
.publish(DataPacket::BasicControl(BasicControl {
_bitfield_1: Default::default(),
_bitfield_align_1: Default::default(),
vel_x_linear: 1.0,
vel_y_linear: 0.0,
vel_z_angular: 0.0,
kick_vel: 0.0,
dribbler_speed: 10.0,
kick_request: KickRequest::KR_DISABLE,
}))
.await;
Timer::after_millis(10).await;

test_command_publisher.publish(DataPacket::BasicControl(BasicControl {
_bitfield_1: Default::default(),
_bitfield_align_1: Default::default(),
vel_x_linear: 1.0,
vel_y_linear: 0.0,
vel_z_angular: 5.0,
kick_vel: 0.0,
dribbler_speed: 10.0,
kick_request: KickRequest::KR_DISABLE,
})).await;
}
}
67 changes: 59 additions & 8 deletions control-board/src/stspin_motor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,10 +33,9 @@ pub struct WheelMotor<
stm32_uart_interface:
Stm32Interface<'a, LEN_RX, LEN_TX, DEPTH_RX, DEPTH_TX, DEBUG_MOTOR_UART_QUEUES>,
firmware_image: &'a [u8],

current_timestamp_ms: u32,
current_state: MotorTelemetry,
current_params_state: ParameterMotorResponse,

version_major: u8,
version_minor: u8,
version_patch: u16,
Expand All @@ -50,6 +49,8 @@ pub struct WheelMotor<
motion_type: MotionCommandType::Type,
reset_flagged: bool,
telemetry_enabled: bool,
motion_enabled: bool,
calibrate_current: bool,
}

impl<
Expand Down Expand Up @@ -81,6 +82,7 @@ impl<
version_major: 0,
version_minor: 0,
version_patch: 0,
current_timestamp_ms: 0,
current_state: start_state,
current_params_state: start_params_state,
vel_pid_constants: Vector3::new(0.0, 0.0, 0.0),
Expand All @@ -93,6 +95,8 @@ impl<
motion_type: OPEN_LOOP,
reset_flagged: false,
telemetry_enabled: false,
motion_enabled: false,
calibrate_current: false,
}
}

Expand Down Expand Up @@ -125,6 +129,7 @@ impl<
version_major: 0,
version_minor: 0,
version_patch: 0,
current_timestamp_ms: 0,
current_state: start_state,
current_params_state: start_params_state,
vel_pid_constants: Vector3::new(0.0, 0.0, 0.0),
Expand All @@ -137,6 +142,8 @@ impl<
motion_type: OPEN_LOOP,
reset_flagged: false,
telemetry_enabled: false,
motion_enabled: false,
calibrate_current: false,
}
}

Expand Down Expand Up @@ -216,6 +223,7 @@ impl<
res = Err(());
}
}

// Make sure that the uart queue is empty of any possible parameter
// response packets, which may cause side effects for the flashing
// process
Expand Down Expand Up @@ -273,6 +281,13 @@ impl<
}
return self.init_firmware_image(flash, self.firmware_image).await;
}

pub async fn save_motor_current_constants(&mut self, current_constant: f32) -> Result<(), ()> {
defmt::debug!("Drive Motor - Saving motor current constant: {:?}", current_constant);
self.stm32_uart_interface.write_current_calibration_constants(current_constant).await

}


pub fn process_packets(&mut self) {
while let Ok(res) = self.stm32_uart_interface.try_read_data() {
Expand Down Expand Up @@ -424,6 +439,18 @@ impl<
self.telemetry_enabled = telemetry_enabled;
}

pub fn set_motion_enabled(&mut self, enabled: bool) {
self.motion_enabled = enabled;
}

pub fn set_calibrate_current(&mut self, calibrate_current: bool) {
self.calibrate_current = calibrate_current;
}

pub fn read_current_timestamp_ms(&self) -> u32 {
return self.current_timestamp_ms;
}

pub fn read_is_error(&self) -> bool {
return self.current_state.master_error() != 0;
}
Expand All @@ -434,10 +461,6 @@ impl<
|| self.current_state.hall_enc_vel_disagreement_error() != 0;
}

pub fn read_current(&self) -> f32 {
return self.current_state.current_estimate;
}

pub fn read_encoder_delta(&self) -> i32 {
return self.current_state.encoder_delta;
}
Expand All @@ -454,7 +477,35 @@ impl<
return self.current_state.vel_setpoint;
}

pub fn read_vel_computed_setpoint(&self) -> f32 {
return self.current_state.vel_computed_setpoint;
pub fn read_vel_computed_duty(&self) -> f32 {
return self.current_state.vel_computed_duty;
}

pub fn read_current(&self) -> f32 {
return self.current_state.current_estimate;
}

pub fn read_torque_setpoint(&self) -> f32 {
return self.current_state.torque_setpoint;
}

pub fn read_torque_estimate(&self) -> f32 {
return self.current_state.torque_estimate;
}

pub fn read_torque_computed_error(&self) -> f32 {
return self.current_state.torque_computed_error;
}

pub fn read_torque_computed_nm(&self) -> f32 {
return self.current_state.torque_computed_nm;
}

pub fn read_torque_computed_duty(&self) -> f32 {
return self.current_state.torque_computed_duty;
}

pub fn read_vbus_voltage(&self) -> f32 {
return self.current_state.vbus_voltage;
}
}
Loading
Loading