/* * Copyright 2020 Daniel Friesel * * SPDX-License-Identifier: BSD-2-Clause */ #include "arch.h" #include "driver/neopixel.h" #include "driver/stdout.h" #include #include #include #include #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 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; 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() { if (buf[0] > 100) { buf[0] = 100; } if (buf[1] + buf[2] + buf[3] > 50) { buf[1] = 5; buf[2] = 0; buf[3] = 0; } 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)); } if (buf[31-col+4] & _BV(row)) { np.setPixelColor(pixel_index, color); } else { np.setPixelColor(pixel_index, 0); } } } 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) { 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) { /* 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) { if (CLOCK_HI && !done) { if (DATA_BIT) { ringbuf[ringbuf_byte] |= ringbuf_bitmask; address = (address << 1) | 1; gpio.led_on(0); } else { ringbuf[ringbuf_byte] &= ~ringbuf_bitmask; address = (address << 1) | 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)) { done = 1; } }