Skip to main content

r_d_inclita_sofware/
hardware_cfg.rs

1//! This file will contain all the hw configs necessary: debug  uart, gps uart, sdmmc , spi
2//! altimeter, i2c gyroscope, etc...
3//! Kinda works like the config.h in the "C" code were used to
4//!
5use embassy_stm32::Peripherals;
6use embassy_stm32::gpio::{Level, Output, Speed};
7use embassy_stm32::i2c::{Config as I2cConfig, I2c};
8use embassy_stm32::mode::{Async, Blocking};
9use embassy_stm32::rcc::*;
10use embassy_stm32::spi::{Config as SpiConfig, Spi};
11use embassy_stm32::usart::{Config as UsartConfig, Uart};
12use embassy_stm32::{Config, bind_interrupts, peripherals, sdmmc, usart};
13// TODO: sdmmc.rs or something, this is messy
14// it is indeed messy... there is no fatfs support for the async sdmmc implemented by embassy_stm32
15// there is a blocking version that supports fatfs! embedded-sdmmc. last time i saw, async support was WIP
16// because of duplicate code (blocking and async).
17// AeroRust is working on a simple data storage protocol!
18
19//NVIC and DMA
20bind_interrupts!(struct Irqs {
21    SDIO => sdmmc::InterruptHandler<peripherals::SDIO>;
22    USART1 => usart::InterruptHandler<peripherals::USART1>;
23
24});
25
26pub struct Board<'a> {
27    pub debug_uart: Uart<'a, Blocking>, //as of now on blocking mode, maybe change this later
28    pub led_mcu_on: Output<'a>,
29    pub led_other_function: Output<'a>,
30    // I2C expects <Lifetime, Mode, MasterMode>
31    pub imu: I2c<'a, Blocking, embassy_stm32::i2c::Master>, // this will prolly work in blocking,
32    // as of now were using bno
33    pub accel: I2c<'a, Blocking, embassy_stm32::i2c::Master>,
34    pub gps_uart: Uart<'a, Async>,
35    // SPI expects <Lifetime, Mode, CommunicationMode>
36    pub altimeter: Spi<'a, Async, embassy_stm32::spi::mode::Master>, //prollly will keep in
37    //blocking mode, as of now were using ms
38    pub altimeter_cs: Output<'a>,
39    pub sd_spi: Spi<'a, Blocking, embassy_stm32::spi::mode::Master>,
40    pub sd_cs: Output<'a>,
41    pub lora_spi: Spi<'a, Blocking, embassy_stm32::spi::mode::Master>,
42    pub lora_cs: Output<'a>,
43    pub lora_reset: Output<'a>,
44}
45
46impl Board<'static> {
47    //we need this because of the sd card
48    pub fn set_clock() -> Config {
49        let mut config = Config::default();
50
51        config.rcc.hse = None; // We dont have an external oscilator
52        config.rcc.hsi = true;
53
54        config.rcc.pll_src = PllSource::HSI;
55
56        // math to suply the sdio with 48mhz
57        config.rcc.pll = Some(Pll {
58            // MATH: HSI is 16 MHz
59            prediv: PllPreDiv::DIV8, // 16 MHz / 8 = 2 MHz (Optimal VCO input)
60            mul: PllMul::MUL192,     // 2 MHz * 192 = 384 MHz (Internal VCO frequency)
61            divp: Some(PllPDiv::DIV4), // 384 MHz / 4 = 96 MHz (Main CPU Clock - Safe!)
62            divq: Some(PllQDiv::DIV8), // 384 MHz / 8 = 48 MHz (Exact SDMMC requirement!)
63            divr: None,
64        });
65        config.rcc.ahb_pre = AHBPrescaler::DIV1;
66        config.rcc.apb1_pre = APBPrescaler::DIV4;
67        config.rcc.apb2_pre = APBPrescaler::DIV2;
68        config.rcc.sys = Sysclk::PLL1_P;
69
70        config
71    }
72    pub fn new(p: Peripherals) -> Self {
73        let mut debug_uart_cfg = UsartConfig::default();
74        debug_uart_cfg.baudrate = 115200;
75        let debug_uart = Uart::new_blocking(p.USART2, p.PA3, p.PA2, debug_uart_cfg).unwrap();
76
77        let led_mcu_on = Output::new(p.PA12, Level::High, Speed::Low);
78        let led_other_function = Output::new(p.PB15, Level::High, Speed::Low);
79
80        // GPS UART
81        let mut gps_uart_cfg = UsartConfig::default();
82        gps_uart_cfg.baudrate = 38400;
83        let gps_uart = Uart::new(
84            p.USART1,
85            p.PA10,
86            p.PA9,
87            Irqs,
88            p.DMA2_CH7,
89            p.DMA2_CH2,
90            gps_uart_cfg,
91        )
92        .unwrap();
93
94        // GYRO I2C
95        let i2c_cfg = I2cConfig::default();
96        let imu = I2c::new_blocking(p.I2C1, p.PB6, p.PB7, i2c_cfg);
97
98        let mut i2c_config_pulls = I2cConfig::default();
99
100        // 2. Enable the internal pull-up resistors!
101        i2c_config_pulls.sda_pullup = true;
102        i2c_config_pulls.scl_pullup = true;
103        let accel = I2c::new_blocking(p.I2C3, p.PA8, p.PB4, i2c_config_pulls);
104
105        let mut spi_cfg = SpiConfig::default();
106        let altimeter = Spi::new(
107            p.SPI2, p.PB13, p.PC1, p.PC2, p.DMA1_CH4, p.DMA1_CH3, spi_cfg,
108        );
109
110        let altimeter_cs = Output::new(p.PA0, Level::High, Speed::High); //initalized
111        //to high -> MS inactive
112
113        // SD CARD SPI
114        let mut sd_spi_cfg = SpiConfig::default();
115        // SD cards usually need to start slow (e.g., 400kHz) for initialization,
116        // the embedded-sdmmc crate handles this, but we'll set a moderate default.
117        sd_spi_cfg.frequency = embassy_stm32::time::mhz(1);
118
119        let sd_spi = Spi::new_blocking(
120            p.SPI3, p.PC10, // SCK
121            p.PB5,  // MOSI
122            p.PC11, // MISO
123            sd_spi_cfg,
124        );
125        // --- LORA SPI SETUP ---
126        let mut lora_spi_cfg = SpiConfig::default();
127        lora_spi_cfg.frequency = embassy_stm32::time::mhz(1); // 1 MHz is safe for RFM95 init
128
129        let lora_spi = Spi::new_blocking(
130            p.SPI1,
131            p.PA5,
132            p.PA7,
133            p.PA6,
134            lora_spi_cfg, // SPI1: SCK, MOSI, MISO
135        );
136
137        // CS is active low, so initialize it High
138        let lora_cs = Output::new(p.PA4, Level::High, Speed::High);
139
140        // Reset is active low, so initialize it High
141        let lora_reset = Output::new(p.PC4, Level::High, Speed::High);
142        // Chip Select must start HIGH (deselected)
143        let sd_cs = Output::new(p.PA1, Level::High, Speed::High);
144        Self {
145            debug_uart,
146            led_mcu_on,
147            led_other_function,
148            imu,
149            accel,
150            gps_uart,
151            altimeter,
152            altimeter_cs,
153            sd_spi,
154            sd_cs,
155            lora_spi,
156            lora_cs,
157            lora_reset,
158        }
159    }
160}