Support fan PWM settings #73

Merged
sb10q merged 16 commits from esavkin/thermostat:69-fan_pwm into master 2023-03-22 17:15:49 +08:00
5 changed files with 55 additions and 8 deletions
Showing only changes of commit 30350a3651 - Show all commits

View File

@ -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)]

View File

@ -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)

View File

@ -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)
} }

View File

@ -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,

View File

@ -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
} }
} }
} }