webradio/firmware/main.c
Markus Koch f71c65106f fw: Only update display if a full frame was received
Sometimes, the RPi fails to send out a message in time, leading
to two, back-to-back SPI transactions. The beginning of the second
is then lost in the long lcd_display() call. By applying this
patch, we now miss the incomplete frame entirely, but at least we
don't display garbage on the screen. Just looks like stutter.

The real solution would be to fix in on the Linux / Python side,
but this workaround is better than nothing for now.
2020-07-19 21:20:30 +02:00

63 lines
1.0 KiB
C

#include <avr/io.h>
#include <avr/pgmspace.h>
#include <avr/delay.h>
#include "oled-display/lcd.h"
#define PORT_SPI(t) t##B
#define PIN_SPI_CS (1 << 2)
void spi_proc()
{
static uint8_t new_data = 0;
static uint8_t x = 0;
static uint8_t y = DISPLAY_HEIGHT / 8 - 1;
uint8_t spi_cs;
spi_cs = !(PORT_SPI(PIN) & PIN_SPI_CS);
if (spi_cs) {
if (SPSR & (1 << SPIF)) {
lcd_set_buffer(x, y, SPDR);
if (y == 0) {
y = DISPLAY_HEIGHT / 8 - 1;
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;
}
x = 0;
y = DISPLAY_HEIGHT / 8 - 1;
}
}
int main()
{
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();
SPCR = (1 << SPE);
_delay_ms(10);
while (1) {
spi_proc();
}
return 0;
}