Skip to content
Snippets Groups Projects
Commit 3a6d5a26 authored by Birte Kristina Friesel's avatar Birte Kristina Friesel
Browse files

ws2812b dmap: use double buffering and more efficient RX ring buffer

parent cd266af4
No related branches found
No related tags found
No related merge requests found
...@@ -19,6 +19,7 @@ ...@@ -19,6 +19,7 @@
#define BUF_SIZE 36 #define BUF_SIZE 36
#define BUF_MAX ((BUF_SIZE)-1) #define BUF_MAX ((BUF_SIZE)-1)
#define RINGBUF_SIZE ((BUF_SIZE)+2)
#define NUM_PIXELS 256 #define NUM_PIXELS 256
...@@ -27,21 +28,24 @@ Adafruit_NeoPixel np(NUM_PIXELS, GPIO::pb0, NEO_GRB+NEO_KHZ800); ...@@ -27,21 +28,24 @@ Adafruit_NeoPixel np(NUM_PIXELS, GPIO::pb0, NEO_GRB+NEO_KHZ800);
#define MYADDRESS (0x0006) #define MYADDRESS (0x0006)
volatile uint16_t address; volatile uint16_t address;
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 buf[BUF_SIZE];
volatile uint8_t done; volatile uint8_t done;
void update() void update()
{ {
if (buf[35] > 100) { if (buf[0] > 100) {
buf[35] = 100; buf[0] = 100;
} }
if (buf[32] + buf[33] + buf[34] > 50) { if (buf[1] + buf[2] + buf[3] > 50) {
buf[32] = 0; buf[1] = 5;
buf[33] = 0; buf[2] = 0;
buf[34] = 5; buf[3] = 0;
} }
uint32_t color = np.Color(buf[34], buf[33], buf[32]); uint32_t color = np.Color(buf[1], buf[2], buf[3]);
uint8_t rgb = buf[35]; uint8_t rgb = buf[0];
for (uint8_t col = 0; col < 32; col++) { for (uint8_t col = 0; col < 32; col++) {
for (uint8_t row = 0; row < 8; row++) { for (uint8_t row = 0; row < 8; row++) {
uint8_t pixel_index = col*8; uint8_t pixel_index = col*8;
...@@ -53,7 +57,7 @@ void update() ...@@ -53,7 +57,7 @@ void update()
if (rgb) { if (rgb) {
color = np.gamma32(np.ColorHSV(((uint16_t)col*8+row) * 255, 255, rgb)); color = np.gamma32(np.ColorHSV(((uint16_t)col*8+row) * 255, 255, rgb));
} }
if (buf[col] & _BV(row)) { if (buf[31-col+4] & _BV(row)) {
np.setPixelColor(pixel_index, color); np.setPixelColor(pixel_index, color);
} else { } else {
np.setPixelColor(pixel_index, 0); np.setPixelColor(pixel_index, 0);
...@@ -63,6 +67,40 @@ void update() ...@@ -63,6 +67,40 @@ void update()
np.show(); np.show();
} }
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) int main(void)
{ {
...@@ -85,6 +123,21 @@ int main(void) ...@@ -85,6 +123,21 @@ int main(void)
while (1) { while (1) {
arch.idle(); arch.idle();
if (done) { if (done) {
/*
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(); update();
done = 0; done = 0;
} }
...@@ -95,17 +148,22 @@ int main(void) ...@@ -95,17 +148,22 @@ int main(void)
ISR(INT1_vect) ISR(INT1_vect)
{ {
if (CLOCK_HI) { if (CLOCK_HI && !done) {
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) { if (DATA_BIT) {
ringbuf[ringbuf_byte] |= ringbuf_bitmask;
address = (address << 1) | 1;
gpio.led_on(0); gpio.led_on(0);
} else { } else {
ringbuf[ringbuf_byte] &= ~ringbuf_bitmask;
address = (address << 1) | 0;
gpio.led_off(0); gpio.led_off(0);
} }
if (ringbuf_bitmask > 0x01) {
ringbuf_bitmask >>= 1;
} else {
ringbuf_byte = (ringbuf_byte + 1) % RINGBUF_SIZE;
ringbuf_bitmask = 0x80;
}
} }
else if (DATA_HI && (address == MYADDRESS)) { else if (DATA_HI && (address == MYADDRESS)) {
done = 1; done = 1;
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment