Johan Kritzinger
/
FRDMKL25Z-ShiftBrite
A few classes to interface one or more ShiftBrite module to the FRDM KL25Z.
sbDriver.h
- Committer:
- JoKer
- Date:
- 2014-08-20
- Revision:
- 3:9376bf1f1bbd
- Parent:
- 2:3935d2ed40cd
- Child:
- 4:d2f8ddb423e2
File content as of revision 3:9376bf1f1bbd:
//Low level driver for shiftbrite modules #ifndef SHIFTBTIRE #define SHIFTBTIRE #include "mbed.h" //#include <string> // NOT string.h... hope this works with mbed //REFER TO FRDM_LIGHTFX modules for hardware code //============================================================================================= //class frame{//Would this help? /*house a complete frame of data This would include a shiftBriteDisplay as a member The shiftBriteDisplay would then be fed a frame of data at a time OR would it be better to have a movie class, holding all frames, as an member in shiftBriteDisplay shiftBriteDisplay would then call loadFrame from the movie class Movie class is essentially an array of frames with a circular buffer type of implementation I think first option better as this would mean I can easily change movie content and have the movie in control of updating the frame etc. */ //}; //class movie{ /*house several frames that can be played in sequence*/ //}; //============================================================================================= /** 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" //This code is licenced as "BEERWARE" and used at own your own risk and discretion. Coded by Johan Kritzinger 8/2014. Serial PC(PTA2, PTA1);//Access to serial port for sending error messages 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(&PC,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. * * * * TO DO: * See if thee is a better way to deal with the serial port. * Write a frame and movie class to abstract dealing with individual LED's * @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 // 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. */ 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). */ 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. */ void setCurrentCorr( unsigned short int red, unsigned short int green, unsigned short int blue);//ALL modules /** same as above but call up the stored default values. */ 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. */ void rotateLeft(); /**shiftLeft() * is used to shift the whole display colours one step left. * A blank dot is shifted in. */ void shiftLeft();//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. */ void rotateRight(); /**shiftRight() * is used to shift the whole display colours one step right. * A blank dot is shifted in. */ void shiftRight();//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