// 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(); }
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(); }
// 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; }
/* * 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; } } }