thermostat/src/pins.rs

160 lines
4.5 KiB
Rust
Raw Normal View History

use stm32f4xx_hal::{
gpio::{
AF5, Alternate,
2020-03-13 00:26:14 +08:00
gpioa::*,
gpiob::*,
gpioc::*,
gpioe::*,
gpiog::*,
GpioExt,
Output, PushPull,
Speed::VeryHigh,
},
rcc::Clocks,
2020-03-13 00:26:14 +08:00
pwm::{self, PwmChannels},
spi::Spi,
2020-03-13 00:26:14 +08:00
stm32::{GPIOA, GPIOB, GPIOC, GPIOE, GPIOG, SPI2, TIM1, TIM3},
time::{U32Ext, Hertz},
2020-03-09 07:27:35 +08:00
};
/// SPI peripheral used for communication with the ADC
type AdcSpi = Spi<SPI2, (PB10<Alternate<AF5>>, PB14<Alternate<AF5>>, PB15<Alternate<AF5>>)>;
pub struct Pins {
pub adc_spi: AdcSpi,
pub adc_nss: PB12<Output<PushPull>>,
2020-03-13 00:26:14 +08:00
pub pwm: PwmPins,
}
impl Pins {
/// Setup GPIO pins and configure MCU peripherals
2020-03-13 00:26:14 +08:00
pub fn setup(
clocks: Clocks,
tim1: TIM1,
tim3: TIM3,
gpioa: GPIOA, gpiob: GPIOB, gpioc: GPIOC, gpioe: GPIOE, gpiog: GPIOG,
spi2: SPI2
) -> Self {
let gpioa = gpioa.split();
let gpiob = gpiob.split();
let gpioc = gpioc.split();
2020-03-13 00:26:14 +08:00
let gpioe = gpioe.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();
2020-03-13 00:26:14 +08:00
let pwm = PwmPins::setup(
clocks, tim1, tim3,
gpioc.pc6, gpioc.pc7,
gpioe.pe9, gpioe.pe11,
gpioe.pe13, gpioe.pe14
);
Pins {
adc_spi,
adc_nss,
2020-03-13 00:26:14 +08:00
pwm,
}
}
/// Configure the GPIO pins for SPI operation, and initialize SPI
fn setup_spi_adc<M1, M2, M3>(
clocks: Clocks,
spi2: SPI2,
sck: PB10<M1>,
miso: PB14<M2>,
mosi: PB15<M3>,
) -> 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
)
}
/// Configure the GPIO pins for Ethernet operation
fn setup_ethernet<M1, M2, M3, M4, M5, M6, M7, M8, M9>(
pa1: PA1<M1>, pa2: PA2<M2>, pc1: PC1<M3>, pa7: PA7<M4>,
pc4: PC4<M5>, pc5: PC5<M6>, pb11: PB11<M7>, pg13: PG13<M8>,
pb13: PB13<M9>
) {
// 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);
}
2020-03-09 07:27:35 +08:00
}
2020-03-13 00:26:14 +08:00
pub struct PwmPins {
max_v0: PwmChannels<TIM3, pwm::C1>,
max_v1: PwmChannels<TIM3, pwm::C2>,
max_i_pos0: PwmChannels<TIM1, pwm::C1>,
max_i_pos1: PwmChannels<TIM1, pwm::C2>,
max_i_neg0: PwmChannels<TIM1, pwm::C3>,
max_i_neg1: PwmChannels<TIM1, pwm::C4>,
}
impl PwmPins {
fn setup<M1, M2, M3, M4, M5, M6>(
clocks: Clocks,
tim1: TIM1,
tim3: TIM3,
max_v0: PC6<M1>,
max_v1: PC7<M2>,
max_i_pos0: PE9<M3>,
max_i_pos1: PE11<M4>,
max_i_neg0: PE13<M5>,
max_i_neg1: PE14<M6>,
) -> 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,
}
}
}