From c184fcbf0fcec8c337afe3d7c321fb996def3fe0 Mon Sep 17 00:00:00 2001 From: Christian Kroll Date: Mon, 19 May 2014 07:13:48 +0200 Subject: [PATCH] added support for Arduino Leonardo (and maybe Mega1280/2560, untested) --- config.in | 1 + profiles/LoL-Shield_Leonardo | 125 +++ ...d => LoL-Shield_Uno-Duemilanove-Diavolino} | 1 + src/borg_hw/borg_hw_lolshield.c | 978 ++++++++++++++---- src/borg_hw/config.in | 2 +- src/borg_hw/config_lolshield.in | 2 + src/util.c | 4 +- 7 files changed, 919 insertions(+), 194 deletions(-) create mode 100644 profiles/LoL-Shield_Leonardo rename profiles/{LoL-Shield => LoL-Shield_Uno-Duemilanove-Diavolino} (99%) diff --git a/config.in b/config.in index 809eada..61b6bf3 100644 --- a/config.in +++ b/config.in @@ -8,6 +8,7 @@ comment "General Setup" choice 'Target MCU' \ "ATmega8 atmega8 \ ATmega32 atmega32 \ + ATmega32U4 atmega32u4 \ ATmega328 atmega328 \ ATmega328p atmega328p \ ATmega644 atmega644 \ diff --git a/profiles/LoL-Shield_Leonardo b/profiles/LoL-Shield_Leonardo new file mode 100644 index 0000000..3edf168 --- /dev/null +++ b/profiles/LoL-Shield_Leonardo @@ -0,0 +1,125 @@ +# +# Automatically generated by make menuconfig: don't edit +# + +# +# General Setup +# +MCU=atmega32u4 +FREQ=16000000 + +# +# Borg Hardware +# +NUM_ROWS=9 +NUM_COLS=14 +NUMPLANE=3 +BORG_HW=HW_LOLSHIELD + +# +# lolshield setup +# +USER_TIMER0_FOR_WAIT=1 +BRIGHTNESS=127 + +# +# Features +# +RANDOM_SUPPORT=y +# LAP_TIME_EXTENSION is not set +SCROLLTEXT_SUPPORT=y +SCROLLTEXT_FONT=FONT_C64 +SCROLLTEXT_BUFFER_SIZE=128 +SCROLL_X_SPEED=20 +SCROLL_Y_SPEED=20 +SCROLLTEXT_TEXT=" #include #include +#if NUMPLANE >= 8 +# include +#endif #include "borg_hw.h" // buffer which holds the currently shown frame unsigned char pixmap[NUMPLANE][NUM_ROWS][LINEBYTES]; +// Number of ticks of the prescaled timer per cycle per frame, based on the +// CPU clock speed and the desired frame rate. #define FRAMERATE 80UL +#define TICKS (F_CPU + 6 * (FRAMERATE << SLOWSCALERSHIFT)) / (12 * (FRAMERATE << SLOWSCALERSHIFT)) #define CUTOFF(scaler) ((128 * 12 - 6) * FRAMERATE * scaler) -// BEWARE: only the Diavolino Kit is supported at the moment -// other platforms don't work, yet -const uint8_t #if defined (__AVR_ATmega168__) || defined (__AVR_ATmega48__) || defined (__AVR_ATmega88__) || defined (__AVR_ATmega328P__) || defined (__AVR_ATmega1280__) || defined (__AVR_ATmega2560__) || defined (__AVR_ATmega8__) -# if F_CPU < CUTOFF(8) - fastPrescaler = _BV(CS20), // 1 - slowPrescaler = _BV(CS21); // 8 -# define SLOWSCALERSHIFT 3 -# define FASTSCALERSHIFT 3 -# elif F_CPU < CUTOFF(32) - fastPrescaler = _BV(CS21), // 8 - slowPrescaler = _BV(CS21) | _BV(CS20); // 32 -# define SLOWSCALERSHIFT 5 -# define FASTSCALERSHIFT 2 -# elif F_CPU < CUTOFF(64) - fastPrescaler = _BV(CS21), // 8 - slowPrescaler = _BV(CS22); // 64 -# define SLOWSCALERSHIFT 6 -# define FASTSCALERSHIFT 3 +# if F_CPU < CUTOFF(8) +# define FASTPRESCALER (_BV(CS20)) // 1 +# define SLOWPRESCALER (_BV(CS21)) // 8 +# define FASTSCALERSHIFT 3 +# define SLOWSCALERSHIFT 3 +# elif F_CPU < CUTOFF(32) +# define FASTPRESCALER (_BV(CS21)) // 8 +# define SLOWPRESCALER (_BV(CS21) | _BV(CS20)) // 32 +# define FASTSCALERSHIFT 2 +# define SLOWSCALERSHIFT 5 +# elif F_CPU < CUTOFF(64) +# define FASTPRESCALER (_BV(CS21)) // 8 +# define SLOWPRESCALER (_BV(CS22)) // 64 +# define FASTSCALERSHIFT 3 +# define SLOWSCALERSHIFT 6 # elif F_CPU < CUTOFF(128) - fastPrescaler = _BV(CS21) | _BV(CS20), // 32 - slowPrescaler = _BV(CS22) | _BV(CS20); // 128 -# define SLOWSCALERSHIFT 7 -# define FASTSCALERSHIFT 2 -# elif F_CPU < CUTOFF(256) - fastPrescaler = _BV(CS21) | _BV(CS20), // 32 - slowPrescaler = _BV(CS22) | _BV(CS21); // 256 -# define SLOWSCALERSHIFT 8 -# define FASTSCALERSHIFT 3 +# define FASTPRESCALER (_BV(CS21) | _BV(CS20)) // 32 +# define SLOWPRESCALER (_BV(CS22) | _BV(CS20)) // 128 +# define FASTSCALERSHIFT 2 +# define SLOWSCALERSHIFT 7 +# elif F_CPU < CUTOFF(256) +# define FASTPRESCALER (_BV(CS21) | _BV(CS20)) // 32 +# define SLOWPRESCALER (_BV(CS22) | _BV(CS21)) // 256 +# define FASTSCALERSHIFT 3 +# define SLOWSCALERSHIFT 8 # elif F_CPU < CUTOFF(1024) - fastPrescaler = _BV(CS22) | _BV(CS20), // 128 - slowPrescaler = _BV(CS22) | _BV(CS21) | _BV(CS20); // 1024 -# define SLOWSCALERSHIFT 10 -# define FASTSCALERSHIFT 3 -# else -# error frame rate is too low -# endif +# define FASTPRESCALER (_BV(CS22) | _BV(CS20)) // 128 +# define SLOWPRESCALER (_BV(CS22) | _BV(CS21) | _BV(CS20)) // 1024 +# define FASTSCALERSHIFT 3 +# define SLOWSCALERSHIFT 10 +# else +# error frame rate is too low +# endif +#elif defined (__AVR_ATmega32U4__) +# if F_CPU < CUTOFF(8) +# define FASTPRESCALER (_BV(WGM12) | _BV(CS10)) // 1 +# define SLOWPRESCALER (_BV(WGM12) | _BV(CS11)) // 8 +# define FASTSCALERSHIFT 3 +# define SLOWSCALERSHIFT 3 +# elif F_CPU < CUTOFF(64) +# define FASTPRESCALER (_BV(WGM12) | _BV(CS11)) // 8 +# define SLOWPRESCALER (_BV(WGM12) | _BV(CS11) | _BV(CS10)) // 64 +# define FASTSCALERSHIFT 3 +# define SLOWSCALERSHIFT 6 +# elif F_CPU < CUTOFF(256) +# define FASTPRESCALER (_BV(WGM12) | _BV(CS11) | _BV(CS10)) // 64 +# define SLOWPRESCALER (_BV(WGM12) | _BV(CS12)) // 256 +# define FASTSCALERSHIFT 2 +# define SLOWSCALERSHIFT 8 +# elif F_CPU < CUTOFF(1024) +# define FASTPRESCALER (_BV(WGM12) | _BV(CS12)) // 256 +# define SLOWPRESCALER (_BV(WGM12) | _BV(CS12) | _BV(CS10)) // 1024 +# define FASTSCALERSHIFT 2 +# define SLOWSCALERSHIFT 10 +# else +# error frame rate is too low +# endif #else # error no support for this chip #endif -ISR(TIMER2_OVF_vect) { - // For each cycle, we have potential planes to display. Once every plane has - // been displayed, then we move on to the next cycle. - // NOTE: a "cycle" means a subset of LEDs +#ifndef BRIGHTNESS +# define BRIGHTNESS 127 /* full brightness by default */ +#elif BRIGHTNESS < 0 || BRIGHTNESS > 127 +# error BRIGHTNESS must be between 0 and 127 +#endif - // 12 Cycles of Matrix - static uint8_t cycle = 0; +#define BRIGHTNESSPERCENT ((BRIGHTNESS * BRIGHTNESS + 8ul) / 16ul) +#define M (TICKS << FASTSCALERSHIFT) * BRIGHTNESSPERCENT /*10b*/ +#define C(x) ((M * (unsigned long)(x * 1024) + (1 << 19)) >> 20) /*10b+10b-20b=0b*/ - // planes to display - // NOTE: a "plane" in the Borgware is the same as a "page" in Jimmie's lib - static uint8_t plane = 0; +#if NUMPLANE < 8 +uint8_t const prescaler[NUMPLANE + 1] = { + FASTPRESCALER, +# if NUMPLANE >= 2 + FASTPRESCALER, +# endif +# if NUMPLANE >= 3 + FASTPRESCALER, +# endif +# if NUMPLANE >= 4 + FASTPRESCALER, +# endif +# if NUMPLANE >= 5 + FASTPRESCALER, +# endif +# if NUMPLANE >= 6 + FASTPRESCALER, +# endif +# if NUMPLANE >= 7 + FASTPRESCALER, +# endif + SLOWPRESCALER +}; +#else +uint8_t prescaler[NUMPLANE + 1] = {0}; +#endif +uint8_t counts[NUMPLANE + 1] = {0}; + +/** + * Set the overall brightness of the screen from 0 (off) to 127 (full on). + */ +static void setBrightness() +{ + /* ---- This needs review! Please review. -- thilo */ + // set up page counts + uint8_t i; + + // NOTE: The argument of C() is calculated as follows: + // pow((double)x / (double)NUMPLANE, 1.8) with 0 <= x <= NUMPLANE + // Changing the scale of 1.8 invalidates any tables above! +#if NUMPLANE < 8 + int const temp_counts[NUMPLANE + 1] = { + 0.000000000000000000000000000, +# if NUMPLANE == 2 + C(0.287174588749258719033719), +# elif NUMPLANE == 3 + C(0.138414548846168578011273), + C(0.481987453865643789008288), +# elif NUMPLANE == 4 + C(0.082469244423305887448095), + C(0.287174588749258719033719), + C(0.595813410589956848895099), +# elif NUMPLANE == 5 + C(0.055189186458448592775827), + C(0.192179909437029006191722), + C(0.398723883569384374148115), + C(0.669209313658414961523135), +# elif NUMPLANE == 6 + C(0.039749141141812646682574), + C(0.138414548846168578011273), + C(0.287174588749258719033719), + C(0.481987453865643789008288), + C(0.720234228706005730202833), +# elif NUMPLANE == 7 + C(0.030117819624378608378557), + C(0.104876339357015443964904), + C(0.217591430058779483625031), + C(0.365200625214741059210155), + C(0.545719579451565794947498), + C(0.757697368024318751444923), +# endif + C(1.000000000000000000000000), + }; +#else +# warning "NUMPLANE >= 8 links floating point stuff into the image" + // NOTE: Changing "scale" invalidates any tables above! + const float scale = 1.8f; + int temp_counts[NUMPLANE + 1] = {0}; + + for (i = 1; i < (NUMPLANE + 1); i++) { + temp_counts[i] = C(pow(i / (float)(NUMPLANE), scale)); + } +#endif + + // Compute on time for each of the pages + // Use the fast timer; slow timer is only useful for < 3 shades. + for (i = 0; i < NUMPLANE; i++) { + int interval = temp_counts[i + 1] - temp_counts[i]; + counts[i] = 256 - (interval ? interval : 1); +#if NUMPLANE >= 8 + prescaler[i] = FASTPRESCALER; +#endif + } + + // Compute off time + int interval = TICKS - (temp_counts[i] >> FASTSCALERSHIFT); + counts[i] = 256 - (interval ? interval : 1); +#if NUMPLANE >= 8 + prescaler[i] = SLOWPRESCALER; +#endif +} + +/** + * Distributes the framebuffer content among current cycle pins. + * @param cycle The cycle whose pattern should to be composed. + * @param plane The plane ("page" in LoL Shield lingo) to be drawn. + */ +static void compose_cycle(uint8_t const cycle, uint8_t plane) { // pointer to corresponding bitmap - uint8_t *p = &pixmap[plane][0][0]; - - // tune timer values (fiddle around with them to adjust brightness) - static uint8_t const prescaler[NUMPLANE + 1] = {3, 3, 3, 6}; - TCCR2B = prescaler[plane]; - static uint8_t const counts[NUMPLANE + 1] = {241, 198, 148, 255}; - TCNT2 = counts[plane]; + uint8_t *const p = &pixmap[plane][0][0]; +#if defined (__AVR_ATmega1280__) || defined (__AVR_ATmega2560__) +# warning "BEWARE: Borgware-2D has not been tested on Arduino Mega 1280/2560!" // Set sink pin to Vcc/source, turning off current. - static uint8_t sink_b, sink_d = 0; + static uint8_t sink_b = 0, sink_e = 0, sink_g = 0, sink_h = 0; + PINB = sink_b; + PINE = sink_e; + PING = sink_g; + PINH = sink_h; + + DDRB &= ~0xf0; + DDRE &= ~0x38; + DDRG &= ~0x20; + DDRH &= ~0x78; + + static uint8_t const sink_b_cycle[] = + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x20, 0x40, 0x80}; + static uint8_t const sink_e_cycle[] = + {0x10, 0x20, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; + static uint8_t const sink_g_cycle[] = + {0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; + static uint8_t const sink_h_cycle[] = + {0x00, 0x00, 0x00, 0x00, 0x08, 0x10, 0x20, 0x40, 0x00, 0x00, 0x00, 0x00}; + + uint8_t pins_b = sink_b = pgm_read_byte(&sink_b_cycle[cycle]); + uint8_t pins_e = sink_e = pgm_read_byte(&sink_e_cycle[cycle]); + uint8_t pins_g = sink_g = pgm_read_byte(&sink_g_cycle[cycle]); + uint8_t pins_h = sink_h = pgm_read_byte(&sink_h_cycle[cycle]); + + // convert framebuffer to LoL Shield cycles on Arduino Mega 1280/2560 + // (I could have done this with a lookup table, but that would be slower as + // non-constant bit shifts are quite expensive on AVR) + // NOTE: (0,0) is UPPER RIGHT in the Borgware realm + if (plane < NUMPLANE) { + switch(cycle) { + case 0: + pins_b |= (0x02u & p[ 0]) << 6; // x= 1, y= 0, mapped pin D13 + pins_b |= (0x02u & p[ 2]) << 5; // x= 1, y= 1, mapped pin D12 + pins_b |= (0x02u & p[ 4]) << 4; // x= 1, y= 2, mapped pin D11 + pins_b |= (0x02u & p[ 6]) << 3; // x= 1, y= 3, mapped pin D10 + pins_e |= (0x02u & p[16]) << 2; // x= 1, y= 8, mapped pin D5 + pins_h |= (0x02u & p[ 8]) << 5; // x= 1, y= 4, mapped pin D9 + pins_h |= (0x02u & p[10]) << 4; // x= 1, y= 5, mapped pin D8 + pins_h |= (0x02u & p[12]) << 3; // x= 1, y= 6, mapped pin D7 + pins_h |= (0x02u & p[14]) << 2; // x= 1, y= 7, mapped pin D6 + break; + case 1: + pins_b |= (0x08u & p[ 0]) << 4; // x= 3, y= 0, mapped pin D13 + pins_b |= (0x08u & p[ 2]) << 3; // x= 3, y= 1, mapped pin D12 + pins_b |= (0x08u & p[ 4]) << 2; // x= 3, y= 2, mapped pin D11 + pins_b |= (0x08u & p[ 6]) << 1; // x= 3, y= 3, mapped pin D10 + pins_e |= (0x08u & p[16]); // x= 3, y= 8, mapped pin D5 + pins_h |= (0x08u & p[ 8]) << 3; // x= 3, y= 4, mapped pin D9 + pins_h |= (0x08u & p[10]) << 2; // x= 3, y= 5, mapped pin D8 + pins_h |= (0x08u & p[12]) << 1; // x= 3, y= 6, mapped pin D7 + pins_h |= (0x08u & p[14]); // x= 3, y= 7, mapped pin D6 + break; + case 2: + pins_b |= (0x20u & p[ 0]) << 2; // x= 5, y= 0, mapped pin D13 + pins_b |= (0x20u & p[ 2]) << 1; // x= 5, y= 1, mapped pin D12 + pins_b |= (0x20u & p[ 4]); // x= 5, y= 2, mapped pin D11 + pins_b |= (0x20u & p[ 6]) >> 1; // x= 5, y= 3, mapped pin D10 + pins_e |= (0x20u & p[16]) >> 2; // x= 5, y= 8, mapped pin D5 + pins_h |= (0x20u & p[ 8]) << 1; // x= 5, y= 4, mapped pin D9 + pins_h |= (0x20u & p[10]); // x= 5, y= 5, mapped pin D8 + pins_h |= (0x20u & p[12]) >> 1; // x= 5, y= 6, mapped pin D7 + pins_h |= (0x20u & p[14]) >> 2; // x= 5, y= 7, mapped pin D6 + break; + case 3: + pins_b |= (0x20u & p[ 1]) << 2; // x=13, y= 0, mapped pin D13 + pins_b |= (0x20u & p[ 3]) << 1; // x=13, y= 1, mapped pin D12 + pins_b |= (0x20u & p[ 5]); // x=13, y= 2, mapped pin D11 + pins_b |= (0x20u & p[ 7]) >> 1; // x=13, y= 3, mapped pin D10 + pins_e |= (0x01u & p[16]) << 4; // x= 0, y= 8, mapped pin D2 + pins_e |= (0x04u & p[16]) << 3; // x= 2, y= 8, mapped pin D3 + pins_g |= (0x10u & p[16]) << 1; // x= 4, y= 8, mapped pin D4 + pins_h |= (0x20u & p[ 9]) << 1; // x=13, y= 4, mapped pin D9 + pins_h |= (0x20u & p[11]); // x=13, y= 5, mapped pin D8 + pins_h |= (0x20u & p[13]) >> 1; // x=13, y= 6, mapped pin D7 + pins_h |= (0x20u & p[15]) >> 2; // x=13, y= 7, mapped pin D6 + break; + case 4: + pins_b |= (0x10u & p[ 1]) << 3; // x=12, y= 0, mapped pin D13 + pins_b |= (0x10u & p[ 3]) << 2; // x=12, y= 1, mapped pin D12 + pins_b |= (0x10u & p[ 5]) << 1; // x=12, y= 2, mapped pin D11 + pins_b |= (0x10u & p[ 7]); // x=12, y= 3, mapped pin D10 + pins_e |= (0x01u & p[14]) << 4; // x= 0, y= 7, mapped pin D2 + pins_e |= (0x04u & p[14]) << 3; // x= 2, y= 7, mapped pin D3 + pins_e |= (0x20u & p[17]) >> 2; // x=13, y= 8, mapped pin D5 + pins_g |= (0x10u & p[14]) << 1; // x= 4, y= 7, mapped pin D4 + pins_h |= (0x10u & p[ 9]) << 2; // x=12, y= 4, mapped pin D9 + pins_h |= (0x10u & p[11]) << 1; // x=12, y= 5, mapped pin D8 + pins_h |= (0x10u & p[13]); // x=12, y= 6, mapped pin D7 + break; + case 5: + pins_b |= (0x08u & p[ 1]) << 4; // x=11, y= 0, mapped pin D13 + pins_b |= (0x08u & p[ 3]) << 3; // x=11, y= 1, mapped pin D12 + pins_b |= (0x08u & p[ 5]) << 2; // x=11, y= 2, mapped pin D11 + pins_b |= (0x08u & p[ 7]) << 1; // x=11, y= 3, mapped pin D10 + pins_e |= (0x01u & p[12]) << 4; // x= 0, y= 6, mapped pin D2 + pins_e |= (0x04u & p[12]) << 3; // x= 2, y= 6, mapped pin D3 + pins_e |= (0x10u & p[17]) >> 1; // x=12, y= 8, mapped pin D5 + pins_g |= (0x10u & p[12]) << 1; // x= 4, y= 6, mapped pin D4 + pins_h |= (0x08u & p[ 9]) << 3; // x=11, y= 4, mapped pin D9 + pins_h |= (0x08u & p[11]) << 2; // x=11, y= 5, mapped pin D8 + pins_h |= (0x10u & p[15]) >> 1; // x=12, y= 7, mapped pin D6 + break; + case 6: + pins_b |= (0x04u & p[ 1]) << 5; // x=10, y= 0, mapped pin D13 + pins_b |= (0x04u & p[ 3]) << 4; // x=10, y= 1, mapped pin D12 + pins_b |= (0x04u & p[ 5]) << 3; // x=10, y= 2, mapped pin D11 + pins_b |= (0x04u & p[ 7]) << 2; // x=10, y= 3, mapped pin D10 + pins_e |= (0x01u & p[10]) << 4; // x= 0, y= 5, mapped pin D2 + pins_e |= (0x04u & p[10]) << 3; // x= 2, y= 5, mapped pin D3 + pins_e |= (0x08u & p[17]); // x=11, y= 8, mapped pin D5 + pins_g |= (0x10u & p[10]) << 1; // x= 4, y= 5, mapped pin D4 + pins_h |= (0x04u & p[ 9]) << 4; // x=10, y= 4, mapped pin D9 + pins_h |= (0x08u & p[13]) << 1; // x=11, y= 6, mapped pin D7 + pins_h |= (0x08u & p[15]); // x=11, y= 7, mapped pin D6 + break; + case 7: + pins_b |= (0x02u & p[ 1]) << 6; // x= 9, y= 0, mapped pin D13 + pins_b |= (0x02u & p[ 3]) << 5; // x= 9, y= 1, mapped pin D12 + pins_b |= (0x02u & p[ 5]) << 4; // x= 9, y= 2, mapped pin D11 + pins_b |= (0x02u & p[ 7]) << 3; // x= 9, y= 3, mapped pin D10 + pins_e |= (0x01u & p[ 8]) << 4; // x= 0, y= 4, mapped pin D2 + pins_e |= (0x04u & p[ 8]) << 3; // x= 2, y= 4, mapped pin D3 + pins_e |= (0x04u & p[17]) << 1; // x=10, y= 8, mapped pin D5 + pins_g |= (0x10u & p[ 8]) << 1; // x= 4, y= 4, mapped pin D4 + pins_h |= (0x04u & p[11]) << 3; // x=10, y= 5, mapped pin D8 + pins_h |= (0x04u & p[13]) << 2; // x=10, y= 6, mapped pin D7 + pins_h |= (0x04u & p[15]) << 1; // x=10, y= 7, mapped pin D6 + break; + case 8: + pins_b |= (0x01u & p[ 1]) << 7; // x= 8, y= 0, mapped pin D13 + pins_b |= (0x01u & p[ 3]) << 6; // x= 8, y= 1, mapped pin D12 + pins_b |= (0x01u & p[ 5]) << 5; // x= 8, y= 2, mapped pin D11 + pins_e |= (0x01u & p[ 6]) << 4; // x= 0, y= 3, mapped pin D2 + pins_e |= (0x02u & p[17]) << 2; // x= 9, y= 8, mapped pin D5 + pins_e |= (0x04u & p[ 6]) << 3; // x= 2, y= 3, mapped pin D3 + pins_g |= (0x10u & p[ 6]) << 1; // x= 4, y= 3, mapped pin D4 + pins_h |= (0x02u & p[ 9]) << 5; // x= 9, y= 4, mapped pin D9 + pins_h |= (0x02u & p[11]) << 4; // x= 9, y= 5, mapped pin D8 + pins_h |= (0x02u & p[13]) << 3; // x= 9, y= 6, mapped pin D7 + pins_h |= (0x02u & p[15]) << 2; // x= 9, y= 7, mapped pin D6 + break; + case 9: + pins_b |= (0x01u & p[ 7]) << 4; // x= 8, y= 3, mapped pin D10 + pins_b |= (0x80u & p[ 0]); // x= 7, y= 0, mapped pin D13 + pins_b |= (0x80u & p[ 2]) >> 1; // x= 7, y= 1, mapped pin D12 + pins_e |= (0x01u & p[ 4]) << 4; // x= 0, y= 2, mapped pin D2 + pins_e |= (0x01u & p[17]) << 3; // x= 8, y= 8, mapped pin D5 + pins_e |= (0x04u & p[ 4]) << 3; // x= 2, y= 2, mapped pin D3 + pins_g |= (0x10u & p[ 4]) << 1; // x= 4, y= 2, mapped pin D4 + pins_h |= (0x01u & p[ 9]) << 6; // x= 8, y= 4, mapped pin D9 + pins_h |= (0x01u & p[11]) << 5; // x= 8, y= 5, mapped pin D8 + pins_h |= (0x01u & p[13]) << 4; // x= 8, y= 6, mapped pin D7 + pins_h |= (0x01u & p[15]) << 3; // x= 8, y= 7, mapped pin D6 + break; + case 10: + pins_b |= (0x40u & p[ 0]) << 1; // x= 6, y= 0, mapped pin D13 + pins_b |= (0x80u & p[ 4]) >> 2; // x= 7, y= 2, mapped pin D11 + pins_b |= (0x80u & p[ 6]) >> 3; // x= 7, y= 3, mapped pin D10 + pins_e |= (0x01u & p[ 2]) << 4; // x= 0, y= 1, mapped pin D2 + pins_e |= (0x04u & p[ 2]) << 3; // x= 2, y= 1, mapped pin D3 + pins_e |= (0x80u & p[16]) >> 4; // x= 7, y= 8, mapped pin D5 + pins_g |= (0x10u & p[ 2]) << 1; // x= 4, y= 1, mapped pin D4 + pins_h |= (0x80u & p[ 8]) >> 1; // x= 7, y= 4, mapped pin D9 + pins_h |= (0x80u & p[10]) >> 2; // x= 7, y= 5, mapped pin D8 + pins_h |= (0x80u & p[12]) >> 3; // x= 7, y= 6, mapped pin D7 + pins_h |= (0x80u & p[14]) >> 4; // x= 7, y= 7, mapped pin D6 + break; + case 11: + pins_b |= (0x40u & p[ 2]); // x= 6, y= 1, mapped pin D12 + pins_b |= (0x40u & p[ 4]) >> 1; // x= 6, y= 2, mapped pin D11 + pins_b |= (0x40u & p[ 6]) >> 2; // x= 6, y= 3, mapped pin D10 + pins_e |= (0x01u & p[ 0]) << 4; // x= 0, y= 0, mapped pin D2 + pins_e |= (0x04u & p[ 0]) << 3; // x= 2, y= 0, mapped pin D3 + pins_e |= (0x40u & p[16]) >> 3; // x= 6, y= 8, mapped pin D5 + pins_g |= (0x10u & p[ 0]) << 1; // x= 4, y= 0, mapped pin D4 + pins_h |= (0x40u & p[ 8]); // x= 6, y= 4, mapped pin D9 + pins_h |= (0x40u & p[10]) >> 1; // x= 6, y= 5, mapped pin D8 + pins_h |= (0x40u & p[12]) >> 2; // x= 6, y= 6, mapped pin D7 + pins_h |= (0x40u & p[14]) >> 3; // x= 6, y= 7, mapped pin D6 + break; + } + } + + // Enable pullups (by toggling) on new output pins. + PINB = PORTB ^ pins_b; + PINE = PORTE ^ pins_e; + PING = PORTG ^ pins_g; + PINH = PORTH ^ pins_h; + + // Set pins to output mode; pullups become Vcc/source. + DDRB |= pins_b; + DDRE |= pins_e; + DDRG |= pins_g; + DDRH |= pins_h; + + // Set sink pin to GND/sink, turning on current. + PINB = sink_b; + PINE = sink_e; + PING = sink_g; + PINH = sink_h; +#elif defined (__AVR_ATmega32U4__) + // Set sink pin to Vcc/source, turning off current. + static uint8_t sink_b = 0, sink_c = 0, sink_d = 0, sink_e = 0; + PINB = sink_b; + PINC = sink_c; + PIND = sink_d; + PINE = sink_e; + + DDRB &= ~0xF0; + DDRC &= ~0xC0; + DDRD &= ~0xD3; + DDRE &= ~0x40; + + static uint8_t const PROGMEM sink_b_cycle[] = + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x20, 0x40, 0x80, 0x00, 0x00}; + static uint8_t const PROGMEM sink_c_cycle[] = + {0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80}; + static uint8_t const PROGMEM sink_d_cycle[] = + {0x02, 0x01, 0x10, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00}; + static uint8_t const PROGMEM sink_e_cycle[] = + {0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; + + uint8_t pins_b = sink_b = pgm_read_byte(&sink_b_cycle[cycle]); + uint8_t pins_c = sink_c = pgm_read_byte(&sink_c_cycle[cycle]); + uint8_t pins_d = sink_d = pgm_read_byte(&sink_d_cycle[cycle]); + uint8_t pins_e = sink_e = pgm_read_byte(&sink_e_cycle[cycle]); + + // convert Borgware-2D framebuffer to LoL Shield cycles on Arduino Leonardo + // (I could have done this with a lookup table, but that would be slower as + // non-constant bit shifts are quite expensive on AVR) + // NOTE: (0,0) is UPPER RIGHT in the Borgware realm + if (plane < NUMPLANE) { + switch(cycle) { + case 0: + pins_b |= (0x02u & p[ 4]) << 6; // x= 1, y= 2, mapped pin D11 + pins_b |= (0x02u & p[ 6]) << 5; // x= 1, y= 3, mapped pin D10 + pins_b |= (0x02u & p[ 8]) << 4; // x= 1, y= 4, mapped pin D9 + pins_b |= (0x02u & p[10]) << 3; // x= 1, y= 5, mapped pin D8 + pins_c |= (0x02u & p[ 0]) << 6; // x= 1, y= 0, mapped pin D13 + pins_c |= (0x02u & p[16]) << 5; // x= 1, y= 8, mapped pin D5 + pins_d |= (0x02u & p[ 2]) << 5; // x= 1, y= 1, mapped pin D12 + pins_d |= (0x02u & p[14]) << 6; // x= 1, y= 7, mapped pin D6 + pins_e |= (0x02u & p[12]) << 5; // x= 1, y= 6, mapped pin D7 + break; + case 1: + pins_b |= (0x08u & p[ 4]) << 4; // x= 3, y= 2, mapped pin D11 + pins_b |= (0x08u & p[ 6]) << 3; // x= 3, y= 3, mapped pin D10 + pins_b |= (0x08u & p[ 8]) << 2; // x= 3, y= 4, mapped pin D9 + pins_b |= (0x08u & p[10]) << 1; // x= 3, y= 5, mapped pin D8 + pins_c |= (0x08u & p[ 0]) << 4; // x= 3, y= 0, mapped pin D13 + pins_c |= (0x08u & p[16]) << 3; // x= 3, y= 8, mapped pin D5 + pins_d |= (0x08u & p[ 2]) << 3; // x= 3, y= 1, mapped pin D12 + pins_d |= (0x08u & p[14]) << 4; // x= 3, y= 7, mapped pin D6 + pins_e |= (0x08u & p[12]) << 3; // x= 3, y= 6, mapped pin D7 + break; + case 2: + pins_b |= (0x20u & p[ 4]) << 2; // x= 5, y= 2, mapped pin D11 + pins_b |= (0x20u & p[ 6]) << 1; // x= 5, y= 3, mapped pin D10 + pins_b |= (0x20u & p[ 8]); // x= 5, y= 4, mapped pin D9 + pins_b |= (0x20u & p[10]) >> 1; // x= 5, y= 5, mapped pin D8 + pins_c |= (0x20u & p[ 0]) << 2; // x= 5, y= 0, mapped pin D13 + pins_c |= (0x20u & p[16]) << 1; // x= 5, y= 8, mapped pin D5 + pins_d |= (0x20u & p[ 2]) << 1; // x= 5, y= 1, mapped pin D12 + pins_d |= (0x20u & p[14]) << 2; // x= 5, y= 7, mapped pin D6 + pins_e |= (0x20u & p[12]) << 1; // x= 5, y= 6, mapped pin D7 + break; + case 3: + pins_b |= (0x20u & p[ 5]) << 2; // x=13, y= 2, mapped pin D11 + pins_b |= (0x20u & p[ 7]) << 1; // x=13, y= 3, mapped pin D10 + pins_b |= (0x20u & p[ 9]); // x=13, y= 4, mapped pin D9 + pins_b |= (0x20u & p[11]) >> 1; // x=13, y= 5, mapped pin D8 + pins_c |= (0x20u & p[ 1]) << 2; // x=13, y= 0, mapped pin D13 + pins_d |= (0x01u & p[16]) << 1; // x= 0, y= 8, mapped pin D2 + pins_d |= (0x04u & p[16]) >> 2; // x= 2, y= 8, mapped pin D3 + pins_d |= (0x10u & p[16]); // x= 4, y= 8, mapped pin D4 + pins_d |= (0x20u & p[ 3]) << 1; // x=13, y= 1, mapped pin D12 + pins_d |= (0x20u & p[15]) << 2; // x=13, y= 7, mapped pin D6 + pins_e |= (0x20u & p[13]) << 1; // x=13, y= 6, mapped pin D7 + break; + case 4: + pins_b |= (0x10u & p[ 5]) << 3; // x=12, y= 2, mapped pin D11 + pins_b |= (0x10u & p[ 7]) << 2; // x=12, y= 3, mapped pin D10 + pins_b |= (0x10u & p[ 9]) << 1; // x=12, y= 4, mapped pin D9 + pins_b |= (0x10u & p[11]); // x=12, y= 5, mapped pin D8 + pins_c |= (0x10u & p[ 1]) << 3; // x=12, y= 0, mapped pin D13 + pins_c |= (0x20u & p[17]) << 1; // x=13, y= 8, mapped pin D5 + pins_d |= (0x01u & p[14]) << 1; // x= 0, y= 7, mapped pin D2 + pins_d |= (0x04u & p[14]) >> 2; // x= 2, y= 7, mapped pin D3 + pins_d |= (0x10u & p[ 3]) << 2; // x=12, y= 1, mapped pin D12 + pins_d |= (0x10u & p[14]); // x= 4, y= 7, mapped pin D4 + pins_e |= (0x10u & p[13]) << 2; // x=12, y= 6, mapped pin D7 + break; + case 5: + pins_b |= (0x08u & p[ 5]) << 4; // x=11, y= 2, mapped pin D11 + pins_b |= (0x08u & p[ 7]) << 3; // x=11, y= 3, mapped pin D10 + pins_b |= (0x08u & p[ 9]) << 2; // x=11, y= 4, mapped pin D9 + pins_b |= (0x08u & p[11]) << 1; // x=11, y= 5, mapped pin D8 + pins_c |= (0x08u & p[ 1]) << 4; // x=11, y= 0, mapped pin D13 + pins_c |= (0x10u & p[17]) << 2; // x=12, y= 8, mapped pin D5 + pins_d |= (0x01u & p[12]) << 1; // x= 0, y= 6, mapped pin D2 + pins_d |= (0x04u & p[12]) >> 2; // x= 2, y= 6, mapped pin D3 + pins_d |= (0x08u & p[ 3]) << 3; // x=11, y= 1, mapped pin D12 + pins_d |= (0x10u & p[12]); // x= 4, y= 6, mapped pin D4 + pins_d |= (0x10u & p[15]) << 3; // x=12, y= 7, mapped pin D6 + break; + case 6: + pins_b |= (0x04u & p[ 5]) << 5; // x=10, y= 2, mapped pin D11 + pins_b |= (0x04u & p[ 7]) << 4; // x=10, y= 3, mapped pin D10 + pins_b |= (0x04u & p[ 9]) << 3; // x=10, y= 4, mapped pin D9 + pins_c |= (0x04u & p[ 1]) << 5; // x=10, y= 0, mapped pin D13 + pins_c |= (0x08u & p[17]) << 3; // x=11, y= 8, mapped pin D5 + pins_d |= (0x01u & p[10]) << 1; // x= 0, y= 5, mapped pin D2 + pins_d |= (0x04u & p[ 3]) << 4; // x=10, y= 1, mapped pin D12 + pins_d |= (0x04u & p[10]) >> 2; // x= 2, y= 5, mapped pin D3 + pins_d |= (0x08u & p[15]) << 4; // x=11, y= 7, mapped pin D6 + pins_d |= (0x10u & p[10]); // x= 4, y= 5, mapped pin D4 + pins_e |= (0x08u & p[13]) << 3; // x=11, y= 6, mapped pin D7 + break; + case 7: + pins_b |= (0x02u & p[ 5]) << 6; // x= 9, y= 2, mapped pin D11 + pins_b |= (0x02u & p[ 7]) << 5; // x= 9, y= 3, mapped pin D10 + pins_b |= (0x04u & p[11]) << 2; // x=10, y= 5, mapped pin D8 + pins_c |= (0x02u & p[ 1]) << 6; // x= 9, y= 0, mapped pin D13 + pins_c |= (0x04u & p[17]) << 4; // x=10, y= 8, mapped pin D5 + pins_d |= (0x01u & p[ 8]) << 1; // x= 0, y= 4, mapped pin D2 + pins_d |= (0x02u & p[ 3]) << 5; // x= 9, y= 1, mapped pin D12 + pins_d |= (0x04u & p[ 8]) >> 2; // x= 2, y= 4, mapped pin D3 + pins_d |= (0x04u & p[15]) << 5; // x=10, y= 7, mapped pin D6 + pins_d |= (0x10u & p[ 8]); // x= 4, y= 4, mapped pin D4 + pins_e |= (0x04u & p[13]) << 4; // x=10, y= 6, mapped pin D7 + break; + case 8: + pins_b |= (0x01u & p[ 5]) << 7; // x= 8, y= 2, mapped pin D11 + pins_b |= (0x02u & p[ 9]) << 4; // x= 9, y= 4, mapped pin D9 + pins_b |= (0x02u & p[11]) << 3; // x= 9, y= 5, mapped pin D8 + pins_c |= (0x01u & p[ 1]) << 7; // x= 8, y= 0, mapped pin D13 + pins_c |= (0x02u & p[17]) << 5; // x= 9, y= 8, mapped pin D5 + pins_d |= (0x01u & p[ 3]) << 6; // x= 8, y= 1, mapped pin D12 + pins_d |= (0x01u & p[ 6]) << 1; // x= 0, y= 3, mapped pin D2 + pins_d |= (0x02u & p[15]) << 6; // x= 9, y= 7, mapped pin D6 + pins_d |= (0x04u & p[ 6]) >> 2; // x= 2, y= 3, mapped pin D3 + pins_d |= (0x10u & p[ 6]); // x= 4, y= 3, mapped pin D4 + pins_e |= (0x02u & p[13]) << 5; // x= 9, y= 6, mapped pin D7 + break; + case 9: + pins_b |= (0x01u & p[ 7]) << 6; // x= 8, y= 3, mapped pin D10 + pins_b |= (0x01u & p[ 9]) << 5; // x= 8, y= 4, mapped pin D9 + pins_b |= (0x01u & p[11]) << 4; // x= 8, y= 5, mapped pin D8 + pins_c |= (0x01u & p[17]) << 6; // x= 8, y= 8, mapped pin D5 + pins_c |= (0x80u & p[ 0]); // x= 7, y= 0, mapped pin D13 + pins_d |= (0x01u & p[ 4]) << 1; // x= 0, y= 2, mapped pin D2 + pins_d |= (0x01u & p[15]) << 7; // x= 8, y= 7, mapped pin D6 + pins_d |= (0x04u & p[ 4]) >> 2; // x= 2, y= 2, mapped pin D3 + pins_d |= (0x10u & p[ 4]); // x= 4, y= 2, mapped pin D4 + pins_d |= (0x80u & p[ 2]) >> 1; // x= 7, y= 1, mapped pin D12 + pins_e |= (0x01u & p[13]) << 6; // x= 8, y= 6, mapped pin D7 + break; + case 10: + pins_b |= (0x80u & p[ 4]); // x= 7, y= 2, mapped pin D11 + pins_b |= (0x80u & p[ 6]) >> 1; // x= 7, y= 3, mapped pin D10 + pins_b |= (0x80u & p[ 8]) >> 2; // x= 7, y= 4, mapped pin D9 + pins_b |= (0x80u & p[10]) >> 3; // x= 7, y= 5, mapped pin D8 + pins_c |= (0x40u & p[ 0]) << 1; // x= 6, y= 0, mapped pin D13 + pins_c |= (0x80u & p[16]) >> 1; // x= 7, y= 8, mapped pin D5 + pins_d |= (0x01u & p[ 2]) << 1; // x= 0, y= 1, mapped pin D2 + pins_d |= (0x04u & p[ 2]) >> 2; // x= 2, y= 1, mapped pin D3 + pins_d |= (0x10u & p[ 2]); // x= 4, y= 1, mapped pin D4 + pins_d |= (0x80u & p[14]); // x= 7, y= 7, mapped pin D6 + pins_e |= (0x80u & p[12]) >> 1; // x= 7, y= 6, mapped pin D7 + break; + case 11: + pins_b |= (0x40u & p[ 4]) << 1; // x= 6, y= 2, mapped pin D11 + pins_b |= (0x40u & p[ 6]); // x= 6, y= 3, mapped pin D10 + pins_b |= (0x40u & p[ 8]) >> 1; // x= 6, y= 4, mapped pin D9 + pins_b |= (0x40u & p[10]) >> 2; // x= 6, y= 5, mapped pin D8 + pins_c |= (0x40u & p[16]); // x= 6, y= 8, mapped pin D5 + pins_d |= (0x01u & p[ 0]) << 1; // x= 0, y= 0, mapped pin D2 + pins_d |= (0x04u & p[ 0]) >> 2; // x= 2, y= 0, mapped pin D3 + pins_d |= (0x10u & p[ 0]); // x= 4, y= 0, mapped pin D4 + pins_d |= (0x40u & p[ 2]); // x= 6, y= 1, mapped pin D12 + pins_d |= (0x40u & p[14]) << 1; // x= 6, y= 7, mapped pin D6 + pins_e |= (0x40u & p[12]); // x= 6, y= 6, mapped pin D7 + break; + } + } + + // Enable pullups (by toggling) on new output pins. + PINB = PORTB ^ pins_b; + PINC = PORTC ^ pins_c; + PIND = PORTD ^ pins_d; + PINE = PORTE ^ pins_e; + + // Set pins to output mode; pullups become Vcc/source. + DDRB |= pins_b; + DDRC |= pins_c; + DDRD |= pins_d; + DDRE |= pins_e; + + // Set sink pin to GND/sink, turning on current. + PINB = sink_b; + PINC = sink_c; + PIND = sink_d; + PINE = sink_e; +#else + // Set sink pin to Vcc/source, turning off current. + static uint8_t sink_b = 0, sink_d = 0; PIND = sink_d; PINB = sink_b; @@ -114,168 +650,169 @@ ISR(TIMER2_OVF_vect) { DDRD = 0; DDRB = 0; - static uint8_t const sink_d_cycle[] = + static uint8_t const PROGMEM sink_d_cycle[] = {0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; - static uint8_t const sink_b_cycle[] = + static uint8_t const PROGMEM sink_b_cycle[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20}; - uint8_t pins_d = sink_d = sink_d_cycle[cycle]; - uint8_t pins_b = sink_b = sink_b_cycle[cycle]; + uint8_t pins_d = sink_d = pgm_read_byte(&sink_d_cycle[cycle]); + uint8_t pins_b = sink_b = pgm_read_byte(&sink_b_cycle[cycle]); - // convert Borgware-2D framebuffer to LoL Shield cycles + // convert Borgware-2D framebuffer to LoL Shield cycles on Diavolino // (I could have done this with a lookup table, but that would be slower as // non-constant bit shifts are quite expensive on AVR) + // NOTE: (0,0) is UPPER RIGHT in the Borgware realm if (plane < NUMPLANE) { switch(cycle) { case 0: - pins_b |= (0x02u & p[ 0]) << 4; // x=12, y= 0, high=13 - pins_b |= (0x02u & p[ 2]) << 3; // x=12, y= 1, high=12 - pins_b |= (0x02u & p[ 4]) << 2; // x=12, y= 2, high=11 - pins_b |= (0x02u & p[ 6]) << 1; // x=12, y= 3, high=10 - pins_b |= (0x02u & p[ 8]); // x=12, y= 4, high= 9 - pins_b |= (0x02u & p[10]) >> 1; // x=12, y= 5, high= 8 - pins_d |= (0x02u & p[12]) << 6; // x=12, y= 6, high= 7 - pins_d |= (0x02u & p[14]) << 5; // x=12, y= 7, high= 6 - pins_d |= (0x02u & p[16]) << 4; // x=12, y= 8, high= 5 + pins_b |= (0x02u & p[ 0]) << 4; // x= 1, y= 0, mapped pin D13 + pins_b |= (0x02u & p[ 2]) << 3; // x= 1, y= 1, mapped pin D12 + pins_b |= (0x02u & p[ 4]) << 2; // x= 1, y= 2, mapped pin D11 + pins_b |= (0x02u & p[ 6]) << 1; // x= 1, y= 3, mapped pin D10 + pins_b |= (0x02u & p[ 8]); // x= 1, y= 4, mapped pin D9 + pins_b |= (0x02u & p[10]) >> 1; // x= 1, y= 5, mapped pin D8 + pins_d |= (0x02u & p[12]) << 6; // x= 1, y= 6, mapped pin D7 + pins_d |= (0x02u & p[14]) << 5; // x= 1, y= 7, mapped pin D6 + pins_d |= (0x02u & p[16]) << 4; // x= 1, y= 8, mapped pin D5 break; case 1: - pins_b |= (0x08u & p[ 0]) << 2; // x=10, y= 0, high=13 - pins_b |= (0x08u & p[ 2]) << 1; // x=10, y= 1, high=12 - pins_b |= (0x08u & p[ 4]); // x=10, y= 2, high=11 - pins_b |= (0x08u & p[ 6]) >> 1; // x=10, y= 3, high=10 - pins_b |= (0x08u & p[ 8]) >> 2; // x=10, y= 4, high= 9 - pins_b |= (0x08u & p[10]) >> 3; // x=10, y= 5, high= 8 - pins_d |= (0x08u & p[12]) << 4; // x=10, y= 6, high= 7 - pins_d |= (0x08u & p[14]) << 3; // x=10, y= 7, high= 6 - pins_d |= (0x08u & p[16]) << 2; // x=10, y= 8, high= 5 + pins_b |= (0x08u & p[ 0]) << 2; // x= 3, y= 0, mapped pin D13 + pins_b |= (0x08u & p[ 2]) << 1; // x= 3, y= 1, mapped pin D12 + pins_b |= (0x08u & p[ 4]); // x= 3, y= 2, mapped pin D11 + pins_b |= (0x08u & p[ 6]) >> 1; // x= 3, y= 3, mapped pin D10 + pins_b |= (0x08u & p[ 8]) >> 2; // x= 3, y= 4, mapped pin D9 + pins_b |= (0x08u & p[10]) >> 3; // x= 3, y= 5, mapped pin D8 + pins_d |= (0x08u & p[12]) << 4; // x= 3, y= 6, mapped pin D7 + pins_d |= (0x08u & p[14]) << 3; // x= 3, y= 7, mapped pin D6 + pins_d |= (0x08u & p[16]) << 2; // x= 3, y= 8, mapped pin D5 break; case 2: - pins_b |= (0x20u & p[ 0]); // x= 8, y= 0, high=13 - pins_b |= (0x20u & p[ 2]) >> 1; // x= 8, y= 1, high=12 - pins_b |= (0x20u & p[ 4]) >> 2; // x= 8, y= 2, high=11 - pins_b |= (0x20u & p[ 6]) >> 3; // x= 8, y= 3, high=10 - pins_b |= (0x20u & p[ 8]) >> 4; // x= 8, y= 4, high= 9 - pins_b |= (0x20u & p[10]) >> 5; // x= 8, y= 5, high= 8 - pins_d |= (0x20u & p[12]) << 2; // x= 8, y= 6, high= 7 - pins_d |= (0x20u & p[14]) << 1; // x= 8, y= 7, high= 6 - pins_d |= (0x20u & p[16]); // x= 8, y= 8, high= 5 + pins_b |= (0x20u & p[ 0]); // x= 5, y= 0, mapped pin D13 + pins_b |= (0x20u & p[ 2]) >> 1; // x= 5, y= 1, mapped pin D12 + pins_b |= (0x20u & p[ 4]) >> 2; // x= 5, y= 2, mapped pin D11 + pins_b |= (0x20u & p[ 6]) >> 3; // x= 5, y= 3, mapped pin D10 + pins_b |= (0x20u & p[ 8]) >> 4; // x= 5, y= 4, mapped pin D9 + pins_b |= (0x20u & p[10]) >> 5; // x= 5, y= 5, mapped pin D8 + pins_d |= (0x20u & p[12]) << 2; // x= 5, y= 6, mapped pin D7 + pins_d |= (0x20u & p[14]) << 1; // x= 5, y= 7, mapped pin D6 + pins_d |= (0x20u & p[16]); // x= 5, y= 8, mapped pin D5 break; case 3: - pins_b |= (0x20u & p[ 1]); // x= 0, y= 0, high=13 - pins_b |= (0x20u & p[ 3]) >> 1; // x= 0, y= 1, high=12 - pins_b |= (0x20u & p[ 5]) >> 2; // x= 0, y= 2, high=11 - pins_b |= (0x20u & p[ 7]) >> 3; // x= 0, y= 3, high=10 - pins_b |= (0x20u & p[ 9]) >> 4; // x= 0, y= 4, high= 9 - pins_b |= (0x20u & p[11]) >> 5; // x= 0, y= 5, high= 8 - pins_d |= (0x01u & p[16]) << 2; // x=13, y= 8, high= 2 - pins_d |= (0x04u & p[16]) << 1; // x=11, y= 8, high= 3 - pins_d |= (0x10u & p[16]); // x= 9, y= 8, high= 4 - pins_d |= (0x20u & p[13]) << 2; // x= 0, y= 6, high= 7 - pins_d |= (0x20u & p[15]) << 1; // x= 0, y= 7, high= 6 + pins_b |= (0x20u & p[ 1]); // x=13, y= 0, mapped pin D13 + pins_b |= (0x20u & p[ 3]) >> 1; // x=13, y= 1, mapped pin D12 + pins_b |= (0x20u & p[ 5]) >> 2; // x=13, y= 2, mapped pin D11 + pins_b |= (0x20u & p[ 7]) >> 3; // x=13, y= 3, mapped pin D10 + pins_b |= (0x20u & p[ 9]) >> 4; // x=13, y= 4, mapped pin D9 + pins_b |= (0x20u & p[11]) >> 5; // x=13, y= 5, mapped pin D8 + pins_d |= (0x01u & p[16]) << 2; // x= 0, y= 8, mapped pin D2 + pins_d |= (0x04u & p[16]) << 1; // x= 2, y= 8, mapped pin D3 + pins_d |= (0x10u & p[16]); // x= 4, y= 8, mapped pin D4 + pins_d |= (0x20u & p[13]) << 2; // x=13, y= 6, mapped pin D7 + pins_d |= (0x20u & p[15]) << 1; // x=13, y= 7, mapped pin D6 break; case 4: - pins_b |= (0x10u & p[ 1]) << 1; // x= 1, y= 0, high=13 - pins_b |= (0x10u & p[ 3]); // x= 1, y= 1, high=12 - pins_b |= (0x10u & p[ 5]) >> 1; // x= 1, y= 2, high=11 - pins_b |= (0x10u & p[ 7]) >> 2; // x= 1, y= 3, high=10 - pins_b |= (0x10u & p[ 9]) >> 3; // x= 1, y= 4, high= 9 - pins_b |= (0x10u & p[11]) >> 4; // x= 1, y= 5, high= 8 - pins_d |= (0x01u & p[14]) << 2; // x=13, y= 7, high= 2 - pins_d |= (0x04u & p[14]) << 1; // x=11, y= 7, high= 3 - pins_d |= (0x10u & p[13]) << 3; // x= 1, y= 6, high= 7 - pins_d |= (0x10u & p[14]); // x= 9, y= 7, high= 4 - pins_d |= (0x20u & p[17]); // x= 0, y= 8, high= 5 + pins_b |= (0x10u & p[ 1]) << 1; // x=12, y= 0, mapped pin D13 + pins_b |= (0x10u & p[ 3]); // x=12, y= 1, mapped pin D12 + pins_b |= (0x10u & p[ 5]) >> 1; // x=12, y= 2, mapped pin D11 + pins_b |= (0x10u & p[ 7]) >> 2; // x=12, y= 3, mapped pin D10 + pins_b |= (0x10u & p[ 9]) >> 3; // x=12, y= 4, mapped pin D9 + pins_b |= (0x10u & p[11]) >> 4; // x=12, y= 5, mapped pin D8 + pins_d |= (0x01u & p[14]) << 2; // x= 0, y= 7, mapped pin D2 + pins_d |= (0x04u & p[14]) << 1; // x= 2, y= 7, mapped pin D3 + pins_d |= (0x10u & p[13]) << 3; // x=12, y= 6, mapped pin D7 + pins_d |= (0x10u & p[14]); // x= 4, y= 7, mapped pin D4 + pins_d |= (0x20u & p[17]); // x=13, y= 8, mapped pin D5 break; case 5: - pins_b |= (0x08u & p[ 1]) << 2; // x= 2, y= 0, high=13 - pins_b |= (0x08u & p[ 3]) << 1; // x= 2, y= 1, high=12 - pins_b |= (0x08u & p[ 5]); // x= 2, y= 2, high=11 - pins_b |= (0x08u & p[ 7]) >> 1; // x= 2, y= 3, high=10 - pins_b |= (0x08u & p[ 9]) >> 2; // x= 2, y= 4, high= 9 - pins_b |= (0x08u & p[11]) >> 3; // x= 2, y= 5, high= 8 - pins_d |= (0x01u & p[12]) << 2; // x=13, y= 6, high= 2 - pins_d |= (0x04u & p[12]) << 1; // x=11, y= 6, high= 3 - pins_d |= (0x10u & p[12]); // x= 9, y= 6, high= 4 - pins_d |= (0x10u & p[15]) << 2; // x= 1, y= 7, high= 6 - pins_d |= (0x10u & p[17]) << 1; // x= 1, y= 8, high= 5 + pins_b |= (0x08u & p[ 1]) << 2; // x=11, y= 0, mapped pin D13 + pins_b |= (0x08u & p[ 3]) << 1; // x=11, y= 1, mapped pin D12 + pins_b |= (0x08u & p[ 5]); // x=11, y= 2, mapped pin D11 + pins_b |= (0x08u & p[ 7]) >> 1; // x=11, y= 3, mapped pin D10 + pins_b |= (0x08u & p[ 9]) >> 2; // x=11, y= 4, mapped pin D9 + pins_b |= (0x08u & p[11]) >> 3; // x=11, y= 5, mapped pin D8 + pins_d |= (0x01u & p[12]) << 2; // x= 0, y= 6, mapped pin D2 + pins_d |= (0x04u & p[12]) << 1; // x= 2, y= 6, mapped pin D3 + pins_d |= (0x10u & p[12]); // x= 4, y= 6, mapped pin D4 + pins_d |= (0x10u & p[15]) << 2; // x=12, y= 7, mapped pin D6 + pins_d |= (0x10u & p[17]) << 1; // x=12, y= 8, mapped pin D5 break; case 6: - pins_b |= (0x04u & p[ 1]) << 3; // x= 3, y= 0, high=13 - pins_b |= (0x04u & p[ 3]) << 2; // x= 3, y= 1, high=12 - pins_b |= (0x04u & p[ 5]) << 1; // x= 3, y= 2, high=11 - pins_b |= (0x04u & p[ 7]); // x= 3, y= 3, high=10 - pins_b |= (0x04u & p[ 9]) >> 1; // x= 3, y= 4, high= 9 - pins_d |= (0x01u & p[10]) << 2; // x=13, y= 5, high= 2 - pins_d |= (0x04u & p[10]) << 1; // x=11, y= 5, high= 3 - pins_d |= (0x08u & p[13]) << 4; // x= 2, y= 6, high= 7 - pins_d |= (0x08u & p[15]) << 3; // x= 2, y= 7, high= 6 - pins_d |= (0x08u & p[17]) << 2; // x= 2, y= 8, high= 5 - pins_d |= (0x10u & p[10]); // x= 9, y= 5, high= 4 + pins_b |= (0x04u & p[ 1]) << 3; // x=10, y= 0, mapped pin D13 + pins_b |= (0x04u & p[ 3]) << 2; // x=10, y= 1, mapped pin D12 + pins_b |= (0x04u & p[ 5]) << 1; // x=10, y= 2, mapped pin D11 + pins_b |= (0x04u & p[ 7]); // x=10, y= 3, mapped pin D10 + pins_b |= (0x04u & p[ 9]) >> 1; // x=10, y= 4, mapped pin D9 + pins_d |= (0x01u & p[10]) << 2; // x= 0, y= 5, mapped pin D2 + pins_d |= (0x04u & p[10]) << 1; // x= 2, y= 5, mapped pin D3 + pins_d |= (0x08u & p[13]) << 4; // x=11, y= 6, mapped pin D7 + pins_d |= (0x08u & p[15]) << 3; // x=11, y= 7, mapped pin D6 + pins_d |= (0x08u & p[17]) << 2; // x=11, y= 8, mapped pin D5 + pins_d |= (0x10u & p[10]); // x= 4, y= 5, mapped pin D4 break; case 7: - pins_b |= (0x02u & p[ 1]) << 4; // x= 4, y= 0, high=13 - pins_b |= (0x02u & p[ 3]) << 3; // x= 4, y= 1, high=12 - pins_b |= (0x02u & p[ 5]) << 2; // x= 4, y= 2, high=11 - pins_b |= (0x02u & p[ 7]) << 1; // x= 4, y= 3, high=10 - pins_b |= (0x04u & p[11]) >> 2; // x= 3, y= 5, high= 8 - pins_d |= (0x01u & p[ 8]) << 2; // x=13, y= 4, high= 2 - pins_d |= (0x04u & p[ 8]) << 1; // x=11, y= 4, high= 3 - pins_d |= (0x04u & p[13]) << 5; // x= 3, y= 6, high= 7 - pins_d |= (0x04u & p[15]) << 4; // x= 3, y= 7, high= 6 - pins_d |= (0x04u & p[17]) << 3; // x= 3, y= 8, high= 5 - pins_d |= (0x10u & p[ 8]); // x= 9, y= 4, high= 4 + pins_b |= (0x02u & p[ 1]) << 4; // x= 9, y= 0, mapped pin D13 + pins_b |= (0x02u & p[ 3]) << 3; // x= 9, y= 1, mapped pin D12 + pins_b |= (0x02u & p[ 5]) << 2; // x= 9, y= 2, mapped pin D11 + pins_b |= (0x02u & p[ 7]) << 1; // x= 9, y= 3, mapped pin D10 + pins_b |= (0x04u & p[11]) >> 2; // x=10, y= 5, mapped pin D8 + pins_d |= (0x01u & p[ 8]) << 2; // x= 0, y= 4, mapped pin D2 + pins_d |= (0x04u & p[ 8]) << 1; // x= 2, y= 4, mapped pin D3 + pins_d |= (0x04u & p[13]) << 5; // x=10, y= 6, mapped pin D7 + pins_d |= (0x04u & p[15]) << 4; // x=10, y= 7, mapped pin D6 + pins_d |= (0x04u & p[17]) << 3; // x=10, y= 8, mapped pin D5 + pins_d |= (0x10u & p[ 8]); // x= 4, y= 4, mapped pin D4 break; case 8: - pins_b |= (0x01u & p[ 1]) << 5; // x= 5, y= 0, high=13 - pins_b |= (0x01u & p[ 3]) << 4; // x= 5, y= 1, high=12 - pins_b |= (0x01u & p[ 5]) << 3; // x= 5, y= 2, high=11 - pins_b |= (0x02u & p[ 9]); // x= 4, y= 4, high= 9 - pins_b |= (0x02u & p[11]) >> 1; // x= 4, y= 5, high= 8 - pins_d |= (0x01u & p[ 6]) << 2; // x=13, y= 3, high= 2 - pins_d |= (0x02u & p[13]) << 6; // x= 4, y= 6, high= 7 - pins_d |= (0x02u & p[15]) << 5; // x= 4, y= 7, high= 6 - pins_d |= (0x02u & p[17]) << 4; // x= 4, y= 8, high= 5 - pins_d |= (0x04u & p[ 6]) << 1; // x=11, y= 3, high= 3 - pins_d |= (0x10u & p[ 6]); // x= 9, y= 3, high= 4 + pins_b |= (0x01u & p[ 1]) << 5; // x= 8, y= 0, mapped pin D13 + pins_b |= (0x01u & p[ 3]) << 4; // x= 8, y= 1, mapped pin D12 + pins_b |= (0x01u & p[ 5]) << 3; // x= 8, y= 2, mapped pin D11 + pins_b |= (0x02u & p[ 9]); // x= 9, y= 4, mapped pin D9 + pins_b |= (0x02u & p[11]) >> 1; // x= 9, y= 5, mapped pin D8 + pins_d |= (0x01u & p[ 6]) << 2; // x= 0, y= 3, mapped pin D2 + pins_d |= (0x02u & p[13]) << 6; // x= 9, y= 6, mapped pin D7 + pins_d |= (0x02u & p[15]) << 5; // x= 9, y= 7, mapped pin D6 + pins_d |= (0x02u & p[17]) << 4; // x= 9, y= 8, mapped pin D5 + pins_d |= (0x04u & p[ 6]) << 1; // x= 2, y= 3, mapped pin D3 + pins_d |= (0x10u & p[ 6]); // x= 4, y= 3, mapped pin D4 break; case 9: - pins_b |= (0x01u & p[ 7]) << 2; // x= 5, y= 3, high=10 - pins_b |= (0x01u & p[ 9]) << 1; // x= 5, y= 4, high= 9 - pins_b |= (0x01u & p[11]); // x= 5, y= 5, high= 8 - pins_b |= (0x80u & p[ 0]) >> 2; // x= 6, y= 0, high=13 - pins_b |= (0x80u & p[ 2]) >> 3; // x= 6, y= 1, high=12 - pins_d |= (0x01u & p[ 4]) << 2; // x=13, y= 2, high= 2 - pins_d |= (0x01u & p[13]) << 7; // x= 5, y= 6, high= 7 - pins_d |= (0x01u & p[15]) << 6; // x= 5, y= 7, high= 6 - pins_d |= (0x01u & p[17]) << 5; // x= 5, y= 8, high= 5 - pins_d |= (0x04u & p[ 4]) << 1; // x=11, y= 2, high= 3 - pins_d |= (0x10u & p[ 4]); // x= 9, y= 2, high= 4 + pins_b |= (0x01u & p[ 7]) << 2; // x= 8, y= 3, mapped pin D10 + pins_b |= (0x01u & p[ 9]) << 1; // x= 8, y= 4, mapped pin D9 + pins_b |= (0x01u & p[11]); // x= 8, y= 5, mapped pin D8 + pins_b |= (0x80u & p[ 0]) >> 2; // x= 7, y= 0, mapped pin D13 + pins_b |= (0x80u & p[ 2]) >> 3; // x= 7, y= 1, mapped pin D12 + pins_d |= (0x01u & p[ 4]) << 2; // x= 0, y= 2, mapped pin D2 + pins_d |= (0x01u & p[13]) << 7; // x= 8, y= 6, mapped pin D7 + pins_d |= (0x01u & p[15]) << 6; // x= 8, y= 7, mapped pin D6 + pins_d |= (0x01u & p[17]) << 5; // x= 8, y= 8, mapped pin D5 + pins_d |= (0x04u & p[ 4]) << 1; // x= 2, y= 2, mapped pin D3 + pins_d |= (0x10u & p[ 4]); // x= 4, y= 2, mapped pin D4 break; case 10: - pins_b |= (0x40u & p[ 0]) >> 1; // x= 7, y= 0, high=13 - pins_b |= (0x80u & p[ 4]) >> 4; // x= 6, y= 2, high=11 - pins_b |= (0x80u & p[ 6]) >> 5; // x= 6, y= 3, high=10 - pins_b |= (0x80u & p[ 8]) >> 6; // x= 6, y= 4, high= 9 - pins_b |= (0x80u & p[10]) >> 7; // x= 6, y= 5, high= 8 - pins_d |= (0x01u & p[ 2]) << 2; // x=13, y= 1, high= 2 - pins_d |= (0x04u & p[ 2]) << 1; // x=11, y= 1, high= 3 - pins_d |= (0x10u & p[ 2]); // x= 9, y= 1, high= 4 - pins_d |= (0x80u & p[12]); // x= 6, y= 6, high= 7 - pins_d |= (0x80u & p[14]) >> 1; // x= 6, y= 7, high= 6 - pins_d |= (0x80u & p[16]) >> 2; // x= 6, y= 8, high= 5 + pins_b |= (0x40u & p[ 0]) >> 1; // x= 6, y= 0, mapped pin D13 + pins_b |= (0x80u & p[ 4]) >> 4; // x= 7, y= 2, mapped pin D11 + pins_b |= (0x80u & p[ 6]) >> 5; // x= 7, y= 3, mapped pin D10 + pins_b |= (0x80u & p[ 8]) >> 6; // x= 7, y= 4, mapped pin D9 + pins_b |= (0x80u & p[10]) >> 7; // x= 7, y= 5, mapped pin D8 + pins_d |= (0x01u & p[ 2]) << 2; // x= 0, y= 1, mapped pin D2 + pins_d |= (0x04u & p[ 2]) << 1; // x= 2, y= 1, mapped pin D3 + pins_d |= (0x10u & p[ 2]); // x= 4, y= 1, mapped pin D4 + pins_d |= (0x80u & p[12]); // x= 7, y= 6, mapped pin D7 + pins_d |= (0x80u & p[14]) >> 1; // x= 7, y= 7, mapped pin D6 + pins_d |= (0x80u & p[16]) >> 2; // x= 7, y= 8, mapped pin D5 break; case 11: - pins_b |= (0x40u & p[ 2]) >> 2; // x= 7, y= 1, high=12 - pins_b |= (0x40u & p[ 4]) >> 3; // x= 7, y= 2, high=11 - pins_b |= (0x40u & p[ 6]) >> 4; // x= 7, y= 3, high=10 - pins_b |= (0x40u & p[ 8]) >> 5; // x= 7, y= 4, high= 9 - pins_b |= (0x40u & p[10]) >> 6; // x= 7, y= 5, high= 8 - pins_d |= (0x01u & p[ 0]) << 2; // x=13, y= 0, high= 2 - pins_d |= (0x04u & p[ 0]) << 1; // x=11, y= 0, high= 3 - pins_d |= (0x10u & p[ 0]); // x= 9, y= 0, high= 4 - pins_d |= (0x40u & p[12]) << 1; // x= 7, y= 6, high= 7 - pins_d |= (0x40u & p[14]); // x= 7, y= 7, high= 6 - pins_d |= (0x40u & p[16]) >> 1; // x= 7, y= 8, high= 5 + pins_b |= (0x40u & p[ 2]) >> 2; // x= 6, y= 1, mapped pin D12 + pins_b |= (0x40u & p[ 4]) >> 3; // x= 6, y= 2, mapped pin D11 + pins_b |= (0x40u & p[ 6]) >> 4; // x= 6, y= 3, mapped pin D10 + pins_b |= (0x40u & p[ 8]) >> 5; // x= 6, y= 4, mapped pin D9 + pins_b |= (0x40u & p[10]) >> 6; // x= 6, y= 5, mapped pin D8 + pins_d |= (0x01u & p[ 0]) << 2; // x= 0, y= 0, mapped pin D2 + pins_d |= (0x04u & p[ 0]) << 1; // x= 2, y= 0, mapped pin D3 + pins_d |= (0x10u & p[ 0]); // x= 4, y= 0, mapped pin D4 + pins_d |= (0x40u & p[12]) << 1; // x= 6, y= 6, mapped pin D7 + pins_d |= (0x40u & p[14]); // x= 6, y= 7, mapped pin D6 + pins_d |= (0x40u & p[16]) >> 1; // x= 6, y= 8, mapped pin D5 break; } } @@ -289,8 +826,40 @@ ISR(TIMER2_OVF_vect) { // Set sink pin to GND/sink, turning on current. PIND = sink_d; PINB = sink_b; +#endif +} - plane++; +#if !defined (__AVR_ATmega32U4__) +ISR(TIMER2_OVF_vect) { +#else +ISR(TIMER1_COMPA_vect) { +#endif + // For each cycle, we have potential planes to display. Once every plane has + // been displayed, then we move on to the next cycle. + // NOTE: a "cycle" is a subset of LEDs that can be driven at once. + + // 12 Cycles of Matrix + static uint8_t cycle = 0; + + // planes to display + // NOTE: a "plane" in the Borgware is the same as a "page" in Jimmie's lib + static uint8_t plane = 0; + +#if defined (__AVR_ATmega168__) || defined (__AVR_ATmega48__) || defined (__AVR_ATmega88__) || defined (__AVR_ATmega328P__) || defined (__AVR_ATmega1280__) || defined (__AVR_ATmega2560__) + TCCR2B = prescaler[plane]; +#elif defined (__AVR_ATmega8__) || defined (__AVR_ATmega128__) + TCCR2 = prescaler[page]; +#elif defined (__AVR_ATmega32U4__) + TCCR1B = prescaler[plane]; +#endif +#if !defined (__AVR_ATmega32U4__) + TCNT2 = counts[plane]; +#else + TCNT1 = counts[plane]; +#endif + + // distribute framebuffer contents among current cycle pins + compose_cycle(cycle, plane++); if (plane >= (NUMPLANE + 1)) { plane = 0; @@ -303,20 +872,49 @@ ISR(TIMER2_OVF_vect) { } void borg_hw_init() { - // prepare Timer2 + +#if defined (__AVR_ATmega168__) || defined (__AVR_ATmega48__) || defined (__AVR_ATmega88__) || defined (__AVR_ATmega328P__) || defined (__AVR_ATmega1280__) || defined (__AVR_ATmega2560__) TIMSK2 &= ~(_BV(TOIE2) | _BV(OCIE2A)); TCCR2A &= ~(_BV(WGM21) | _BV(WGM20)); TCCR2B &= ~_BV(WGM22); ASSR &= ~_BV(AS2); +#elif defined (__AVR_ATmega8__) + TIMSK &= ~(_BV(TOIE2) | _BV(OCIE2)); + TCCR2 &= ~(_BV(WGM21) | _BV(WGM20)); + ASSR &= ~_BV(AS2); +#elif defined (__AVR_ATmega128__) + TIMSK &= ~(_BV(TOIE2) | _BV(OCIE2)); + TCCR2 &= ~(_BV(WGM21) | _BV(WGM20)); +#elif defined (__AVR_ATmega32U4__) + // The only 8bit timer on the Leonardo is used by default, so we use the 16bit Timer1 + // in CTC mode with a compare value of 256 to achieve the same behaviour. + TIMSK1 &= ~(_BV(TOIE1) | _BV(OCIE1A)); + TCCR1A &= ~(_BV(WGM10) | _BV(WGM11)); + OCR1A = 256; +#endif - // Then start the display - TIMSK2 |= _BV(TOIE2); - TCCR2B = fastPrescaler; + setBrightness(); - // interrupt ASAP - TCNT2 = 0xff; + // Then start the display +#if defined (__AVR_ATmega168__) || defined (__AVR_ATmega48__) || defined (__AVR_ATmega88__) || defined (__AVR_ATmega328P__) || defined (__AVR_ATmega1280__) || defined (__AVR_ATmega2560__) + TIMSK2 |= _BV(TOIE2); + TCCR2B = FASTPRESCALER; +#elif defined (__AVR_ATmega8__) || defined (__AVR_ATmega128__) + TIMSK |= _BV(TOIE2); + TCCR2 = FASTPRESCALER; +#elif defined (__AVR_ATmega32U4__) + // Enable output compare match interrupt + TIMSK1 |= _BV(OCIE1A); + TCCR1B = FASTPRESCALER; +#endif + // interrupt ASAP +#if !defined (__AVR_ATmega32U4__) + TCNT2 = 255; +#else + TCNT1 = 255; +#endif // activate watchdog timer wdt_reset(); - wdt_enable(0x00); // 17ms watchdog + wdt_enable(WDTO_500MS); // 17ms watchdog } diff --git a/src/borg_hw/config.in b/src/borg_hw/config.in index 9aabae5..7c1d244 100644 --- a/src/borg_hw/config.in +++ b/src/borg_hw/config.in @@ -14,7 +14,7 @@ choice 'Hardware Driver' \ Andre-Borg HW_BORG_ANDRE \ Laufschrift-Borg HW_BORG_LS \ Laufschrift-Borg-MH HW_BORG_MH \ - LoL-Shield/Diavolino HW_LOLSHIELD \ + LoL-Shield HW_LOLSHIELD \ FFM-Jochen HW_BORG_LSJO \ FFM-LedBrett HW_LEDBRETT \ Borg-Mini HW_BORG_MINI \ diff --git a/src/borg_hw/config_lolshield.in b/src/borg_hw/config_lolshield.in index ceaf309..fd99bed 100644 --- a/src/borg_hw/config_lolshield.in +++ b/src/borg_hw/config_lolshield.in @@ -3,4 +3,6 @@ comment "lolshield setup" define_int USER_TIMER0_FOR_WAIT 1 +uint "Brightness (0-127)" BRIGHTNESS 127 + endmenu diff --git a/src/util.c b/src/util.c index bdd2a29..3b608e9 100644 --- a/src/util.c +++ b/src/util.c @@ -21,7 +21,6 @@ extern jmp_buf newmode_jmpbuf; void wait(int ms){ - /* Always use Timer1 except for the Arduino/LoL Shield platform. */ #ifndef USER_TIMER0_FOR_WAIT TCCR1B = _BV(WGM12) | _BV(CS12); //CTC Mode, clk/256 @@ -36,7 +35,6 @@ void wait(int ms){ OCR0A = (F_CPU/256000); //1000Hz #endif - for(;ms>0;ms--){ #ifdef CAN_SUPPORT @@ -57,7 +55,7 @@ void wait(int ms){ } #endif -#if defined (__AVR_ATmega644P__) || defined (__AVR_ATmega644__) || defined (__AVR_ATmega328__) || defined (__AVR_ATmega328P__) || (__AVR_ATmega1284P__) || defined (__AVR_ATmega1284__) +#if defined (__AVR_ATmega32U4__) || defined (__AVR_ATmega644P__) || defined (__AVR_ATmega644__) || defined (__AVR_ATmega328__) || defined (__AVR_ATmega328P__) || (__AVR_ATmega1284P__) || defined (__AVR_ATmega1284__) /* Timer1 for the masses */ # ifndef USER_TIMER0_FOR_WAIT while(!(TIFR1 & _BV(OCF1A))); //wait for compare match flag