Markus Koch
f71c65106f
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.
63 lines
1.0 KiB
C
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;
|
|
}
|