main: put IR capture in function

This commit is contained in:
King Kévin 2022-10-12 17:36:04 +02:00
parent b493d982ad
commit 536ca1f755
1 changed files with 36 additions and 31 deletions

67
main.c
View File

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