main: add NEC code transmission
This commit is contained in:
parent
536ca1f755
commit
e813e6bf46
93
main.c
93
main.c
|
@ -174,6 +174,82 @@ static void timer_ir_in(void)
|
||||||
IRM_ON_PORT->ODR.reg |= IRM_ON_PIN; // switch IR demodulator on
|
IRM_ON_PORT->ODR.reg |= IRM_ON_PIN; // switch IR demodulator on
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define TIM1_PERIOD 421U // 16E6/(0+1)/38000
|
||||||
|
|
||||||
|
// configure timer to transmit IR burst at 38 kHz
|
||||||
|
static void timer_ir_out(void)
|
||||||
|
{
|
||||||
|
IRM_ON_PORT->ODR.reg &= ~IRM_ON_PIN; // switch IR demodulator off
|
||||||
|
|
||||||
|
TIM1->CR1.reg = 0; // disable counter before reconfiguring it
|
||||||
|
TIM1->CCER1.reg = 0; // reset register
|
||||||
|
TIM1->CCER2.reg = 0; // reset register
|
||||||
|
TIM1->IER.reg = 0; // reset interrupts
|
||||||
|
TIM1->PSCRH.reg = 0; // set prescaler to get most precise 38 kHz
|
||||||
|
TIM1->PSCRL.reg = 0; // 16E6/(0+1)/65536 = down to 244 Hz
|
||||||
|
TIM1->ARRH.reg = (TIM1_PERIOD >> 8); // set auto-reload register for 38 kHz period
|
||||||
|
TIM1->ARRL.reg = (TIM1_PERIOD & 0xff); // 16E6/(0+1)/38000
|
||||||
|
TIM1->CCR4H.reg = (TIM1_PERIOD / 3) >> 8; // set duty cycle to 33%
|
||||||
|
TIM1->CCR4L.reg = (TIM1_PERIOD / 3 ) & 0xff; // set duty cycle to 33%
|
||||||
|
TIM1->CCMR4.output_fields.OC4M = 6; // set PWM1 mode
|
||||||
|
TIM1->CCMR4.output_fields.CC4S = 0; // use channel as output
|
||||||
|
TIM1->CCER2.fields.CC4E = 1; // enable channel output
|
||||||
|
TIM1->BKR.fields.MOE = 1; // enable outputs
|
||||||
|
TIM1->SR1.reg = 0; // clear all flags
|
||||||
|
TIM1->CNTRL.reg = 0; // reset counter
|
||||||
|
TIM1->CNTRH.reg = 0; // reset counter
|
||||||
|
TIM1->CR1.fields.OPM = 1; // send one pulse at a time
|
||||||
|
TIM1->EGR.fields.UG = 1; // transfer all registers
|
||||||
|
// don't enable timer yet
|
||||||
|
}
|
||||||
|
|
||||||
|
// transmit IR pulses
|
||||||
|
static void nec_pulse(uint16_t pulses, bool mark)
|
||||||
|
{
|
||||||
|
if (mark) {
|
||||||
|
TIM1->CCR4H.reg = (TIM1_PERIOD / 3) >> 8; // set duty cycle to 33%
|
||||||
|
TIM1->CCR4L.reg = (TIM1_PERIOD / 3 ) & 0xff; // set duty cycle to 33%
|
||||||
|
} else {
|
||||||
|
TIM1->CCR4H.reg = 0; // set duty cycle to 0%
|
||||||
|
TIM1->CCR4L.reg = 0; // set duty cycle to 0%
|
||||||
|
}
|
||||||
|
while (pulses--) {
|
||||||
|
TIM1->CR1.fields.CEN = 1; // enable counter to start PWM for 1 pulse
|
||||||
|
while (TIM1->CR1.fields.CEN); // wait until pulse completes
|
||||||
|
}
|
||||||
|
// ensure we are off at the end
|
||||||
|
TIM1->CCR4H.reg = 0; // set duty cycle to 0%
|
||||||
|
TIM1->CCR4L.reg = 0; // set duty cycle to 0%
|
||||||
|
}
|
||||||
|
|
||||||
|
// transmit 4 byte NEC code over IR (LSb first)
|
||||||
|
static void nec_transmit(uint32_t code)
|
||||||
|
{
|
||||||
|
if (NULL == code) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
timer_ir_out(); // configure to transmit pulses
|
||||||
|
sim(); // disable interrupts to keep timings tight
|
||||||
|
// all time are hand tuned
|
||||||
|
nec_pulse(333, true); // send AGC burst, 9 ms
|
||||||
|
nec_pulse(166, false); // AGC space, 4.5 ms
|
||||||
|
// transmit bits
|
||||||
|
for (uint8_t i = 0; i < 32; i++) {
|
||||||
|
nec_pulse(21, true); // bit burst, 560 us
|
||||||
|
if (code & 0x1) {
|
||||||
|
nec_pulse(61, false); // bit space, 2.25 ms - 560 us
|
||||||
|
} else {
|
||||||
|
nec_pulse(21, false); // bit space, 1.12 ms - 560 us
|
||||||
|
}
|
||||||
|
code >>= 1; // go to next bit
|
||||||
|
}
|
||||||
|
nec_pulse(22, true); // end pulse, 560 us
|
||||||
|
rim(); // re-enable interrupts
|
||||||
|
|
||||||
|
timer_ir_in(); // go back to IR capture
|
||||||
|
}
|
||||||
|
|
||||||
void main(void)
|
void main(void)
|
||||||
{
|
{
|
||||||
sim(); // disable interrupts (while we reconfigure them)
|
sim(); // disable interrupts (while we reconfigure them)
|
||||||
|
@ -265,23 +341,6 @@ void main(void)
|
||||||
TIM4->CR1.fields.URS = 1; // only update on overflow
|
TIM4->CR1.fields.URS = 1; // only update on overflow
|
||||||
TIM4->CR1.fields.CEN = 1; // enable counter
|
TIM4->CR1.fields.CEN = 1; // enable counter
|
||||||
|
|
||||||
/*
|
|
||||||
// configure timer to modulate IR LEDs at 38 kHz
|
|
||||||
TIM1->PSCRH.reg = 0; // set prescaler to get most precise 38 kHz
|
|
||||||
TIM1->PSCRL.reg = 0; // 16E6/(0+1)/65536 = down to 244 Hz
|
|
||||||
#define TIM1_PERIOD 421U // 16E6/(0+1)/38000
|
|
||||||
TIM1->ARRH.reg = (TIM1_PERIOD >> 8); // set auto-reload register for 38 kHz period
|
|
||||||
TIM1->ARRL.reg = (TIM1_PERIOD & 0xff); // 16E6/(0+1)/38000
|
|
||||||
TIM1->CCR4H.reg = (TIM1_PERIOD / 3) >> 8; // set duty cycle to 33%
|
|
||||||
TIM1->CCR4L.reg = (TIM1_PERIOD / 3 ) & 0xff; // set duty cycle to 33%
|
|
||||||
TIM1->CCMR4.output_fields.OC4M = 6; // set PWM1 mode
|
|
||||||
TIM1->CCMR4.output_fields.CC4S = 0; // use channel as output
|
|
||||||
TIM1->CCER2.fields.CC4E = 1; // enable channel output
|
|
||||||
TIM1->BKR.fields.MOE = 1; // enable outputs
|
|
||||||
TIM1->EGR.fields.UG = 1; // transfer all registers
|
|
||||||
TIM1->CR1.fields.CEN = 1; // enable counter to start PWM
|
|
||||||
*/
|
|
||||||
|
|
||||||
// configure timer to receive IR message
|
// configure timer to receive IR message
|
||||||
timer_ir_in();
|
timer_ir_in();
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue