Newer
Older
/*
* Copyright 2020 Daniel Friesel
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#include "arch.h"
#include "driver/neopixel.h"
#include "driver/stdout.h"
#include <util/delay.h>
#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/wdt.h>
#define CLOCK_LO ( ( PIND & _BV(PD3) ) != 0 )
#define CLOCK_HI ( ( PIND & _BV(PD3) ) == 0 )
#define DATA_LO ( ( PIND & _BV(PD2) ) != 0 )
#define DATA_HI ( ( PIND & _BV(PD2) ) == 0 )
#define DATA_BIT ( ( ~PIND & _BV(PD2) ) >> PD2 )
#define BUF_SIZE 36
#define BUF_MAX ((BUF_SIZE)-1)
Birte Kristina Friesel
committed
#define RINGBUF_SIZE ((BUF_SIZE)+2)
#define NUM_PIXELS 256
Adafruit_NeoPixel np(NUM_PIXELS, GPIO::pb0, NEO_GRB+NEO_KHZ800);
#define MYADDRESS (0x0006)
volatile uint16_t address;
Birte Kristina Friesel
committed
volatile uint8_t ringbuf[RINGBUF_SIZE];
volatile uint8_t ringbuf_byte = 0;
volatile uint8_t ringbuf_bitmask = 0x80;
volatile uint8_t buf[BUF_SIZE];
volatile uint8_t done;
void update()
{
Birte Kristina Friesel
committed
if (buf[0] > 100) {
buf[0] = 100;
Birte Kristina Friesel
committed
if (buf[1] + buf[2] + buf[3] > 50) {
buf[1] = 5;
buf[2] = 0;
buf[3] = 0;
Birte Kristina Friesel
committed
uint32_t color = np.Color(buf[1], buf[2], buf[3]);
uint8_t rgb = buf[0];
for (uint8_t col = 0; col < 32; col++) {
for (uint8_t row = 0; row < 8; row++) {
uint8_t pixel_index = col*8;
if (col % 2) {
pixel_index += 7 - row;
} else {
pixel_index += row;
}
if (rgb) {
color = np.gamma32(np.ColorHSV(((uint16_t)col*8+row) * 255, 255, rgb));
}
Birte Kristina Friesel
committed
if (buf[31-col+4] & _BV(row)) {
np.setPixelColor(pixel_index, color);
} else {
np.setPixelColor(pixel_index, 0);
}
}
}
np.show();
}
Birte Kristina Friesel
committed
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
void next_bit(uint8_t *byte, uint8_t *mask, uint8_t const size)
{
if (*mask > 0x01) {
*mask >>= 1;
} else {
*byte = (*byte + 1) % size;
*mask = 0x80;
}
}
void ringbuf_to_buf(void)
{
uint8_t read_byte = ringbuf_byte;
uint8_t read_bitmask = ringbuf_bitmask;
// byte[bitmask] is the next bit that would be written -- and, thanks to
// the buffer size, also the most significant bit of message byte 0.
for (uint8_t write_byte = 0; write_byte < BUF_SIZE; write_byte++) {
buf[write_byte] = 0;
for (uint8_t write_bitmask = 0x80; write_bitmask > 0; write_bitmask >>= 1) {
if (ringbuf[read_byte] & read_bitmask) {
buf[write_byte] |= write_bitmask;
}
if (read_bitmask > 0x01) {
read_bitmask >>= 1;
} else {
read_byte = (read_byte + 1) % RINGBUF_SIZE;
read_bitmask = 0x80;
}
}
}
}
int main(void)
{
arch.setup();
gpio.setup();
kout.setup();
np.setup();
PORTD = _BV(PD2) | _BV(PD3);
EICRA = _BV(ISC10);
EIMSK = _BV(INT1);
np.setPixelColor(0, np.Color(0, 1, 1));
np.setPixelColor(7, np.Color(0, 1, 1));
np.setPixelColor(248, np.Color(0, 1, 1));
np.setPixelColor(255, np.Color(0, 1, 1));
np.show();
while (1) {
arch.idle();
if (done) {
Birte Kristina Friesel
committed
/*
kout << dec << "done, byte=" << ringbuf_byte << hex << " bitmask=" << ringbuf_bitmask << " ringbuf = " << hex;
for (uint8_t i = 0; i < RINGBUF_SIZE; i++) {
kout << ringbuf[i] << " ";
}
kout << endl;
*/
ringbuf_to_buf();
/*
kout << "update, buf = " << hex;
for (uint8_t i = 0; i < BUF_SIZE; i++) {
kout << buf[i] << " ";
}
kout << endl;
*/
update();
done = 0;
}
}
return 0;
}
ISR(INT1_vect)
{
Birte Kristina Friesel
committed
if (CLOCK_HI && !done) {
Birte Kristina Friesel
committed
ringbuf[ringbuf_byte] |= ringbuf_bitmask;
address = (address << 1) | 1;
gpio.led_on(0);
} else {
Birte Kristina Friesel
committed
ringbuf[ringbuf_byte] &= ~ringbuf_bitmask;
address = (address << 1) | 0;
Birte Kristina Friesel
committed
if (ringbuf_bitmask > 0x01) {
ringbuf_bitmask >>= 1;
} else {
ringbuf_byte = (ringbuf_byte + 1) % RINGBUF_SIZE;
ringbuf_bitmask = 0x80;
}
}
else if (DATA_HI && (address == MYADDRESS)) {
done = 1;
}
}