Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/FastLED/FastLED.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Garcia <danielgarcia@gmail.com>2013-11-11 03:19:23 +0400
committerDaniel Garcia <danielgarcia@gmail.com>2013-11-11 03:19:23 +0400
commit4246ec322047a73147905aafa9ae95396569d528 (patch)
tree3a4160e08a9dc686ceebbae640409ac2e5ec0a41
parent2315a24629e40bb426804333a57cf425fee47bf3 (diff)
Removing unused files
-rw-r--r--FastSPI_LED.cpp746
-rw-r--r--FastSPI_LED.h142
2 files changed, 0 insertions, 888 deletions
diff --git a/FastSPI_LED.cpp b/FastSPI_LED.cpp
deleted file mode 100644
index e4715da3..00000000
--- a/FastSPI_LED.cpp
+++ /dev/null
@@ -1,746 +0,0 @@
-#if defined(ARDUINO) && ARDUINO >= 100
- #include "Arduino.h"
- #include <pins_arduino.h>
-#else
- #include "WProgram.h"
- #include <pins_arduino.h>
-#include "wiring.h"
-#endif
-#include "avr/interrupt.h"
-#include "avr/io.h"
-#include "FastSPI_LED.h"
-
-// #define DEBUG_SPI
-#ifdef DEBUG_SPI
-# define DPRINT Serial.print
-# define DPRINTLN Serial.println
-#else
-# define DPRINT(x)
-# define DPRINTLN(x)
-#endif
-
-// #define COUNT_ROUNDS 1
-
-// some spi defines
-// Duemilanove and mini w/328
-#if defined(__AVR_ATmega328P__) || defined(__AVR_ATmega168__)
-#define SPI_PORT PORTB
-#define SPI_DDR DDRB
-#define SPI_PIN PINB
-#define SPI_MOSI 3 // Arduino pin 11.
-#define SPI_MISO 4 // Arduino pin 12.
-#define SPI_SCK 5 // Arduino pin 13.
-#define SPI_SSN 2 // Arduino pin 10.
-#define DATA_PIN 11
-#define SLAVE_PIN 12
-#define CLOCK_PIN 13
-#define LATCH_PIN 10
-#define TIMER_AVAILABLE 1
-
-// Mega.
-#elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
-#define SPI_PORT PORTB
-#define SPI_DDR DDRB
-#define SPI_PIN PINB
-#define SPI_MOSI 2 // Arduino pin 51.
-#define SPI_MISO 3 // Arduino pin 50.
-#define SPI_SCK 1 // Arduino pin 52.
-#define SPI_SSN 0 // Arduino pin 53.
-#define DATA_PIN 51
-#define SLAVE_PIN 50
-#define CLOCK_PIN 52
-#define LATCH_PIN 53
-#define TIMER_AVAILABLE 1
-
-// Leonardo, teensy, blinkm
-#elif defined(__AVR_ATmega32U4__)
-
-#define SPI_PORT PORTB
-#define SPI_DDR DDRB
-#define SPI_PIN PINB
-#define SPI_MOSI 2 // Arduino pin 10.
-#define SPI_MISO 3 // Arduino pin 11.
-#define SPI_SCK 1 // Arduino pin 9.
-#define SPI_SSN 0 // Arduino pin 8.
-#define DATA_PIN 16 // PB2, pin 10, Digital16
-#define SLAVE_PIN 14 // PB3, pin 11, Digital14
-#define CLOCK_PIN 15 // PB1, pin 9, Digital15
-#define LATCH_PIN 17 // PB0, pin 8, Digital17
-#define TIMER_AVAILABLE 1
-
-#elif defined(__MK20DX128__) // for Teensy 3.0
-#define SPI_PORT PORTB
-#define SPI_DDR DDRB
-#define SPI_PIN PINB
-#define SPI_MOSI 2 // Arduino pin 10.
-#define SPI_MISO 3 // Arduino pin 11.
-#define SPI_SCK 1 // Arduino pin 9.
-#define SPI_SSN 0 // Arduino pin 8.
-#define DATA_PIN 11 // PB2, pin 10, Digital16
-#define SLAVE_PIN 12 // PB3, pin 11, Digital14
-#define CLOCK_PIN 13 // PB1, pin 9, Digital15
-#define LATCH_PIN 10 // PB0, pin 8, Digital17
-
-#define NOT_A_PIN NULL
-#define TIMER_AVAILABLE 0
-#endif
-
-#define BIT_HI(R, P) (R) |= _BV(P)
-#define BIT_LO(R, P) (R) &= ~_BV(P)
-
-#define MASK_HI(R, P) (R) |= (P)
-#define MASK_LO(R, P) (R) &= ~(P)
-
-// HL1606 defines
-//Commands for each LED to be ORd together.
-
-#define TM_1606 153
-
-#define Command B10000000
-#define Commandx2 B11000000 //Use this one to make dimming twice as fast.
-#define BlueOff B00000000
-#define BlueOn B00010000
-#define BlueUp B00100000
-#define BlueDown B00110000
-#define RedOff B00000000
-#define RedOn B00000100
-#define RedUp B00001000
-#define RedDown B00001100
-#define GreenOff B00000000
-#define GreenOn B00000001
-#define GreenUp B00000010
-#define GreenDown B00000011
-
-#define BRIGHT_MAX 256
-
-// Some ASM defines
-#if defined(__arm__)
-# define NOP __asm__ __volatile__ ("nop\n");
-#else
-# define NOP __asm__ __volatile__ ("cp r0,r0\n");
-#endif
-
-#define NOP2 NOP NOP
-#define NOP1 NOP
-#define NOP3 NOP NOP2
-#define NOP4 NOP NOP3
-#define NOP5 NOP NOP4
-#define NOP6 NOP NOP5
-#define NOP7 NOP NOP6
-#define NOP8 NOP NOP7
-#define NOP9 NOP NOP8
-#define NOP10 NOP NOP9
-#define NOP11 NOP NOP10
-#define NOP12 NOP NOP11
-#define NOP13 NOP NOP12
-#define NOP14 NOP NOP13
-#define NOP15 NOP10 NOP5
-#define NOP16 NOP14 NOP2
-#define NOP20 NOP10 NOP10
-#define NOP22 NOP20 NOP2
-
-#define NOP_SHORT NOP2
-#define NOP_LONG NOP5
-
-// TODO: Better: MASH_HI(_PORT,PIN); NOP; NOP; MASK_SET(_PORT, PIN, X & (1<<N)); NOP; NOP; MASK_LO(_PORT, PIN); (loop logic)
-// TODO: Best - interleave X lines
-#define TM1809_BIT_SET(X,N,_PORT) if( X & (1<<N) ) { MASK_HI(_PORT,PIN); NOP_LONG; MASK_LO(_PORT,PIN); NOP_SHORT; } else { MASK_HI(_PORT,PIN); NOP_SHORT; MASK_LO(_PORT,PIN); NOP_LONG; }
-
-#define TM1809_BIT_ALL(_PORT) \
-TM1809_BIT_SET(x,7,_PORT); \
-TM1809_BIT_SET(x,6,_PORT); \
-TM1809_BIT_SET(x,5,_PORT); \
-TM1809_BIT_SET(x,4,_PORT); \
-TM1809_BIT_SET(x,3,_PORT); \
-TM1809_BIT_SET(x,2,_PORT); \
-TM1809_BIT_SET(x,1,_PORT); \
-TM1809_BIT_SET(x,0,_PORT);
-
-#define TM1809_ALL(_PORT,PTR, END) \
-while(PTR != END) { register unsigned char x = *PTR++; TM1809_BIT_ALL(_PORT); \
- x = *PTR++; TM1809_BIT_ALL(_PORT); \
- x = *PTR++; TM1809_BIT_ALL(_PORT); }
-
-#define NOP_SHORT_1903 NOP2
-#define NOP_LONG_1903 NOP15
-
-#define UCS1903_BIT_SET(X,N,_PORT) if( X & (1<<N) ) { MASK_HI(_PORT,PIN); NOP_LONG_1903; MASK_LO(_PORT,PIN); NOP_SHORT_1903; } else { MASK_HI(_PORT,PIN); NOP_SHORT_1903; MASK_LO(_PORT,PIN); NOP_LONG_1903; }
-
-#define UCS1903_BIT_ALL(_PORT) \
- UCS1903_BIT_SET(x,7,_PORT); \
- UCS1903_BIT_SET(x,6,_PORT); \
- UCS1903_BIT_SET(x,5,_PORT); \
- UCS1903_BIT_SET(x,4,_PORT); \
- UCS1903_BIT_SET(x,3,_PORT); \
- UCS1903_BIT_SET(x,2,_PORT); \
- UCS1903_BIT_SET(x,1,_PORT); \
- UCS1903_BIT_SET(x,0,_PORT);
-
-#define UCS1903_ALL(_PORT,PTR, END) \
- while(PTR != END) { register unsigned char x = *PTR++; UCS1903_BIT_ALL(_PORT); \
- x = *PTR++; UCS1903_BIT_ALL(_PORT); \
- x = *PTR++; UCS1903_BIT_ALL(_PORT); }
-
-#define TM1809_BIT_ALLD TM1809_BIT_ALL(PORTD);
-#define TM1809_BIT_ALLB TM1809_BIT_ALL(PORTB);
-
-#define SPI_A(data) SPDR=data;
-#define SPI_B while(!(SPSR & (1<<SPIF)));
-#define SPI_TRANSFER(data) { SPDR=data; while(!(SPSR & (1<<SPIF))); }
-#define SPI_BIT(bit) digitalWrite(DATA_PIN, bit); digitalWrite(CLOCK_PIN, HIGH); digitalWrite(CLOCK_PIN, LOW);
-
-
- CFastSPI_LED FastSPI_LED;
-
-// local prototyps
- extern "C" {
- void spi595(void);
- void spihl1606(void);
- void spilpd6803(void);
- };
-
-// local variables used for state tracking and pre-computed values
-// TODO: move these into the class as necessary
- static unsigned char *pData;
- static unsigned char nBrightIdx=0;
- static unsigned char nBrightMax=0;
- static unsigned char nCountBase=0;
- static unsigned char nCount=0;
- static unsigned char nLedBlocks=0;
- unsigned char nChip=0;
-//static unsigned long adjustedUSecTime;
-
-#define USE_TIMER (m_eChip == SPI_595 || m_eChip == SPI_HL1606 || m_eChip == SPI_LPD6803)
-#define USE_SPI (m_eChip != SPI_TM1809 && m_eChip != SPI_UCS1903)
-
- void CFastSPI_LED::setDirty() { m_nDirty = 1; }
-
- void CFastSPI_LED::init() {
- // store some static locals (makes lookup faster)
- pData = m_pDataEnd;
- nCountBase = m_nLeds / 3;
- // set up the spi timer - also do some initial timing loops to get base adjustments
- // for the timer below
- setup_hardware_spi();
- if(USE_TIMER) {
- delay(10);
- setup_timer1_ovf();
- }
-
- if(m_eChip == SPI_LPD8806) {
- // write out the initial set of 0's to latch out the world
- int n = (m_nLeds + 191 / 192);
- while(n--) {
- SPI_A(0);
- SPI_B; SPI_A(0);
- SPI_B; SPI_A(0);
- SPI_B;
- }
- }
- }
-
-//
- void CFastSPI_LED::start() {
-#if TIMER_AVAILABLE
- if(USE_TIMER) {
- TCCR1B |= clockSelectBits; // reset clock select register
- }
-#endif
-}
-
-void CFastSPI_LED::stop() {
-#if TIMER_AVAILABLE
- if(USE_TIMER) {
- // clear the clock select bits
- TCCR1B &= ~(_BV(CS10) | _BV(CS11) | _BV(CS12));
- }
-#endif
-}
-
-
-void CFastSPI_LED::setChipset(EChipSet eChip) {
- m_eChip = eChip;
- nChip = eChip;
- switch(eChip) {
- case SPI_595:
- nBrightIdx = 256 / 128;
- nBrightMax = 256 - nBrightIdx;
- // Set some info used for taking advantage of extreme loop unrolling elsewhere
- if(m_nLeds % 24 == 0 ) {
- nLedBlocks = m_nLeds / 24;
- if(nLedBlocks > 4) { nLedBlocks = 0; }
- } else {
- nLedBlocks = 0;
- }
- break;
- case SPI_HL1606:
- // nTimerKick = 153; // shooting for ~ 125,000 rounds/second - 66% cpu
- nBrightIdx = (m_nLeds <= 20) ? (256 / 80) : (256 / 32);
- nBrightMax = 256 - nBrightIdx;
- nCount = nCountBase;
- break;
- case SPI_LPD6803:
- nBrightIdx = 0;
- break;
- default:
- // no one else does anything 'special' here
- break;
-
- }
-
- // set default cpu percentage targets
- switch(FastSPI_LED.m_eChip) {
- case CFastSPI_LED::SPI_595: m_cpuPercentage = 53; break;
- case CFastSPI_LED::SPI_LPD6803: m_cpuPercentage = 50; break;
- case CFastSPI_LED::SPI_HL1606: m_cpuPercentage = 65; break;
- case CFastSPI_LED::SPI_LPD8806:
- case CFastSPI_LED::SPI_SM16716:
- case CFastSPI_LED::SPI_WS2801: m_cpuPercentage = 25; break;
- case CFastSPI_LED::SPI_TM1809: m_cpuPercentage = 5; break;
- case CFastSPI_LED::SPI_UCS1903: m_cpuPercentage = 5; break;
-}
-
- // set default spi rates
-switch(m_eChip) {
- case CFastSPI_LED::SPI_HL1606:
- m_nDataRate = 2;
- if(m_nLeds > 20) {
- m_nDataRate = 3;
- }
- break;
- case CFastSPI_LED::SPI_595:
- case CFastSPI_LED::SPI_LPD6803:
- case CFastSPI_LED::SPI_LPD8806:
- case CFastSPI_LED::SPI_WS2801:
- case CFastSPI_LED::SPI_SM16716:
- case CFastSPI_LED::SPI_TM1809:
- case CFastSPI_LED::SPI_UCS1903:
- m_nDataRate = 0;
- break;
-}
-}
-
-#if TIMER_AVAILABLE
-// Why not use function pointers? They're expensive! Having TIMER1_OVF_vect call a chip
-// specific interrupt function through a pointer adds approximately 1.3µs over the if/else blocks
-// below per cycle. That doesn't sound like a lot, though, right? Wrong. For the HL-1606, with
-// 40 leds, you may want to push up to 125,000 cycles/second. 1.3µs extra per cycle means 162.5
-// milliseconds. Put a different way, you just cost yourself 16.25% of your cpu time. This is on
-// a 16Mhz processor. On an 8Mhz processor, the hit is even more severe, percentage wise. 1.3µs
-// is also, for another point of data, only 20 clocks on a 20Mhz processor. Every extra register push/pop
-// that needs to be added to the function is 4 cycles (2 for push, 2 for pop) - or .25µs. To call through
-// a function pointer requires two pushes and two pops (to save r30/r31) or 8 cycles, plus the actual call
-// which is 4 clocks, and then a reti which is another 4 clocks, plus the loading of the function pointer
-// which is itself 4 clocks (2 clocks for each of loading the high and low bytes of the function's address)
-// The asm below only adds 12 clocks (and did some other tightening in the hl1606 code to get us closer
-// to being able to saturate as well) - wouldn't have to worry push/pop'ing r1 if someone out there wasn't
-// misbehaving and using r1 for something other than zero!
-extern "C" void TIMER1_OVF_vect(void) __attribute__ ((signal,naked,__INTR_ATTRS));
-void TIMER1_OVF_vect(void) {
-#if 1
- __asm__ __volatile__ ( "push r1");
- __asm__ __volatile__ ( "lds r1, nChip" );
- __asm__ __volatile__ ( "sbrc r1, 1" ); // if(nChip == SPI_HL1606) {
- __asm__ __volatile__ ( "rjmp do1606" ); // do1606();
- __asm__ __volatile__ ( "sbrs r1, 0" ); // } else if(nChip != SPI_595) {
- __asm__ __volatile__ ( "rjmp do6803" ); // do6803();
- __asm__ __volatile__ ( "do595: pop r1" ); // } else if(nChip == SPI_595) {
- __asm__ __volatile__ ( " jmp spi595" ); // do595();
- __asm__ __volatile__ ( "do6803: pop r1" ); // }
- __asm__ __volatile__ ( " jmp spilpd6803" );
- __asm__ __volatile__ ( "do1606: pop r1" );
- __asm__ __volatile__ ( " jmp spihl1606" );
-#else
- __asm__ __volatile__ ( "lds r1, nChip" );
- __asm__ __volatile__ ( "sbrc r1, 1" );
- __asm__ __volatile__ ( "jmp spihl1606" );
- __asm__ __volatile__ ( "sbrc r1, 2" );
- __asm__ __volatile__ ( "jmp spilpd6803");
- __asm__ __volatile__ ( "jmp spi595" );
-#endif
-}
-
-// if(FastSPI_LED.m_eChip == CFastSPI_LED::SPI_HL1606)
-ISR(spihl1606)
-{
- static unsigned char nBrightness = 1;
- register unsigned char aByte = Command;
-
- //if(pData == FastSPI_LED.m_pData)
- if(nCount != 0)
- {
- register unsigned char nCheck = nBrightness;
- if(*(--pData) > nCheck) { aByte |= BlueOn; } if(*(--pData) > nCheck) { aByte |= GreenOn; } if(*(--pData) > nCheck) { aByte |= RedOn; }
- // SPI_B;
- SPI_A(aByte);
- nCount--;
- return;
-}
-else
-{
- BIT_HI(SPI_PORT,SPI_SSN);
- pData = FastSPI_LED.m_pDataEnd;
- BIT_LO(SPI_PORT,SPI_SSN);
- if (nBrightness <= nBrightMax) { nBrightness += nBrightIdx; }
- else { nBrightness = 1; }
- BIT_HI(SPI_PORT,SPI_SSN);
- // if( (nBrightness += nBrightIdx) > BRIGHT_MAX) { nBrightness = 1; }
- nCount = nCountBase;
- BIT_LO(SPI_PORT,SPI_SSN);
- SPI_A(aByte);
- return;
-}
-}
- //else if(FastSPI_LED.m_eChip == CFastSPI_LED::SPI_595)
-ISR(spi595)
-{
- static unsigned char nBrightness = 1;
- if(nBrightness > nBrightMax) { nBrightness = 1; }
- else { nBrightness += nBrightIdx; }
- // register unsigned char nCheck = nBrightness;
- register unsigned char aByte;
- //register unsigned char *
- {
- BIT_LO(SPI_PORT,SPI_SSN);
-
-#define BIT_SET(nBit) if(*(--pData) >= nBrightness) { aByte |= nBit; }
-#define BLOCK8 aByte=0; BIT_SET(0x80); BIT_SET(0x40); BIT_SET(0x20); BIT_SET(0x10); BIT_SET(0x08); BIT_SET(0x04); BIT_SET(0x02); BIT_SET(0x01);
-#define COMMANDA BLOCK8 ; SPI_A(aByte);
-#define COMMANDB BLOCK8 ; SPI_B; SPI_A(aByte);
-#define COM3A COMMANDA ; COMMANDB ; COMMANDB
-#define COM3B COMMANDB ; COMMANDB ; COMMANDB
-#define COM12 COM3A ; COM3B ; COM3B ; COM3B
-
- // If we have blocks of 3 8 bit shift registers, that gives us 8 rgb leds, we'll do some aggressive
- // loop unrolling for cases where we have multiples of 3 shift registers - i should expand this out to
- // handle a wider range of cases at some point
- switch(nLedBlocks) {
- case 4: COM12; break;
- case 3: COM3A; COM3B; COM3B; break;
- case 2: COM3A; COM3B; break;
- case 1: COM3A; break;
- default:
- BLOCK8;
- SPI_A(aByte);
- for(register char i = FastSPI_LED.m_nLeds; i > 8; i-= 8) {
- BLOCK8;
- SPI_B;
- SPI_A(aByte);
- }
- }
- BIT_HI(SPI_PORT,SPI_SSN);
- pData = FastSPI_LED.m_pDataEnd;
- return;
- }
-}
- //else // if(FastSPI_LED.m_eChip == CFastSPI_LED::SPI_LPD6803)
-ISR(spilpd6803)
-{
- static unsigned char nState=1;
- if(FastSPI_LED.m_eChip == CFastSPI_LED::SPI_LPD6803)
- {
- if(nState==1)
- {
- SPI_A(0);
- if(FastSPI_LED.m_nDirty==1) {
- nState = 0;
- FastSPI_LED.m_nDirty = 0;
- SPI_B;
- SPI_A(0);
- pData = FastSPI_LED.m_pData;
- return;
- }
- SPI_B;
- SPI_A(0);
- return;
- }
- else
- {
- register unsigned int command;
- command = 0x8000;
- command |= (*(pData++) & 0xF8) << 7; // red is the high 5 bits
- command |= (*(pData++) & 0xF8) << 2; // green is the middle 5 bits
- command |= *(pData++) >> 3 ; // blue is the low 5 bits
- SPI_B;
- SPI_A( (command>>8) &0xFF);
- if(pData == FastSPI_LED.m_pDataEnd) {
- nState = 1;
- }
- SPI_B;
- SPI_A( command & 0xFF);
- return;
-}
-}
-}
-#endif
-
-void CFastSPI_LED::show() {
- static byte run=0;
-
- setDirty();
- if(FastSPI_LED.m_eChip == CFastSPI_LED::SPI_WS2801)
- {
- cli();
- register byte *p = m_pData;
- register byte *e = m_pDataEnd;
-
- // If we haven't run through yet - nothing has primed the SPI bus,
- // and the first SPI_B will block.
- if(!run) {
- run = 1;
- SPI_A(*p++);
- SPI_B; SPI_A(*p++);
- SPI_B; SPI_A(*p++);
- }
- while(p != e) {
- SPI_B; SPI_A(*p++);
- SPI_B; SPI_A(*p++);
- SPI_B; SPI_A(*p++);
- }
- m_nDirty = 0;
- sei();
- }
- else if(FastSPI_LED.m_eChip == CFastSPI_LED::SPI_SM16716)
- {
- cli();
- register byte *p = m_pData;
- register byte *e = m_pDataEnd;
-
- // SM167176 starts with a control block of 50 bits
- SPI_A(0);
- SPI_B; SPI_A(0);
- SPI_B; SPI_A(0);
- SPI_B; SPI_A(0);
- SPI_B; SPI_A(0);
- SPI_B; SPI_A(0);
- SPI_B;
- SPI_BIT(0);
- SPI_BIT(0);
-
- while(p != e) {
- // every 24 bit block starts with a 1 bit being sent
- SPI_BIT(1);
- SPI_A(*p++); SPI_B;
- SPI_A(*p++); SPI_B;
- SPI_A(*p++); SPI_B;
- }
- m_nDirty = 0;
- sei();
-}else if(FastSPI_LED.m_eChip == CFastSPI_LED::SPI_UCS1903)
-{
- cli();
- m_nDirty = 0;
- register byte *pData = m_pData;
- for(int iPins = 0; iPins < m_nPins; iPins++) {
- register byte *pEnd = pData + m_pPinLengths[iPins];
- register unsigned char PIN = digitalPinToBitMask(FastSPI_LED.m_pPins[iPins]);
- register volatile uint8_t *pPort = m_pPorts[iPins];
-
- if(pPort == NOT_A_PIN) { /* do nothing */ }
- else { UCS1903_ALL(*pPort, pData, pEnd); }
- }
- sei();
-}
-else if(FastSPI_LED.m_eChip == CFastSPI_LED::SPI_TM1809)
-{
- cli();
- m_nDirty = 0;
- register byte *pData = m_pData;
- for(int iPins = 0; iPins < m_nPins; iPins++) {
- register byte *pEnd = pData + m_pPinLengths[iPins];
- register unsigned char PIN = digitalPinToBitMask(FastSPI_LED.m_pPins[iPins]);
- register volatile uint8_t *pPort = m_pPorts[iPins];
-
- if(pPort == NOT_A_PIN) { /* do nothing */ }
- else { TM1809_ALL(*pPort, pData, pEnd); }
- }
- sei();
-}
-else if(FastSPI_LED.m_eChip == CFastSPI_LED::SPI_LPD8806)
-{
- cli();
- register byte *p = m_pData;
- register byte *e = m_pDataEnd;
-
- // The LPD8806 requires the high bit to be set
- while(p != e) {
- SPI_B; SPI_A( *p++ >> 1 | 0x80);
- SPI_B; SPI_A( *p++ >> 1 | 0x80);
- SPI_B; SPI_A( *p++ >> 1 | 0x80);
- }
-
- // Latch out our 0's to set the data stream
- int n = (m_nLeds + 191 )/ 192;
- while(n--) {
- SPI_B; SPI_A(0);
- SPI_B; SPI_A(0);
- SPI_B; SPI_A(0);
- }
- m_nDirty=0;
- sei();
-}
-}
-
-void CFastSPI_LED::setDataRate(int datarate) {
- m_nDataRate = datarate;
-}
-
-void CFastSPI_LED::setPinCount(int nPins) {
- m_nPins = nPins;
- m_pPins = (unsigned int*)malloc(sizeof(unsigned int) * nPins);
- m_pPinLengths = (unsigned int*)malloc(sizeof(unsigned int) * nPins);
- m_pPorts = (uint8_t**)malloc(sizeof(uint8_t*) * nPins);
- for(int i = 0; i < nPins; i++) {
- m_pPins[i] = m_pPinLengths[i] = 0;
- m_pPorts[i] = NULL;
- }
-}
-
-void CFastSPI_LED::setPin(int iPins, int nPin, int nLength) {
- m_pPins[iPins] = nPin;
- m_pPinLengths[iPins] = nLength*3;
- m_pPorts[iPins] = (uint8_t*)portOutputRegister(digitalPinToPort(nPin));
-}
-
-void CFastSPI_LED::setup_hardware_spi(void) {
- byte clr;
-
- if(USE_SPI) {
- pinMode(DATA_PIN,OUTPUT);
- pinMode(LATCH_PIN,OUTPUT);
- pinMode(CLOCK_PIN,OUTPUT);
- pinMode(SLAVE_PIN,OUTPUT);
- digitalWrite(DATA_PIN,LOW);
- digitalWrite(LATCH_PIN,LOW);
- digitalWrite(CLOCK_PIN,LOW);
- digitalWrite(SLAVE_PIN,LOW);
-
- // spi prescaler:
- // SPI2X SPR1 SPR0
- // 0 0 0 fosc/4
- // 0 0 1 fosc/16
- // 0 1 0 fosc/64
- // 0 1 1 fosc/128
- // 1 0 0 fosc/2
- // 1 0 1 fosc/8
- // 1 1 0 fosc/32
- // 1 1 1 fosc/64
- SPCR |= ( (1<<SPE) | (1<<MSTR) ); // enable SPI as master
- SPCR &= ~ ( (1<<SPR1) | (1<<SPR0) ); // clear prescaler bits
- clr=SPSR; // clear SPI status reg
- clr=SPDR; // clear SPI data reg
-
- // set the prescalar bits based on the chosen data rate values
- bool b2x = false;
- switch(m_nDataRate) {
- /* fosc/2 */ case 0: b2x=true; break;
- /* fosc/4 */ case 1: break;
- /* fosc/8 */ case 2: SPCR |= (1<<SPR0); b2x=true; break;
- /* fosc/16 */ case 3: SPCR |= (1<<SPR0); break;
- /* fosc/32 */ case 4: SPCR |= (1<<SPR1); b2x=true; break;
- /* fosc/64 */ case 5: SPCR |= (1<<SPR1); break;
- /* fosc/64 */ case 6: SPCR |= (1<<SPR1); SPCR |= (1<<SPR0); b2x=true; break;
- /* fosc/128 */ default: SPCR |= (1<<SPR1); SPCR |= (1<<SPR0); break;
- }
- if(b2x) { SPSR |= (1<<SPI2X); }
- else { SPSR &= ~ (1<<SPI2X); }
-
- } else {
- for(int i = 0; i < m_nPins; i++) {
- pinMode(m_pPins[i], OUTPUT);
- digitalWrite(m_pPins[i],LOW);
- }
- }
-
- // dig out some timing info
-#if TIMER_AVAILABLE
- if(USE_TIMER && USE_SPI) {
- SPI_A(0);
- TIMER1_OVF_vect();
-
- // First thing to do is count our cycles to figure out how to line
- // up the desired performance percentages
- unsigned long nRounds=0;
- volatile int x = 0;
- unsigned long mCStart = millis();
- for(volatile int i = 0 ; i < 10000; i++) {
- ;
-#ifdef COUNT_ROUNDS
- m_nCounter++;
-#endif
- }
- unsigned long mCEnd = millis();
- m_nCounter=0;
- nRounds = 10000;
- DPRINT("10000 round empty loop in ms: "); DPRINTLN(mCEnd - mCStart);
- unsigned long mStart,mStop;
- if(!USE_TIMER) {
-#ifdef DEBUG_SPI
- mStart = millis();
- for(volatile int i = 0; i < 10000; i++) {
- show();
- }
- mStop = millis();
-#endif
- } else {
- mStart = millis();
- for(volatile int i = 0; i < 10000; i++) {
- TIMER1_OVF_vect();
- }
- mStop = millis();
- }
- DPRINT(nRounds); DPRINT(" rounds of rgb out in ms: "); DPRINTLN(mStop - mStart);
-
- // This gives us the time for 10 rounds in µs
- m_adjustedUSecTime = (mStop-mStart) - (mCEnd - mCStart);
- }
-#endif
-}
-
-// Core borrowed and adapted from the Timer1 Arduino library - by Jesse Tane
-#define RESOLUTION 65536
-
-void CFastSPI_LED::setup_timer1_ovf(void) {
-#if TIMER_AVAILABLE
- // Now that we have our per-cycle timing, figure out how to set up the timer to
- // match the desired cpu percentage
- TCCR1A = 0;
- TCCR1B = _BV(WGM13);
-
- unsigned long baseCounts = (((unsigned long)m_cpuPercentage) * 100000) / m_adjustedUSecTime;
- unsigned long us10;
- switch(FastSPI_LED.m_eChip) {
- case CFastSPI_LED::SPI_LPD6803: us10 = (1000000 ) / baseCounts; break;
- case CFastSPI_LED::SPI_HL1606: us10 = (1000000 ) / baseCounts; break;
- case CFastSPI_LED::SPI_595: us10 = (1000000 ) / baseCounts; break;
- }
-
- DPRINT("bc:"); DPRINTLN(baseCounts);
- DPRINT("us*10:"); DPRINTLN(us10);
-
- long cycles = ( (F_CPU)*us10) / (2000000); // the counter runs backwards after TOP, interrupt is at BOTTOM so divide microseconds by 2
-
- if(FastSPI_LED.m_eChip == SPI_HL1606) {
- // can't have a cycle at or less than 66 cycles on a 16Mhz system, or 33 cycles on an 8Mhz system
- // with the hl1606's - at least with 40 leds. Stupid timing constraints. The chips whig out if you send
- // data at a faster rate. This rate limit means we don't waste time waiting on SPSR
- if(F_CPU == 16000000 && cycles < 67) { cycles = 67; }
- if(F_CPU == 8000000 && cycles < 34) { cycles = 34; }
- }
- DPRINT("cy:"); DPRINTLN(cycles);
-
- if(cycles < RESOLUTION) clockSelectBits = _BV(CS10); // no prescale, full xtal/TCCR
- else if((cycles >>= 3) < RESOLUTION) clockSelectBits = _BV(CS11); // prescale by /8
- else if((cycles >>= 3) < RESOLUTION) clockSelectBits = _BV(CS11) | _BV(CS10); // prescale by /64
- else if((cycles >>= 2) < RESOLUTION) clockSelectBits = _BV(CS12); // prescale by /256
- else if((cycles >>= 2) < RESOLUTION) clockSelectBits = _BV(CS12) | _BV(CS10); // prescale by /1024
- else cycles = RESOLUTION - 1, clockSelectBits = _BV(CS12) | _BV(CS10); // request was out of bounds, set as maximum
- ICR1 = cycles; // ICR1 is TOP in p & f correct pwm mode
- TCCR1B &= ~(_BV(CS10) | _BV(CS11) | _BV(CS12));
- // call start explicitly TCCR1B |= clockSelectBits; // reset clock select register
-
- TIMSK1 = _BV(TOIE1);
- sei();
-#endif
-}
-
diff --git a/FastSPI_LED.h b/FastSPI_LED.h
deleted file mode 100644
index 7e671b05..00000000
--- a/FastSPI_LED.h
+++ /dev/null
@@ -1,142 +0,0 @@
-#ifndef __INC_SPIRGB_H
-#define __INC_SPIRGB_H
-#if defined(ARDUINO) && ARDUINO >= 100
- #include "Arduino.h"
-#else
- #include "WProgram.h"
- #include <pins_arduino.h>
-#endif
-#include "HardwareSerial.h"
-#include "string.h"
-#include "avr/pgmspace.h"
-
-extern "C" {
- void TIMER1_OVF_vect(void) __attribute__ ((signal,naked,__INTR_ATTRS));
- void SPI_STC_vect(void) __attribute__ ((signal,__INTR_ATTRS));
-};
-
-/// A class for controlling a shift-register based LED decoder board such as this one: http://www.usledsupply.com/shop/rgb-32-spi-dmx-decoder.html
-/// or using the hl1606 or the lpd6803 controller chips
-class CFastSPI_LED {
-public:
- unsigned char clockSelectBits;
- unsigned int m_cpuPercentage;
-
- // computed time to run 10 cycles
- unsigned long m_adjustedUSecTime;
-
- // timer setup functions - will auto-calibrate (timer1, at least) based on other decisions user has made
- void setup_timer1_ovf();
- void setup_hardware_spi();
-
- friend void TIMER1_OVF_vect(void);
- friend void SPI_STC_vect(void);
-public:
- enum EChipSet {
- SPI_595 = 0x01,
- SPI_HL1606 = 0x02,
- SPI_LPD6803 = 0x04,
- SPI_WS2801 = 0x08,
- SPI_TM1809 = 0x10,
- SPI_WS2811 = 0x10,
- SPI_TM1804 = 0x10,
- SPI_LPD8806 = 0x20,
- SPI_UCS1903 = 0x40,
- SPI_SM16716 = 0x80
- };
-
-public:
- int m_nLeds;
- unsigned char m_nDataRate;
- unsigned char m_nDirty;
- unsigned char m_eChip;
- unsigned long m_nCounter;
- unsigned char *m_pData;
- unsigned char *m_pDataEnd;
- unsigned int *m_pPins; // used by tm1809
- unsigned int *m_pPinLengths;
- unsigned int m_nPins;
- uint8_t **m_pPorts;
- unsigned int m_nDDR;
-public:
- CFastSPI_LED() {m_nDataRate=0; m_cpuPercentage=50; m_nCounter = 0; m_nDirty=0; m_eChip = SPI_595; m_adjustedUSecTime=0; m_nPins = 0; m_pPins = NULL; m_pPinLengths=NULL;}
-
- // set the number of rgb leds
- void setLeds(int nLeds) { m_nLeds = nLeds * 3; m_nCounter = 0; m_nDirty = 0; m_pData = (unsigned char*)malloc(m_nLeds); memset(m_pData,0,m_nLeds); m_pDataEnd = m_pData + m_nLeds; }
-
- // set the chipset being used - note: this will reset default values for cpuPercentage and refresh/color level rates
- void setChipset(EChipSet);
-
- // set the desired cpu percentage - changes won't take effect until calling init
- void setCPUPercentage(unsigned int perc) { m_cpuPercentage = perc; }
-
- // set the desired number of color levels (only useful for software pwm chipsets (e.g. 595 or hl1606), chipsets
- // like the lpd6803 offload pwm to the chip, meaning the number of color levels is hardwired to some predefined
- // number, e.g. 32 for the lpd6803. Note that raising this value will lower the refresh rate in hz that you
- // have. Maxes out at 255
- void setColorLevels(unsigned int nLevels) { }
-
- // set the desired refresh rate in hz (only useful for software pwm chipsets, e.g. 595 or hl1606).
- // note that increasining the desired refresh rate may reduce the number of color levels you have available
- // to you. Note that your requested refresh rate may not be possible.
- void setRefreshRate(unsigned int nDesiredRate) { }
-
- // initialize the engine - note this will also be re-called if one of the auto-calibration values
- // (e.g. percentage, refresh rate, brightness levels) is changed
- void init();
-
- // start the rgb output
- void start();
-
- // stop the rgb output
- void stop();
-
- // call this method whenever you want to output a block of rgb data. It is assumed that
- // rgbData is nNumLeds * 3 bytes long.
- void setRGBData(unsigned char *rgbData) { memcpy(m_pData,rgbData,m_nLeds); m_nDirty=1;}
-
- // call this method to get a pointer to the raw rgb data
- unsigned char *getRGBData() { return m_pData; }
-
- // mark the current data as 'dirty' (used by some chipsets) - should be called
- // when writing data in manually using getRGBData instead of setRGBData
- void setDirty();
-
- // 'show' or push the current led data (note, with some chipsets, data shows up in the
- // leds as soon as it is written to the array returned by getRGBData.
- void show();
-
- // get a count of how many output cycles have been performed. Only useful during debugging, this
- // will often return 0
- unsigned long getCounter() { return m_nCounter; }
-
- // clear the output cycle counter.
- void clearCounter() { m_nCounter=0; }
-
- // get the time in µs to run one cycle of output
- unsigned long getCycleTime() { return m_adjustedUSecTime / 10; }
-
- // get the target number of cycles per second - cycleTarget / nLeds - total number of full updates for lights
- // available per second. For manually PWM'd chipsets like 595 or hl1606, that base number is also
- // desiredHz * colorLevels - higher refresh rate means fewer color levels, which may mean more flickering
- unsigned long getCycleTarget() { return (((unsigned long)m_cpuPercentage) * 100000) / m_adjustedUSecTime; }
-
- // override the spi data rate - the library sets a default data rate for each chipset. You
- // can forcibly change the data rate that you want used, with 0 being the fastest and 7 being
- // the slowest. Note that you may need to play around with the max cpu percentage a bit if you
- // change the data rate. Call this after you have set the chipset to override the chipset's data rate
- void setDataRate(int datarate);
-
- // set the pin used for output. Note, at the moment this only makes sense for the TM1809 based leds, as everything
- // else makes use of the spi infrastructure for its work. Setting pins is done in two parts. First, set the number
- // of pins (even if only one, for now, we'll do saner defaults later). Then set each individual pin and how many
- // leds you want it to take up. Note that this is linear, so if pin 0 has 20 leds, pin 1 will start at the 21st led
- void setPinCount(int nPins);
- void setPin(int iPins, int nPin, int nLength);
- void setPin(int nPin) { setPinCount(1); setPin(0, nPin, m_nLeds / 3); }
- int lengthAtPin(int nPin) { return m_pPinLengths[nPin]; }
-};
-
-extern CFastSPI_LED FastSPI_LED;
-#endif
-