Common subdirectories: LedControl-unpatched/examples and LedControl/examples
diff -u LedControl-unpatched/LedControl.cpp LedControl/LedControl.cpp
--- LedControl-unpatched/LedControl.cpp	2008-10-14 02:21:21.000000000 -0700
+++ LedControl/LedControl.cpp	2012-09-02 01:24:35.000000000 -0700
@@ -35,20 +35,23 @@
 #define OP_SHUTDOWN    12
 #define OP_DISPLAYTEST 15
 
-LedControl::LedControl(int dataPin, int clkPin, int csPin, int numDevices) {
+LedControl::LedControl(int dataPin, int clkPin, int csPin, int numDevices, bool anode) {
     SPI_MOSI=dataPin;
     SPI_CLK=clkPin;
     SPI_CS=csPin;
     if(numDevices<=0 || numDevices>8 )
 	numDevices=8;
     maxDevices=numDevices;
+    anodeMode=anode;
     pinMode(SPI_MOSI,OUTPUT);
     pinMode(SPI_CLK,OUTPUT);
     pinMode(SPI_CS,OUTPUT);
     digitalWrite(SPI_CS,HIGH);
     SPI_MOSI=dataPin;
-    for(int i=0;i<64;i++) 
+    for(int i=0;i<64;i++) { 
 	status[i]=0x00;
+	statusTransposed[i]=0x00;
+    }
     for(int i=0;i<maxDevices;i++) {
 	spiTransfer(i,OP_DISPLAYTEST,0);
 	//scanlimit is set to max on startup
@@ -97,7 +100,16 @@
     offset=addr*8;
     for(int i=0;i<8;i++) {
 	status[offset+i]=0;
-	spiTransfer(addr, i+1,status[offset+i]);
+    }
+    if (anodeMode) {
+    	transposeData(addr);
+    	for(int i=0;i<8;i++) {
+	    spiTransfer(addr, i+1, statusTransposed[offset+i]);
+    	}
+    } else {
+    	for(int i=0;i<8;i++) {
+	    spiTransfer(addr, i+1, status[offset+i]);
+    	}
     }
 }
 
@@ -158,8 +170,16 @@
     if(dp)
 	v|=B10000000;
     status[offset+digit]=v;
-    spiTransfer(addr, digit+1,v);
-    
+    if (anodeMode) {
+    	//transpose the digit matrix
+    	transposeData(addr);
+    	//send the entire set of digits
+    	for(int i=0;i<8;i++) {
+	    spiTransfer(addr, i+1, statusTransposed[offset+i]);
+    	}
+    } else {
+    	spiTransfer(addr, digit+1, v);
+    }
 }
 
 void LedControl::setChar(int addr, int digit, char value, boolean dp) {
@@ -173,14 +193,23 @@
     offset=addr*8;
     index=(byte)value;
     if(index >127) {
-	//nothing define we use the space char
+	//nothing defined we use the space char
 	value=32;
     }
     v=charTable[index];
     if(dp)
 	v|=B10000000;
     status[offset+digit]=v;
-    spiTransfer(addr, digit+1,v);
+    if (anodeMode) {
+    	//transpose the digit matrix
+    	transposeData(addr);
+    	//send the entire set of digits
+    	for(int i=0;i<8;i++) {
+	    spiTransfer(addr, i+1, statusTransposed[offset+i]);
+    	}
+    } else {
+    	spiTransfer(addr, digit+1, v);
+    }
 }
 
 void LedControl::spiTransfer(int addr, volatile byte opcode, volatile byte data) {
@@ -202,4 +231,73 @@
     digitalWrite(SPI_CS,HIGH);
 }    
 
+void LedControl::transposeData(int addr) {
+  int offset=addr*8;
+  byte a0, a1, a2, a3, a4, a5, a6, a7,
+       b0, b1, b2, b3, b4, b5, b6, b7;
+  
+  // Perform a bitwise transpose operation on an 8x8 bit matrix, stored as 8-byte array.
+  // We have to use the naive method because we're working on a 16-bit microprocessor.
+
+  // Load the array into eight one-byte variables.
+  a0 = status[offset];
+  a1 = status[offset+1];
+  a2 = status[offset+2];
+  a3 = status[offset+3];
+  a4 = status[offset+4];
+  a5 = status[offset+5];
+  a6 = status[offset+6];
+  a7 = status[offset+7];
+  
+  // Magic happens. Credit goes to: http://www.hackersdelight.org/HDcode/transpose8.c.txt
+  b0 = (a0 & 128)    | (a1 & 128)/2  | (a2 & 128)/4  | (a3 & 128)/8 |
+       (a4 & 128)/16 | (a5 & 128)/32 | (a6 & 128)/64 | (a7      )/128;
+  b1 = (a0 &  64)*2  | (a1 &  64)    | (a2 &  64)/2  | (a3 &  64)/4 |
+       (a4 &  64)/8  | (a5 &  64)/16 | (a6 &  64)/32 | (a7 &  64)/64;
+  b2 = (a0 &  32)*4  | (a1 &  32)*2  | (a2 &  32)    | (a3 &  32)/2 |
+       (a4 &  32)/4  | (a5 &  32)/8  | (a6 &  32)/16 | (a7 &  32)/32;
+  b3 = (a0 &  16)*8  | (a1 &  16)*4  | (a2 &  16)*2  | (a3 &  16)   |
+       (a4 &  16)/2  | (a5 &  16)/4  | (a6 &  16)/8  | (a7 &  16)/16;
+  b4 = (a0 &   8)*16 | (a1 &   8)*8  | (a2 &   8)*4  | (a3 &   8)*2 |
+       (a4 &   8)    | (a5 &   8)/2  | (a6 &   8)/4  | (a7 &   8)/8;
+  b5 = (a0 &   4)*32 | (a1 &   4)*16 | (a2 &   4)*8  | (a3 &   4)*4 |
+       (a4 &   4)*2  | (a5 &   4)    | (a6 &   4)/2  | (a7 &   4)/4;
+  b6 = (a0 &   2)*64 | (a1 &   2)*32 | (a2 &   2)*16 | (a3 &   2)*8 |
+       (a4 &   2)*4  | (a5 &   2)*2  | (a6 &   2)    | (a7 &   2)/2;
+  b7 = (a0      )*128| (a1 &   1)*64 | (a2 &   1)*32 | (a3 &   1)*16|
+       (a4 &   1)*8  | (a5 &   1)*4  | (a6 &   1)*2  | (a7 &   1);
+
+  // Assemble into output array.
+  statusTransposed[offset] = b0;
+  statusTransposed[offset+1] = b1;
+  statusTransposed[offset+2] = b2;
+  statusTransposed[offset+3] = b3;
+  statusTransposed[offset+4] = b4;
+  statusTransposed[offset+5] = b5;
+  statusTransposed[offset+6] = b6;
+  statusTransposed[offset+7] = b7;
+
+}
+
+void LedControl::setDirectDigit(int addr, int digit, byte value) {
+    int offset;
+
+    if(addr<0 || addr>=maxDevices)
+	return;
+    if(digit<0 || digit>7)
+	return;
+    offset=addr*8;
+    status[offset+digit]=value;
+    if (anodeMode) {
+    	transposeData(addr);
+    	for(int i=0;i<8;i++) {
+	    spiTransfer(addr, i+1, statusTransposed[offset+i]);
+    	}
+    } else {
+    	spiTransfer(addr, digit+1, value);
+    }
+}
+
+
+
 
diff -u LedControl-unpatched/LedControl.h LedControl/LedControl.h
--- LedControl-unpatched/LedControl.h	2011-09-20 23:49:06.000000000 -0700
+++ LedControl/LedControl.h	2012-09-02 00:18:47.000000000 -0700
@@ -58,6 +58,8 @@
 
     /* We keep track of the led-status for all 8 devices in this array */
     byte status[64];
+    /* We also keep track of the transposed version */
+    byte statusTransposed[64];
     /* Data is shifted out of this pin*/
     int SPI_MOSI;
     /* The clock is signaled on this pin */
@@ -66,6 +68,8 @@
     int SPI_CS;
     /* The maximum number of devices we use */
     int maxDevices;
+    /* Choose whether we're using common cathode or common anode displays */
+    bool anodeMode;
     
  public:
     /* 
@@ -75,8 +79,9 @@
      * clockPin		pin for the clock
      * csPin		pin for selecting the device 
      * numDevices	maximum number of devices that can be controled
+     * anode		false for common-cathode displays, true for common-anode displays
      */
-    LedControl(int dataPin, int clkPin, int csPin, int numDevices=1);
+    LedControl(int dataPin, int clkPin, int csPin, int numDevices=1, bool anode=false);
 
     /*
      * Gets the number of devices attached to this LedControl.
@@ -173,9 +178,25 @@
      * dp	sets the decimal point.
      */
     void setChar(int addr, int digit, char value, boolean dp);
+    
+    /*
+     * Transpose data matrix for use with common-anode displays.
+     * Params:
+     * addr	address of the display
+     */
+    void transposeData(int addr);
+    
+    /*
+     * Light up segments of a 7-segment display directly by passing a binary value.
+     * The eight bits of the byte each refer to a segment:
+     *     Byte:   0 0 0 0 0 0 0 0
+     *  Segments: DP A B C D E F G
+     * Params:
+     * addr	address of the display
+     * digit	the position of the character on the display (0..7)
+     * value	the binary value to be displayed
+     */
+    void setDirectDigit(int addr, int digit, byte value);
 };
 
 #endif	//LedControl.h
-
-
-
