Support fan PWM settings #73
|
@ -342,12 +342,20 @@ impl Channels {
|
||||||
get(&self.pwm.max_i_neg0),
|
get(&self.pwm.max_i_neg0),
|
||||||
(0, PwmPin::MaxV) =>
|
(0, PwmPin::MaxV) =>
|
||||||
get(&self.pwm.max_v0),
|
get(&self.pwm.max_v0),
|
||||||
|
(0, PwmPin::Tacho) =>
|
||||||
|
get(&self.pwm.tacho),
|
||||||
|
(0, PwmPin::Fan) =>
|
||||||
|
get(&self.pwm.fan),
|
||||||
(1, PwmPin::MaxIPos) =>
|
(1, PwmPin::MaxIPos) =>
|
||||||
get(&self.pwm.max_i_pos1),
|
get(&self.pwm.max_i_pos1),
|
||||||
(1, PwmPin::MaxINeg) =>
|
(1, PwmPin::MaxINeg) =>
|
||||||
get(&self.pwm.max_i_neg1),
|
get(&self.pwm.max_i_neg1),
|
||||||
(1, PwmPin::MaxV) =>
|
(1, PwmPin::MaxV) =>
|
||||||
get(&self.pwm.max_v1),
|
get(&self.pwm.max_v1),
|
||||||
|
(1, PwmPin::Tacho) =>
|
||||||
|
get(&self.pwm.tacho),
|
||||||
|
(1, PwmPin::Fan) =>
|
||||||
|
get(&self.pwm.fan),
|
||||||
_ =>
|
_ =>
|
||||||
unreachable!(),
|
unreachable!(),
|
||||||
}
|
}
|
||||||
|
@ -381,7 +389,7 @@ impl Channels {
|
||||||
(self.read_tec_u_meas(channel) - ElectricPotential::new::<volt>(1.5)) * 4.0
|
(self.read_tec_u_meas(channel) - ElectricPotential::new::<volt>(1.5)) * 4.0
|
||||||
}
|
}
|
||||||
|
|
||||||
fn set_pwm(&mut self, channel: usize, pin: PwmPin, duty: f64) -> f64 {
|
pub fn set_pwm(&mut self, channel: usize, pin: PwmPin, duty: f64) -> f64 {
|
||||||
fn set<P: hal::PwmPin<Duty=u16>>(pin: &mut P, duty: f64) -> f64 {
|
fn set<P: hal::PwmPin<Duty=u16>>(pin: &mut P, duty: f64) -> f64 {
|
||||||
let max = pin.get_max_duty();
|
let max = pin.get_max_duty();
|
||||||
let value = ((duty * (max as f64)) as u16).min(max);
|
let value = ((duty * (max as f64)) as u16).min(max);
|
||||||
|
@ -397,12 +405,16 @@ impl Channels {
|
||||||
set(&mut self.pwm.max_i_neg0, duty),
|
set(&mut self.pwm.max_i_neg0, duty),
|
||||||
(0, PwmPin::MaxV) =>
|
(0, PwmPin::MaxV) =>
|
||||||
set(&mut self.pwm.max_v0, duty),
|
set(&mut self.pwm.max_v0, duty),
|
||||||
|
(0, PwmPin::Fan) =>
|
||||||
|
set(&mut self.pwm.fan, duty),
|
||||||
(1, PwmPin::MaxIPos) =>
|
(1, PwmPin::MaxIPos) =>
|
||||||
set(&mut self.pwm.max_i_pos1, duty),
|
set(&mut self.pwm.max_i_pos1, duty),
|
||||||
(1, PwmPin::MaxINeg) =>
|
(1, PwmPin::MaxINeg) =>
|
||||||
set(&mut self.pwm.max_i_neg1, duty),
|
set(&mut self.pwm.max_i_neg1, duty),
|
||||||
(1, PwmPin::MaxV) =>
|
(1, PwmPin::MaxV) =>
|
||||||
set(&mut self.pwm.max_v1, duty),
|
set(&mut self.pwm.max_v1, duty),
|
||||||
|
(1, PwmPin::Fan) =>
|
||||||
|
set(&mut self.pwm.fan, duty),
|
||||||
_ =>
|
_ =>
|
||||||
unreachable!(),
|
unreachable!(),
|
||||||
}
|
}
|
||||||
|
@ -481,6 +493,8 @@ impl Channels {
|
||||||
max_v: (self.get_max_v(channel), ElectricPotential::new::<volt>(5.0)).into(),
|
max_v: (self.get_max_v(channel), ElectricPotential::new::<volt>(5.0)).into(),
|
||||||
max_i_pos: self.get_max_i_pos(channel).into(),
|
max_i_pos: self.get_max_i_pos(channel).into(),
|
||||||
max_i_neg: self.get_max_i_neg(channel).into(),
|
max_i_neg: self.get_max_i_neg(channel).into(),
|
||||||
|
tacho: self.get_pwm(0, PwmPin::Tacho),
|
||||||
|
fan: self.get_pwm(0, PwmPin::Fan),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -578,6 +592,8 @@ pub struct PwmSummary {
|
||||||
max_v: PwmSummaryField<ElectricPotential>,
|
max_v: PwmSummaryField<ElectricPotential>,
|
||||||
max_i_pos: PwmSummaryField<ElectricCurrent>,
|
max_i_pos: PwmSummaryField<ElectricCurrent>,
|
||||||
max_i_neg: PwmSummaryField<ElectricCurrent>,
|
max_i_neg: PwmSummaryField<ElectricCurrent>,
|
||||||
|
tacho: f64,
|
||||||
|
fan: f64,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Serialize)]
|
#[derive(Serialize)]
|
||||||
|
|
|
@ -199,6 +199,10 @@ impl Handler {
|
||||||
let current = ElectricCurrent::new::<ampere>(value);
|
let current = ElectricCurrent::new::<ampere>(value);
|
||||||
channels.set_max_i_neg(channel, current);
|
channels.set_max_i_neg(channel, current);
|
||||||
}
|
}
|
||||||
|
PwmPin::Tacho => {}
|
||||||
|
PwmPin::Fan => {
|
||||||
|
channels.set_pwm(channel, PwmPin::Fan, value);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
send_line(socket, b"{}");
|
send_line(socket, b"{}");
|
||||||
Ok(Handler::Handled)
|
Ok(Handler::Handled)
|
||||||
|
|
|
@ -127,6 +127,8 @@ pub enum PwmPin {
|
||||||
MaxIPos,
|
MaxIPos,
|
||||||
MaxINeg,
|
MaxINeg,
|
||||||
MaxV,
|
MaxV,
|
||||||
|
Tacho,
|
||||||
|
Fan
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
||||||
|
@ -299,7 +301,18 @@ fn pwm_setup(input: &[u8]) -> IResult<&[u8], Result<(PwmPin, f64), Error>> {
|
||||||
)
|
)
|
||||||
),
|
),
|
||||||
result_with_pin(PwmPin::MaxV)
|
result_with_pin(PwmPin::MaxV)
|
||||||
))
|
),
|
||||||
|
map(
|
||||||
|
preceded(
|
||||||
|
tag("fan"),
|
||||||
|
preceded(
|
||||||
|
whitespace,
|
||||||
|
float
|
||||||
|
)
|
||||||
|
),
|
||||||
|
result_with_pin(PwmPin::Fan)
|
||||||
|
)
|
||||||
|
)
|
||||||
)(input)
|
)(input)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -119,7 +119,7 @@ fn main() -> ! {
|
||||||
timer::setup(cp.SYST, clocks);
|
timer::setup(cp.SYST, clocks);
|
||||||
|
|
||||||
let (pins, mut leds, mut eeprom, eth_pins, usb) = Pins::setup(
|
let (pins, mut leds, mut eeprom, eth_pins, usb) = Pins::setup(
|
||||||
clocks, dp.TIM1, dp.TIM3,
|
clocks, dp.TIM1, dp.TIM3, dp.TIM8,
|
||||||
dp.GPIOA, dp.GPIOB, dp.GPIOC, dp.GPIOD, dp.GPIOE, dp.GPIOF, dp.GPIOG,
|
dp.GPIOA, dp.GPIOB, dp.GPIOC, dp.GPIOD, dp.GPIOE, dp.GPIOF, dp.GPIOG,
|
||||||
dp.I2C1,
|
dp.I2C1,
|
||||||
dp.SPI2, dp.SPI4, dp.SPI5,
|
dp.SPI2, dp.SPI4, dp.SPI5,
|
||||||
|
|
24
src/pins.rs
24
src/pins.rs
|
@ -23,7 +23,7 @@ use stm32f4xx_hal::{
|
||||||
I2C1,
|
I2C1,
|
||||||
OTG_FS_GLOBAL, OTG_FS_DEVICE, OTG_FS_PWRCLK,
|
OTG_FS_GLOBAL, OTG_FS_DEVICE, OTG_FS_PWRCLK,
|
||||||
SPI2, SPI4, SPI5,
|
SPI2, SPI4, SPI5,
|
||||||
TIM1, TIM3,
|
TIM1, TIM3, TIM8
|
||||||
},
|
},
|
||||||
timer::Timer,
|
timer::Timer,
|
||||||
time::U32Ext,
|
time::U32Ext,
|
||||||
|
@ -114,7 +114,7 @@ impl Pins {
|
||||||
/// Setup GPIO pins and configure MCU peripherals
|
/// Setup GPIO pins and configure MCU peripherals
|
||||||
pub fn setup(
|
pub fn setup(
|
||||||
clocks: Clocks,
|
clocks: Clocks,
|
||||||
tim1: TIM1, tim3: TIM3,
|
tim1: TIM1, tim3: TIM3, tim8: TIM8,
|
||||||
gpioa: GPIOA, gpiob: GPIOB, gpioc: GPIOC, gpiod: GPIOD, gpioe: GPIOE, gpiof: GPIOF, gpiog: GPIOG,
|
gpioa: GPIOA, gpiob: GPIOB, gpioc: GPIOC, gpiod: GPIOD, gpioe: GPIOE, gpiof: GPIOF, gpiog: GPIOG,
|
||||||
i2c1: I2C1,
|
i2c1: I2C1,
|
||||||
spi2: SPI2, spi4: SPI4, spi5: SPI5,
|
spi2: SPI2, spi4: SPI4, spi5: SPI5,
|
||||||
|
@ -135,10 +135,10 @@ impl Pins {
|
||||||
let pins_adc = Adc::adc1(adc1, true, Default::default());
|
let pins_adc = Adc::adc1(adc1, true, Default::default());
|
||||||
|
|
||||||
let pwm = PwmPins::setup(
|
let pwm = PwmPins::setup(
|
||||||
clocks, tim1, tim3,
|
clocks, tim1, tim3, tim8,
|
||||||
gpioc.pc6, gpioc.pc7,
|
gpioc.pc6, gpioc.pc7,
|
||||||
gpioe.pe9, gpioe.pe11,
|
gpioe.pe9, gpioe.pe11,
|
||||||
gpioe.pe13, gpioe.pe14
|
gpioe.pe13, gpioe.pe14, gpioc.pc8, gpioc.pc9
|
||||||
);
|
);
|
||||||
|
|
||||||
let (dac0_spi, dac0_sync) = Self::setup_dac0(
|
let (dac0_spi, dac0_sync) = Self::setup_dac0(
|
||||||
|
@ -283,19 +283,24 @@ pub struct PwmPins {
|
||||||
pub max_i_pos1: PwmChannels<TIM1, pwm::C2>,
|
pub max_i_pos1: PwmChannels<TIM1, pwm::C2>,
|
||||||
pub max_i_neg0: PwmChannels<TIM1, pwm::C3>,
|
pub max_i_neg0: PwmChannels<TIM1, pwm::C3>,
|
||||||
pub max_i_neg1: PwmChannels<TIM1, pwm::C4>,
|
pub max_i_neg1: PwmChannels<TIM1, pwm::C4>,
|
||||||
|
pub tacho: PwmChannels<TIM8, pwm::C3>,
|
||||||
|
pub fan: PwmChannels<TIM8, pwm::C4>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl PwmPins {
|
impl PwmPins {
|
||||||
fn setup<M1, M2, M3, M4, M5, M6>(
|
fn setup<M1, M2, M3, M4, M5, M6, M7, M8>(
|
||||||
clocks: Clocks,
|
clocks: Clocks,
|
||||||
tim1: TIM1,
|
tim1: TIM1,
|
||||||
tim3: TIM3,
|
tim3: TIM3,
|
||||||
|
tim8: TIM8,
|
||||||
max_v0: PC6<M1>,
|
max_v0: PC6<M1>,
|
||||||
max_v1: PC7<M2>,
|
max_v1: PC7<M2>,
|
||||||
max_i_pos0: PE9<M3>,
|
max_i_pos0: PE9<M3>,
|
||||||
max_i_pos1: PE11<M4>,
|
max_i_pos1: PE11<M4>,
|
||||||
max_i_neg0: PE13<M5>,
|
max_i_neg0: PE13<M5>,
|
||||||
max_i_neg1: PE14<M6>,
|
max_i_neg1: PE14<M6>,
|
||||||
|
tacho: PC8<M7>,
|
||||||
|
fan: PC9<M8>,
|
||||||
) -> PwmPins {
|
) -> PwmPins {
|
||||||
let freq = 20u32.khz();
|
let freq = 20u32.khz();
|
||||||
|
|
||||||
|
@ -312,6 +317,14 @@ impl PwmPins {
|
||||||
init_pwm_pin(&mut max_v0);
|
init_pwm_pin(&mut max_v0);
|
||||||
init_pwm_pin(&mut max_v1);
|
init_pwm_pin(&mut max_v1);
|
||||||
|
|
||||||
|
let channels = (
|
||||||
|
tacho.into_alternate(),
|
||||||
|
fan.into_alternate(),
|
||||||
|
);
|
||||||
|
let (mut tacho, mut fan) = Timer::new(tim8, &clocks).pwm(channels, freq);
|
||||||
|
init_pwm_pin(&mut tacho);
|
||||||
|
init_pwm_pin(&mut fan);
|
||||||
|
|
||||||
let channels = (
|
let channels = (
|
||||||
max_i_pos0.into_alternate(),
|
max_i_pos0.into_alternate(),
|
||||||
max_i_pos1.into_alternate(),
|
max_i_pos1.into_alternate(),
|
||||||
|
@ -329,6 +342,7 @@ impl PwmPins {
|
||||||
max_v0, max_v1,
|
max_v0, max_v1,
|
||||||
max_i_pos0, max_i_pos1,
|
max_i_pos0, max_i_pos1,
|
||||||
max_i_neg0, max_i_neg1,
|
max_i_neg0, max_i_neg1,
|
||||||
|
tacho, fan
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue