Ejemplo n.º 1
0
// 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 );
}
Ejemplo n.º 2
0
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;
}
Ejemplo n.º 3
0
static int8_t on_get_messages_response(int8_t cid, uint16_t status_code, GSwifi::GSREQUESTSTATE state) {
    HTTPLOG_PRINT(P("< G /m ")); HTTPLOG_PRINTLN(status_code);

    if (status_code != 200) {
        gs.bufferClear();
    }

    switch (status_code) {
    case 200:
        while (! gs.bufferEmpty()) {
            char letter = gs.bufferGet();

            parse_json( letter );
        }

        if (state == GSwifi::GSREQUESTSTATE_RECEIVED) {
            // should not be WRITING here, should be XMITTING or IDLE (xmit finished)
            if (IrCtrl.state == IR_WRITING) {
                // prevent from locking in WRITING state forever
                IR_state( IR_IDLE );
            }

            ring_put( &commands, COMMAND_CLOSE );
            ring_put( &commands, cid );
            if ((polling_cid == cid) || (polling_cid == CID_UNDEFINED)) {
                polling_cid = CID_UNDEFINED;
                ring_put( &commands, COMMAND_START_POLLING );
            }
            // if polling_cid != cid
            // there's already an ongoing polling request, so request again when that one finishes
        }
        break;
    case HTTP_STATUSCODE_CLIENT_TIMEOUT:
        polling_cid = CID_UNDEFINED;
        ring_put( &commands, COMMAND_CLOSE );
        ring_put( &commands, cid );
        irkit_httpclient_start_polling( 5 );
        break;
    case HTTP_STATUSCODE_DISCONNECT:
        polling_cid = CID_UNDEFINED;
        irkit_httpclient_start_polling( 5 );
        break;
    // heroku responds with 503 if longer than 30sec,
    // or when deploy occurs
    case 503:
    default:
        if (state == GSwifi::GSREQUESTSTATE_RECEIVED) {
            ring_put( &commands, COMMAND_CLOSE );
            ring_put( &commands, cid );
            irkit_httpclient_start_polling( 5 );
        }
        break;
    }

    return 0;
}
Ejemplo n.º 4
0
void IR_loop ()
{
    if (IrCtrl.state == IR_RECVED) {
        IrCtrl.on_receive();
#ifndef FACTORY_CHECKER
        // factory checker xmits after receive
        IR_state( IR_RECVED_IDLE );
#endif
    }
}
Ejemplo n.º 5
0
void IR_initialize (IRReceiveCallback _on_receive)
{
    IR_INIT_TIMER();
    IR_INIT_XMIT();

    IrCtrl.on_receive  = _on_receive;

    IR_state( IR_DISABLED );

    irpacker_init( &packer_state, (volatile uint8_t*)sharedbuffer );
}
Ejemplo n.º 6
0
void IR_timer (void)
{
    if (IrCtrl.state == IR_RECVING) {
        TIMER_TICK( IrCtrl.recv_timer );

        if ( TIMER_FIRED( IrCtrl.recv_timer ) ) {
            TIMER_STOP( IrCtrl.recv_timer );
            IR_state( IR_RECVED );
        }
    }

    if (IrCtrl.state == IR_XMITTING) {
        TIMER_TICK( IrCtrl.xmit_timer );

        if ( TIMER_FIRED( IrCtrl.xmit_timer ) ) {
            TIMER_STOP( IrCtrl.xmit_timer );
            IR_state( IR_IDLE );
        }
    }
}
Ejemplo n.º 7
0
static int8_t on_get_messages_request(int8_t cid, GSwifi::GSREQUESTSTATE state) {
    if (state != GSwifi::GSREQUESTSTATE_RECEIVED) {
        return -1;
    }

    gs.writeHead(cid, 200);

    if ( (IrCtrl.len <= 0) ||
         (IrCtrl.state != IR_RECVED_IDLE) ) {
        // if no data
        gs.writeEnd();
        ring_put( &commands, COMMAND_CLOSE );
        ring_put( &commands, cid );
        return 0;
    }

    IR_state( IR_READING );

    gs.write("{\"format\":\"raw\",\"freq\":"); // format fixed to "raw" for now
    gs.write(IrCtrl.freq);
    gs.write(",\"data\":[");
    for (uint16_t i=0; i<IrCtrl.len; i++) {
        gs.write( IR_get() );
        if (i != IrCtrl.len - 1) {
            gs.write(",");
        }
    }
    gs.write("]}");
    gs.writeEnd();
    ring_put( &commands, COMMAND_CLOSE );
    ring_put( &commands, cid );

    IR_state( IR_IDLE );

#ifdef USE_INTERNET
    TIMER_START( suspend_polling_timer, SUSPEND_GET_MESSAGES_INTERVAL );
#endif

    return 0;
}
Ejemplo n.º 8
0
static int8_t on_post_door_response(int8_t cid, uint16_t status_code, GSwifi::GSREQUESTSTATE state) {
    HTTPLOG_PRINT(P("< P /d ")); HTTPLOG_PRINTLN(status_code);

    gs.bufferClear();

    if (state != GSwifi::GSREQUESTSTATE_RECEIVED) {
        return 0;
    }

    switch (status_code) {
    case 200:
        keys.setKeyValid(true);
        // save only independent area, since sharedbuffer might be populated by IR or so.
        keys.save2();
        IR_state( IR_IDLE );

        ring_put( &commands, COMMAND_CLOSE );
        ring_put( &commands, cid );
#ifdef USE_INTERNET
        ring_put( &commands, COMMAND_START_POLLING );
#endif

        on_irkit_ready();

        break;
#ifdef USE_INTERNET
    case 401:
    case HTTP_STATUSCODE_CLIENT_TIMEOUT:
        // keys have expired, we have to start listening for POST /wifi again
        keys.clear();
        keys.save();
        software_reset();

        break;
    case 400: // must be program bug, happens when there's no hostname parameter
    case 408:
    case 503: // heroku responds with 503 if longer than 30sec
    default:
        // retry again on next loop
        ring_put( &commands, COMMAND_CLOSE );
        ring_put( &commands, cid );
        ring_put( &commands, COMMAND_POST_DOOR );
        break;
#endif
    }

    return 0;
}
Ejemplo n.º 9
0
static void on_json_start() {
    HTTPLOG_PRINTLN("j<");

    IR_state( IR_WRITING );
}
Ejemplo n.º 10
0
static void on_json_start() {
    HTTPLOG_PRINTLN("j<");

    IR_state( IR_WRITING );
    has_valid_pass = false;
}
Ejemplo n.º 11
0
// IR receiving interrupt on either edge of input
ISR_CAPTURE()
{
    static _timer_reg_t last_interrupt;

    _timer_reg_t counter = IR_CAPTURE_REG();

    if ((IrCtrl.state == IR_RECVED) || (IrCtrl.state == IR_RECVED_IDLE)) {
        IR_state( IR_IDLE );
    }
    if ((IrCtrl.state != IR_IDLE) && (IrCtrl.state != IR_RECVING)) {
        return;
    }
    if (irpacker_safelength(&packer_state) >= IR_BUFF_SIZE) {
        // receive buffer overflow
        // data in buffer might be valid (later data might just be "repeat" data)
        // so wait for recv timeout and successfully transit to RECVED state
        return;
    }

    if (IR_CAPTURED_RISING()) {

        // Rising edge: on stop of burst

        if (IrCtrl.state == IR_IDLE) {
            // can't happen
            return;
        }

        _timer_reg_t low_width = counter - last_interrupt;
        last_interrupt         = counter;

        IrCtrl.trailer_count = T_TRAIL_COUNT;

        IR_CAPTURE_FALL();
        IR_COMPARE_ENABLE(T_TRAIL); // Enable trailer timer

        IR_put_(low_width); // use cycles after enabling timer
        return;
    }

    // Falling edge: on start of burst

    _timer_reg_t high_width = counter - last_interrupt;
    last_interrupt          = counter;

    if (IrCtrl.state == IR_IDLE) {
        IR_state( IR_RECVING );
    }
    else { // is IR_RECVING
        uint8_t trailer;
        for (trailer=T_TRAIL_COUNT; trailer>IrCtrl.trailer_count; trailer--) {
            IR_put_(65535);
            IR_put_(0);
            if (irpacker_safelength(&packer_state) >= IR_BUFF_SIZE) {
                return;
            }
        }
        IR_put_(high_width);
    }

    IR_CAPTURE_RISE();
    IR_COMPARE_DISABLE(); // Disable trailer timer
}