#include <avr/io.h>
#include <avr/interrupt.h>
+#include "lcd.h"
+#include "serial.h"
#define DATA_OUT PORTD2
#define CLOCK PIND3
#define BIT(n) (1<<(n))
+void receive(uint8_t);
+uint8_t hexdigit(uint8_t);
uint8_t decode_hex(uint8_t);
-volatile uint8_t rx_buf[3];
-volatile uint8_t rx_fill = 0;
-volatile uint8_t input = 0;
-volatile uint8_t latch = 0;
+volatile uint8_t rx_buf[7];
+volatile uint8_t rx_fill = 0xFF;
+volatile uint8_t input[128] = { 0 };
+volatile uint8_t latch[128] = { 0 };
+uint8_t log_pos = 0;
int main()
{
uint8_t clock_high = 0;
uint8_t bits = 0;
+ uint8_t n_bits = 8;
+ uint8_t offset = 0;
DDRD = 0x06; // 00000110
PIND = 0xC0; // 11000000
DDRB = 0x20; // 00100000
PINB = 0x1F; // 00011111
- // 9600 baud, 8N1
- UBRR0H = 0;
- UBRR0L = 103;
- UCSR0C = BIT(UCSZ00) | BIT(UCSZ01);
- UCSR0B = BIT(RXEN0) | BIT(TXEN0) | BIT(RXCIE0);
+ serial_init(9600);
+ serial_set_callback(receive);
+ lcd_init();
+ lcd_on();
+ lcd_clear();
sei();
if(!clock_high)
{
if(d_pins&BIT(LOAD))
- bits = latch;
+ {
+ offset = 0;
+ bits = latch[0];
+ n_bits = 8;
+ }
else
+ {
bits >>= 1;
+ if(!--n_bits)
+ {
+ ++offset;
+ bits = latch[offset];
+ n_bits = 8;
+ }
+ }
if(bits&1)
PORTD |= BIT(DATA_OUT);
clock_high = 0;
if(d_pins&BIT(RESET))
- latch = input;
+ {
+ uint8_t i;
+ for(i=0; i<128; ++i)
+ latch[i] = input[i];
+ }
}
}
-ISR(USART_RX_vect)
+void receive(uint8_t c)
{
- uint8_t c = UDR0;
- if(rx_fill==0)
+ if(rx_fill==0xFF)
{
if(c==':')
- rx_buf[rx_fill++] = c;
+ rx_fill = 0;
}
- else
+ else if(c=='.')
{
- rx_buf[rx_fill++] = c;
- if(rx_buf[0]==':' && rx_fill==3)
+ if(rx_fill>=4)
{
- input = (decode_hex(rx_buf[1])<<4) | decode_hex(rx_buf[2]);
- latch |= input;
- rx_fill = 0;
+ uint16_t offset;
+ uint8_t nibbles;
+ uint8_t i;
+
+ offset = (decode_hex(rx_buf[0])<<8) | (decode_hex(rx_buf[1])<<4) | decode_hex(rx_buf[2]);
+ nibbles = (offset&3);
+ offset >>= 2;
+ if(rx_fill>3+nibbles)
+ {
+ for(i=0; i<=nibbles; ++i)
+ {
+ uint16_t j = offset+nibbles-i;
+ uint8_t shift = 4*(j&1);
+ uint8_t bits = decode_hex(rx_buf[3+i]);
+ input[j/2] = (input[j/2]&~(0xF<<shift)) | (bits<<shift);
+ latch[j/2] = input[j/2];
+ }
+ }
+
+ lcd_gotoxy(0, 0);
+ for(i=10; i--;)
+ {
+ lcd_write(hexdigit(input[i]>>4));
+ lcd_write(hexdigit(input[i]));
+ }
}
+ rx_fill = 0xFF;
+ }
+ else
+ {
+ if(rx_fill<sizeof(rx_buf))
+ rx_buf[rx_fill++] = c;
+ else
+ rx_fill = 0xFF;
}
+
+ lcd_gotoxy(log_pos%20, 1+log_pos/20);
+ lcd_write(c);
+ ++log_pos;
+ if(log_pos>=60)
+ log_pos = 0;
+ lcd_gotoxy(log_pos%20, 1+log_pos/20);
+ lcd_write(255);
+}
+
+uint8_t hexdigit(uint8_t n)
+{
+ n &= 0xF;
+ if(n<10)
+ return '0'+n;
+ else
+ return 'A'+(n-0xA);
}
uint8_t decode_hex(uint8_t c)