1use defmt::info;
2use embassy_stm32::bind_interrupts;
3use embassy_stm32::usart::{self, Uart};
4use embassy_stm32::peripherals;
5use embassy_stm32::gpio::{Output, Input, Level, Speed, Pull};
6use embassy_stm32::Peripheral;
7use embassy_stm32::mode::Blocking;
8
9bind_interrupts!(struct UartIrqs {
10 USART1 => usart::InterruptHandler<peripherals::USART1>;
11});
12
13#[derive(Copy, Clone, PartialEq)]
14pub enum Mode {
15 Gpio,
16 Uart,
17}
18
19#[allow(non_camel_case_types)]
21pub struct L6360_HW<'a> {
22 uart_instance: Option<peripherals::USART1>,
23 tx_pin: Option<peripherals::PA9>,
24 rx_pin: Option<peripherals::PA10>,
25 enl_plus: Output<'a>,
26 en_cq: Output<'a>,
27 in_cq: Option<Output<'a>>,
28 out_cq: Option<Input<'a>>,
29 uart: Option<Uart<'a, Blocking>>,
30 mode: Mode,
31}
32
33impl<'a> L6360_HW<'a> {
34 pub fn new(
35 uart_instance: peripherals::USART1,
36 tx_pin: peripherals::PA9,
37 rx_pin: peripherals::PA10,
38 enl_plus: peripherals::PA6,
39 en_cq: peripherals::PC0,
40 ) -> Self {
41 #[allow(unsafe_code)]
43 let tx_clone = unsafe { tx_pin.clone_unchecked() };
44 #[allow(unsafe_code)]
45 let rx_clone = unsafe { rx_pin.clone_unchecked() };
46
47 Self {
48 uart_instance: Some(uart_instance),
49 tx_pin: Some(tx_pin),
50 rx_pin: Some(rx_pin),
51 enl_plus: Output::new(enl_plus, Level::Low, Speed::Low),
52 en_cq: Output::new(en_cq, Level::Low, Speed::Low),
53 in_cq: Some(Output::new(tx_clone, Level::Low, Speed::Low)),
54 out_cq: Some(Input::new(rx_clone, Pull::None)),
55 uart: None,
56 mode: Mode::Gpio,
57 }
58 }
59
60 pub fn switch_to_uart(&mut self) {
61 drop(self.in_cq.take());
63 drop(self.out_cq.take());
64
65 let mut config = usart::Config::default();
66 config.baudrate = 38_400; config.data_bits = usart::DataBits::DataBits8;
68 config.stop_bits = usart::StopBits::STOP1;
69 config.parity = usart::Parity::ParityEven;
70 config.detect_previous_overrun = true;
71 config.assume_noise_free = false;
72 config.rx_pull = Pull::None;
73
74 self.uart = Some(Uart::new_blocking(
75 self.uart_instance.take().unwrap(),
76 self.rx_pin.take().unwrap(),
77 self.tx_pin.take().unwrap(),
78 config,
79 ).unwrap());
80
81 self.mode = Mode::Uart;
82 }
83
84 pub fn get_mode(&self) -> Mode {
85 self.mode
86 }
87}
88
89impl<'a> l6360::HardwareAccess for L6360_HW<'a> {
90 fn enl_plus(&mut self, level: l6360::PinState) {
91 match level {
92 l6360::PinState::High => self.enl_plus.set_level(Level::High),
93 l6360::PinState::Low => self.enl_plus.set_level(Level::Low),
94 }
95 }
96
97 fn en_cq(&mut self, level: l6360::PinState) {
98 match level {
99 l6360::PinState::High => self.en_cq.set_level(Level::High),
100 l6360::PinState::Low => self.en_cq.set_level(Level::Low),
101 }
102 }
103
104 fn in_cq(&mut self, level: l6360::PinState) {
105 let pin = self.in_cq.as_mut().unwrap();
106 match level {
107 l6360::PinState::High => pin.set_level(Level::High),
108 l6360::PinState::Low => pin.set_level(Level::Low),
109 }
110 }
111
112 fn out_cq(&self) -> l6360::PinState {
113 match self.out_cq.as_ref().unwrap().get_level() {
114 Level::High => l6360::PinState::High,
115 Level::Low => l6360::PinState::Low,
116 }
117 }
118
119 async fn exchange(&mut self, data: &[u8], answer: &mut [u8]) {
120 self.en_cq(l6360::PinState::High);
121 self.uart.as_mut().unwrap().blocking_write(data).unwrap();
122 self.uart.as_mut().unwrap().blocking_flush().unwrap();
123
124 self.en_cq(l6360::PinState::Low);
125 self.uart.as_mut().unwrap().blocking_read(answer).unwrap();
126
127 for byte in answer{
128 info!("answer: {:#04x}", byte);
129 }
130 }
131}