1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
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
104
105
106
107
108
109
110
111
112
113
114
115
|
/*
* Copyright 2020 Daniel Friesel
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#include "arch.h"
#include "driver/neopixel.h"
#include "driver/stdin.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)
#define NUM_PIXELS 256
Adafruit_NeoPixel np(NUM_PIXELS, GPIO::pb0, NEO_GRB+NEO_KHZ800);
#define MYADDRESS (0x0006)
volatile uint16_t address;
volatile uint8_t buf[BUF_SIZE];
volatile uint8_t done;
void update()
{
if (buf[35] > 100) {
buf[35] = 100;
}
if (buf[32] + buf[33] + buf[34] > 50) {
buf[32] = 0;
buf[33] = 0;
buf[34] = 5;
}
uint32_t color = np.Color(buf[34], buf[33], buf[32]);
uint8_t rgb = buf[35];
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));
}
if (buf[col] & _BV(row)) {
np.setPixelColor(pixel_index, color);
} else {
np.setPixelColor(pixel_index, 0);
}
}
}
np.show();
}
int main(void)
{
arch.setup();
gpio.setup();
kout.setup();
kin.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) {
update();
done = 0;
}
}
return 0;
}
ISR(INT1_vect)
{
if (CLOCK_HI) {
for (uint8_t i = BUF_MAX; i > 0; i--) {
buf[i] = (buf[i] << 1) | (buf[i-1] >> 7);
}
buf[0] = (buf[0] << 1) | (address >> 15);
address = (address << 1) | DATA_BIT;
if (DATA_BIT) {
gpio.led_on(0);
} else {
gpio.led_off(0);
}
}
else if (DATA_HI && (address == MYADDRESS)) {
done = 1;
}
}
|