1#![deny(unsafe_code)]
2#![no_main]
3#![cfg_attr(not(test), no_std)]
4
5use defmt::*;
6use embassy_executor::{Spawner, main, task};
7use embassy_stm32::gpio::{Output, Level, Speed};
8use embassy_stm32::i2c::{self, I2c};
9use embassy_stm32::mode::Async;
10use embassy_stm32::bind_interrupts;
11use embassy_stm32::peripherals;
12use embassy_stm32::time::Hertz;
13use embassy_time::Timer;
14use {defmt_rtt as _, panic_probe as _};
15
16use l6360::{self, L6360, HardwareAccess};
17use iol::master;
18
19use embassy_sync::mutex::Mutex;
20use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex;
21
22mod l6360_hw;
23use l6360_hw::L6360_HW;
24
25mod iol_master_actions;
26use iol_master_actions::MasterActions;
27
28static IOL_TRANSCEIVER: Mutex<CriticalSectionRawMutex, Option<L6360<I2c<Async>, L6360_HW>>> = Mutex::new(None);
29
30#[main]
31async fn main(spawner: Spawner) {
32 setup_hardware(spawner).await;
33
34 let mut iol_transceiver_ref = IOL_TRANSCEIVER.lock().await;
36 let iol_transceiver = iol_transceiver_ref.as_mut().unwrap();
37 iol_transceiver.init().await.unwrap();
38
39 iol_transceiver.set_led_pattern(l6360::Led::LED1, 0xFFF0).await.unwrap();
41 iol_transceiver.set_led_pattern(l6360::Led::LED2, 0x000F).await.unwrap();
42
43 iol_transceiver.hw.enl_plus(l6360::PinState::High);
45 drop(iol_transceiver_ref);
47
48 let master = master::Master::new(MasterActions);
50 spawner.spawn(run_master(master)).unwrap();
51
52 Timer::after_millis(2_000).await;
54 info!("startup");
55 master::Master::<MasterActions>::dl_set_mode_startup().await;
56 Timer::after_millis(100_000).await;
57}
58
59#[task]
60async fn run_master(mut master: master::Master<MasterActions>) {
61 info!("run master");
62 master.run().await;
63}
64
65fn heartbeat_led(spawner: Spawner, pin: peripherals::PA5) {
66 let led = Output::new(pin, Level::High, Speed::Low);
67 spawner.spawn(blink(led)).unwrap();
68
69 #[task]
70 async fn blink(mut led: Output<'static>) -> ! {
71 loop {
72 led.set_high();
74 Timer::after_millis(2000).await;
75
76 led.set_low();
78 Timer::after_millis(2000).await;
79 }
80 }
81}
82
83async fn setup_hardware(spawner: Spawner) {
84 let p = embassy_stm32::init(Default::default());
85
86 heartbeat_led(spawner, p.PA5);
87
88 bind_interrupts!(struct I2cIrqs {
89 I2C1_EV => i2c::EventInterruptHandler<peripherals::I2C1>;
90 I2C1_ER => i2c::ErrorInterruptHandler<peripherals::I2C1>;
91 });
92
93 let i2c = I2c::new(
94 p.I2C1,
95 p.PB8,
96 p.PB9,
97 I2cIrqs,
98 p.DMA1_CH6,
99 p.DMA1_CH0,
100 Hertz(400_000),
101 {
102 let mut i2c_config = i2c::Config::default();
103 i2c_config.sda_pullup = true;
104 i2c_config.scl_pullup = true;
105 i2c_config.timeout = embassy_time::Duration::from_millis(1000);
106 i2c_config
107 },
108 );
109
110 let l6360_hw = L6360_HW::new(p.USART1, p.PA9, p.PA10, p.PA6, p.PC0);
111
112 let config = l6360::Config {
113 configuration_register: l6360::ConfigurationRegister {
114 cq_output_stage_configuration: l6360::CqOutputStageConfiguration::PushPull,
115 },
116 control_register_1: l6360::ControlRegister1 {
117 en_cgq_cq_pull_down: l6360::EN_CGQ_CQ_PullDown::ON_IfEnCq0,
118 }
119 };
120
121 *IOL_TRANSCEIVER.lock().await = Some(L6360::new(i2c, l6360_hw, 0b1100_000, config).unwrap());
122}