100 lines
1.6 KiB
C
100 lines
1.6 KiB
C
#include <avr/io.h>
|
|
#include <avr/interrupt.h>
|
|
#include <avr/pgmspace.h>
|
|
#include <util/delay.h>
|
|
#include "oled-display/lcd.h"
|
|
#include "input.h"
|
|
#include "systick.h"
|
|
|
|
#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)) {
|
|
SPDR = spdr_next;
|
|
switch (y) {
|
|
case Y_MAX:
|
|
spdr_next = 55; // TODO: Vbat
|
|
break;
|
|
}
|
|
lcd_set_buffer(x, y, SPDR);
|
|
if (y == 0) {
|
|
y = Y_MAX;
|
|
x++;
|
|
if (x == DISPLAY_WIDTH) {
|
|
x = 0;
|
|
new_data = 1; // Only update the display if a full frame was received
|
|
}
|
|
} else {
|
|
y--;
|
|
}
|
|
}
|
|
} else {
|
|
if (new_data) {
|
|
lcd_display();
|
|
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();
|
|
}
|
|
|
|
return spi_cs;
|
|
}
|
|
|
|
void lcd_startup()
|
|
{
|
|
lcd_init(LCD_DISP_ON);
|
|
lcd_gotoxy(0, 0);
|
|
lcd_puts_p(PSTR("== Internet Radio =="));
|
|
lcd_drawLine(0, 9, 120, 9, WHITE);
|
|
lcd_gotoxy(0, 2);
|
|
lcd_puts_p(PSTR("Starting up."));
|
|
lcd_gotoxy(0, 3);
|
|
lcd_puts_p(PSTR("Please wait..."));
|
|
lcd_display();
|
|
}
|
|
|
|
int main()
|
|
{
|
|
cli();
|
|
|
|
lcd_startup();
|
|
spi_init();
|
|
systick_init();
|
|
input_init();
|
|
|
|
_delay_ms(10);
|
|
|
|
while (1) {
|
|
if (!spi_proc()) {
|
|
timer_proc();
|
|
input_proc();
|
|
}
|
|
}
|
|
return 0;
|
|
}
|