// Transmission timing and Trailer detection ISR_COMPARE() { if (IrCtrl.state == IR_XMITTING) { if (IrCtrl.tx_index >= IrCtrl.len) { // tx successfully finished IR_TX_OFF(); IR_state( IR_IDLE ); return; } uint16_t interval = IrCtrl.next_interval; if (IR_TX_IS_ON()) { // toggle IR_TX_OFF(); } else { if ( IrCtrl.next_interval != 0 ) { // toggle IR_TX_ON(); } else { // 65535,0,XXXX sequence means: // continue TX_OFF for 65535 + XXXX interval and turn TX_ON interval = IR_get(); IrCtrl.tx_index ++; } } IR_COMPARE_NEXT( interval ); // run heavy packer.unpack after setting timer IrCtrl.next_interval = IR_get(); IrCtrl.tx_index ++; return; } else if (IrCtrl.state == IR_RECVING) { IrCtrl.trailer_count --; if (IrCtrl.trailer_count == 0) { // Trailer detected IR_state( IR_RECVED ); } else { // wait for next compare interrupt } return; } IR_state( IR_IDLE ); }
void IR_state (uint8_t nextState) { switch (nextState) { case IR_IDLE: IR_TX_OFF(); IR_COMPARE_DISABLE(); // 1st interrupt when receiving ir must be falling edge IR_CAPTURE_FALL(); IR_CAPTURE_ENABLE(); IR_clear(); break; case IR_RECVING: IR_clear(); TIMER_START( IrCtrl.recv_timer, RECV_TIMEOUT ); break; case IR_RECVED: TIMER_STOP( IrCtrl.recv_timer ); irpacker_packend( &packer_state ); // disable til IRKit.cpp reports IR data to server IR_CAPTURE_DISABLE(); IR_COMPARE_DISABLE(); if (IrCtrl.len < VALID_IR_LEN_MIN) { // received, but probably noise IR_state( IR_IDLE ); return; } break; case IR_RECVED_IDLE: // holds received IR data, and ready to receive next IR_CAPTURE_FALL(); IR_CAPTURE_ENABLE(); break; case IR_READING: irpacker_unpack_start( &packer_state ); IR_CAPTURE_DISABLE(); IR_COMPARE_DISABLE(); break; case IR_WRITING: IR_CAPTURE_DISABLE(); IR_COMPARE_DISABLE(); IR_clear(); break; case IR_XMITTING: IR_CAPTURE_DISABLE(); IR_COMPARE_DISABLE(); IrCtrl.tx_index = 0; TIMER_START( IrCtrl.xmit_timer, XMIT_TIMEOUT ); break; case IR_DISABLED: IR_CAPTURE_DISABLE(); IR_COMPARE_DISABLE(); break; } IrCtrl.state = nextState; }
ISR_COMPARE() { uint8_t st = IrCtrl.state; #if IR_USE_XMIT uint8_t i, d, f = IrCtrl.fmt; uint16_t w; if (st == IR_XMITING) { if (IR_TX_TEST()) /* End of mark? */ { IR_TX_OFF(); /* Stop burst */ i = IrCtrl.phase; if (i < IrCtrl.len) /* Is there a bit to be sent? */ { if (IR_USE_SONY && (f & SONY)) { w = T_SONY; } else { i /= 8; d = IrCtrl.buff[i]; if (IR_USE_AEHA && (f & AEHA)) w = (d & 1) ? T_AEHA * 3 : T_AEHA; else w = (d & 1) ? T_NEC * 3 : T_NEC; IrCtrl.buff[i] = d >> 1; } IR_COMP_NEXT(w); return; } } else { IR_TX_ON(); /* Start burst */ i = ++IrCtrl.phase / 8; if (IR_USE_SONY && (f & SONY)) { d = IrCtrl.buff[i]; w = (d & 1) ? T_SONY * 2 : T_SONY; IrCtrl.buff[i] = d >> 1; } else {