Пример #1
0
// delete this
void dataflash_buffer_write(u8 byte, u8 addr)
{
    df_select();
    spi_write(0x84);
    spi_write(0);
    spi_write(0);
    spi_write(addr);
    spi_write(byte);
    df_deselect();
}
Пример #2
0
u8 dataflash_read_status_reg()
{
    /* opcode 0x57 */
    df_select();
    spi_write(STATUS_REGISTER);
    spi_read();
    spi_write(0);   /* just to toggle clock */
    df_deselect();
    
    return spi_read();
}
Пример #3
0
// delete this
u8 dataflash_buffer_read(u8 addr)
{
    u8 ret;
    df_select();
    spi_write(0x54);
    spi_write(0);
    spi_write(0);
    spi_write(addr);
    spi_write(0);
    spi_write(0);
    ret = spi_read();
    
    df_deselect();

    return ret;
}
Пример #4
0
/*
 * main function
 */
int main(void)
{
    /* hardware on port D:
     * PD0: RX
     * PD1: TX
     * PD2: D+
     * PD3: INT1/IR_IN
     * PD4: D-
     * PD5: IR_OUT
     * PD7: DF_CS
     */
    DDRD = _BV(PD5) | _BV(PD7);
    PORTD = _BV(PD7);

    /* configure pin change interrupt for button 1 and 2,
     * for waking up from sleep mode... */
    PCMSK1 = _BV(PCINT12) | _BV(PCINT13);

    /* hardware on port B:
     * PB0: PUD
     * PB1: /LED2
     * PB2: /LED1
     * PB3: MOSI
     * PB4: MISO
     * PB5: SCK
     */
    DDRB = _BV(PB0) | _BV(PB1) | _BV(PB2) | _BV(PB3) | _BV(PB5);
    PORTB = _BV(PB1) | _BV(PB2);

    /* hardware on port C:
     * PC0: IR_IN2
     * PC1: POWER
     * PC2: BTN4
     * PC3: BTN3
     * PC4: BTN2
     * PC5: BTN1
     */
    DDRC = 0;
    PORTC = _BV(PC2) | _BV(PC3) | _BV(PC4) | _BV(PC5);

    /* init analog to digital converter,
     * convert on PC1(ADC1)
     * prescaler 64 => 250khz frequency */
    ADMUX = _BV(REFS0) | _BV(ADLAR) | _BV(ADIF) | _BV(MUX0);
    ADCSRA = _BV(ADEN) | _BV(ADPS1);

    /* init spi */
    SPCR = _BV(SPE) | _BV(MSTR);
    SPSR |= _BV(SPI2X);

    /* init timer2 for key debouncing, CTC, prescaler 1024,
     * timeout after 10ms */
    TCCR2A = _BV(WGM21);
    TCCR2B = _BV(CS22) | _BV(CS21) | _BV(CS20);
    TIMSK2 = _BV(OCIE2A);
    OCR2A = F_CPU/100/1024;

    /* configure sleep mode */
    set_sleep_mode(SLEEP_MODE_STANDBY);

#ifdef DEBUG_UART
    /* uart */
    UBRR0H = 0;
    UBRR0L = 8;
    UCSR0C = _BV(UCSZ00) | _BV(UCSZ01);
    UCSR0B = _BV(TXEN0);

    UDR0 = 'b';
    while(!(UCSR0A & _BV(UDRE0)));
#endif

    /* read dataflash status */
    df_select();
    SPDR = 0xd7;
    while(!(SPSR & _BV(SPIF)));
    SPDR = 0;
    while(!(SPSR & _BV(SPIF)));

    uint8_t df_status = SPDR;

    /* read battery voltage */
    uint8_t bat = battery_voltage();

#ifdef DEBUG_UART
    UDR0 = 'D';
    while(!(UCSR0A & _BV(UDRE0)));
    UDR0 = df_status;
    while(!(UCSR0A & _BV(UDRE0)));
    UDR0 = 'V';
    while(!(UCSR0A & _BV(UDRE0)));
    UDR0 = bat;
    while(!(UCSR0A & _BV(UDRE0)));
#endif

    df_release();

    sei();

#ifdef BLINK_START
    /* blink start sequence */
    blink(BLINK_START);
#endif

    if (df_status == DF_STATUS_IDLE)
        blink(BLINK_DF_SEEN);
    else
        blink(BLINK_DF_ERROR);

    if (bat >= MIN_BAT_VOLTAGE)
        blink(BLINK_BAT_OK);
    else
        blink(BLINK_BAT_FAIL);

    uint8_t pos;
    uint8_t button_sum = 0;

    while (1)
    {
        /* if a button has been pressed and we're idle, wait some more time to determine mode */
        if (state == IDLE && (button_press[0] > 0 || button_press[1] > 0)) {

            /* wait one second via timer1, using prescaler 1024 */
            TIFR1 = TIFR1;
            OCR1A = F_CPU/1024/2;
            TCCR1B = _BV(CS12) | _BV(CS10);

            button_sum = 0;
            state = READ_COMMAND;
        }

        /* if we're waiting for a command, and some button has been pressed, reset timeout */
        uint8_t sum = button_press[0] + button_press[1];
        if (state == READ_COMMAND && sum != button_sum) {
            TCNT1 = 0;
            button_sum = sum;
        }

        /* if we're waiting for a command, check if the timer expired */
        if (state == READ_COMMAND && (TIFR1 & _BV(OCF1A))) {

            /* disable timer1 */
            TCCR1B = 0;
            TCNT1 = 0;

            /* parse button presses */
            if (button_press[0] == 1 && button_press[1] == 0) {

                if (battery_voltage() < MIN_BAT_VOLTAGE && !options.ignore_bat) {
                    blink(BLINK_VOLTAGE);
                } else {

                    /* start transmitting */
                    pos = 0;

                    current_code = &codes[0];
                    single_code = &codes[0];
                    state = LOAD_CODE;

#ifdef BLINK_MODE1
                    /* blink mode 1 */
                    blink(BLINK_MODE1);
#endif

                    if (!options.silent)
                        PORTB &= ~_BV(PB1);
                }
            } else if (button_press[0] == 0) {
                if (button_press[1] == 1) {
                    options.silent = !options.silent;

                    /* blink for silent toggle */
                    if (options.silent)
                        blink(BLINK_SILENT);
                    else
                        blink(BLINK_NONSILENT);

                } else if (button_press[1] == 2) {
                    options.single_step = !options.single_step;

                    /* blink for single step toggle */
                    if (options.single_step)
                        blink(BLINK_STEP);
                    else
                        blink(BLINK_NOSTEP);
                } else if (button_press[1] == 3) {
                    options.ignore_bat = !options.ignore_bat;

                    /* blink for ignore battery toggle */
                    if (options.ignore_bat)
                        blink(BLINK_BAT_IGNORE);
                    else
                        blink(BLINK_BAT_HONOR);
                } else
                    blink(BLINK_INVALID);
            } else
                blink(BLINK_INVALID);

            /* reset state, if not yet done */
            if (state == READ_COMMAND)
                state = IDLE;

            /* reset buttons */
            button_press[0] = 0;
            button_press[1] = 0;
            button_press[2] = 0;
        }

        if (state == LOAD_CODE) {

            /* if we're in single-step mode, wait for a keypress */
            if (options.single_step) {
                while (button_press[0] == 0 && button_press[1] == 0 && button_press[2] == 0);

                /* send next code if button1 has been pressed, stop if button2
                 * has been pressed, resend code if button3 has been pressed */
                if (button_press[2]) {
                    current_code = single_code;
                    button_press[1] = 0;
                } else if (!button_press[1]) {
                    button_press[1] = 0;
                }

                /* reset buttons */
                button_press[0] = 0;
                button_press[2] = 0;
            }

            /* stop sending if button2 has been pressed */
            if (button_press[1] > 0) {
                button_press[0] = 0;
                button_press[1] = 0;
                PORTB |= _BV(PB1);

#ifdef BLINK_MODE1_END
                blink(BLINK_MODE1_END);
#endif

                state = IDLE;
            } else {

#ifdef DEBUG_UART
                UDR0 = 'L';
                while(!(UCSR0A & _BV(UDRE0)));
#endif
                /* if we're in single step mode, remember code address for single-retransmit */
                single_code = current_code;

                /* load next generating function and generate timing table */
                void (*func)(void);
                uint16_t ptr = next_word();
                func = (void *)ptr;

                if (func != NULL) {
#ifdef DEBUG_UART
                    UDR0 = 'p';
                    while(!(UCSR0A & _BV(UDRE0)));
                    UDR0 = pos++;
                    while(!(UCSR0A & _BV(UDRE0)));
#endif

                    /* call generating function */
                    func();

#ifdef DEBUG_UART
                    UDR0 = 'f';
                    while(!(UCSR0A & _BV(UDRE0)));
#endif

                    /* reset timing pointer */
                    current_timing = &timing[0];

                    /* update state */
                    state = TRANSMIT_CODE;

                    /* init timer1 for initial delay before sending:
                     * prescaler 256, CTC mode (TOP == OCR1A)
                     * enable compare interrupts */
                    OCR1A = DELAY_NEXT_CODE;
                    OCR1B = 0xffff;
                    TIFR1 = TIFR1;
                    TIMSK1 = _BV(OCIE1A) | _BV(OCIE1B);
                    TCCR1B = _BV(CS12) | _BV(WGM12);
                } else {
#ifdef DEBUG_UART
                    UDR0 = 'E';
                    while(!(UCSR0A & _BV(UDRE0)));
#endif

                    PORTB |= _BV(PB1);

#ifdef BLINK_MODE1_END
                    blink(BLINK_MODE1_END);
#endif

                    state = IDLE;
                }

                sleep_counter = 0;
            }
        }

        if (state == SLEEP) {
            /* enable pin change interrupt for button 1 and 2,
             * for waking up from sleep mode... */
            PCICR = _BV(PCIE1);

            /* set and enter sleep mode */
            sleep_mode();
            sleep_counter = SLEEP_COUNTER_VALUE;
            state = IDLE;

            /* disable pin change interrupt for button 1 and 2,
             * for waking up from sleep mode... */
            PCICR = 0;

        }
    }
}