blackbox/interrupts.c

Fri, 09 Dec 2011 22:15:50 +0100

author
Malte Bayer <mbayer@neo-soft.org>
date
Fri, 09 Dec 2011 22:15:50 +0100
changeset 66
1e220602b7a7
parent 56
a20f59a3016c
child 69
27c0c0095e26
permissions
-rw-r--r--

pitlane response enter/exit pitlane, led lit when car is in pitlane

ISR ( TIMER1_COMPA_vect ) {
    //PORTC ^= _BV(PC0); // DEBUG OUTPUT SYSTEM CLOCK

    // trigger packet transfer:
    if (sysclk_packettimer == 14) { // 15*500 = 7500 NS
        transmit_len = transmit_len_next;
        sysclk_packettimer = 0;
    } else sysclk_packettimer++;
    // here is some more time to do something else...

    // reset both car counters to overflow
    car0_old = TIMER1_500NS;
    car1_old = TIMER1_500NS;

    sysclk.value++; // increment 500ns timer
}

ISR ( TIMER2_COMP_vect ) {
    //OCR2 = TIMER2_50US; // make sure that timer2 is 50µs !!!
    // data packet timer 100µs pro bit...
    if (transmit_len >= 0xFE) {
        if (transmit_len != 0xFF) {
            RAIL_POWER_PORT |= _BV(RAIL_POWER); // end of transmission
            transmit_len = 0xFF;
            transmit_buffer = transmit_buffer_queue;
            transmit_buffer_queue = 0;
            transmit_len_next = transmit_len_queue;

            // start the response receiver timer
            // TODO: only on 8 timeslots, not on every transmission
            // TODO: give slot number to timer - then store the transmission to 8 slots array
            TCNT0 = TIMER0_250US;
            timer0_delay = TIMER0_2300NS;
            response = 0;
            response_len = 0;
            TIMSK |= _BV(TOIE0);

        }
    } else {
        uint16_t bit = (1<<(transmit_len & 0b01111111));
        uint16_t clock;
        if ((transmit_len & 0b10000000) == 0) clock = 0; else clock = 0xffff;
        if ( ((transmit_buffer ^ clock) & bit) != 0 )
            RAIL_POWER_PORT |= _BV(RAIL_POWER); else
            RAIL_POWER_PORT &= ~_BV(RAIL_POWER);
        if ( (transmit_len & 0b10000000) == 0 ) {
            // block 0
            //if (transmit_len == 0) transmit_len = 0xFF; else transmit_len |= 0b10000000; // set clock
            transmit_len |= 0b10000000; // set clock
        } else {
            // block 1, output the current bit
            transmit_len &= 0b01111111; // reset clock
            //if (transmit_len != 0) transmit_len--; // next bit
            if (transmit_len == 0) transmit_len = 0xFE; else transmit_len--; // next bit
        }
    }
}


ISR ( TIMER0_OVF_vect ) {
// TODO: last bit should be set by the sender, not from us!
    TCNT0 = TIMER0_250US;
    if (timer0_delay == 0) {
        RAIL_POWER_PORT &= ~_BV(RAIL_POWER); // pull rails low
        _delay_us(28); // wait some cycles
        if ((PIN(RAIL_DETECT_PORT) & _BV(RAIL_DETECT)) != 0) { // check for logic zero
            if (response == 0) {
                // there is no start bit, so stop the timer and cancel response receiving
                TIMSK &= ~_BV(TOIE0);
            } else {
                // we received a bit (logic low)
                response = response << 1;
                response_len++;
            }
        } else {
            // okay, we have logic high
            response = response << 1;
            response |= 1;
            response_len++;
        }
        if (response_len == 15) { // maximum response length reached
            RAIL_POWER_PORT |= _BV(RAIL_POWER); // restore rails power
            TIMSK &= ~_BV(TOIE0);
        } else {
            _delay_us(20); // wait some cycles
            RAIL_POWER_PORT |= _BV(RAIL_POWER); // restore rails power
        }
    } else timer0_delay--; // 2.3 ms delay not reached yet
}

ISR (INT0_vect) {
    // car0 detector
    uint16_t tmp = 0;
    car0_new = TCNT1; // get current counter
    if (car0_old < car0_new) {
        // calculate difference
        if (car0 == 0) tmp = car0_new-car0_old;
        if ( (tmp > 54) && (tmp < 74) ) car0 = 1;
        if ( (tmp > 118) && (tmp < 138) ) car0 = 2;
        if ( (tmp > 186) && (tmp < 206) ) car0 = 3;
        if ( (tmp > 246) && (tmp < 266) ) car0 = 4;
        if ( (tmp > 310) && (tmp < 330) ) car0 = 5;
        if ( (tmp > 374) && (tmp < 394) ) car0 = 6;
    }
    car0_old = car0_new;
}

ISR (INT1_vect) {
    // car1 detector
    uint16_t tmp = 0;
    car1_new = TCNT1; // get current counter
    if (car1_old < car1_new) {
        // calculate difference
        if (car1 == 0) tmp = car1_new-car1_old;
        if ( (tmp > 54) && (tmp < 74) ) car1 = 1;
        if ( (tmp > 118) && (tmp < 138) ) car1 = 2;
        if ( (tmp > 186) && (tmp < 206) ) car1 = 3;
        if ( (tmp > 246) && (tmp < 266) ) car1 = 4;
        if ( (tmp > 310) && (tmp < 330) ) car1 = 5;
        if ( (tmp > 374) && (tmp < 394) ) car1 = 6;
    }
    car1_old = car1_new;
}


ISR (INT2_vect) {
    // Lap counter Interrupt
    // do not know if this ever occurs ?! this is normally an output pin to trigger the counter start
}

mercurial