use embedded_hal::{ blocking::spi::Transfer, digital::v2::OutputPin, }; use stm32f4xx_hal::{ gpio::{ AF5, Alternate, gpioa::*, gpiob::*, gpioc::*, gpioe::*, gpiof::*, gpiog::*, GpioExt, Output, PushPull, Speed::VeryHigh, }, rcc::Clocks, pwm::{self, PwmChannels}, spi::{self, Spi, NoMiso}, stm32::{GPIOA, GPIOB, GPIOC, GPIOE, GPIOF, GPIOG, SPI2, SPI4, SPI5, TIM1, TIM3}, time::{U32Ext, Hertz, MegaHertz}, }; /// SPI peripheral used for communication with the ADC type AdcSpi = Spi>, PB14>, PB15>)>; type Dac0Spi = Spi>, NoMiso, PE6>)>; type Dac1Spi = Spi>, NoMiso, PF9>)>; const DAC_FREQ: MegaHertz = MegaHertz(30); pub struct Pins { pub adc_spi: AdcSpi, pub adc_nss: PB12>, pub pwm: PwmPins, pub dac0_spi: Dac0Spi, pub dac0_sync: PE4>, pub dac1_spi: Dac1Spi, pub dac1_sync: PF6>, } impl Pins { /// Setup GPIO pins and configure MCU peripherals pub fn setup( clocks: Clocks, tim1: TIM1, tim3: TIM3, gpioa: GPIOA, gpiob: GPIOB, gpioc: GPIOC, gpioe: GPIOE, gpiof: GPIOF, gpiog: GPIOG, spi2: SPI2, spi4: SPI4, spi5: SPI5 ) -> Self { let gpioa = gpioa.split(); let gpiob = gpiob.split(); let gpioc = gpioc.split(); let gpioe = gpioe.split(); let gpiof = gpiof.split(); let gpiog = gpiog.split(); Self::setup_ethernet( gpioa.pa1, gpioa.pa2, gpioc.pc1, gpioa.pa7, gpioc.pc4, gpioc.pc5, gpiob.pb11, gpiog.pg13, gpiob.pb13 ); let adc_spi = Self::setup_spi_adc(clocks, spi2, gpiob.pb10, gpiob.pb14, gpiob.pb15); let adc_nss = gpiob.pb12.into_push_pull_output(); let (dac0_spi, dac0_sync) = Self::setup_dac0( clocks, spi4, gpioe.pe2, gpioe.pe4, gpioe.pe6 ); let (dac1_spi, dac1_sync) = Self::setup_dac1( clocks, spi5, gpiof.pf7, gpiof.pf6, gpiof.pf9 ); let pwm = PwmPins::setup( clocks, tim1, tim3, gpioc.pc6, gpioc.pc7, gpioe.pe9, gpioe.pe11, gpioe.pe13, gpioe.pe14 ); Pins { adc_spi, adc_nss, pwm, dac0_spi, dac0_sync, dac1_spi, dac1_sync, } } /// Configure the GPIO pins for SPI operation, and initialize SPI fn setup_spi_adc( clocks: Clocks, spi2: SPI2, sck: PB10, miso: PB14, mosi: PB15, ) -> AdcSpi { let sck = sck.into_alternate_af5(); let miso = miso.into_alternate_af5(); let mosi = mosi.into_alternate_af5(); Spi::spi2( spi2, (sck, miso, mosi), crate::ad7172::SPI_MODE, crate::ad7172::SPI_CLOCK.into(), clocks ) } fn setup_dac0( clocks: Clocks, spi4: SPI4, sclk: PE2, sync: PE4, sdin: PE6 ) -> (Dac0Spi, PE4>) { let sclk = sclk.into_alternate_af5(); let sdin = sdin.into_alternate_af5(); let spi = Spi::spi4( spi4, (sclk, NoMiso, sdin), spi::Mode { polarity: spi::Polarity::IdleHigh, phase: spi::Phase::CaptureOnSecondTransition, }, DAC_FREQ.into(), clocks ); let sync = sync.into_push_pull_output(); (spi, sync) } fn setup_dac1( clocks: Clocks, spi5: SPI5, sclk: PF7, sync: PF6, sdin: PF9 ) -> (Dac1Spi, PF6>) { let sclk = sclk.into_alternate_af5(); let sdin = sdin.into_alternate_af5(); let spi = Spi::spi5( spi5, (sclk, NoMiso, sdin), spi::Mode { polarity: spi::Polarity::IdleHigh, phase: spi::Phase::CaptureOnSecondTransition, }, DAC_FREQ.into(), clocks ); let sync = sync.into_push_pull_output(); (spi, sync) } /// Configure the GPIO pins for Ethernet operation fn setup_ethernet( pa1: PA1, pa2: PA2, pc1: PC1, pa7: PA7, pc4: PC4, pc5: PC5, pb11: PB11, pg13: PG13, pb13: PB13 ) { // PA1 RMII Reference Clock - SB13 ON pa1.into_alternate_af11().set_speed(VeryHigh); // PA2 RMII MDIO - SB160 ON pa2.into_alternate_af11().set_speed(VeryHigh); // PC1 RMII MDC - SB164 ON pc1.into_alternate_af11().set_speed(VeryHigh); // PA7 RMII RX Data Valid D11 JP6 ON pa7.into_alternate_af11().set_speed(VeryHigh); // PC4 RMII RXD0 - SB178 ON pc4.into_alternate_af11().set_speed(VeryHigh); // PC5 RMII RXD1 - SB181 ON pc5.into_alternate_af11().set_speed(VeryHigh); // PB11 RMII TX Enable - SB183 ON pb11.into_alternate_af11().set_speed(VeryHigh); // PG13 RXII TXD0 - SB182 ON pg13.into_alternate_af11().set_speed(VeryHigh); // PB13 RMII TXD1 I2S_A_CK JP7 ON pb13.into_alternate_af11().set_speed(VeryHigh); } } pub struct PwmPins { max_v0: PwmChannels, max_v1: PwmChannels, max_i_pos0: PwmChannels, max_i_pos1: PwmChannels, max_i_neg0: PwmChannels, max_i_neg1: PwmChannels, } impl PwmPins { fn setup( clocks: Clocks, tim1: TIM1, tim3: TIM3, max_v0: PC6, max_v1: PC7, max_i_pos0: PE9, max_i_pos1: PE11, max_i_neg0: PE13, max_i_neg1: PE14, ) -> PwmPins { let freq = 20u32.khz(); let channels = ( max_v0.into_alternate_af2(), max_v1.into_alternate_af2(), ); let (max_v0, max_v1) = pwm::tim3(tim3, channels, clocks, freq); let channels = ( max_i_pos0.into_alternate_af1(), max_i_pos1.into_alternate_af1(), max_i_neg0.into_alternate_af1(), max_i_neg1.into_alternate_af1(), ); let (max_i_pos0, max_i_pos1, max_i_neg0, max_i_neg1) = pwm::tim1(tim1, channels, clocks, freq); PwmPins { max_v0, max_v1, max_i_pos0, max_i_pos1, max_i_neg0, max_i_neg1, } } }