fix(crl200s): restore GD32 telemetry after cold boot
This commit is contained in:
@@ -69,9 +69,9 @@ pub use state::ComponentState;
|
||||
// Internal imports
|
||||
use crate::config::AxisTransform3D;
|
||||
use crate::core::types::{Command, SensorGroupData, StreamSender};
|
||||
use crate::devices::crl200s::constants::{INIT_RETRY_DELAY_MS, SERIAL_READ_TIMEOUT_MS};
|
||||
use crate::devices::crl200s::constants::SERIAL_READ_TIMEOUT_MS;
|
||||
use crate::error::{Error, Result};
|
||||
use packet::{TxPacket, initialize_packet};
|
||||
use packet::TxPacket;
|
||||
use serialport::SerialPort;
|
||||
use std::sync::atomic::{AtomicBool, Ordering};
|
||||
use std::sync::{Arc, Mutex};
|
||||
@@ -128,29 +128,63 @@ impl GD32Driver {
|
||||
///
|
||||
/// Version is requested by reader thread after first packet received.
|
||||
pub fn initialize(&mut self) -> Result<()> {
|
||||
log::info!("Initializing GD32 device...");
|
||||
log::info!("Initializing GD32 with AuxCtrl-compatible wake sequence...");
|
||||
|
||||
// Send init commands (like sangam-io2-backup approach)
|
||||
// Don't wait for response here - reader thread will handle it
|
||||
let init_pkt = initialize_packet();
|
||||
let mut port = self
|
||||
.port
|
||||
.lock()
|
||||
.map_err(|e| Error::MutexPoisoned(format!("serial port (init): {}", e)))?;
|
||||
|
||||
for attempt in 1..=5 {
|
||||
{
|
||||
let mut port = self
|
||||
.port
|
||||
.lock()
|
||||
.map_err(|e| Error::MutexPoisoned(format!("serial port (init): {}", e)))?;
|
||||
if let Err(e) = init_pkt.send_to(&mut *port) {
|
||||
log::warn!("Init send failed (attempt {}): {}", attempt, e);
|
||||
}
|
||||
}
|
||||
thread::sleep(Duration::from_millis(INIT_RETRY_DELAY_MS));
|
||||
let mut pkt = TxPacket::new();
|
||||
|
||||
// 1. Protocol synchronization
|
||||
pkt.set_protocol_sync();
|
||||
pkt.send_to(&mut *port).map_err(Error::Io)?;
|
||||
thread::sleep(Duration::from_millis(8));
|
||||
|
||||
// 2. Initial LED state
|
||||
pkt.set_led(1);
|
||||
pkt.send_to(&mut *port).map_err(Error::Io)?;
|
||||
thread::sleep(Duration::from_millis(8));
|
||||
|
||||
// 3. Request GD32 firmware version
|
||||
pkt.set_version_request();
|
||||
pkt.send_to(&mut *port).map_err(Error::Io)?;
|
||||
thread::sleep(Duration::from_millis(8));
|
||||
|
||||
// 4. Explicit idle motor mode
|
||||
pkt.set_motor_mode(0x00);
|
||||
pkt.send_to(&mut *port).map_err(Error::Io)?;
|
||||
thread::sleep(Duration::from_millis(8));
|
||||
|
||||
// 5. Lidar motor stopped during initialization
|
||||
pkt.set_lidar_pwm(0);
|
||||
pkt.send_to(&mut *port).map_err(Error::Io)?;
|
||||
|
||||
// Timing observed in the AuxCtrl startup sequence
|
||||
thread::sleep(Duration::from_millis(200));
|
||||
|
||||
// LED burst observed during initialization
|
||||
for i in 0..4 {
|
||||
pkt.set_led(1);
|
||||
pkt.send_to(&mut *port).map_err(Error::Io)?;
|
||||
|
||||
if i < 3 {
|
||||
thread::sleep(Duration::from_millis(8));
|
||||
}
|
||||
|
||||
log::info!("GD32 initialization sequence sent");
|
||||
Ok(())
|
||||
}
|
||||
|
||||
thread::sleep(Duration::from_millis(8));
|
||||
|
||||
// Wake / heartbeat
|
||||
pkt.set_heartbeat();
|
||||
pkt.send_to(&mut *port).map_err(Error::Io)?;
|
||||
|
||||
log::info!("GD32 wake sequence sent");
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Start heartbeat and reader threads
|
||||
///
|
||||
/// # Arguments
|
||||
|
||||
Reference in New Issue
Block a user