@@ -8,23 +8,18 @@ mod utils;
88
99mod common;
1010
11- use core:: ops:: Sub ;
12-
13- use fugit:: { ExtU32 , HertzU32 , MicrosDurationU32 } ;
11+ use fugit:: HertzU32 ;
1412use stm32_hrtim:: compare_register:: HrCompareRegister ;
1513use stm32_hrtim:: control:: HrPwmControl ;
1614use stm32_hrtim:: external_event:: { self , ExternalEventSource , ToExternalEventSource } ;
1715use stm32_hrtim:: output:: HrOut1 ;
1816use stm32_hrtim:: pac:: HRTIM_TIMA ;
1917use stm32_hrtim:: timer_eev_cfg:: { EevCfg , EevCfgs , EventFilter } ;
20- use stm32_hrtim:: {
21- DacResetOnCounterReset , DacStepOnCmp2 , HrParts , HrPwmAdvExt , HrtimPrescaler , Pscl128 ,
22- } ;
23- use stm32g4xx_hal:: adc:: { self , AdcClaim , AdcCommonExt } ;
18+ use stm32_hrtim:: { DacResetOnCounterReset , DacStepOnCmp2 , HrParts , HrPwmAdvExt , HrtimPrescaler } ;
2419use stm32g4xx_hal:: comparator:: { self , Comparator , ComparatorExt , ComparatorSplit } ;
2520use stm32g4xx_hal:: dac:: { self , DacExt , DacOut , SawtoothConfig } ;
2621use stm32g4xx_hal:: delay:: { self , SYSTDelayExt } ;
27- use stm32g4xx_hal:: gpio:: { self , GpioExt } ;
22+ use stm32g4xx_hal:: gpio:: GpioExt ;
2823use stm32g4xx_hal:: hrtim:: external_event:: EevInputExt ;
2924use stm32g4xx_hal:: hrtim:: { HrControltExt , HrPwmBuilderExt } ;
3025use stm32g4xx_hal:: pwr:: PwrExt ;
@@ -36,29 +31,15 @@ use stm32g4xx_hal::stasis::{Freeze, Frozen};
3631
3732pub const F_SYS : HertzU32 = HertzU32 :: MHz ( 120 ) ;
3833pub const CYCLES_PER_US : u32 = F_SYS . raw ( ) / 1_000_000 ;
39- type Timer = crate :: common:: Timer < CYCLES_PER_US > ;
40-
41- pub fn enable_timer ( cp : & mut stm32:: CorePeripherals ) {
42- cp. DCB . enable_trace ( ) ;
43- cp. DWT . enable_cycle_counter ( ) ;
44- }
45-
46- pub fn now ( ) -> MicrosDurationU32 {
47- ( stm32:: DWT :: cycle_count ( ) / CYCLES_PER_US ) . micros ( )
48- }
34+ //type Timer = crate::common::Timer<CYCLES_PER_US>;
4935
5036#[ embedded_test:: tests]
5137mod tests {
52- use fugit :: ExtU32 ;
38+ use embedded_hal :: delay :: DelayNs ;
5339 use stm32_hrtim:: {
54- compare_register:: HrCompareRegister , output:: HrOutput , timer:: HrTimer , HrtimPrescaler ,
55- Pscl128 ,
56- } ;
57- use stm32g4xx_hal:: { dac:: DacOut , stm32:: GPIOA } ;
58-
59- use crate :: {
60- abs_diff, common:: { await_hi, await_lo} , now, F_SYS
40+ compare_register:: HrCompareRegister , output:: HrOutput , timer:: HrTimer , Pscl128 ,
6141 } ;
42+ use stm32g4xx_hal:: dac:: DacOut ;
6243
6344 /// | \
6445 /// | \
@@ -70,13 +51,10 @@ mod tests {
7051 ///
7152 #[ test]
7253 fn hrtim_slope_compensated ( ) {
73- type Prescaler = Pscl128 ;
74- type Us = fugit:: Duration < u32 , 1 , 1000_000 > ;
75-
7654 let prescaler = Pscl128 ;
7755 let period = 0xFFFF ;
78- let dac_step_per_trigger = 550 ;
79- let cr2_ticks_per_dac_trigger = 1024 ;
56+ let dac_step_per_trigger = 16 ;
57+ let cr2_ticks_per_dac_trigger = dac_step_per_trigger ;
8058
8159 let crate :: Peripherals {
8260 mut hrtimer,
@@ -85,130 +63,84 @@ mod tests {
8563 comp,
8664 mut value_dac,
8765 mut ref_dac,
88- adc,
89- pa2,
90- rcc,
91- delay,
92- timer
66+ mut delay,
67+ ..
9368 } = super :: setup (
9469 prescaler,
9570 period,
9671 dac_step_per_trigger,
9772 cr2_ticks_per_dac_trigger,
9873 ) ;
99- let pin_num = 8 ;
10074
10175 hrtimer. cr1 . set_duty ( period / 10 ) ; // Set blanking window to give the ref_dac time to reset
102- //out.enable_rst_event(&cr1); // Set low on compare match with cr1
76+ //out.enable_rst_event(&cr1); // Set low on compare match with cr1
10377 hrtimer. out . enable_rst_event ( & eev_input4) ; // Set low on compare match with cr1
10478 hrtimer. out . enable_set_event ( & hrtimer. timer ) ; // Set high at new period
10579
106- hrtimer. out . enable ( ) ;
107- hrtimer. timer . start ( & mut hr_control. control ) ;
108-
109- defmt:: println!( "state: {}" , hrtimer. out. get_state( ) ) ;
110-
111- //out.enable_rst_event(&eev_input4);
112-
113- let gpioa = unsafe { & * GPIOA :: PTR } ;
114- let f_pwm = ( F_SYS * 32 ) / ( Prescaler :: VALUE as u32 * period as u32 ) ;
115- let period_duration: Us = f_pwm. into_duration ( ) ;
116- defmt:: println!( "period_duration: {}" , period_duration) ;
117- let timeout: Us = 2 * period_duration;
118-
11980 ref_dac. set_value ( 4095 ) ;
12081 value_dac. set_value ( 2048 ) ;
12182
122- loop {
123- let out = comp. output ( ) ;
124- let ref_dac = ref_dac. get_value ( ) ;
125- let value_dac = value_dac. get_value ( ) ;
126- let cnt = hrtimer. timer . get_counter_value ( ) ;
127- defmt:: println!(
128- "out: {}, ref: {}, val: {}, cnt: {}" ,
129- out,
130- ref_dac,
131- value_dac,
132- cnt
133- ) ;
134- }
135-
136- // TODO: My device seems to have quite a bit of offset error on ref_dac DAC3CH1
137- for s_ref in 4 ..=255 {
138- let s_ref = s_ref << 4 ; // Convert from 8 to 12 bits
139- if s_ref & 0xFF == 0 {
140- defmt:: println!( "{}/{}..." , s_ref, 4095 ) ;
141- }
142-
143- ref_dac. set_value ( s_ref) ;
144- for s_value in 0 ..=255 {
145- let s_value = s_value << 4 ; // Convert from 8 to 12 bits
146-
147- let value_dac_as_u16: u16 = s_value << 4 ; // Convert from 12 to 16 bits
148- let expected_duty = value_dac_as_u16. saturating_sub ( s_ref) ;
149- let expected_pw = ( timeout * u32:: from ( expected_duty) ) / u32:: from ( period) ;
150-
151- defmt:: debug!( "Awaiting first rising edge..." ) ;
152- value_dac. set_value ( s_value) ;
153- loop {
154- let out = comp. output ( ) ;
155- defmt:: println!( "out: {}" , out) ;
156- }
157- let duration_until_lo = await_lo ( & timer, pin_num, timeout) . unwrap ( ) ;
158- let first_lo_duration = await_hi ( & timer, pin_num, timeout) ;
83+ hrtimer. timer . start ( & mut hr_control. control ) ;
15984
160- let ( period, duty) = match first_lo_duration {
161- Ok ( lo_duration) => {
162- let duty = await_lo ( & timer, pin_num, timeout) . unwrap ( ) ;
163- let period = lo_duration + duty;
164- ( period, duty)
165- }
166- Err ( _) => ( timeout, 0u32 . micros ( ) ) ,
167- } ;
85+ // Await first dac rst trigger
86+ while ref_dac. get_value ( ) == 0 { }
16887
169- let duty_tolerance: Us = 20 . micros ( ) ;
170- let period_tolerance: Us = 20 . micros ( ) ;
88+ hrtimer. out . enable ( ) ;
17189
90+ for i in 0 ..10 {
91+ let mut last_cnt = 0 ;
92+ while hrtimer. timer . get_counter_value ( ) < dac_step_per_trigger { }
93+ loop {
17294 let out = comp. output ( ) ;
173- assert ! (
174- abs_diff( expected_pw, duty) < duty_tolerance,
175- "expected_duty: {}, duty: {}" ,
176- expected_duty,
177- duty,
178- ) ;
179- assert ! (
180- abs_diff( period_duration, period) < period_tolerance,
181- "timeout: {}, period: {}" ,
182- period_duration,
183- period,
184- ) ;
95+ let ref_dac = ref_dac. get_value ( ) ;
96+ let inv_ref_dac = 4095 - ref_dac;
97+ let value_dac = value_dac. get_value ( ) ;
98+ let cnt = hrtimer. timer . get_counter_value ( ) ;
99+ if cnt < last_cnt {
100+ // New period
101+ break ;
102+ }
103+ last_cnt = cnt;
104+ let count_as_12bit = cnt >> 4 ;
105+ let range = count_as_12bit. saturating_sub ( dac_step_per_trigger)
106+ ..=count_as_12bit. saturating_add ( dac_step_per_trigger) ;
107+ if !range. contains ( & inv_ref_dac) {
108+ defmt:: error!(
109+ "-: {}, +: {}, out: {}, count_as_12bit: {}, i: {}, inv_ref_dac: {}" ,
110+ ref_dac,
111+ value_dac,
112+ out as u8 ,
113+ count_as_12bit,
114+ i,
115+ inv_ref_dac
116+ ) ;
117+ delay. delay_ms ( 20 ) ;
118+
119+ panic ! ( ) ;
120+ }
185121 }
186122 }
187123 }
188124}
189125
190- fn abs_diff < T : Ord + Sub + Copy > ( a : T , b : T ) -> T :: Output {
191- a. max ( b) - a. min ( b)
192- }
193-
194- /// Vrefint = 1.212V typical
195- /// Vref+ = 3.3V for nucleo
196- /// 1.212V/3.3V*4095 = 1504 adc value
197- const VREF_ADC_BITS : u16 = 1504 ;
198-
199126struct Peripherals < PSCL > {
200- hrtimer :
201- HrParts < HRTIM_TIMA , PSCL , HrOut1 < HRTIM_TIMA , PSCL , DacResetOnCounterReset , DacStepOnCmp2 > , DacResetOnCounterReset , DacStepOnCmp2 > ,
127+ hrtimer : HrParts <
128+ HRTIM_TIMA ,
129+ PSCL ,
130+ HrOut1 < HRTIM_TIMA , PSCL , DacResetOnCounterReset , DacStepOnCmp2 > ,
131+ DacResetOnCounterReset ,
132+ DacStepOnCmp2 ,
133+ > ,
202134 hr_control : HrPwmControl ,
203135 eev_input4 : ExternalEventSource < 4 , false > ,
204136 comp : Comparator < comparator:: COMP1 , comparator:: Enabled > ,
205137 value_dac : dac:: Dac1Ch1 < { dac:: M_EXT_PIN } , dac:: Enabled > ,
206138 ref_dac : Frozen < dac:: Dac3Ch1 < { dac:: M_INT_SIG } , dac:: SawtoothGenerator > , 1 > ,
207- adc : adc:: Adc < stm32:: ADC1 , adc:: Disabled > ,
208- pa2 : gpio:: gpioa:: PA2 < gpio:: Analog > ,
209- rcc : rcc:: Rcc ,
139+ // adc: adc::Adc<stm32::ADC1, adc::Disabled>,
140+ // pa2: gpio::gpioa::PA2<gpio::Analog>,
141+ // rcc: rcc::Rcc,
210142 delay : delay:: SystDelay ,
211- timer : Timer ,
143+ // timer: Timer,
212144}
213145
214146fn setup < PSCL : HrtimPrescaler > (
@@ -221,9 +153,9 @@ fn setup<PSCL: HrtimPrescaler>(
221153 //DAC1_OUT1 PA4 -> A2
222154
223155 // TODO: Is it ok to steal these?
224- let mut cp = stm32:: CorePeripherals :: take ( ) . unwrap ( ) ;
156+ let cp = stm32:: CorePeripherals :: take ( ) . unwrap ( ) ;
225157 let dp = stm32:: Peripherals :: take ( ) . unwrap ( ) ;
226- let timer = Timer :: enable_timer ( & mut cp) ;
158+ // let timer = Timer::enable_timer(&mut cp);
227159 // Set system frequency to 16MHz * 15/1/2 = 120MHz
228160 // This would lead to HrTim running at 120MHz * 32 = 3.84...
229161 defmt:: info!( "rcc" ) ;
@@ -240,20 +172,19 @@ fn setup<PSCL: HrtimPrescaler>(
240172 pwr,
241173 ) ;
242174 assert_eq ! ( rcc. clocks. sys_clk, F_SYS ) ;
243- enable_timer ( & mut cp) ;
244175 let mut delay = cp. SYST . delay ( & rcc. clocks ) ;
245176
246- let adc12_common = dp
247- . ADC12_COMMON
248- . claim ( adc:: config:: ClockMode :: AdcHclkDiv4 , & mut rcc) ;
249- let adc = adc12_common. claim ( dp. ADC1 , & mut delay) ;
177+ // let adc12_common = dp
178+ // .ADC12_COMMON
179+ // .claim(adc::config::ClockMode::AdcHclkDiv4, &mut rcc);
180+ // let adc = adc12_common.claim(dp.ADC1, &mut delay);
250181
251182 let gpioa = dp. GPIOA . split ( & mut rcc) ;
252183 let pa1 = gpioa. pa1 . into_analog ( ) ;
253- let pa2 = gpioa. pa2 . into_analog ( ) ;
184+ // let pa2 = gpioa.pa2.into_analog();
254185 let pa4 = gpioa. pa4 . into_analog ( ) ;
255186 let pa8 = gpioa. pa8 ;
256- let pa9 = gpioa. pa9 ;
187+ // let pa9 = gpioa.pa9;
257188
258189 let dac1ch1 = dp. DAC1 . constrain ( pa4, & mut rcc) ;
259190 let dac3ch1 = dp. DAC3 . constrain ( dac:: Dac3IntSig1 , & mut rcc) ;
@@ -265,7 +196,6 @@ fn setup<PSCL: HrtimPrescaler>(
265196 let ( comp, ..) = dp. COMP . split ( & mut rcc) ;
266197
267198 type Comparator = comparator:: Comparator < comparator:: COMP1 , comparator:: Enabled > ;
268- type Prescaler = Pscl128 ;
269199
270200 let ( mut hr_control, _, eev_inputs) =
271201 dp. HRTIM_COMMON . hr_control ( & mut rcc) . wait_for_calibration ( ) ;
@@ -286,7 +216,13 @@ fn setup<PSCL: HrtimPrescaler>(
286216 let mut hr_control = hr_control. constrain ( ) ;
287217 let eev_cfgs =
288218 EevCfgs :: default ( ) . eev4 ( EevCfg :: default ( ) . filter ( EventFilter :: BlankingResetToCmp1 ) ) ;
289- let mut hrtimer: HrParts < _ , PSCL , HrOut1 < _ , PSCL , DacResetOnCounterReset , DacStepOnCmp2 > , DacResetOnCounterReset , DacStepOnCmp2 > = dp
219+ let mut hrtimer: HrParts <
220+ _ ,
221+ PSCL ,
222+ HrOut1 < _ , PSCL , DacResetOnCounterReset , DacStepOnCmp2 > ,
223+ DacResetOnCounterReset ,
224+ DacStepOnCmp2 ,
225+ > = dp
290226 . HRTIM_TIMA
291227 . pwm_advanced ( pa8)
292228 . prescaler ( prescaler)
@@ -318,10 +254,65 @@ fn setup<PSCL: HrtimPrescaler>(
318254 comp,
319255 value_dac,
320256 ref_dac,
321- adc,
322- pa2,
323- rcc,
257+ // adc,
258+ // pa2,
259+ // rcc,
324260 delay,
325- timer,
261+ //timer,
262+ }
263+ }
264+ /*
265+ fn foo() {
266+ // TODO: My device seems to have quite a bit of offset error on ref_dac DAC3CH1
267+ for s_ref in 4..=255 {
268+ let s_ref = s_ref << 4; // Convert from 8 to 12 bits
269+ if s_ref & 0xFF == 0 {
270+ defmt::println!("{}/{}...", s_ref, 4095);
271+ }
272+
273+ ref_dac.set_value(s_ref);
274+ for s_value in 0..=255 {
275+ let s_value = s_value << 4; // Convert from 8 to 12 bits
276+
277+ let value_dac_as_u16: u16 = s_value << 4; // Convert from 12 to 16 bits
278+ let expected_duty = value_dac_as_u16.saturating_sub(s_ref);
279+ let expected_pw = (timeout * u32::from(expected_duty)) / u32::from(period);
280+
281+ defmt::debug!("Awaiting first rising edge...");
282+ value_dac.set_value(s_value);
283+ loop {
284+ let out = comp.output();
285+ defmt::println!("out: {}", out);
286+ }
287+ let duration_until_lo = await_lo(&timer, pin_num, timeout).unwrap();
288+ let first_lo_duration = await_hi(&timer, pin_num, timeout);
289+
290+ let (period, duty) = match first_lo_duration {
291+ Ok(lo_duration) => {
292+ let duty = await_lo(&timer, pin_num, timeout).unwrap();
293+ let period = lo_duration + duty;
294+ (period, duty)
295+ }
296+ Err(_) => (timeout, 0u32.micros()),
297+ };
298+
299+ let duty_tolerance: Us = 20.micros();
300+ let period_tolerance: Us = 20.micros();
301+
302+ let out = comp.output();
303+ assert!(
304+ abs_diff(expected_pw, duty) < duty_tolerance,
305+ "expected_duty: {}, duty: {}",
306+ expected_duty,
307+ duty,
308+ );
309+ assert!(
310+ abs_diff(period_duration, period) < period_tolerance,
311+ "timeout: {}, period: {}",
312+ period_duration,
313+ period,
314+ );
315+ }
326316 }
327317}
318+ */
0 commit comments