Skip to content
Snippets Groups Projects
main.cc 3.6 KiB
Newer Older
  • Learn to ignore specific revisions
  • /*
     * 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)
    
    
    #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[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));
    			}
    
    				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;
    			*/
    
    			ringbuf[ringbuf_byte] |= ringbuf_bitmask;
    			address = (address << 1) | 1;
    
    			gpio.led_on(0);
    		} else {
    
    			ringbuf[ringbuf_byte] &= ~ringbuf_bitmask;
    			address = (address << 1) | 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;
    	}
    }