#include #include #include #include #include "oled-display/lcd.h" #include "input.h" #include "systick.h" #include "batmon.h" #include "pm.h" #define TIME_POWERON 8000 /* Time after power enable to gpio-poweroff signal expected */ #define TIME_POWEROFF 3000 /* gpio-poweroff low time before removing power */ #define PORT_SPI(t) t##B #define PIN_SPI_CS (1 << 2) int dbg = 0; void spi_init() { SPCR = (1 << SPE); SPSR = (1 << SPI2X); DDRB |= (1 << 4); } #define Y_MAX (DISPLAY_HEIGHT / 8 - 1) uint8_t spi_proc() { static uint8_t new_data = 0; static uint8_t x = 0; static uint8_t y = Y_MAX; uint8_t spi_cs; static uint8_t spdr_next = 0; spi_cs = !(PORT_SPI(PIN) & PIN_SPI_CS); if (spi_cs) { if (SPSR & (1 << SPIF)) { switch (y) { case Y_MAX - 1: spdr_next = batmon_get_voltage(); break; } SPDR = spdr_next; lcd_set_buffer(x, y, SPDR); if (y == 0) { y = Y_MAX; x++; if (x == DISPLAY_WIDTH) { x = 0; y = Y_MAX; new_data = 1; // Only update the display if a full frame was received lcd_display(); } } else { y--; } } } else { if (new_data) { new_data = 0; } else if ((y == Y_MAX - 3) && (x == 0)) { // If the last one was a I/O frame input_clear_events(); } x = 0; y = Y_MAX; SPDR = get_switch_event(); spdr_next = get_rotary_delta() | (batmon_is_charging() << 7); } return spi_cs; } void lcd_title(const char *msg1, const char *msg2) { lcd_clrscr(); lcd_gotoxy(0, 0); lcd_puts_p(PSTR("== Internet Radio ==")); lcd_drawLine(0, 9, 120, 9, WHITE); lcd_gotoxy(0, 2); lcd_puts_p(msg1); lcd_gotoxy(0, 3); lcd_puts_p(msg2); lcd_display(); } int main() { char *post_msg; uint8_t sched = 0; MCUSR &= ~(1 << WDRF); WDTCSR = (1 << WDCE); cli(); _delay_ms(25); suspend(); pm_init(); lcd_init(LCD_DISP_ON); lcd_title(PSTR("Starting IOC Rev."), PSTR(GITREV)); spi_init(); systick_init(); input_init(); batmon_init(); if (post_msg = post()) { lcd_title(PSTR("POST Error!"), post_msg); _delay_ms(2000); reset(); } lcd_title(PSTR("Starting up."), PSTR("Please wait.")); pm_sbc_on(); _delay_ms(10); timer_set(TIMID_POWEROFF, MS_TO_TICKS(TIME_POWERON)); lcd_title(PSTR("Starting up."), PSTR("Please wait...")); while (1) { if (!spi_proc()) { switch (sched) { case 0: timer_proc(); break; case 1: input_proc(); break; case 2: if (get_sbc_state()) timer_set(TIMID_POWEROFF, MS_TO_TICKS(TIME_POWEROFF)); if (timer_expired(TIMID_POWEROFF)) reset(); } } sched = sched + 1; if (sched == 5) { sched = 0; if (batmon_proc()) reset(); } if (PORT_KEYPAD(PIN) == 0b11111001) { _delay_ms(500); reset(); } } return 0; }