/* 2008 - robert:aT:spitzenpfeil_d*t:org */ #define __spi_clock 13 // SCK - hardware SPI #define __spi_latch 10 #define __spi_data 11 // MOSI - hardware SPI #define __spi_data_in 12 // MISO - hardware SPI (unused) #define __display_enable 9 #define __rows 8 #define __max_row __rows-1 #define __leds_per_row 8 #define __max_led __leds_per_row-1 #define __brightness_levels 32 // 0...15 above 28 is bad for ISR ( move to timer1, lower irq freq ! ) #define __max_brightness __brightness_levels-1 #define __fade_delay 4 #define __TIMER1_MAX 0xFFFF // 16 bit CTR #define __TIMER1_CNT 0x0130 // 32 levels --> 0x0130; 38 --> 0x0157 (flicker) #define __TIMER2_MAX 0xFF // 8 bit CTR #define __TIMER2_CNT 0xFF // max 28 levels ! #include #include #include byte brightness_red[__leds_per_row][__rows]; byte brightness_green[__leds_per_row][__rows]; byte brightness_blue[__leds_per_row][__rows]; ISR(TIMER1_OVF_vect) { //TCNT2 = __TIMER2_MAX - __TIMER2_CNT; // precharge TIMER2 to maximize ISR time --> max led brightness TCNT1 = __TIMER1_MAX - __TIMER1_CNT; byte cycle; digitalWrite(__display_enable,LOW); // enable display inside ISR for(cycle = 0; cycle < __max_brightness; cycle++) { byte led; byte row = B00000000; // row: current source. on when (1) byte red; // current sinker when on (0) byte green; // current sinker when on (0) byte blue; // current sinker when on (0) for(row = 0; row <= __max_row; row++) { red = B11111111; // off green = B11111111; // off blue = B11111111; // off for(led = 0; led <= __max_led; led++) { if(cycle < brightness_red[row][led]) { red &= ~(1<= 0) & (ctr1 != 255); ctr1--) { for(row = 0; row <= __max_row; row++) { for(led = 0; led <= __max_led; led++) { set_led_rgb(row,led,ctr1,ctr1,ctr1); } } delay(__fade_delay); } } void fader_hue(void) { int ctr1; byte row; byte led; for(ctr1 = 0; ctr1 < 360; ctr1=ctr1+3) { set_matrix_hue((float)(ctr1)); delay(__fade_delay); } } void no_irq_fader(void) { byte ctr1; byte row; byte led; byte ctr2; for(ctr1 = 0; ctr1 <= __max_brightness; ctr1++) { for(row = 0; row <= __max_row; row++) { for(led = 0; led <= __max_led; led++) { set_led_rgb(row,led,ctr1,ctr1,ctr1); } } for(ctr2 = 0; ctr2 <= __fade_delay; ctr2++) { no_irq_pwm(); } } for(ctr1 = __max_brightness; (ctr1 >= 0) & (ctr1 != 255); ctr1--) { for(row = 0; row <= __max_row; row++) { for(led = 0; led <= __max_led; led++) { set_led_rgb(row,led,ctr1,ctr1,ctr1); } } for(ctr2 = 0; ctr2 <= __fade_delay; ctr2++) { no_irq_pwm(); } } } void no_irq_pwm(void) { byte cycle; for(cycle = 0; cycle < __max_brightness; cycle++) { byte led; byte row = B00000000; // row: current source. on when (1) byte red; // current sinker when on (0) byte green; // current sinker when on (0) byte blue; // current sinker when on (0) for(row = 0; row <= __max_row; row++) { red = B11111111; // off green = B11111111; // off blue = B11111111; // off for(led = 0; led <= __max_led; led++) { if(cycle < brightness_red[row][led]) { red &= ~(1<>led)&(B00000001) ) { set_led_hue(row,led,hue); } else { set_led_rgb(row,led,0,0,0); } } } void setup_hardware_spi(void) { byte clr; // 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<