From 7f6902380cd46427841ca631051be3b0b675c264 Mon Sep 17 00:00:00 2001 From: root Date: Fri, 30 Aug 2013 02:06:28 +0000 Subject: [PATCH] Minor cleanup, including: * If DOUBLE_BUFFER is commented out, don't bother to use extra pointer for the display buffer. * There's no need to wait for a buffer flip when starting up. It's fine to display the first (blank) frame indefinitely. * Don't bother using delay() while waiting for flips. All it does is bloat the code. --- lib/Charliplexing.cpp | 114 ++++++++++++++++-------------------------- lib/Charliplexing.h | 2 + 2 files changed, 45 insertions(+), 71 deletions(-) diff --git a/lib/Charliplexing.cpp b/lib/Charliplexing.cpp index b4e45b0..21b3432 100644 --- a/lib/Charliplexing.cpp +++ b/lib/Charliplexing.cpp @@ -41,42 +41,33 @@ #include "Charliplexing.h" -struct videoPage { - uint16_t pixels[12*(SHADES-1)]; -}; - /* ----------------------------------------------------------------- */ -/** Table for the LED multiplexing cycles - * Each frame is made of 24 bytes (for the 24 display cycles) - * There are SHADES frames per buffer in grayscale mode (one for each brigtness) - * and twice that many to support double-buffered grayscale. - */ -#ifdef DOUBLE_BUFFER -videoPage leds[2]; -#else -videoPage leds[1]; -#endif - /// Determines whether the display is in single or double buffer mode uint8_t displayMode = SINGLE_BUFFER; -/// Flag indicating that the display page should be flipped as soon as the -/// current frame is displayed + +/** Table for the LED multiplexing cycles + * Each frame is made of 24 bytes (for the 12 display cycles) + * There are SHADES-1 frames per buffer in grayscale mode (one for each + * brightness) and twice that many to support double-buffered grayscale. + */ +struct videoPage { + uint16_t pixels[12*(SHADES-1)]; +}; + +/// Display buffers; only account two if DOUBLE_BUFFER is configured #ifdef DOUBLE_BUFFER volatile boolean videoFlipPage = false; +videoPage leds[2], *displayBuffer, *workBuffer; +#else +videoPage leds; +#define displayBuffer (&leds) +#define workBuffer (&leds) #endif -/// Pointer to the buffer that is currently being displayed -videoPage* displayBuffer; +/// Pointer inside the buffer that is currently being displayed uint16_t* displayPointer; -/// Pointer to the buffer that should currently be drawn to -videoPage* workBuffer; - -/// Flag indicating that the timer buffer should be flipped as soon as the -/// current frame is displayed -volatile boolean videoFlipTimer = false; - // Timer counts to display each page for, plus off time typedef struct timerInfo { @@ -84,11 +75,10 @@ typedef struct timerInfo { uint8_t prescaler[SHADES]; }; -// Double buffer the timing information, of course. -timerInfo* frontTimer; -timerInfo* backTimer; +/// Timing buffers (see SetBrightness()) +volatile boolean videoFlipTimer = false; +timerInfo timer[2], *frontTimer, *backTimer; -timerInfo timer[2]; // Record a slow and fast prescaler for later use typedef struct prescalerInfo { @@ -125,24 +115,25 @@ const prescalerInfo # error no support for this chip #endif + static bool initialized = false; + /// Uncomment to set analog pin 5 high during interrupts, so that an /// oscilloscope can be used to measure the processor time taken by it #undef MEASURE_ISR_TIME #ifdef MEASURE_ISR_TIME -uint8_t statusPIN = 19; +const uint8_t statusPIN = 19; #endif -typedef struct LEDPosition { - uint8_t high; - uint8_t cycle; -}; - /* ----------------------------------------------------------------- */ /** Table for LED Position in leds[] ram table */ +typedef struct LEDPosition { + uint8_t high; + uint8_t cycle; +}; #if defined (__AVR_ATmega1280__) || defined (__AVR_ATmega2560__) #define P(pin) ((pin < 5) ? (pin + 1) : (pin == 5) ? (2) : (pin)) @@ -177,6 +168,7 @@ const LEDPosition PROGMEM ledMap[126] = { L( 5, 6), L( 5, 7), L( 5, 8), L( 5, 9), L( 5,10), L( 5,11), L( 5,12), L( 5,13), L( 5, 4), L( 4, 5), L( 5, 3), L( 3, 5), L( 5, 2), L( 2, 5), }; +#undef P(pin) #undef L(high, low) /* @@ -254,39 +246,31 @@ void LedSign::Init(uint8_t mode) // Record whether we are in single or double buffer mode displayMode = mode; -#ifdef DOUBLE_BUFFER - videoFlipPage = false; -#endif - - // Point the display buffer to the first physical buffer - displayBuffer = &leds[0]; - displayPointer = displayBuffer->pixels; #ifdef DOUBLE_BUFFER + videoFlipPage = false; // If we are in single buffered mode, point the work buffer // at the same physical buffer as the display buffer. Otherwise, // point it at the second physical buffer. - if( displayMode & DOUBLE_BUFFER ) { + if (displayMode & DOUBLE_BUFFER) workBuffer = &leds[1]; - } else { - workBuffer = displayBuffer; - } -#else - workBuffer = displayBuffer; + else + workBuffer = &leds[0]; + displayBuffer = &leds[0]; #endif + // Point the display buffer to the first physical buffer + displayPointer = displayBuffer->pixels; + // Set up the timer buffering - frontTimer = &timer[0]; + videoFlipTimer = false; backTimer = &timer[1]; + frontTimer = &timer[0]; - videoFlipTimer = false; SetBrightness(127); // Clear the buffer and display it LedSign::Clear(0); -#ifdef DOUBLE_BUFFER - LedSign::Flip(false); -#endif // Then start the display #if defined (__AVR_ATmega168__) || defined (__AVR_ATmega48__) || defined (__AVR_ATmega88__) || defined (__AVR_ATmega328P__) || defined (__AVR_ATmega1280__) || defined (__AVR_ATmega2560__) @@ -307,17 +291,6 @@ void LedSign::Init(uint8_t mode) TCNT1 = 255; #endif -#ifdef DOUBLE_BUFFER - // If we are in double-buffer mode, wait until the display flips before we - // return - if (displayMode & DOUBLE_BUFFER) - { - while (videoFlipPage) { - delay(1); - } - } -#endif - initialized = true; } @@ -336,9 +309,9 @@ void LedSign::Flip(bool blocking) videoFlipPage = true; // If we are blocking, sit here until the page flips. - while (blocking && videoFlipPage) { - delay(1); - } + if (blocking) + while (videoFlipPage) + ; } } #endif @@ -447,9 +420,8 @@ void LedSign::SetBrightness(uint8_t brightness) #endif // Wait until the previous brightness request goes through - while( videoFlipTimer ) { - delay(1); - } + while (videoFlipTimer) + ; // Compute on time for each of the pages // Use the fast timer; slow timer is only useful for < 3 shades. diff --git a/lib/Charliplexing.h b/lib/Charliplexing.h index d85af3b..a1d4403 100644 --- a/lib/Charliplexing.h +++ b/lib/Charliplexing.h @@ -28,7 +28,9 @@ namespace LedSign extern void Init(uint8_t mode = SINGLE_BUFFER); extern void Set(uint8_t x, uint8_t y, uint8_t c = 1); extern void SetBrightness(uint8_t brightness); +#ifdef DOUBLE_BUFFER extern void Flip(bool blocking = false); +#endif extern void Clear(uint8_t c = 0); extern void Horizontal(uint8_t y, uint8_t c = 0); extern void Vertical(uint8_t x, uint8_t c = 0);