A few classes to interface one or more ShiftBrite module to the FRDM KL25Z.

Dependencies:   mbed

sbDriver.h

Committer:
JoKer
Date:
2014-08-19
Revision:
0:f76850de7b57
Child:
1:4a62ae180af0

File content as of revision 0:f76850de7b57:

//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
  @param Latch Pin
  @param Enable Pin 
  @param Reset Pin 
  @param SPI Port (Data and Clock)
  @param moduleCount int
*
*   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
    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
    shiftBriteDisplay (Serial *port,DigitalOut &latch, DigitalOut &enable, DigitalOut &reset, SPI &spiPort, unsigned int moduleCount); //constructor

//    Destructor
    ~shiftBriteDisplay();//destructor - needs to release module_p
    
//    Setters    
    void setLed(unsigned int moduleNum, unsigned long int rgbValue);
    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
    void setCurrentCorr( unsigned short int red/* = 0x78*/, unsigned short int green/* = 0x64*/, unsigned short int blue/* = 0x64*/);//ALL modules
    void setCurrentCorr();//overload - meaning, read the vals from the class member and set accordingly
//    Display update    
    void displayFrame();// write a whole display's worth of data.
};
#endif