stm32f446re/
iol_master_actions.rs1use defmt::*;
2use embassy_time::Timer;
3use embassy_time::Instant;
4use embassy_stm32::i2c::I2c;
5use embassy_stm32::mode::Async;
6
7use iol::master;
8use l6360::{self, L6360, HardwareAccess};
9
10use crate::l6360_hw::{self, L6360_HW};
11use super::IOL_TRANSCEIVER;
12
13#[derive(Copy, Clone)]
14pub struct MasterActions;
15
16impl master::Actions for MasterActions {
17 async fn wait_us(&self, duration: u64) {
18 Timer::after_micros(duration).await;
19 }
20
21 async fn wait_ms(&self, duration: u64) {
22 Timer::after_millis(duration).await;
23 }
24
25 async fn get_cq(&self) -> l6360::PinState {
26 if let Some(l6360) = IOL_TRANSCEIVER.lock().await.as_mut() {
27 l6360.hw.en_cq(l6360::PinState::Low);
28 Timer::after_nanos(500).await; match l6360.hw.out_cq() {
32 l6360::PinState::Low => l6360::PinState::High,
33 l6360::PinState::High => l6360::PinState::Low,
34 }
35 }
36 else {
37 crate::panic!("Lock to L6360 failed");
38 }
39 }
40
41 async fn wake_up_pulse(&self, direction: master::WakeUpPulseDirection) {
42 if let Some(l6360) = IOL_TRANSCEIVER.lock().await.as_mut() {
43 fn wait_blocking() {
44 let mut count = 0;
46 while count < 35 {
47 count += 1;
48 }
49 }
50
51 match direction {
58 master::WakeUpPulseDirection::Up => {
59 l6360.hw.in_cq(l6360::PinState::Low);
60 l6360.hw.en_cq(l6360::PinState::High);
61 wait_blocking();
62 l6360.hw.in_cq(l6360::PinState::High);
63 }
64 master::WakeUpPulseDirection::Down => {
65 l6360.hw.in_cq(l6360::PinState::High);
66 l6360.hw.en_cq(l6360::PinState::High);
67 wait_blocking();
68 l6360.hw.in_cq(l6360::PinState::Low);
69 }
70 }
71 }
72 else {
73 crate::panic!("Lock to L6360 failed");
74 }
75 }
76
77 async fn port_power_on(&self) {
78 info!("port power on ...");
79 if let Some(l6360) = IOL_TRANSCEIVER.lock().await.as_mut() {
80 l6360.hw.enl_plus(l6360::PinState::High);
81 }
82 info!("done");
83 }
84
85 async fn port_power_off(&self) {
86 info!("port power off ...");
87 if let Some(l6360) = IOL_TRANSCEIVER.lock().await.as_mut() {
88 l6360.hw.enl_plus(l6360::PinState::Low);
89 }
90 info!("done");
91 }
92
93 async fn await_event_with_timeout_ms<F, T>(&self, duration: u64, future: F) -> Option<T>
94 where
95 F: core::future::Future<Output = T> + Send
96 {
97 embassy_time::with_timeout(embassy_time::Duration::from_millis(duration), future).await.ok()
98 }
99
100 async fn await_ready_pulse_with_timeout_ms(&self, duration: u64) -> master::ReadyPulseResult {
101 if let Some(l6360) = IOL_TRANSCEIVER.lock().await.as_mut() {
102 let result = embassy_time::with_timeout(
103 embassy_time::Duration::from_millis(duration),
104 measure_ready_pulse(l6360),
105 ).await;
106
107 match result {
108 Ok(_) => master::ReadyPulseResult::ReadyPulseOk,
109 Err(_) => master::ReadyPulseResult::TimeToReadyElapsed,
110 }
111 }
112 else {
113 crate::panic!("Lock to L6360 failed"); }
115 }
116
117 async fn exchange_data(&self, data: &[u8], answer: &mut [u8]) {
118 if let Some(l6360) = IOL_TRANSCEIVER.lock().await.as_mut() {
119 if l6360.hw.get_mode() != l6360_hw::Mode::Uart {
120 l6360.hw.switch_to_uart();
121 }
122 l6360.hw.exchange(data, answer).await;
123 }
124 else {
125 crate::panic!("Lock to L6360 failed"); }
127 }
128}
129
130
131async fn measure_ready_pulse(l6360: &mut L6360<I2c<'static, Async>, L6360_HW<'static>>) {
132 info!("waiting for ready-pulse...");
151 while l6360.hw.out_cq() == l6360::PinState::High {}
152 let start = Instant::now();
153 while l6360.hw.out_cq() == l6360::PinState::Low {}
154 let end = Instant::now();
155 info!("ready-pulse received");
156
157 let high_time_us = (end - start).as_micros();
158 info!("Pin was high for {} us", high_time_us);
159}