416 lines
12 KiB
C
416 lines
12 KiB
C
#include <samd21g18a.h>
|
|
#include "NeoPixel.h"
|
|
#include "Timer.h"
|
|
#include "DMA.h"
|
|
#include "SPI.h"
|
|
#include "ADC.h"
|
|
|
|
static uint8_t pixel_buffer[NUM_PIXELS * 3]; // 3 bytes per pixel (G-R-B)
|
|
static uint8_t dma_buffer[NUM_PIXELS * 3 * 3 + 90]; // each byte is expanded to 3 bytes + 90 bytes (zero) for latching
|
|
static const uint32_t bit_expand[256]; // lookup table for bit expansion
|
|
|
|
static Animation current_animation;
|
|
static int frame;
|
|
|
|
void NeoPixel_init(void)
|
|
{
|
|
/* initialize pixel buffer */
|
|
NeoPixel_clear_pixels();
|
|
|
|
/* initialize DMA buffer */
|
|
for (int i = 0 ; i < sizeof dma_buffer ; i++)
|
|
dma_buffer[i] = 0x00;
|
|
|
|
/* configure and enable DMA controller */
|
|
/* set up transfer descriptor */
|
|
DmacDescriptor descriptor;
|
|
descriptor.DSTADDR.reg = (uint32_t)&SERCOM0->SPI.DATA; // destination address is SPI DATA register
|
|
descriptor.SRCADDR.reg = (uint32_t)(dma_buffer + sizeof dma_buffer); // source address is the DMA buffer
|
|
descriptor.DESCADDR.reg = 0; // only one transfer descriptor
|
|
descriptor.BTCTRL.bit.BEATSIZE = DMAC_BTCTRL_BEATSIZE_BYTE_Val; // beat size is one byte
|
|
descriptor.BTCTRL.bit.DSTINC = 0; // destination address increment disabled
|
|
descriptor.BTCTRL.bit.SRCINC = 1; // source address increment enabled
|
|
descriptor.BTCTRL.bit.STEPSEL = DMAC_BTCTRL_STEPSEL_SRC_Val; // flexible source address increment size
|
|
descriptor.BTCTRL.bit.STEPSIZE = DMAC_BTCTRL_STEPSIZE_X1_Val; // source address increment is one byte
|
|
descriptor.BTCTRL.bit.BLOCKACT = DMAC_BTCTRL_BLOCKACT_NOACT_Val; // request interrupt at end of block transfer
|
|
descriptor.BTCNT.reg = sizeof dma_buffer; // beat count
|
|
descriptor.BTCTRL.bit.VALID = 1; // descriptor is valid
|
|
/* initialize DMA controller */
|
|
DMA_init();
|
|
/* add and enable SERCOM0 (SPI) channel */
|
|
DMA_add_channel(DMA_SOURCE_SERCOM0, &descriptor);
|
|
/* enable DMA */
|
|
DMA_enable();
|
|
|
|
/* initialize timer */
|
|
Timer_init();
|
|
|
|
/* initialize SPI */
|
|
SPI_init();
|
|
}
|
|
|
|
/* set pixel color (pixel are numbered from 0 to NUM_PIXELS - 1) */
|
|
void NeoPixel_set_pixel(int pixel, uint8_t red, uint8_t green, uint8_t blue)
|
|
{
|
|
if (pixel < 0 || pixel >= NUM_PIXELS)
|
|
return;
|
|
int n = pixel * 3;
|
|
pixel_buffer[n] = green;
|
|
pixel_buffer[n + 1] = red;
|
|
pixel_buffer[n + 2] = blue;
|
|
}
|
|
|
|
/* all pixels off */
|
|
void NeoPixel_clear_pixels(void)
|
|
{
|
|
for (int i = 0 ; i < NUM_PIXELS * 3 ; i++)
|
|
pixel_buffer[i] = 0;
|
|
}
|
|
|
|
/* update DMA buffer */
|
|
void NeoPixel_update(void)
|
|
{
|
|
for (int i = 0, j = 0 ; i < sizeof pixel_buffer ; i++, j += 3)
|
|
{
|
|
uint32_t expanded = bit_expand[pixel_buffer[i]];
|
|
dma_buffer[j] = expanded >> 16;
|
|
dma_buffer[j + 1] = expanded >> 8;
|
|
dma_buffer[j + 2] = expanded;
|
|
}
|
|
}
|
|
|
|
void NeoPixel_update_animation(void)
|
|
{
|
|
static int v = 1;
|
|
static int on = 0;
|
|
int sound_value = 0;
|
|
|
|
if (frame_time) // if all DMA transfers for a frame has occurred
|
|
{
|
|
frame_time = 0; // acknowledge/clear flag from timer
|
|
/* update pixel buffer */
|
|
switch (current_animation)
|
|
{
|
|
case KITT:
|
|
NeoPixel_clear_pixels();
|
|
NeoPixel_set_pixel(frame, 255, 0, 0);
|
|
NeoPixel_set_pixel(frame - v, 255, 0, 0);
|
|
NeoPixel_set_pixel(frame - 2*v, 200, 0, 0);
|
|
NeoPixel_set_pixel(frame - 3*v, 100, 0, 0);
|
|
NeoPixel_set_pixel(frame - 4*v, 50, 0, 0);
|
|
if (frame == NUM_PIXELS - 1 || frame == 0)
|
|
v = -v;
|
|
frame += v;
|
|
break;
|
|
case BREATHING:
|
|
for (int i = 0 ; i < NUM_PIXELS ; i++)
|
|
NeoPixel_set_pixel(i, 0 , 0, frame*4);
|
|
if (frame == 63 || frame == 0)
|
|
v = -v;
|
|
frame += v;
|
|
break;
|
|
case BLINK:
|
|
if (!(frame++ % 20))
|
|
if (!on)
|
|
{
|
|
on = 1;
|
|
for (int i = 0 ; i < NUM_PIXELS ; i++)
|
|
NeoPixel_set_pixel(i, 0, 255, 0);
|
|
}
|
|
else
|
|
{
|
|
on = 0;
|
|
NeoPixel_clear_pixels();
|
|
}
|
|
break;
|
|
case SOUND:
|
|
#define THRESHOLD 200
|
|
if (adc_value < THRESHOLD) // threshold
|
|
sound_value = 0;
|
|
else
|
|
sound_value = (adc_value - THRESHOLD) * ((255.0 - 0.0)/(400.0 - THRESHOLD)); // linear map: y = (x - x1) * (y2 - y1)/(x2 - x1)
|
|
if (sound_value >= 255)
|
|
sound_value = 255;
|
|
for (int i = 0 ; i < NUM_PIXELS ; i++)
|
|
NeoPixel_set_pixel(i, sound_value, sound_value, 0);
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
|
|
/* send frame to DMA buffer */
|
|
NeoPixel_update();
|
|
}
|
|
}
|
|
|
|
void NeoPixel_set_animation(Animation animation)
|
|
{
|
|
current_animation = animation;
|
|
if (animation == SOUND)
|
|
ADC_init();
|
|
else
|
|
ADC_deinit();
|
|
frame = 1;
|
|
NeoPixel_clear_pixels();
|
|
}
|
|
|
|
/* bit expansion lookup table */
|
|
static const uint32_t bit_expand[256] = {
|
|
0b100100100100100100100100,
|
|
0b100100100100100100100110,
|
|
0b100100100100100100110100,
|
|
0b100100100100100100110110,
|
|
0b100100100100100110100100,
|
|
0b100100100100100110100110,
|
|
0b100100100100100110110100,
|
|
0b100100100100100110110110,
|
|
0b100100100100110100100100,
|
|
0b100100100100110100100110,
|
|
0b100100100100110100110100,
|
|
0b100100100100110100110110,
|
|
0b100100100100110110100100,
|
|
0b100100100100110110100110,
|
|
0b100100100100110110110100,
|
|
0b100100100100110110110110,
|
|
0b100100100110100100100100,
|
|
0b100100100110100100100110,
|
|
0b100100100110100100110100,
|
|
0b100100100110100100110110,
|
|
0b100100100110100110100100,
|
|
0b100100100110100110100110,
|
|
0b100100100110100110110100,
|
|
0b100100100110100110110110,
|
|
0b100100100110110100100100,
|
|
0b100100100110110100100110,
|
|
0b100100100110110100110100,
|
|
0b100100100110110100110110,
|
|
0b100100100110110110100100,
|
|
0b100100100110110110100110,
|
|
0b100100100110110110110100,
|
|
0b100100100110110110110110,
|
|
0b100100110100100100100100,
|
|
0b100100110100100100100110,
|
|
0b100100110100100100110100,
|
|
0b100100110100100100110110,
|
|
0b100100110100100110100100,
|
|
0b100100110100100110100110,
|
|
0b100100110100100110110100,
|
|
0b100100110100100110110110,
|
|
0b100100110100110100100100,
|
|
0b100100110100110100100110,
|
|
0b100100110100110100110100,
|
|
0b100100110100110100110110,
|
|
0b100100110100110110100100,
|
|
0b100100110100110110100110,
|
|
0b100100110100110110110100,
|
|
0b100100110100110110110110,
|
|
0b100100110110100100100100,
|
|
0b100100110110100100100110,
|
|
0b100100110110100100110100,
|
|
0b100100110110100100110110,
|
|
0b100100110110100110100100,
|
|
0b100100110110100110100110,
|
|
0b100100110110100110110100,
|
|
0b100100110110100110110110,
|
|
0b100100110110110100100100,
|
|
0b100100110110110100100110,
|
|
0b100100110110110100110100,
|
|
0b100100110110110100110110,
|
|
0b100100110110110110100100,
|
|
0b100100110110110110100110,
|
|
0b100100110110110110110100,
|
|
0b100100110110110110110110,
|
|
0b100110100100100100100100,
|
|
0b100110100100100100100110,
|
|
0b100110100100100100110100,
|
|
0b100110100100100100110110,
|
|
0b100110100100100110100100,
|
|
0b100110100100100110100110,
|
|
0b100110100100100110110100,
|
|
0b100110100100100110110110,
|
|
0b100110100100110100100100,
|
|
0b100110100100110100100110,
|
|
0b100110100100110100110100,
|
|
0b100110100100110100110110,
|
|
0b100110100100110110100100,
|
|
0b100110100100110110100110,
|
|
0b100110100100110110110100,
|
|
0b100110100100110110110110,
|
|
0b100110100110100100100100,
|
|
0b100110100110100100100110,
|
|
0b100110100110100100110100,
|
|
0b100110100110100100110110,
|
|
0b100110100110100110100100,
|
|
0b100110100110100110100110,
|
|
0b100110100110100110110100,
|
|
0b100110100110100110110110,
|
|
0b100110100110110100100100,
|
|
0b100110100110110100100110,
|
|
0b100110100110110100110100,
|
|
0b100110100110110100110110,
|
|
0b100110100110110110100100,
|
|
0b100110100110110110100110,
|
|
0b100110100110110110110100,
|
|
0b100110100110110110110110,
|
|
0b100110110100100100100100,
|
|
0b100110110100100100100110,
|
|
0b100110110100100100110100,
|
|
0b100110110100100100110110,
|
|
0b100110110100100110100100,
|
|
0b100110110100100110100110,
|
|
0b100110110100100110110100,
|
|
0b100110110100100110110110,
|
|
0b100110110100110100100100,
|
|
0b100110110100110100100110,
|
|
0b100110110100110100110100,
|
|
0b100110110100110100110110,
|
|
0b100110110100110110100100,
|
|
0b100110110100110110100110,
|
|
0b100110110100110110110100,
|
|
0b100110110100110110110110,
|
|
0b100110110110100100100100,
|
|
0b100110110110100100100110,
|
|
0b100110110110100100110100,
|
|
0b100110110110100100110110,
|
|
0b100110110110100110100100,
|
|
0b100110110110100110100110,
|
|
0b100110110110100110110100,
|
|
0b100110110110100110110110,
|
|
0b100110110110110100100100,
|
|
0b100110110110110100100110,
|
|
0b100110110110110100110100,
|
|
0b100110110110110100110110,
|
|
0b100110110110110110100100,
|
|
0b100110110110110110100110,
|
|
0b100110110110110110110100,
|
|
0b100110110110110110110110,
|
|
0b110100100100100100100100,
|
|
0b110100100100100100100110,
|
|
0b110100100100100100110100,
|
|
0b110100100100100100110110,
|
|
0b110100100100100110100100,
|
|
0b110100100100100110100110,
|
|
0b110100100100100110110100,
|
|
0b110100100100100110110110,
|
|
0b110100100100110100100100,
|
|
0b110100100100110100100110,
|
|
0b110100100100110100110100,
|
|
0b110100100100110100110110,
|
|
0b110100100100110110100100,
|
|
0b110100100100110110100110,
|
|
0b110100100100110110110100,
|
|
0b110100100100110110110110,
|
|
0b110100100110100100100100,
|
|
0b110100100110100100100110,
|
|
0b110100100110100100110100,
|
|
0b110100100110100100110110,
|
|
0b110100100110100110100100,
|
|
0b110100100110100110100110,
|
|
0b110100100110100110110100,
|
|
0b110100100110100110110110,
|
|
0b110100100110110100100100,
|
|
0b110100100110110100100110,
|
|
0b110100100110110100110100,
|
|
0b110100100110110100110110,
|
|
0b110100100110110110100100,
|
|
0b110100100110110110100110,
|
|
0b110100100110110110110100,
|
|
0b110100100110110110110110,
|
|
0b110100110100100100100100,
|
|
0b110100110100100100100110,
|
|
0b110100110100100100110100,
|
|
0b110100110100100100110110,
|
|
0b110100110100100110100100,
|
|
0b110100110100100110100110,
|
|
0b110100110100100110110100,
|
|
0b110100110100100110110110,
|
|
0b110100110100110100100100,
|
|
0b110100110100110100100110,
|
|
0b110100110100110100110100,
|
|
0b110100110100110100110110,
|
|
0b110100110100110110100100,
|
|
0b110100110100110110100110,
|
|
0b110100110100110110110100,
|
|
0b110100110100110110110110,
|
|
0b110100110110100100100100,
|
|
0b110100110110100100100110,
|
|
0b110100110110100100110100,
|
|
0b110100110110100100110110,
|
|
0b110100110110100110100100,
|
|
0b110100110110100110100110,
|
|
0b110100110110100110110100,
|
|
0b110100110110100110110110,
|
|
0b110100110110110100100100,
|
|
0b110100110110110100100110,
|
|
0b110100110110110100110100,
|
|
0b110100110110110100110110,
|
|
0b110100110110110110100100,
|
|
0b110100110110110110100110,
|
|
0b110100110110110110110100,
|
|
0b110100110110110110110110,
|
|
0b110110100100100100100100,
|
|
0b110110100100100100100110,
|
|
0b110110100100100100110100,
|
|
0b110110100100100100110110,
|
|
0b110110100100100110100100,
|
|
0b110110100100100110100110,
|
|
0b110110100100100110110100,
|
|
0b110110100100100110110110,
|
|
0b110110100100110100100100,
|
|
0b110110100100110100100110,
|
|
0b110110100100110100110100,
|
|
0b110110100100110100110110,
|
|
0b110110100100110110100100,
|
|
0b110110100100110110100110,
|
|
0b110110100100110110110100,
|
|
0b110110100100110110110110,
|
|
0b110110100110100100100100,
|
|
0b110110100110100100100110,
|
|
0b110110100110100100110100,
|
|
0b110110100110100100110110,
|
|
0b110110100110100110100100,
|
|
0b110110100110100110100110,
|
|
0b110110100110100110110100,
|
|
0b110110100110100110110110,
|
|
0b110110100110110100100100,
|
|
0b110110100110110100100110,
|
|
0b110110100110110100110100,
|
|
0b110110100110110100110110,
|
|
0b110110100110110110100100,
|
|
0b110110100110110110100110,
|
|
0b110110100110110110110100,
|
|
0b110110100110110110110110,
|
|
0b110110110100100100100100,
|
|
0b110110110100100100100110,
|
|
0b110110110100100100110100,
|
|
0b110110110100100100110110,
|
|
0b110110110100100110100100,
|
|
0b110110110100100110100110,
|
|
0b110110110100100110110100,
|
|
0b110110110100100110110110,
|
|
0b110110110100110100100100,
|
|
0b110110110100110100100110,
|
|
0b110110110100110100110100,
|
|
0b110110110100110100110110,
|
|
0b110110110100110110100100,
|
|
0b110110110100110110100110,
|
|
0b110110110100110110110100,
|
|
0b110110110100110110110110,
|
|
0b110110110110100100100100,
|
|
0b110110110110100100100110,
|
|
0b110110110110100100110100,
|
|
0b110110110110100100110110,
|
|
0b110110110110100110100100,
|
|
0b110110110110100110100110,
|
|
0b110110110110100110110100,
|
|
0b110110110110100110110110,
|
|
0b110110110110110100100100,
|
|
0b110110110110110100100110,
|
|
0b110110110110110100110100,
|
|
0b110110110110110100110110,
|
|
0b110110110110110110100100,
|
|
0b110110110110110110100110,
|
|
0b110110110110110110110100,
|
|
0b110110110110110110110110
|
|
};
|