thesis_bldc_controller/Examples/NeoPixel Example/NeoPixel.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
};