A few classes to interface one or more ShiftBrite module to the FRDM KL25Z.
sbDriver.h
- Committer:
- JoKer
- Date:
- 2014-08-22
- Revision:
- 7:a0f62fc80de0
- Parent:
- 5:aa0424f31fa1
File content as of revision 7:a0f62fc80de0:
//Low level driver for shiftbrite modules
#ifndef SHIFTBTIRE
#define SHIFTBTIRE
#include "mbed.h"
//REFER TO FRDM_LIGHTFX modules for hardware code
//=============================================================================================
/** Colour class
* Used as a base class for storing ShiftBrite colour information
*
* It is inherited by rgbLed class and is of little use if instanciated directly.
* Please see class shiftBriteDisplay for intended use.
*/
class colour{
private:
unsigned short int value; //0-1023 range
public:
void setColour(unsigned short int v){ v <= 1023 ? value = v : value = 1023;} // include range limiting
unsigned short int getColour(void){return value;}
colour operator =( unsigned short int v); //overload = relative to unsigned short int
colour operator =( colour c); // overload = relative to colour
};
//=============================================================================================
/** rgbLed class
* Used to instanciate a single rgb ShiftBrite object.
*
* ShiftBrite module consists of a single RGB led but
* modules can be hooked in serial to form a chain of 2 or more modules
*
* This class is used as a dynamically allocated member in class shiftBriteDisplay.
* It contains NO member functions for updating the physical shiftbright module so
* is of limited use if instanciated directly. Please see class shiftBriteDisplay for intended use.
*/
class rgbLed : public colour{//Inherit colour as a led consists of 3 colours
private:
colour red, green, blue;
//Could add in 3 members here to track each module's individual current control (Dot correction)
//but, this is not a critical app and I'd rather hang on to the extra memory so I elected
//to have one set of Dot Corr values for ALL modules. This is handled by shiftBriteDisplay class. see below
public:
// the constructors
rgbLed(unsigned long int rgbValue); // constructor for RGB value e.g. 0xFFFFFF. Will expand 0XFF to 0x3FF as per colour range
rgbLed(unsigned short int red, unsigned short int green, unsigned short int blue); //overload for seperate r,g,b arguments
rgbLed();//overload for no arguments
// the setters
void setRgbLed(unsigned long int rgbValue); // RGB value e.g. 0xFFFFFF. Will expand 0XFF to 0x3FF as per colour range, also, update packet
void setRgbLed(unsigned short int red, unsigned short int green, unsigned short int blue); //overload for seperate r,g,b arguments, also update packet
unsigned long int getPacket();
// the getters
unsigned short int getRed(){return red.getColour();}
unsigned short int getGreen(){return green.getColour();}
unsigned short int getBlue(){return blue.getColour();}
};
//=============================================================================================
/** shiftBriteDisplay class.
* Used to write data to one (or more) shiftBrite module(s) via the SPI port on FRDM KL25Z module.
*
* Dynamically allocates storage for each module, based on <moduleCount> provided to the constructor.
* Takes in references for the required hardware: SPI, Latch, Enable, and, if implemented, Reset.
* Shiftbrite modules does NOT have a reset line but can be reset by removing the power. The reset line
* referenced will toggle to allow you to implement the required hardware.
* @param Serial Pointer to instance of Serial object.
@param Latch Pin used to control data latching on shiftbrite module.
@param Enable Pin used to control LED output buffers of shiftbrite module.
@param Reset Pin used to signal a circuit that control the +ve power to the shiftbrite modules. This can be ignored if no reset required.
@param SPI Port to send serial data to shoftbrite module. (Data and Clock).
@param moduleCount int, the number of connected modules.
*
* Example:
* @code
#include "mbed.h"
#include "sbDriver.h"
DigitalOut latch(PTC16);//to LI pin of shiftBrite module
DigitalOut enable(PTA13);//to EI pin of shiftBrite module
DigitalOut reset(PTC12);//to power control circuit of your doing - NOT MANDATORY
SPI spi(PTD2,NC,PTD1);//PDT2 = MOSI to DI and PDT1 to CI of shiftBrite module
shiftBriteDisplay sbDisplay(latch, enable, reset, spi,6);//for, say, 6 modules wired in SERIES.
//If you wish to change the DOT CORR registers
sbDisplay.setCurrentCorr(0x78,0x64,0x64);//use values you want to set as default. These are the suggested values
//Now, you can either call a member function to update the actual display OR
//set it up using a Ticker. This is how you setup a ticker
Ticker t;
t.attach_us(&sbDisplay,&shiftBriteDisplay::displayFrame,41666);//call updateFrame 24 times per second (every 41666uS)
//Ticker will automatically call sbDisplay.displayFrame()
while(1){
//Now just fill in the colours you want
sbDisplay.setLed(0,1023,0,0); //FULL on red on the LAST display in the chain
sbDisplay.setLed(5,0,1023,0); //FULL on green on first (remember the display has 6 leds in this example) LED
//etc......
}
* @endcode
*
* @note - Usage of shifBriteDisplay::setLed() member is as follows:
* @code object.setLed(LedModuleNum,red, green, blue); //where colours are in the range of 0-1023@endcode
* or
* @code object.setLed(LedModuleNnum,RGB);// where RGB is in a range from 0x000000 to 0XFFFFFF (0xRRGGBB)@endcode
* @note NB, In the second method each colour has a range of 0-255 (0-0xFF) but that is expanded to the full range. This can be convenient but
* I suggest the first method is the best.
*
*
* @endnote
*/
class shiftBriteDisplay{
private:
//Serial *serial_p; // for debug printing
//Harware control lines - common to all leds in display
DigitalOut sb_latch;
DigitalOut sb_enable;
DigitalOut sb_reset;//Note, this effected by toggling power to the modules, it's not inherent shiftbrite functionality
SPI spi;
//Led module(s)
rgbLed *module_p; // points to the array of modules with same number of elements as LED modules
unsigned int moduleCount;
unsigned char rCorr, gCorr, bCorr; //These are the 'global' values for the current correction reg. DOT CORRECTION.
unsigned short int f_update;// flags that object is in an update cycle so that new req are ignored
// hardware control member methods
void priv_SBEnable(void){sb_enable = 0;}
void priv_SBDisable(void){sb_enable = 1;}
void priv_SBLatch(void){wait(0.0001);sb_latch = 1;wait(0.0001);sb_latch = 0;}
void priv_reset(void);//{sb_reset=0;wait(0.1);sb_reset=1;
// writes a single rgbLed RGB values as stored in the module_p array
void send(rgbLed M, unsigned short int commandStatus=0); // accesses rgbLed.getPacket()
public:
//TO DO - Modify the constructor to initialise the spi PWM, and setup defaults for the SB control sinals (i.e. enable, latch and reset)
// Also, initialize the SB current control registers(this WILL need to be done each time the SB modules are reset)
/**Constructor
See the example code for usage instructions.
*/
// shiftBriteDisplay (Serial *port,DigitalOut &latch, DigitalOut &enable, DigitalOut &reset, SPI &spiPort, unsigned int moduleCount); //constructor
shiftBriteDisplay (DigitalOut &latch, DigitalOut &enable, DigitalOut &reset, SPI &spiPort, unsigned int moduleCount); //constructor
// Destructor
~shiftBriteDisplay();//destructor - needs to release module_p
// Setters
/**used to set the colour for a specific dot (LED) using the RGB system. e.g. 0XFF0000 is full blue. I would suggest not using this
* unless you have no option because it only allows specifying 256 levels for each colour whereas the ShiftBright modules are
* capable of 1024. Use the overloaded member function. Example:
* @code
myDisplay.setLed(ledNum,0X007F00);//Set led module 'ledNum' to half brightness green
myDisplay.setLed(ledNum+1,0X00FF00); // Set module 'ledNum+1' to full brightness green
@endcode
*/
void setLed(unsigned int moduleNum, unsigned long int rgbValue);
/**used to set the colour for a specific dot (LED) using the full ability of the ShiftBrite modules. Each colour is supplied
* individualy in the range of 0-1023 (0-0x3FF). Example:
* @code
myDisplay.setLed(ledNum,0,512,0);//Set led module 'ledNum' to half brightness green using a decimal no
myDisplay.setLed(ledNum+1,0,0x3FF,0); // Set module 'ledNum+1' to full brightness green using a hex no
@endcode
*/
void setLed(unsigned int moduleNum, unsigned short int red, unsigned short int green, unsigned short int blue);//Overloaded
// void setCurrentCorr( unsigned long int rgbValue=0x786464);//ALL modules
/** used to adjust the maximum current to each colour. Consists of 3 values, one each for red, green and blue.
* This allow you to adjust the brightness level of the reds, green and blues. Is usefull if one colour is brighter than the others
* that causes colours to mix incorrectly. When used it will record the arguments as the default values. Range is from 0 to 127 for each colour.
* This equated to rought 30% to 100% full brightness. NOTE, This is NOT for setting the brightness of the display (even though
* it can be abused that way), it is intended for adjusting the brightness balance between colours so that, for example, 0X3FF red and 0X3FF
* green makes yellow and not reddy-yellow or greeny-yellow etc.
* @code
myDisplay.setCurrentCorr(0x78,0x64,0x64); // set and record values as default. Retained only until master reset or powerdown.
@endcode
*
*/
void setCurrentCorr( unsigned short int red, unsigned short int green, unsigned short int blue);//ALL modules
/**Overloaded version of above but calls up the stored values.
* These can either be the default (as Suggested by the ShiftBrite manufacturer) if they were not overwritten
* with the alternate member function (above).
*/
void setCurrentCorr();//overload - meaning, read the vals from the class member and set accordingly
// Getters
// Display update
/** used to refresh the display. All colour values are written out.
*/
void displayFrame();// write a whole display's worth of data.
unsigned int getModuleCount(){return moduleCount;}
// Basic effects
/**rotateLeft()
* is used to shift the whole display colours one step left.
*The first colour is rotated around and shifted in the last dot.
* @code
for(loop=0; loop !=NumOfLeds; loop++){
sbDisplay.rotateLeft();
sbDisplay.displayFrame();
wait(0.2);
}
* @endcode
*/
void rotateLeft();
/**shiftLeft()
* is used to shift the whole display colours one step left.
* A blank dot is shifted in unless a colour is given in the argument.
* @code
for(loop=0; loop !=NumOfLeds; loop++){
sbDisplay.shiftLeft();//or, to shift in a colour .shiftLeft(1000,200,0);
sbDisplay.displayFrame();
wait(0.2);
}
* @endcode
*/
void shiftLeft(unsigned short int inR=0,unsigned short int inG=0,unsigned short int inB=0);//info shifted out is lost
/**rotateRight()
* is used to shift the whole display colours one step right.
*The first colour is rotated around and shifted in the last dot.
* @code
for(loop=0; loop !=NumOfLeds; loop++){
sbDisplay.rotateRight();
sbDisplay.displayFrame();
wait(0.2);
}
* @endcode
*/
void rotateRight();
/**shiftRight()
* is used to shift the whole display colours one step right.
* A blank dot is shifted in unless a colour is given as an argument.
* @code
for(loop=0; loop !=NumOfLeds; loop++){
sbDisplay.shiftRight(); // or, to feed in a colour sbDisplay.shiftRight(0,0XF0,0x30);
sbDisplay.displayFrame();
wait(0.2);
}
* @endcode
*/
void shiftRight(unsigned short int inR=0,unsigned short int inG=0,unsigned short int inB=0);//info shifted out is lost
/**Display output is turned enabled.
*/
void turnOn();
/**Display output is turned disabled.
*/
void turnOff();
/**Used to exchange display values left to right and right to left.
*/
void flip(); //swop positions
/**Changes all display colours with it's mathematical opposite.
*/
void invert(); //invert colours
};
#endif