From 536ca1f755c934a19fd7343ca4b636ad60deca7a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?King=20K=C3=A9vin?= Date: Wed, 12 Oct 2022 17:36:04 +0200 Subject: [PATCH] main: put IR capture in function --- main.c | 67 +++++++++++++++++++++++++++++++--------------------------- 1 file changed, 36 insertions(+), 31 deletions(-) diff --git a/main.c b/main.c index a46ecd8..cb01af4 100644 --- a/main.c +++ b/main.c @@ -140,6 +140,40 @@ void led_blue(uint16_t bightness) TIM2->CCR1L.reg = (bightness >> 0); // set duty cycle } +// configure timer to capture IR NEC codes +static void timer_ir_in(void) +{ + TIM1->CR1.reg = 0; // disable counter before reconfiguring it + TIM1->IER.reg = 0; // reset interrupts + TIM1->BKR.reg = 0; // reset register + TIM1->CCER1.reg = 0; // reset register + TIM1->CCER2.reg = 0; // reset register + TIM1->PSCRH.reg = 0; // set prescaler to get most precise 9+4.5 ms + TIM1->PSCRL.reg = 3; // 16E6/(3+1)/65536 = up to 16 ms + TIM1->ARRH.reg = 0xff; // let it count to the end + TIM1->ARRL.reg = 0xff; // an overflow means the signal is corrupted + TIM1->CCMR1.input_fields.CC1S = 1; // configure channel as input and map CH1 to TI1FP1 + TIM1->CCER1.fields.CC1P = 1; // trigger on a low level or falling edge of TI1F + TIM1->CCMR2.input_fields.CC2S = 2; // configure channel as input and map CH2 to TI1FP2 + TIM1->CCER1.fields.CC2P = 0; // trigger on a high level or rising edge of TI1F + TIM1->SMCR.fields.TS = 5; // set trigger to filtered timer input 1 (TI1FP1) + // don't filter the external trigger + TIM1->SMCR.fields.SMS = 4; // reset on trigger + TIM1->CCER1.fields.CC1E = 1; // enable channel 1 for input capture + TIM1->CCER1.fields.CC2E = 1; // enable channel 2 for input capture + TIM1->IER.fields.CC1IE = 1; // enable interrupt for channel + TIM1->IER.fields.CC2IE = 1; // enable interrupt for channel + TIM1->IER.fields.UIE = 1; // enable update interrupt + TIM1->CR1.fields.URS = 1; // only update on overflow + TIM1->SR1.reg = 0; // clear all flags + TIM1->CNTRL.reg = 0; // reset counter + TIM1->CNTRH.reg = 0; // reset counter + TIM1->EGR.fields.UG = 1; // transfer all registers + TIM1->CR1.fields.CEN = 1; // enable counter to start capture + nec_bit = -2; // invalidate current packet + IRM_ON_PORT->ODR.reg |= IRM_ON_PIN; // switch IR demodulator on +} + void main(void) { sim(); // disable interrupts (while we reconfigure them) @@ -176,7 +210,6 @@ void main(void) // configure IR demodulator pin IRM_ON_PORT->ODR.reg &= ~IRM_ON_PIN; // switch IR demodulator off - IRM_ON_PORT->ODR.reg |= IRM_ON_PIN; // switch IR demodulator on IRM_ON_PORT->CR1.reg |= IRM_ON_PIN; // use as push-pull IRM_ON_PORT->DDR.reg |= IRM_ON_PIN; // switch pin to output @@ -212,13 +245,6 @@ void main(void) TIM2->EGR.fields.UG = 1; // transfer all registers TIM2->CR1.fields.CEN = 1; // enable counter to start PWM -/* - // configure IR LED - LED_IR_PORT->ODR.reg &= ~LED_IR_PIN; // switch LED off - LED_IR_PORT->CR1.reg |= LED_IR_PIN; // use as push-pull - LED_IR_PORT->DDR.reg |= LED_IR_PIN; // use pin to output -*/ - // configure UV LED LED_UV_PORT->ODR.reg &= ~LED_UV_PIN; // switch LED off LED_UV_PORT->CR1.reg |= LED_UV_PIN; // use as push-pull @@ -257,29 +283,7 @@ void main(void) */ // configure timer to receive IR message - TIM1->CR1.fields.CEN = 0; // disable counter before reconfiguring it - TIM1->PSCRH.reg = 0; // set prescaler to get most precise 9+4.5 ms - TIM1->PSCRL.reg = 3; // 16E6/(3+1)/65536 = up to 16 ms - TIM1->ARRH.reg = 0xff; // let it count to the end - TIM1->ARRL.reg = 0xff; // an overflow means the signal is corrupted - TIM1->CCMR1.input_fields.CC1S = 1; // configure channel as input and map CH1 to TI1FP1 - TIM1->CCER1.fields.CC1P = 1; // trigger on a low level or falling edge of TI1F - TIM1->CCMR2.input_fields.CC2S = 2; // configure channel as input and map CH2 to TI1FP2 - TIM1->CCER1.fields.CC2P = 0; // trigger on a high level or rising edge of TI1F - TIM1->SMCR.fields.TS = 5; // set trigger to filtered timer input 1 (TI1FP1) - // don't filter the external trigger - TIM1->SMCR.fields.SMS = 4; // reset on trigger - TIM1->CCER1.fields.CC1E = 1; // enable channel 1 for input capture - TIM1->CCER1.fields.CC2E = 1; // enable channel 2 for input capture - TIM1->CCER2.fields.CC3E = 0; // ensure other channel is not used - TIM1->CCER2.fields.CC4E = 0; // ensure other channel is not used - TIM1->IER.fields.CC1IE = 1; // enable interrupt for channel - TIM1->IER.fields.CC2IE = 1; // enable interrupt for channel - TIM1->IER.fields.UIE = 1; // enable update interrupt - TIM1->CR1.fields.URS = 1; // only update on overflow - TIM1->SR1.reg = 0; // clear all flags - TIM1->EGR.fields.UG = 1; // transfer all registers - TIM1->CR1.fields.CEN = 1; // enable counter to start capture + timer_ir_in(); /* don't use the AWU, else it will cause an active-halt instead of halt, using more power // configure auto-wakeup (AWU) to be able to refresh the watchdog @@ -346,6 +350,7 @@ void main(void) puts("rest\r\n"); time_count = 0; // reset counter LED_UV_PORT->ODR.reg &= ~LED_UV_PIN; // switch UV LED off + IRM_ON_PORT->ODR.reg &= ~IRM_ON_PIN; // switch IR demodulator off led_red(0); // ensure LED is off led_green(0); // ensure LED is off led_blue(0); // ensure LED is off