Thumbnail

steew/gilgamesh.git

Clone URL: https://git.buni.party/steew/gilgamesh.git

Viewing file on branch master

1use defmt::trace;
2use embassy_stm32::{
3 exti::ExtiInput,
4 i2c::{I2c, Master},
5 mode::Async,
6 usart::Uart,
7};
8use embassy_sync::{
9 blocking_mutex::raw::ThreadModeRawMutex,
10 channel::{Receiver, Sender},
11};
12use embassy_time::{Delay, Instant};
13use mpu6050_dmp::{
14 calibration::CalibrationParameters, quaternion::Quaternion, sensor_async::Mpu6050,
15 yaw_pitch_roll::YawPitchRoll,
16};
17
18pub const BUFFERED_QUATERNIONS: usize = 5;
19
20#[embassy_executor::task]
21pub async fn telemetry_sender(
22 mut telemetry_port: Uart<'static, Async>,
23 channel: Receiver<'static, ThreadModeRawMutex, Quaternion, BUFFERED_QUATERNIONS>,
24) {
25 let mut previous: Instant = Instant::now();
26 let mut now: Instant;
27
28 loop {
29 // await until we receive a new quaternion packet from the sync channel
30 let next_quaternion_value = channel.receive().await.normalize();
31 // let ypr_format = YawPitchRoll::from(next_quaternion_value);
32
33 now = Instant::now();
34 let elapsed = now - previous;
35 defmt::info!("Time elapsed since last data: {} ms", elapsed.as_millis());
36 previous = now;
37
38 let w = &next_quaternion_value.w;
39 let x = &next_quaternion_value.x;
40 let y = &next_quaternion_value.y;
41 let z = &next_quaternion_value.z;
42
43 let _send_result_w = telemetry_port.write(&w.to_le_bytes()).await;
44 let _send_result_x = telemetry_port.write(&x.to_le_bytes()).await;
45 let _send_result_y = telemetry_port.write(&y.to_le_bytes()).await;
46 let _send_result_z = telemetry_port.write(&z.to_le_bytes()).await;
47
48 telemetry_port.flush().await.unwrap();
49 defmt::info! {"Data: {} {} {} {}", w, x, y, z};
50 }
51}
52
53#[embassy_executor::task]
54pub async fn read_mpu(
55 iic: I2c<'static, Async, Master>,
56 mut ext: ExtiInput<'static>,
57 channel: Sender<'static, ThreadModeRawMutex, Quaternion, BUFFERED_QUATERNIONS>,
58) {
59 trace! {"Entering MPU thread"};
60 let mut mpu = Mpu6050::new(iic, mpu6050_dmp::address::Address::default())
61 .await
62 .unwrap();
63 // initialize the DMP processor for the MPU
64 mpu.initialize_dmp(&mut Delay).await.unwrap();
65
66 // Configure calibration parameters
67 // let calibration_params = CalibrationParameters::new(
68 // mpu6050_dmp::accel::AccelFullScale::G2,
69 // mpu6050_dmp::gyro::GyroFullScale::Deg2000,
70 // mpu6050_dmp::calibration::ReferenceGravity::ZN,
71 // );
72 // trace!("Calibrating Sensor");
73 // mpu
74 // .calibrate(&mut Delay, &calibration_params)
75 // .await
76 // .unwrap();
77 // trace!("Sensor Calibrated");
78 mpu.set_clock_source(mpu6050_dmp::clock_source::ClockSource::Xgyro).await.unwrap();
79 mpu.enable_dmp().await.unwrap();
80 mpu.load_firmware().await.unwrap();
81 mpu.boot_firmware().await.unwrap();
82 mpu.set_sample_rate_divider(4).await.unwrap();
83 mpu.set_digital_lowpass_filter(mpu6050_dmp::config::DigitalLowPassFilter::Filter0)
84 .await
85 .unwrap();
86
87 let mut fifo: [u8; 28] = [0; 28];
88
89 // set up the interrupt so we receive data from the internal mpu6050 dmp,
90 // combining gyro and accel
91 mpu.enable_fifo().await.unwrap();
92 trace! {"Enabling FIFO interrupt"};
93 mpu.interrupt_fifo_oflow_en().await.unwrap();
94
95 loop {
96 // block until we get an interrupt from the MPU line
97 ext.wait_for_rising_edge().await;
98 // read the combined data from the MPU fifo. It sends 28 byte packets, of which the first
99 // 16 are the quaternion data.
100 mpu.read_fifo(&mut fifo).await.unwrap();
101 // obtain the first 16 quaternion packets
102 let quaternion_packet = Quaternion::from_bytes(&fifo[..16]).unwrap().normalize();
103 // send quaternion value to sync channel
104 channel.send(quaternion_packet).await;
105
106 // clear the pending interrupt and wait for the next
107 mpu.reset_fifo().await.unwrap();
108 mpu.interrupt_read_clear().await.unwrap();
109 }
110}
111