First commit

This commit is contained in:
Jonathan Wyss 2024-02-27 12:42:35 +01:00
commit 9bbd50c4f5
23 changed files with 1324 additions and 0 deletions

52
avr_adc.c Normal file
View File

@ -0,0 +1,52 @@
//setup adc for an attiny85
//
#include<avr/io.h>
#include"avr_adc.h"
#define _BS(bit) (1<<bit)
#define _BC(bit) ~(1<<bit)
#define STARTADC ADCSRA |= _BS(ADSC)
//1.setup_prescaler
/* this function initialises the ADC
ADC Prescaler Notes:
--------------------
ADC Prescaler needs to be set so that the ADC input frequency is between 50 - 200kHz.
For more information, see table 17.5 "ADC Prescaler Selections" in
chapter 17.13.2 "ADCSRA ADC Control and Status Register A"
(pages 140 and 141 on the complete ATtiny25/45/85 datasheet, Rev. 2586MAVR07/10)
Valid prescaler values for various clock speeds
Clock Available prescaler values
---------------------------------------
1 MHz 8 (125kHz), 16 (62.5kHz)
4 MHz 32 (125kHz), 64 (62.5kHz)
8 MHz 64 (125kHz), 128 (62.5kHz)
16 MHz 128 (125kHz)
Below example set prescaler to 128 for mcu running at 8MHz
(check the datasheet for the proper bit values to set the prescaler)
*/
void setupADC(void)
{
ADMUX = //_BC(REFS0) | //Set_Vref
//_BC(REFS1) | //Set_Vref
//_BC(MUX3) | //
//_BC(MUX2) | //
_BS(MUX1) | //
_BS(MUX0) | //PORT Select PB3
_BS(ADLAR) ; //left shift conversion results(used in 8bit mode)
ADCSRA = _BS(ADEN) | //Enable ADC
//_BC(ADATE) | //Disable AutoTrigger aka Freerunning mode
_BS(ADPS2) | //Select Prescaler clk/32
//_BC(ADPS1) |
_BS(ADPS0);
}

1
avr_adc.h Normal file
View File

@ -0,0 +1 @@
void setupADC(void);

BIN
avr_adc.o Normal file

Binary file not shown.

269
fix_fft.c Normal file
View File

@ -0,0 +1,269 @@
#include <avr/pgmspace.h>
#include "fix_fft.h"
//#include <WProgram.h> depreacted
/* fix_fft.c - Fixed-point in-place Fast Fourier Transform */
/*
All data are fixed-point short integers, in which -32768
to +32768 represent -1.0 to +1.0 respectively. Integer
arithmetic is used for speed, instead of the more natural
floating-point.
For the forward FFT (time -> freq), fixed scaling is
performed to prevent arithmetic overflow, and to map a 0dB
sine/cosine wave (i.e. amplitude = 32767) to two -6dB freq
coefficients. The return value is always 0.
For the inverse FFT (freq -> time), fixed scaling cannot be
done, as two 0dB coefficients would sum to a peak amplitude
of 64K, overflowing the 32k range of the fixed-point integers.
Thus, the fix_fft() routine performs variable scaling, and
returns a value which is the number of bits LEFT by which
the output must be shifted to get the actual amplitude
(i.e. if fix_fft() returns 3, each value of fr[] and fi[]
must be multiplied by 8 (2**3) for proper scaling.
Clearly, this cannot be done within fixed-point short
integers. In practice, if the result is to be used as a
filter, the scale_shift can usually be ignored, as the
result will be approximately correctly normalized as is.
Written by: Tom Roberts 11/8/89
Made portable: Malcolm Slaney 12/15/94 malcolm@interval.com
Enhanced: Dimitrios P. Bouras 14 Jun 2006 dbouras@ieee.org
Modified for 8bit values David Keller 10.10.2010
*/
#define N_WAVE 256 /* full length of Sinewave[] */
#define LOG2_N_WAVE 8 /* log2(N_WAVE) */
/*
Since we only use 3/4 of N_WAVE, we define only
this many samples, in order to conserve data space.
*/
//typedef uint8_t PROGMEM prog_uint8_t;
const uint8_t Sinewave[N_WAVE-N_WAVE/4] PROGMEM = {
0, 3, 6, 9, 12, 15, 18, 21,
24, 28, 31, 34, 37, 40, 43, 46,
48, 51, 54, 57, 60, 63, 65, 68,
71, 73, 76, 78, 81, 83, 85, 88,
90, 92, 94, 96, 98, 100, 102, 104,
106, 108, 109, 111, 112, 114, 115, 117,
118, 119, 120, 121, 122, 123, 124, 124,
125, 126, 126, 127, 127, 127, 127, 127,
127, 127, 127, 127, 127, 127, 126, 126,
125, 124, 124, 123, 122, 121, 120, 119,
118, 117, 115, 114, 112, 111, 109, 108,
106, 104, 102, 100, 98, 96, 94, 92,
90, 88, 85, 83, 81, 78, 76, 73,
71, 68, 65, 63, 60, 57, 54, 51,
48, 46, 43, 40, 37, 34, 31, 28,
24, 21, 18, 15, 12, 9, 6, 3,
0, -3, -6, -9, -12, -15, -18, -21,
-24, -28, -31, -34, -37, -40, -43, -46,
-48, -51, -54, -57, -60, -63, -65, -68,
-71, -73, -76, -78, -81, -83, -85, -88,
-90, -92, -94, -96, -98, -100, -102, -104,
-106, -108, -109, -111, -112, -114, -115, -117,
-118, -119, -120, -121, -122, -123, -124, -124,
-125, -126, -126, -127, -127, -127, -127, -127,
/*-127, -127, -127, -127, -127, -127, -126, -126,
-125, -124, -124, -123, -122, -121, -120, -119,
-118, -117, -115, -114, -112, -111, -109, -108,
-106, -104, -102, -100, -98, -96, -94, -92,
-90, -88, -85, -83, -81, -78, -76, -73,
-71, -68, -65, -63, -60, -57, -54, -51,
-48, -46, -43, -40, -37, -34, -31, -28,
-24, -21, -18, -15, -12, -9, -6, -3, */
};
/*
FIX_MPY() - fixed-point multiplication & scaling.
Substitute inline assembly for hardware-specific
optimization suited to a particluar DSP processor.
Scaling ensures that result remains 16-bit.
*/
static inline char FIX_MPY(char a, char b)
{
//Serial.println(a);
//Serial.println(b);
/* shift right one less bit (i.e. 15-1) */
int c = ((int)a * (int)b) >> 6;
/* last bit shifted out = rounding-bit */
b = c & 0x01;
/* last shift + rounding bit */
a = (c >> 1) + b;
/*
Serial.println(Sinewave[3]);
Serial.println(c);
Serial.println(a);
while(1);*/
return a;
}
/*
fix_fft() - perform forward/inverse fast Fourier transform.
fr[n],fi[n] are real and imaginary arrays, both INPUT AND
RESULT (in-place FFT), with 0 <= n < 2**m; set inverse to
0 for forward transform (FFT), or 1 for iFFT.
*/
int fix_fft(char fr[], char fi[], int m, int inverse)
{
int mr, nn, i, j, l, k, istep, n, scale, shift;
char qr, qi, tr, ti, wr, wi;
n = 1 << m;
/* max FFT size = N_WAVE */
if (n > N_WAVE)
return -1;
mr = 0;
nn = n - 1;
scale = 0;
/* decimation in time - re-order data */
for (m=1; m<=nn; ++m) {
l = n;
do {
l >>= 1;
} while (mr+l > nn);
mr = (mr & (l-1)) + l;
if (mr <= m)
continue;
tr = fr[m];
fr[m] = fr[mr];
fr[mr] = tr;
ti = fi[m];
fi[m] = fi[mr];
fi[mr] = ti;
}
l = 1;
k = LOG2_N_WAVE-1;
while (l < n) {
if (inverse) {
/* variable scaling, depending upon data */
shift = 0;
for (i=0; i<n; ++i) {
j = fr[i];
if (j < 0)
j = -j;
m = fi[i];
if (m < 0)
m = -m;
if (j > 16383 || m > 16383) {
shift = 1;
break;
}
}
if (shift)
++scale;
} else {
/*
fixed scaling, for proper normalization --
there will be log2(n) passes, so this results
in an overall factor of 1/n, distributed to
maximize arithmetic accuracy.
*/
shift = 1;
}
/*
it may not be obvious, but the shift will be
performed on each data point exactly once,
during this pass.
*/
istep = l << 1;
for (m=0; m<l; ++m) {
j = m << k;
/* 0 <= j < N_WAVE/2 */
wr = pgm_read_word_near(Sinewave + j+N_WAVE/4);
/*Serial.println("asdfasdf");
Serial.println(wr);
Serial.println(j+N_WAVE/4);
Serial.println(Sinewave[256]);
Serial.println("");*/
wi = -pgm_read_word_near(Sinewave + j);
if (inverse)
wi = -wi;
if (shift) {
wr >>= 1;
wi >>= 1;
}
for (i=m; i<n; i+=istep) {
j = i + l;
tr = FIX_MPY(wr,fr[j]) - FIX_MPY(wi,fi[j]);
ti = FIX_MPY(wr,fi[j]) + FIX_MPY(wi,fr[j]);
qr = fr[i];
qi = fi[i];
if (shift) {
qr >>= 1;
qi >>= 1;
}
fr[j] = qr - tr;
fi[j] = qi - ti;
fr[i] = qr + tr;
fi[i] = qi + ti;
}
}
--k;
l = istep;
}
return scale;
}
/*
fix_fftr() - forward/inverse FFT on array of real numbers.
Real FFT/iFFT using half-size complex FFT by distributing
even/odd samples into real/imaginary arrays respectively.
In order to save data space (i.e. to avoid two arrays, one
for real, one for imaginary samples), we proceed in the
following two steps: a) samples are rearranged in the real
array so that all even samples are in places 0-(N/2-1) and
all imaginary samples in places (N/2)-(N-1), and b) fix_fft
is called with fr and fi pointing to index 0 and index N/2
respectively in the original array. The above guarantees
that fix_fft "sees" consecutive real samples as alternating
real and imaginary samples in the complex array.
*/
int fix_fftr(char f[], int m, int inverse)
{
int i, N = 1<<(m-1), scale = 0;
char tt, *fr=f, *fi=&f[N];
if (inverse)
scale = fix_fft(fi, fr, m-1, inverse);
for (i=1; i<N; i+=2) {
tt = f[N+i-1];
f[N+i-1] = f[i];
f[i] = tt;
}
if (! inverse)
scale = fix_fft(fi, fr, m-1, inverse);
return scale;
}

38
fix_fft.h Normal file
View File

@ -0,0 +1,38 @@
#ifndef FIXFFT_H
#define FIXFFT_H
//#include <WProgram.h> //depreacted included in arduino.h
/*
fix_fft() - perform forward/inverse fast Fourier transform.
fr[n],fi[n] are real and imaginary arrays, both INPUT AND
RESULT (in-place FFT), with 0 <= n < 2**m; set inverse to
0 for forward transform (FFT), or 1 for iFFT.
*/
int fix_fft(char fr[], char fi[], int m, int inverse);
/*
fix_fftr() - forward/inverse FFT on array of real numbers.
Real FFT/iFFT using half-size complex FFT by distributing
even/odd samples into real/imaginary arrays respectively.
In order to save data space (i.e. to avoid two arrays, one
for real, one for imaginary samples), we proceed in the
following two steps: a) samples are rearranged in the real
array so that all even samples are in places 0-(N/2-1) and
all imaginary samples in places (N/2)-(N-1), and b) fix_fft
is called with fr and fi pointing to index 0 and index N/2
respectively in the original array. The above guarantees
that fix_fft "sees" consecutive real samples as alternating
real and imaginary samples in the complex array.
*/
int fix_fftr(char f[], int m, int inverse);
static inline char FIX_MPY(char a,char b);
#endif

BIN
fix_fft.o Normal file

Binary file not shown.

View File

@ -0,0 +1,52 @@
/*
* ATTENTION: This example uses the old v1.0 interface.
*
* Light_WS2812 library example - Chained Writes
*
* This example shows how to use multiple calls without issuing a reset
* in between, allowing to send the same buffer to the string
* multiple times. This technique can be useful to conserve memory
* or to calculate LED colors on-the-fly.
*
* Please make sure to set your configuration in "WS2812_config.h" first
*
*/
#include <util/delay.h>
#include <avr/io.h>
#include <avr/interrupt.h>
#include "light_ws2812.h"
struct cRGB led[2];
int main(void)
{
uint8_t pos=0;
uint8_t direction=1;
uint8_t i;
#ifdef __AVR_ATtiny10__
CCP=0xD8; // configuration change protection, write signature
CLKPSR=0; // set cpu clock prescaler =1 (8Mhz) (attiny 4/5/9/10)
#endif
led[0].r=16;led[0].g=00;led[0].b=00; // LED 0 is red
led[1].r=16;led[1].g=16;led[1].b=16; // LED 1 is White
while(1)
{
for (i=0; i<pos; i++)
ws2812_sendarray((uint8_t *)&led[0],3); // Repeatedly send "red" to the led string.
// No more than 1-2µs should pass between calls
// to avoid issuing a reset condition.
for (i=0; i<(16-pos); i++)
ws2812_sendarray((uint8_t *)&led[1],3); // white
_delay_ms(50); // Issue reset and wait for 50 ms.
pos+=direction;
if ((pos==16)||(pos==0)) direction=-direction;
}
}

View File

@ -0,0 +1,45 @@
/*
* Light_WS2812 library example - RGBW_blinky
*
* cycles one LED through red, green, blue, white
*
* This example does only work with the SK6812RGBW LEDs
*
* Please make sure to set your configuration in "WS2812_config.h" first
*
*/
#include <util/delay.h>
#include <avr/io.h>
#include <avr/interrupt.h>
#include "light_ws2812.h"
struct cRGBW led[1];
int main(void)
{
#ifdef __AVR_ATtiny10__
CCP=0xD8; // configuration change protection, write signature
CLKPSR=0; // set cpu clock prescaler =1 (8Mhz) (attiny 4/5/9/10)
#endif
while(1)
{
led[0].r=128;led[0].g=00;led[0].b=0;led[0].w=0; // Write red to array
ws2812_setleds_rgbw(led,1);
_delay_ms(500); // wait for 500ms.
led[0].r=0;led[0].g=128;led[0].b=0;led[0].w=0; // green
ws2812_setleds_rgbw(led,1);
_delay_ms(500);
led[0].r=0;led[0].g=0;led[0].b=128;led[0].w=0; // blue
ws2812_setleds_rgbw(led,1);
_delay_ms(500);
led[0].r=0;led[0].g=0;led[0].b=0;led[0].w=128; // white
ws2812_setleds_rgbw(led,1);
_delay_ms(500);
}
}

View File

@ -0,0 +1,38 @@
/*
* Light_WS2812 library example - RGB_blinky
*
* cycles one LED through red, green, blue
*
* This example is configured for a ATtiny85 with PLL clock fuse set and
* the WS2812 string connected to PB4.
*/
#include <util/delay.h>
#include <avr/io.h>
#include <avr/interrupt.h>
#include "light_ws2812.h"
struct cRGB led[1];
int main(void)
{
#ifdef __AVR_ATtiny10__
CCP=0xD8; // configuration change protection, write signature
CLKPSR=0; // set cpu clock prescaler =1 (8Mhz) (attiny 4/5/9/10)
#endif
while(1)
{
led[0].r=255;led[0].g=00;led[0].b=0; // Write red to array
ws2812_setleds(led,1);
_delay_ms(500); // wait for 500ms.
led[0].r=0;led[0].g=255;led[0].b=0; // green
ws2812_setleds(led,1);
_delay_ms(500);
led[0].r=0;led[0].g=00;led[0].b=255; // blue
ws2812_setleds(led,1);
_delay_ms(500);
}
}

View File

@ -0,0 +1,84 @@
/*
*
* This example is configured for a Atmega32 at 16MHz
*/
#include <util/delay.h>
#include <avr/io.h>
#include <avr/interrupt.h>
#include "light_ws2812.h"
#define MAXPIX 30
#define COLORLENGTH (MAXPIX/2)
#define FADE (256/COLORLENGTH)
struct cRGB colors[8];
struct cRGB led[MAXPIX];
int main(void)
{
uint8_t j = 1;
uint8_t k = 1;
DDRB|=_BV(ws2812_pin);
uint8_t i;
for(i=MAXPIX; i>0; i--)
{
led[i-1].r=0;led[i-1].g=0;led[i-1].b=0;
}
//Rainbowcolors
colors[0].r=150; colors[0].g=150; colors[0].b=150;
colors[1].r=255; colors[1].g=000; colors[1].b=000;//red
colors[2].r=255; colors[2].g=100; colors[2].b=000;//orange
colors[3].r=100; colors[3].g=255; colors[3].b=000;//yellow
colors[4].r=000; colors[4].g=255; colors[4].b=000;//green
colors[5].r=000; colors[5].g=100; colors[5].b=255;//light blue (türkis)
colors[6].r=000; colors[6].g=000; colors[6].b=255;//blue
colors[7].r=100; colors[7].g=000; colors[7].b=255;//violet
while(1)
{
//shift all vallues by one led
uint8_t i=0;
for(i=MAXPIX; i>1; i--)
led[i-1]=led[i-2];
//change colour when colourlength is reached
if(k>COLORLENGTH)
{
j++;
if(j>7)
{
j=0;
}
k=0;
}
k++;
//loop colouers
//fade red
if(led[0].r<(colors[j].r-FADE))
led[0].r+=FADE;
if(led[0].r>(colors[j].r+FADE))
led[0].r-=FADE;
if(led[0].g<(colors[j].g-FADE))
led[0].g+=FADE;
if(led[0].g>(colors[j].g+FADE))
led[0].g-=FADE;
if(led[0].b<(colors[j].b-FADE))
led[0].b+=FADE;
if(led[0].b>(colors[j].b+FADE))
led[0].b-=FADE;
_delay_ms(10);
ws2812_sendarray((uint8_t *)led,MAXPIX*3);
}
}

View File

@ -0,0 +1,218 @@
/*
* light weight WS2812 lib V2.5b
*
* Controls WS2811/WS2812/WS2812B RGB-LEDs
* Author: Tim (cpldcpu@gmail.com)
*
* Jan 18th, 2014 v2.0b Initial Version
* Nov 29th, 2015 v2.3 Added SK6812RGBW support
* Nov 11th, 2023 v2.5 Added support for ports that cannot be addressed with "out"
* Added LGT8F88A support
*
* License: GNU GPL v2+ (see License.txt)
*/
#include "light_ws2812.h"
#include <avr/interrupt.h>
#include <avr/io.h>
#include <util/delay.h>
// Normally ws2812_sendarray_mask() runs under disabled-interrupt condition,
// undefine if you want to accept interrupts in that function.
#define interrupt_is_disabled
// Setleds for standard RGB
void inline ws2812_setleds(struct cRGB *ledarray, uint16_t leds)
{
ws2812_setleds_pin(ledarray,leds, _BV(ws2812_pin));
}
void inline ws2812_setleds_pin(struct cRGB *ledarray, uint16_t leds, uint8_t pinmask)
{
ws2812_sendarray_mask((uint8_t*)ledarray,leds+leds+leds,pinmask);
_delay_us(ws2812_resettime);
}
// Setleds for SK6812RGBW
void inline ws2812_setleds_rgbw(struct cRGBW *ledarray, uint16_t leds)
{
ws2812_sendarray_mask((uint8_t*)ledarray,leds<<2,_BV(ws2812_pin));
_delay_us(ws2812_resettime);
}
void ws2812_sendarray(uint8_t *data,uint16_t datlen)
{
ws2812_sendarray_mask(data,datlen,_BV(ws2812_pin));
}
/*
This routine writes an array of bytes with RGB values to the Dataout pin
using the fast 800kHz clockless WS2811/2812 protocol.
*/
// Timing in ns
#define w_zeropulse 350
#define w_onepulse 900
#define w_totalperiod 1250
// Fixed cycles used by the inner loop
#if defined(__LGT8F__)
#define w_fixedlow 4
#define w_fixedhigh 6
#define w_fixedtotal 10
#else
#define w_fixedlow 3
#define w_fixedhigh 6
#define w_fixedtotal 10
#endif
// // Fixed cycles used by the inner loop
// #define w_fixedlow 2
// #define w_fixedhigh 4
// #define w_fixedtotal 8
// Insert NOPs to match the timing, if possible
#define w_zerocycles (((F_CPU/1000)*w_zeropulse )/1000000)
#define w_onecycles (((F_CPU/1000)*w_onepulse +500000)/1000000)
#define w_totalcycles (((F_CPU/1000)*w_totalperiod +500000)/1000000)
// w1 - nops between rising edge and falling edge - low
#define w1 (w_zerocycles-w_fixedlow)
// w2 nops between fe low and fe high
#define w2 (w_onecycles-w_fixedhigh-w1)
// w3 nops to complete loop
#define w3 (w_totalcycles-w_fixedtotal-w1-w2)
#if w1>0
#define w1_nops w1
#else
#define w1_nops 0
#endif
// The only critical timing parameter is the minimum pulse length of the "0"
// Warn or throw error if this timing can not be met with current F_CPU settings.
#define w_lowtime ((w1_nops+w_fixedlow)*1000000)/(F_CPU/1000)
#if w_lowtime>550
#error "Light_ws2812: Sorry, the clock speed is too low. Did you set F_CPU correctly?"
#elif w_lowtime>450
#warning "Light_ws2812: The timing is critical and may only work on WS2812B, not on WS2812(S)."
#warning "Please consider a higher clockspeed, if possible"
#endif
#if w2>0
#define w2_nops w2
#else
#define w2_nops 0
#endif
#if w3>0
#define w3_nops w3
#else
#define w3_nops 0
#endif
#define w_nop1 "nop \n\t"
#ifdef interrupt_is_disabled
#define w_nop2 "brid .+0 \n\t"
#else
#define w_nop2 "brtc .+0 \n\t"
#endif
#define w_nop4 w_nop2 w_nop2
#define w_nop8 w_nop4 w_nop4
#define w_nop16 w_nop8 w_nop8
void inline ws2812_sendarray_mask(uint8_t *data,uint16_t datlen,uint8_t maskhi)
{
uint8_t curbyte,ctr,masklo;
uint8_t sreg_prev;
uint8_t *port = (uint8_t*) _SFR_MEM_ADDR(ws2812_PORTREG);
ws2812_DDRREG |= maskhi; // Enable output
masklo =~maskhi&ws2812_PORTREG;
maskhi |= ws2812_PORTREG;
sreg_prev=SREG;
#ifdef interrupt_is_disabled
cli();
#endif
while (datlen--) {
curbyte=*data++;
asm volatile(
" ldi %0,8 \n\t"
#ifndef interrupt_is_disabled
" clt \n\t"
#endif
"loop%=: \n\t"
" st X,%3 \n\t" // '1' [02] '0' [02] - re
#if (w1_nops&1)
w_nop1
#endif
#if (w1_nops&2)
w_nop2
#endif
#if (w1_nops&4)
w_nop4
#endif
#if (w1_nops&8)
w_nop8
#endif
#if (w1_nops&16)
w_nop16
#endif
#if defined(__LGT8F__)
" bst %1,7 \n\t" // '1' [02] '0' [02]
" brts 1f \n\t" // '1' [04] '0' [03]
" st X,%4 \n\t" // '1' [--] '0' [04] - fe-low
"1: lsl %1 \n\t" // '1' [05] '0' [05]
#else
" sbrs %1,7 \n\t" // '1' [04] '0' [03]
" st X,%4 \n\t" // '1' [--] '0' [05] - fe-low
" lsl %1 \n\t" // '1' [05] '0' [06]
#endif
#if (w2_nops&1)
w_nop1
#endif
#if (w2_nops&2)
w_nop2
#endif
#if (w2_nops&4)
w_nop4
#endif
#if (w2_nops&8)
w_nop8
#endif
#if (w2_nops&16)
w_nop16
#endif
" brcc skipone%= \n\t" // '1' [+1] '0' [+2] -
" st X,%4 \n\t" // '1' [+3] '0' [--] - fe-high
"skipone%=: " // '1' [+3] '0' [+2] -
#if (w3_nops&1)
w_nop1
#endif
#if (w3_nops&2)
w_nop2
#endif
#if (w3_nops&4)
w_nop4
#endif
#if (w3_nops&8)
w_nop8
#endif
#if (w3_nops&16)
w_nop16
#endif
" dec %0 \n\t" // '1' [+4] '0' [+3]
" brne loop%=\n\t" // '1' [+5] '0' [+4]
: "=&d" (ctr)
: "r" (curbyte), "x" (port), "r" (maskhi), "r" (masklo)
);
}
SREG=sreg_prev;
}

View File

@ -0,0 +1,98 @@
/*
* light weight WS2812 lib include
*
* Version 2.3 - Nev 29th 2015
* Author: Tim (cpldcpu@gmail.com)
*
* Please do not change this file! All configuration is handled in "ws2812_config.h"
*
* License: GNU GPL v2+ (see License.txt)
+
*/
#ifndef LIGHT_WS2812_H_
#define LIGHT_WS2812_H_
#include "ws2812_config.h"
#include <avr/io.h>
#include <avr/interrupt.h>
///////////////////////////////////////////////////////////////////////
// Define Reset time in µs.
//
// This is the time the library spends waiting after writing the data.
//
// WS2813 needs 300 µs reset time
// WS2812 and clones only need 50 µs
//
///////////////////////////////////////////////////////////////////////
#if !defined(ws2812_resettime)
#define ws2812_resettime 300
#endif
///////////////////////////////////////////////////////////////////////
// Define I/O pin
///////////////////////////////////////////////////////////////////////
#if !defined(ws2812_port)
#define ws2812_port B // Data port
#endif
#if !defined(ws2812_pin)
#define ws2812_pin 0 // Data out pin
#endif
/*
* Structure of the LED array
*
* cRGB: RGB for WS2812S/B/C/D, SK6812, SK6812Mini, SK6812WWA, APA104, APA106
* cRGBW: RGBW for SK6812RGBW
*/
struct cRGB { uint8_t g; uint8_t r; uint8_t b; };
struct cRGBW { uint8_t g; uint8_t r; uint8_t b; uint8_t w;};
/* User Interface
*
* Input:
* ledarray: An array of GRB data describing the LED colors
* number_of_leds: The number of LEDs to write
* pinmask (optional): Bitmask describing the output bin. e.g. _BV(PB0)
*
* The functions will perform the following actions:
* - Set the data-out pin as output
* - Send out the LED data
* - Wait 50µs to reset the LEDs
*/
void ws2812_setleds (struct cRGB *ledarray, uint16_t number_of_leds);
void ws2812_setleds_pin (struct cRGB *ledarray, uint16_t number_of_leds,uint8_t pinmask);
void ws2812_setleds_rgbw(struct cRGBW *ledarray, uint16_t number_of_leds);
/*
* Old interface / Internal functions
*
* The functions take a byte-array and send to the data output as WS2812 bitstream.
* The length is the number of bytes to send - three per LED.
*/
void ws2812_sendarray (uint8_t *array,uint16_t length);
void ws2812_sendarray_mask(uint8_t *array,uint16_t length, uint8_t pinmask);
/*
* Internal defines
*/
#if !defined(CONCAT)
#define CONCAT(a, b) a ## b
#endif
#if !defined(CONCAT_EXP)
#define CONCAT_EXP(a, b) CONCAT(a, b)
#endif
#define ws2812_PORTREG CONCAT_EXP(PORT,ws2812_port)
#define ws2812_DDRREG CONCAT_EXP(DDR,ws2812_port)
#endif /* LIGHT_WS2812_H_ */

Binary file not shown.

View File

@ -0,0 +1,34 @@
/*
* light_ws2812_config.h
*
* v2.4 - Nov 27, 2016
*
* User Configuration file for the light_ws2812_lib
*
*/
#ifndef WS2812_CONFIG_H_
#define WS2812_CONFIG_H_
///////////////////////////////////////////////////////////////////////
// Define Reset time in µs.
//
// This is the time the library spends waiting after writing the data.
//
// WS2813 needs 300 µs reset time
// WS2812 and clones only need 50 µs
//
///////////////////////////////////////////////////////////////////////
#define ws2812_resettime 300
///////////////////////////////////////////////////////////////////////
// Define I/O pin
///////////////////////////////////////////////////////////////////////
#define ws2812_port B // Data port
#define ws2812_pin 4 // Data out pin
#endif /* WS2812_CONFIG_H_ */

40
light_ws2812_AVR/Makefile Normal file
View File

@ -0,0 +1,40 @@
# Makefile to build light_ws2812 library examples
# This is not a very good example of a makefile - the dependencies do not work, therefore everything is rebuilt every time.
# Change these parameters for your device
F_CPU = 16000000
# DEVICE = attiny85
DEVICE = atmega168p
#
# Tools:
CC = avr-gcc
LIB = light_ws2812
EXAMPLES = RGB_blinky RGBW_blinky Chained_writes Rainbow
DEP = ws2812_config.h Light_WS2812/light_ws2812.h
CFLAGS = -g2 -I. -ILight_WS2812 -mmcu=$(DEVICE) -DF_CPU=$(F_CPU)
CFLAGS+= -Os -ffunction-sections -fdata-sections -fpack-struct -fno-move-loop-invariants -fno-tree-scev-cprop -fno-inline-small-functions
CFLAGS+= -Wall -Wno-pointer-to-int-cast
#CFLAGS+= -Wa,-ahls=$<.lst
LDFLAGS = -Wl,--relax,--section-start=.text=0,-Map=main.map
all: $(EXAMPLES)
$(LIB): $(DEP)
@echo Building Library
@$(CC) $(CFLAGS) -o Objects/$@.o -c Light_WS2812/$@.c
$(EXAMPLES): $(LIB)
@echo Building $@
@$(CC) $(CFLAGS) -o Objects/$@.o Examples/$@.c Light_WS2812/$^.c
@avr-size Objects/$@.o
@avr-objcopy -j .text -j .data -O ihex Objects/$@.o $@.hex
@avr-objdump -d -S Objects/$@.o >Objects/$@.lss
.PHONY: clean
clean:
rm -f *.hex Objects/*.o Objects/*.lss

View File

@ -0,0 +1 @@
empty

42
main.c Normal file
View File

@ -0,0 +1,42 @@
#define F_CPU 1000000UL
#include<util/delay.h>
#include<avr/io.h>
#include"fix_fft.h"
#include"avr_adc.h"
#include"light_ws2812_AVR/Light_WS2812/ws2812_config.h"
#include"light_ws2812_AVR/Light_WS2812/light_ws2812.h"
#define STARTADC ADCSRA |= _BS(ADSC)
#define PB_mic PB0
int main (void)
{
int i;
char sample[128];
char im[128];
struct cRGB led_bar1[1];
//DDRB = (1<<mic);//would be setting output, default is input so no need for setting
//setupADC();
while(1)
{
//######RECORD SAMPLES#######
/*for(i=0;i<128;i++)
{
sample[i] = ADCH; //read Analog value register 8bit
im[i]=0; //pseudo data for funciton
}*/
//fix_fft(sample,im,7,0);//im[i] is always zero
led_bar1[0].r=0;led_bar1[0].g=100;led_bar1[0].b=10;
ws2812_setleds(led_bar1,1);
_delay_ms(500);
led_bar1[0].r=255;led_bar1[0].g=0;led_bar1[0].b=10;
ws2812_setleds(led_bar1,1);
_delay_ms(500);
}
return 0;
}

1
main.eep Normal file
View File

@ -0,0 +1 @@
:00000001FF

BIN
main.elf Executable file

Binary file not shown.

88
main.hex Normal file
View File

@ -0,0 +1,88 @@
:100000006EC075C074C073C072C071C070C06FC064
:100010006EC06DC06CC06BC06AC069C068C00003B0
:1000200006090C0F1215181C1F2225282B2E303301
:1000300036393C3F414447494C4E515355585A5C20
:100040005E60626466686A6C6D6F707273757677F5
:1000500078797A7B7C7C7D7E7E7F7F7F7F7F7F7FD0
:100060007F7F7F7F7E7E7D7C7C7B7A7978777675DB
:100070007372706F6D6C6A68666462605E5C5A5819
:100080005553514E4C494744413F3C393633302E4D
:100090002B2825221F1C1815120F0C09060300FD22
:1000A000FAF7F4F1EEEBE8E4E1DEDBD8D5D2D0CD1F
:1000B000CAC7C4C1BFBCB9B7B4B2AFADABA8A6A4E0
:1000C000A2A09E9C9A9896949391908E8D8B8A89EB
:1000D00088878685848483828281818181811124BD
:1000E0001FBECFE5D2E0DEBFCDBF03D23EC288CF78
:1000F00083E287B985E886B908952F923F924F929F
:100100005F926F927F928F929F92AF92BF92CF92A7
:10011000DF92EF92FF920F931F93CF93DF93CDB7B0
:10012000DEB72E970FB6F894DEBF0FBECDBF3C01F1
:100130004B0129833A8321E030E002C0220F331FB4
:100140004A95E2F73C872B878FEF9FEF213041E004
:100150003407D4F48901015011097301DB0180E0F7
:1001600090E041E050E0041715073CF567E0262ECB
:10017000312CEE24E394F12C4B855C85E416F506D6
:100180000CF44DC080E090E02E960FB6F894DEBFE0
:100190000FBECDBFDF91CF911F910F91FF90EF90D8
:1001A000DF90CF90BF90AF909F908F907F906F9097
:1001B0005F904F903F902F9008952B853C8535950B
:1001C0002795BC01620F731F06171707C4F3B90107
:1001D0006150710986239723820F931F481759078F
:1001E000BCF4F70161819301280F391FF901708177
:1001F000F7017183F901608311966C911197940155
:10020000280F391FF901708111967C931197608333
:100210004F5F5F4FFFEFEF1AFF0A1196A4CF270140
:10022000440C551C00E010E00E151F052CF031E0C9
:10023000231A31087201A0CFC801022C02C0880F16
:10024000991F0A94E2F7FC01E25AFF4F259134917D
:10025000422FFC01E25EFF4F85919491A981BA8102
:10026000AB2B19F48195459585955701A00EB11ECC
:100270006801E42F440FFF0BF887EF83282F880FC6
:10028000330B3A8729872B853C85C216D3061CF091
:100290000F5F1F4FC9CFA3014A0D5B1D5E834D83C6
:1002A000DA012C91022E000C330B8F819885B90155
:1002B0004BD1BC0186FB442740F9660F672F661FB0
:1002C000770B460F4E87F401EA0DFB1DFC83EB8391
:1002D000A0810A2E000CBB0B89859A85BD0134D103
:1002E000BC0186FBEE27E0F9660F672F661F770BD0
:1002F000E60F4E1B4D87CD016F81788525D1DC013E
:1003000089859A85B90120D19C01880F892F881F82
:10031000990BBD01660F672F661F770B860FA6FB33
:10032000AA27A0F9A80F26FB222720F92A0FB3013C
:100330006C0D7D1DDB019C91D401AC0DBD1D8C911C
:1003400049815A81452B11F495958595FE85EF1BC2
:100350003E2F390FED81FE813083382F321BEB8128
:10036000FC813083FD859F0FFB019083280F2C9328
:10037000C40CD51CA40CB51C86CFAF92BF92CF92F3
:10038000DF92EF92FF920F931F93CF93DF93EC01D5
:100390007A018B010150110981E090E06C01002E7F
:1003A00002C0CC0CDD1C0A94E2F75E01AC0CBD1C53
:1003B00080E090E04115510529F09A01A801BE01A5
:1003C000C5019BDEFE0121E030E02C153D0594F0D7
:1003D000EF28D9F420E030E0A801BE01C501DF918B
:1003E000CF911F910F91FF90EF90DF90CF90BF9032
:1003F000AF9083CEDF01AC0DBD1D4C9151815C935C
:1004000041832E5F3F4F3296E0CFDF91CF911F9116
:100410000F91FF90EF90DF90CF90BF90AF90089535
:100420009C01CB0157B3542B57BB68B3542F509545
:10043000562368B3462B6FB7F894820F931FA8E337
:10044000B0E02817390711F46FBF0895F9017191D1
:100450009F01E8E04C93000007F407F407F407F469
:1004600007F407F407F407F407F407F407F407F4B4
:1004700007F407F477FF5C93770F07F407F407F4AA
:1004800007F407F407F407F407F407F407F407F494
:1004900007F407F407F407F408F45C9307F407F48F
:1004A00007F407F407F407F407F407F407F407F474
:1004B00007F407F407F407F4EA9561F6C2CF9C014C
:1004C000CB0163E070E040D0BC01C901A9DF84E644
:1004D0008A95F1F7089540E1F2CF660F771F660F16
:1004E000771F40E19DDF84E68A95F1F7089540E1AA
:1004F00097CF00D00F92CDB7DEB784E6F82E1AE082
:100500000FEF1A82F9821B8361E070E0CE01019641
:10051000E2DF2FE986E891E0215080409040E1F74A
:1005200000C000000A8319821B8361E070E0CE01E5
:100530000196D1DF2FE986E891E02150804090407C
:10054000E1F700C00000DDCF0024552704C0080EED
:10055000591F880F991F009729F076956795B8F372
:0E0560007105B9F7802D952F0895F894FFCFFF
:00000001FF

BIN
main.o Normal file

Binary file not shown.

223
makefile Normal file
View File

@ -0,0 +1,223 @@
# Hey Emacs, this is a -*- makefile -*-
# AVR-GCC Makefile template, derived from the WinAVR template (which
# is public domain), believed to be neutral to any flavor of "make"
# (GNU make, BSD make, SysV make)
MCU = attiny85
FORMAT = ihex
TARGET = main
SRC = $(TARGET).c avr_adc.c fix_fft.c light_ws2812_AVR/Light_WS2812/light_ws2812.c
ASRC =
OPT = s
# Name of this Makefile (used for "make depend").
MAKEFILE = Makefile
# Debugging format.
# Native formats for AVR-GCC's -g are stabs [default], or dwarf-2.
# AVR (extended) COFF requires stabs, plus an avr-objcopy run.
DEBUG = stabs
# Compiler flag to set the C Standard level.
# c89 - "ANSI" C
# gnu89 - c89 plus GCC extensions
# c99 - ISO C99 standard (not yet fully implemented)
# gnu99 - c99 plus GCC extensions
CSTANDARD = -std=gnu99
# Place -D or -U options here
CDEFS = -DF_CPU=1000000UL
# Place -I options here
CINCS =
CDEBUG = -g$(DEBUG)
CWARN = -Wall -Wstrict-prototypes
CTUNING = -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums
#CEXTRA = -Wa,-adhlns=$(<:.c=.lst)
CFLAGS = $(CDEBUG) $(CDEFS) $(CINCS) -O$(OPT) $(CWARN) $(CSTANDARD) $(CEXTRA)
#ASFLAGS = -Wa,-adhlns=$(<:.S=.lst),-gstabs
#Additional libraries.
# Minimalistic printf version
PRINTF_LIB_MIN = -Wl,-u,vfprintf -lprintf_min
# Floating point printf version (requires MATH_LIB = -lm below)
PRINTF_LIB_FLOAT = -Wl,-u,vfprintf -lprintf_flt
PRINTF_LIB =
# Minimalistic scanf version
SCANF_LIB_MIN = -Wl,-u,vfscanf -lscanf_min
# Floating point + %[ scanf version (requires MATH_LIB = -lm below)
SCANF_LIB_FLOAT = -Wl,-u,vfscanf -lscanf_flt
SCANF_LIB =
MATH_LIB = -lm
# External memory options
# 64 KB of external RAM, starting after internal RAM (ATmega128!),
# used for variables (.data/.bss) and heap (malloc()).
#EXTMEMOPTS = -Wl,--section-start,.data=0x801100,--defsym=__heap_end=0x80ffff
# 64 KB of external RAM, starting after internal RAM (ATmega128!),
# only used for heap (malloc()).
#EXTMEMOPTS = -Wl,--defsym=__heap_start=0x801100,--defsym=__heap_end=0x80ffff
EXTMEMOPTS =
#LDMAP = $(LDFLAGS) -Wl,-Map=$(TARGET).map,--cref
LDFLAGS = $(EXTMEMOPTS) $(LDMAP) $(PRINTF_LIB) $(SCANF_LIB) $(MATH_LIB)
# Programming support using avrdude. Settings and variables.
AVRDUDE_PROGRAMMER = arduino#usbasp
#AVRDUDE_PORT = /dev/term/a
AVRDUDE_WRITE_FLASH = -U flash:w:$(TARGET).hex
#AVRDUDE_WRITE_EEPROM = -U eeprom:w:$(TARGET).eep
# Uncomment the following if you want avrdude's erase cycle counter.
# Note that this counter needs to be initialized first using -Yn,
# see avrdude manual.
#AVRDUDE_ERASE_COUNTER = -y
# Uncomment the following if you do /not/ wish a verification to be
# performed after programming the device.
#AVRDUDE_NO_VERIFY = -V
# Increase verbosity level. Please use this when submitting bug
# reports about avrdude. See <http://savannah.nongnu.org/projects/avrdude>
# to submit bug reports.
#AVRDUDE_VERBOSE = -v -v
AVRDUDE_BASIC = -p $(MCU) -c $(AVRDUDE_PROGRAMMER) -B4
AVRDUDE_FLAGS = $(AVRDUDE_BASIC) $(AVRDUDE_NO_VERIFY) $(AVRDUDE_VERBOSE) $(AVRDUDE_ERASE_COUNTER)
CC = avr-gcc
OBJCOPY = avr-objcopy
OBJDUMP = avr-objdump
SIZE = avr-size
NM = avr-nm
AVRDUDE = avrdude
REMOVE = rm -f
MV = mv -f
# Define all object files.
OBJ = $(SRC:.c=.o) $(ASRC:.S=.o)
# Define all listing files.
LST = $(ASRC:.S=.lst) $(SRC:.c=.lst)
# Combine all necessary flags and optional flags.
# Add target processor to flags.
ALL_CFLAGS = -mmcu=$(MCU) -I. $(CFLAGS)
ALL_ASFLAGS = -mmcu=$(MCU) -I. -x assembler-with-cpp $(ASFLAGS)
# Default target.
all: build
build: elf hex eep
elf: $(TARGET).elf
hex: $(TARGET).hex
eep: $(TARGET).eep
lss: $(TARGET).lss
sym: $(TARGET).sym
# Program the device.
program: $(TARGET).hex $(TARGET).eep
$(AVRDUDE) $(AVRDUDE_FLAGS) $(AVRDUDE_WRITE_FLASH) $(AVRDUDE_WRITE_EEPROM)
# Convert ELF to COFF for use in debugging / simulating in AVR Studio or VMLAB.
COFFCONVERT=$(OBJCOPY) --debugging \
--change-section-address .data-0x800000 \
--change-section-address .bss-0x800000 \
--change-section-address .noinit-0x800000 \
--change-section-address .eeprom-0x810000
coff: $(TARGET).elf
$(COFFCONVERT) -O coff-avr $(TARGET).elf $(TARGET).cof
extcoff: $(TARGET).elf
$(COFFCONVERT) -O coff-ext-avr $(TARGET).elf $(TARGET).cof
.SUFFIXES: .elf .hex .eep .lss .sym
.elf.hex:
$(OBJCOPY) -O $(FORMAT) -R .eeprom $< $@
.elf.eep:
-$(OBJCOPY) -j .eeprom --set-section-flags=.eeprom="alloc,load" \
--change-section-lma .eeprom=0 -O $(FORMAT) $< $@
# Create extended listing file from ELF output file.
.elf.lss:
$(OBJDUMP) -h -S $< > $@
# Create a symbol table from ELF output file.
.elf.sym:
$(NM) -n $< > $@
# Link: create ELF output file from object files.
$(TARGET).elf: $(OBJ)
$(CC) $(ALL_CFLAGS) $(OBJ) --output $@ $(LDFLAGS)
# Compile: create object files from C source files.
.c.o:
$(CC) -c $(ALL_CFLAGS) $< -o $@
# Compile: create assembler files from C source files.
.c.s:
$(CC) -S $(ALL_CFLAGS) $< -o $@
# Assemble: create object files from assembler source files.
.S.o:
$(CC) -c $(ALL_ASFLAGS) $< -o $@
# Target: clean project.
clean:
$(REMOVE) $(TARGET).hex $(TARGET).eep $(TARGET).cof $(TARGET).elf \
$(TARGET).map $(TARGET).sym $(TARGET).lss \
$(OBJ) $(LST) $(SRC:.c=.s) $(SRC:.c=.d)
depend:
if grep '^# DO NOT DELETE' $(MAKEFILE) >/dev/null; \
then \
sed -e '/^# DO NOT DELETE/,$$d' $(MAKEFILE) > \
$(MAKEFILE).$$$$ && \
$(MV) $(MAKEFILE).$$$$ $(MAKEFILE); \
fi
echo '# DO NOT DELETE THIS LINE -- make depend depends on it.' \
>> $(MAKEFILE); \
$(CC) -M -mmcu=$(MCU) $(CDEFS) $(CINCS) $(SRC) $(ASRC) >> $(MAKEFILE)
.PHONY: all build elf hex eep lss sym program coff extcoff clean depend

BIN
micronucleus Executable file

Binary file not shown.