diff --git a/src/LedControl.cpp b/src/LedControl.cpp index e43211fd..d4c14f58 100644 --- a/src/LedControl.cpp +++ b/src/LedControl.cpp @@ -1,7 +1,7 @@ /* * LedControl.cpp - A library for controling Leds with a MAX7219/MAX7221 * Copyright (c) 2007 Eberhard Fahle - * + * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without @@ -10,10 +10,10 @@ * copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following * conditions: - * - * This permission notice shall be included in all copies or + * + * This permission notice shall be included in all copies or * substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND @@ -55,7 +55,7 @@ LedControl::LedControl(int dataPin, int clkPin, int csPin, int numDevices) { 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; for(int i=0;i=maxDevices) return; - if(intensity>=0 && intensity<16) + if(intensity>=0 && intensity<16) spiTransfer(addr, OP_INTENSITY,intensity); } @@ -108,6 +108,81 @@ void LedControl::clearDisplay(int addr) { } } +void LedControl::setRotation(int rot) { + rotation = rot; +} + +coord LedControl::flipHorizontally(coord xy) { + xy.x = 7- xy.x; + return xy; +} + +coord LedControl::flipVertically(coord xy) { + xy.y = 7- xy.y; + return xy; +} + +coord LedControl::rotate90(coord xy) { + int tmp = xy.y; + xy.y = xy.x; + xy.x = tmp; + return flipHorizontally(xy); +} + +coord LedControl::rotate180(coord xy) { + return flipHorizontally(flipVertically(xy)); +} + +coord LedControl::rotate270(coord xy) { + return rotate180(rotate90(xy)); +} + +coord LedControl::transform(coord xy) { + if (rotation == 90) { + xy = rotate90(xy); + } else if (rotation == 180) { + xy = rotate180(xy); + } else if (rotation == 270) { + xy = rotate270(xy); + } + return xy; +} + +coord LedControl::transform(int x, int y) { + coord xy; + xy.x = x; + xy.y =y; + return transform(xy); +} + +void LedControl::setXY(int addr, int x, int y, boolean state) { + coord xy; + xy.x = x; + xy.y = y; + xy = transform(xy); + setLed(addr, xy.y, xy.x, state); +} + +void LedControl::setRawXY(int addr, int x, int y, boolean state) { + setLed(addr, y, x, state); +} + +boolean LedControl::getXY(int addr, int x, int y) { + coord xy; + xy.x = x; + xy.y = y; + xy = transform(xy); + return getLed(addr, xy.y, xy.x); +} + +boolean LedControl::getRawXY(int addr, int x, int y) { + return getLed(addr, y, x); +} + +void LedControl::setXY(int addr, coord xy, boolean state) { + setXY(addr, xy.x, xy.y, state); +} + void LedControl::setLed(int addr, int row, int column, boolean state) { int offset; byte val=0x00; @@ -127,6 +202,31 @@ void LedControl::setLed(int addr, int row, int column, boolean state) { spiTransfer(addr, row+1,status[offset+row]); } +void LedControl::invertRawXY(int addr, int x, int y) { + return setRawXY(addr, x, y, !getRawXY(addr, x, y)); +} + +void LedControl::invertXY(int addr, int x, int y) { + return setXY(addr, x, y, !getXY(addr, x, y)); +} + +boolean LedControl::getXY(int addr, coord xy) { + return getXY(addr, xy.x, xy.y); +} + +boolean LedControl::getLed(int addr, int row, int column) { + int offset; + boolean state; + + if(addr<0 || addr>=maxDevices) + return false; + if(row<0 || row>7 || column<0 || column>7) + return false; + offset=addr*8; + state = (1 == ( (status[offset+row] >> (7-column)) & 1)); + return state; +} + void LedControl::setRow(int addr, int row, byte value) { int offset; if(addr<0 || addr>=maxDevices) @@ -143,7 +243,7 @@ void LedControl::setColumn(int addr, int col, byte value) { if(addr<0 || addr>=maxDevices) return; - if(col<0 || col>7) + if(col<0 || col>7) return; for(int row=0;row<8;row++) { val=value >> (7-row); @@ -161,7 +261,7 @@ void LedControl::setDigit(int addr, int digit, byte value, boolean dp) { if(digit<0 || digit>7 || value>15) return; offset=addr*8; - v=pgm_read_byte_near(charTable + value); + v=pgm_read_byte_near(charTable + value); if(dp) v|=B10000000; status[offset+digit]=v; @@ -182,7 +282,7 @@ void LedControl::setChar(int addr, int digit, char value, boolean dp) { //no defined beyond index 127, so we use the space char index=32; } - v=pgm_read_byte_near(charTable + index); + v=pgm_read_byte_near(charTable + index); if(dp) v|=B10000000; status[offset+digit]=v; @@ -199,13 +299,25 @@ void LedControl::spiTransfer(int addr, volatile byte opcode, volatile byte data) //put our device data into the array spidata[offset+1]=opcode; spidata[offset]=data; - //enable the line + //enable the line digitalWrite(SPI_CS,LOW); - //Now shift out the data + //Now shift out the data for(int i=maxbytes;i>0;i--) shiftOut(SPI_MOSI,SPI_CLK,MSBFIRST,spidata[i-1]); //latch the data onto the display digitalWrite(SPI_CS,HIGH); -} - +} +void LedControl::backup() { + memcpy(backupStatus, status, 64); +} +void LedControl::restore() { + memcpy(status, backupStatus, 64); + int offset; + for (int addr=0; addr #endif +struct coord { + int x; + int y; +}; + /* * Segments to be switched on for characters and digits on * 7-Segment Displays @@ -67,6 +72,7 @@ class LedControl { /* We keep track of the led-status for all 8 devices in this array */ byte status[64]; + byte backupStatus[64]; /* Data is shifted out of this pin*/ int SPI_MOSI; /* The clock is signaled on this pin */ @@ -76,17 +82,21 @@ class LedControl { /* The maximum number of devices we use */ int maxDevices; + int rotation; + public: - /* - * Create a new controler + /* + * Create a new controler * Params : * dataPin pin on the Arduino where data gets shifted out * clockPin pin for the clock - * csPin pin for selecting the device + * csPin pin for selecting the device * numDevices maximum number of devices that can be controled */ LedControl(int dataPin, int clkPin, int csPin, int numDevices=1); + void setRotation(int rot); + /* * Gets the number of devices attached to this LedControl. * Returns : @@ -94,7 +104,7 @@ class LedControl { */ int getDeviceCount(); - /* + /* * Set the shutdown (power saving) mode for the device * Params : * addr The address of the display to control @@ -103,7 +113,7 @@ class LedControl { */ void shutdown(int addr, bool status); - /* + /* * Set the number of digits (or rows) to be displayed. * See datasheet for sideeffects of the scanlimit on the brightness * of the display. @@ -113,7 +123,7 @@ class LedControl { */ void setScanLimit(int addr, int limit); - /* + /* * Set the brightness of the display. * Params: * addr the address of the display to control @@ -121,25 +131,46 @@ class LedControl { */ void setIntensity(int addr, int intensity); - /* - * Switch all Leds on the display off. + /* + * Switch all Leds on the display off. * Params: * addr address of the display to control */ void clearDisplay(int addr); - /* + /* * Set the status of a single Led. * Params : - * addr address of the display + * addr address of the display * row the row of the Led (0..7) * col the column of the Led (0..7) - * state If true the led is switched on, + * state If true the led is switched on, * if false it is switched off */ + + void setRawXY(int addr, int x, int y, boolean state); + boolean getRawXY(int addr, int x, int y); + void invertRawXY(int addr, int x, int y); + void setLed(int addr, int row, int col, boolean state); + void setXY(int addr, int x, int y, boolean state); + void setXY(int addr, coord xy, boolean state); + void invertXY(int addr, int x, int y); + boolean getLed(int addr, int row, int col); + boolean getXY(int addr, int x, int y); + boolean getXY(int addr, coord xy); + coord transform(coord xy); + coord transform(int x, int y); + coord flipHorizontally(coord xy); + coord flipVertically(coord xy); + coord rotate90(coord xy); + coord rotate180(coord xy); + coord rotate270(coord xy); + + void backup(); + void restore(); - /* + /* * Set all 8 Led's in a row to a new state * Params: * addr address of the display @@ -149,7 +180,7 @@ class LedControl { */ void setRow(int addr, int row, byte value); - /* + /* * Set all 8 Led's in a column to a new state * Params: * addr address of the display @@ -159,7 +190,7 @@ class LedControl { */ void setColumn(int addr, int col, byte value); - /* + /* * Display a hexadecimal digit on a 7-Segment Display * Params: * addr address of the display @@ -169,22 +200,19 @@ class LedControl { */ void setDigit(int addr, int digit, byte value, boolean dp); - /* + /* * Display a character on a 7-Segment display. * There are only a few characters that make sense here : * '0','1','2','3','4','5','6','7','8','9','0', * 'A','b','c','d','E','F','H','L','P', - * '.','-','_',' ' + * '.','-','_',' ' * Params: * addr address of the display * digit the position of the character on the display (0..7) - * value the character to be displayed. + * value the character to be displayed. * dp sets the decimal point. */ void setChar(int addr, int digit, char value, boolean dp); }; #endif //LedControl.h - - -