Skip to content

Commit

Permalink
Minor cleanup, including:
Browse files Browse the repository at this point in the history
* 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.
  • Loading branch information
root committed Aug 30, 2013
1 parent 7ee75f9 commit 7f69023
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 71 deletions.
114 changes: 43 additions & 71 deletions lib/Charliplexing.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,54 +41,44 @@
#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 {
uint8_t counts[SHADES];
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 {
Expand Down Expand Up @@ -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))
Expand Down Expand Up @@ -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)

/*
Expand Down Expand Up @@ -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__)
Expand All @@ -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;
}

Expand All @@ -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
Expand Down Expand Up @@ -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.
Expand Down
2 changes: 2 additions & 0 deletions lib/Charliplexing.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down

0 comments on commit 7f69023

Please sign in to comment.