This module provides a simple API to the Maxim MAX7456 on-screen display chip

MAX7456.h

Committer:
AjK
Date:
2010-11-16
Revision:
0:d7cd54ad4c3d

File content as of revision 0:d7cd54ad4c3d:

/*
    Copyright (c) 2010 Andy Kirkham
 
    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 restriction, including without limitation the rights
    to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
    copies of the Software, and to permit persons to whom the Software is
    furnished to do so, subject to the following conditions:
 
    The above copyright notice and 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 NONINFRINGEMENT. IN NO EVENT SHALL THE
    AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
    LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
    OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
    THE SOFTWARE.
*/

#ifndef MODMAX7456_H
#define MODMAX7456_H

#include "mbed.h"

/** @defgroup MAX7456_API */
/** @defgroup MAX7456_REGISTER_API */

/** MAX7456 module
 *
 * @see http://mbed.org/cookbook/
 * @see example1.cpp
 *
 * Example:
 * @code
 * #include "mbed.h"
 * #include "MAX7456.h"
 * 
 * DigitalOut led1(LED1);
 * 
 * MAX7456 *max7456;
 * 
 * int main() {
 * 
 *     max7456 = new MAX7456(p5, p6, p7, p8, p20, p15);
 *     
 *     max7456->stringxy(1, 1, "Hello World");
 *     
 *     while(1) {
 *         led1 = 1;
 *         wait(0.5);
 *         led1 = 0;
 *         wait(0.5);
 *     }
 * }
 * @endcode
 */
 
class MAX7456
{
public:
    
    //! MAX7456 register definitions
    enum Registers {
        VM0 = 0,  VM1, HOS, VOS, DMM, DMAH, DMAL, DMDI, CMM, CMAH, CMAL, CMDI, OSDM,
        OSDBL = 0x6C
    };
    
    //! MAX7456 Row brightness register definitions.
    enum RowBrightnessReg {
        RB0 = 16, RB1, RB2, RB3, RB4, RB5, RB6, RB7, RB8, RB9, RB10, RB11, RB12, RB13, RB14, RB15,         
    };
    
    //! Character attributes.
    enum Attributes {
        //! Inverse background
        Inverse = (1 << 5),
        //! Character blinks
        Blink   = (1 << 6),
        //! Use "local background"
        LocalBG = (1 << 7)
    };
    
    //! Background brightness levels (see register VM1)
    enum BGbrightness {
        //! 0%
        Percent_0  = (0 << 4),
        //! 7%
        Percent_7  = (1 << 4),
        //! 14%
        Percent_14 = (2 << 4),
        //! 21%
        Percent_21 = (3 << 4),
        //! 28%
        Percent_28 = (4 << 4),
        //! 35%
        Percent_35 = (5 << 4),
        //! 42%
        Percent_42 = (6 << 4),
        //! 49%
        Percent_49 = (7 << 4)
    };
    
    //! Character blink time.
    enum BlinkTime {
        //! 33milliseconds
        ms_33  = (0 << 2),
        //! 67milliseconds
        ms_67  = (1 << 2),
        //! 100milliseconds
        ms_100 = (2 << 2),
        //! 133milliseconds
        ms_133 = (3 << 2) 
    };
    
    // Blink Time duty cycle.
    enum BlinkingDutyCycle {
        //! 1:1 duty cycle
        BT_BT   = (0 << 0),
        //! 1:2 duty cycle
        BT_BT2  = (1 << 0),
        //! 1:3 duty cycle
        BT_BT3  = (2 << 0),
        //! 3:1 duty cycle
        BT3_BT  = (3 << 0)
    };
    
    //! MAX7456 constructor.
    /**
     * The MAX7456 constructor is used to initialise the MAX7456 object.
     *
     * Example 1
     * @code
     *     #include "mbed.h"
     *     #include "MAX7456.h"
     *
     *     MAX7456 max(p5, p6, p7, NULL, p8, p20, p15);
     *
     *     int main() {
     *
     *         max.stringxy(1, 1, "Hello World");
     *
     *         while(1); 
     *     }
     * @endcode
     * 
     * Example 2
     * @code
     *     #include "mbed.h"
     *     #include "MAX7456.h"
     *
     *     int main() {
     *
     *         MAX7456 max = new MAX7456(p5, p6, p7, NULL, p8, p20, p15);
     *
     *         max->stringxy(1, 1, "Hello World");
     *
     *         while(1); 
     *     }
     * @endcode
     *
     * @ingroup MAX7456_API
     * @param miso PinName p5 or p11
     * @param mosi PinName p6 or p12
     * @param sclk PinName p7 pr p13
     * @param name Optional const char * SSP object name
     * @param cs   PinName CS signal
     * @param rst  PinName RESET signal
     * @param vsync PinName Vertical sync signal
     */
    MAX7456(PinName mosi, PinName miso, PinName sclk, const char *name, PinName cs, PinName rst, PinName vsync);         
    
    //! MAX7456 constructor.
    /**
     * The MAX7456 constructor is used to initialise the MAX7456 object.
     *
      * Example 1
     * @code
     *     #include "mbed.h"
     *     #include "MAX7456.h"
     *
     *     MAX7456 max(p5, p6, p7, p8, p20, p15);
     *
     *     int main() {
     *
     *         max.stringxy(1, 1, "Hello World");
     *
     *         while(1); 
     *     }
     * @endcode
     * 
     * Example 2
     * @code
     *     #include "mbed.h"
     *     #include "MAX7456.h"
     *
     *     int main() {
     *
     *         MAX7456 max = new MAX7456(p5, p6, p7, p8, p20, p15);
     *
     *         max->stringxy(1, 1, "Hello World");
     *
     *         while(1); 
     *     }
     * @endcode
     *
     * @ingroup MAX7456_API
     * @param miso PinName p5 or p11
     * @param mosi PinName p6 or p12
     * @param sclk PinName p7 pr p13
     * @param cs   PinName CS signal
     * @param rst  PinName RESET signal
     * @param vsync PinName Vertical sync signal
     */
    MAX7456(PinName mosi, PinName miso, PinName sclk, PinName cs, PinName rst, PinName vsync);
    
    ~MAX7456();
    
    //! reset()
    /**
     * Resets the MAX7456 device.
     *
     * @ingroup MAX7456_API
     */
    void reset(void);
    
    //! clear_display()
    /**
     * Cleasr the entire display area.
     *
     * @ingroup MAX7456_API
     */
    void clear_display(void);
    
    //! cursor(x,y)
    /**
     * Moves the "cursor" to the screen X,Y position. Future writes to the
     * screen ram will occur at this position.
     *
     * @ingroup MAX7456_API
     * @param x The X position
     * @param y The Y position
     */
    void cursor(int x, int y);
    
    //! convert_string(*s)
    /**
     * Takes a pointer to an ascii string and converts it to chars that will
     * display via teh MAX7456 character set. Note, the string is converted.
     *
     * @param s A char * pointer to the NULL terminated string to convert.
     */
    void convert_string(char *s);
    
    //! string(*s)
    /**
     * Print the string pointed to by s at the current cursor position.
     * The string should be an ASCII NULL terminated string.
     *
     * @ingroup MAX7456_API
     * @param s A char * pointer to the NULL terminated string to print.
     */
    int string(char *s);
    
    //! stringxy(x,y,s)
    /**
     * Print the string pointed to by s at the position supplied by x,y.
     * The string should be an ASCII NULL terminated string.
     *
     * @ingroup MAX7456_API
     * @param x The X position
     * @param y The Y position
     * @param s A char * pointer to the NULL terminated string to print.
     * @return int The length of the string written.
     */
    int stringxy(int x, int y, char *s);
    
    //! stringxy(x,y,s,a)
    /**
     * Print the string pointed to by s at the position supplied by x,y.
     * The string should be an ASCII NULL terminated string.
     *
     * @ingroup MAX7456_API
     * @param x The X position
     * @param y The Y position
     * @param s A char * pointer to the NULL terminated string to print.
     * @param a An attribute byte to appply to the string.
     * @return int The length of the string written.
     */
    int stringxy(int x, int y, char *s, uint8_t a);

    //! stringxy(x,y,s,a)
    /**
     * Print the string pointed to by s at the position supplied by x,y.
     * The string should be an ASCII NULL terminated string.
     *
     * @ingroup MAX7456_API
     * @param x The X position
     * @param y The Y position
     * @param s A char * pointer to the NULL terminated string to print.
     * @param a A char * pointer to the 30byte attribute string.
     * @return int The length of the string written.
     */
    int stringxy(int x, int y, char *s, char *a);

    //! stringxy(x,y,s,len)
    /**
     * Print the string pointed to by s at the position supplied by x,y.
     * The string should be an ASCII terminated string. 
     * len determines the length of the string to print (not the term NULL).
     *
     * @ingroup MAX7456_API
     * @param x The X position
     * @param y The Y position
     * @param s A char * pointer to the NULL terminated string to print.
     * @param len The length of teh string to print.
     */
    void stringl(int x, int y, char *s, int len);
    
    //! attribute_xyl(x,y,s,len)
    /**
     * Write the character attribute bytes at x,y
     * Since attributes can be zero (NULL), the string length 
     * must be provided.
     *
     * @ingroup MAX7456_API
     * @param x The X position
     * @param y The Y position
     * @param s A char * pointer to the NULL terminated string of attributes.
     * @param len The length of the string of attributes.
     */
    void attributes_xyl(int x, int y, char *s, int len);

    /**
     * Set the background brightness
     *
     * @see BGbrightness
     * @ingroup MAX7456_API
     * @param i The brightness level
     */
    void backGround(BGbrightness i) { vm1((vm1() & ~(7 << 4)) | i); } 
    
    /**
     * Set the character blink rate
     *
     * @see BlinkTime
     * @see BlinkingDutyCycle
     * @ingroup MAX7456_API
     * @param bt The blink time
     * @param dc The duty cycle
     */
    void blinkRate(BlinkTime bt, BlinkingDutyCycle dc) { vm1((vm1() & ~(0xf)) | (bt | dc)); } 
    
    //! read_char_map(address,data54)
    /**
     * Read the 54byte character map from MAX7456 ROM.
     *
     * @ingroup MAX7456_API
     * @param address The uchar address to read from (which character)
     * @param data54 A char * pointer to a buffer where to write to.
     */
    void read_char_map(unsigned char address, unsigned char *data54);
    
    //! write_char_map(address,data54)
    /**
     * Write the 54byte character map to the MAX7456 ROM.
     *
     * @ingroup MAX7456_API
     * @param address The uchar address to write to 
     * @param data54 A char * pointer to a buffer where to read from.
     */
    void write_char_map(unsigned char address, const unsigned char *data54);

    //! attach(tptr,mptr)
    /**
     * Attach a callback method to teh vertical sync interrupt.
     *
     * @ingroup MAX7456_API
     * @param tptr The class object pointer conatining the method.
     * @param mptr The method within the object to invoke.
     */ 
    template<typename T>
    void vsync_set_callback(T* tptr, void (T::*mptr)(void)) {
        _vsync_callback.attach(tptr, mptr);   
    }
    
    //! attach(tptr,mptr)
    /**
     * Attach a callback function to the vertical sync interrupt.
     *
     * @ingroup MAX7456_API
     * @param fptr A function pointer to call on vertical sync irq.
     */ 
    void vsync_set_callback(void (*fptr)(void)) { _vsync_callback.attach(fptr); }
    
    // Must be reimplemented by the child class.
    virtual void vsync_isr(void) { _vsync_callback.call(); };
    
    // Register level API.
    
    /** @ingroup MAX7456_REGISTER_API */
    __INLINE  void    vm0(uint8_t i)  { write(VM0, i); }
    /** @ingroup MAX7456_REGISTER_API */
    __INLINE  uint8_t vm0(void)       { return (uint8_t)read(VM0); }
    /** @ingroup MAX7456_REGISTER_API */
    __INLINE  void    vm1(uint8_t i)  { write(VM1, i); }
    /** @ingroup MAX7456_REGISTER_API */
    __INLINE  uint8_t vm1(void)       { return (uint8_t)read(VM1); }
    /** @ingroup MAX7456_REGISTER_API */
    __INLINE  void    hos(uint8_t i)  { write(HOS, i); }
    /** @ingroup MAX7456_REGISTER_API */
    __INLINE  uint8_t hos(void)       { return (uint8_t)read(HOS); }
    /** @ingroup MAX7456_REGISTER_API */
    __INLINE  void    vos(uint8_t i)  { write(VOS, i); }
    /** @ingroup MAX7456_REGISTER_API */
    __INLINE  uint8_t vos(void)       { return (uint8_t)read(VOS); }
    /** @ingroup MAX7456_REGISTER_API */
    __INLINE  void    dmm(uint8_t i)  { write(DMM, i); }
    /** @ingroup MAX7456_REGISTER_API */
    __INLINE  uint8_t dmm(void)       { return (uint8_t)read(DMM); }
    /** @ingroup MAX7456_REGISTER_API */
    __INLINE  void    dmah(uint8_t i) { write(DMAH, i); }
    /** @ingroup MAX7456_REGISTER_API */
    __INLINE  uint8_t dmah(void)      { return (uint8_t)read(DMAH); }
    /** @ingroup MAX7456_REGISTER_API */
    __INLINE  void    dmal(uint8_t i) { write(DMAL, i); }
    /** @ingroup MAX7456_REGISTER_API */
    __INLINE  uint8_t dmal(void)      { return (uint8_t)read(DMAL); }
    /** @ingroup MAX7456_REGISTER_API */
    __INLINE  void    dmdi(uint8_t i) { write(DMDI, i); }
    /** @ingroup MAX7456_REGISTER_API */
    __INLINE  uint8_t dmai(void)      { return (uint8_t)read(DMDI); }
    /** @ingroup MAX7456_REGISTER_API */
    __INLINE  void    cmm(uint8_t i)  { write(CMM, i); }
    /** @ingroup MAX7456_REGISTER_API */
    __INLINE  uint8_t cmm(void)       { return (uint8_t)read(CMM); }
    /** @ingroup MAX7456_REGISTER_API */
    __INLINE  void    cmah(uint8_t i) { write(CMAH, i); }
    /** @ingroup MAX7456_REGISTER_API */
    __INLINE  uint8_t cmah(void)      { return (uint8_t)read(CMAH); }
    /** @ingroup MAX7456_REGISTER_API */
    __INLINE  void    cmal(uint8_t i) { write(CMAL, i); }
    /** @ingroup MAX7456_REGISTER_API */
    __INLINE  uint8_t cmal(void)      { return (uint8_t)read(CMAL); }
    /** @ingroup MAX7456_REGISTER_API */
    __INLINE  void    cmdi(uint8_t i) { write(CMDI, i); }
    /** @ingroup MAX7456_REGISTER_API */
    __INLINE  uint8_t cmai(void)      { return (uint8_t)read(CMDI); }
    /** @ingroup MAX7456_REGISTER_API */
    __INLINE  void    osdm(uint8_t i) { write(OSDM, i); }
    /** @ingroup MAX7456_REGISTER_API */
    __INLINE  uint8_t osdm(void)      { return (uint8_t)read(OSDM); }
    /** @ingroup MAX7456_REGISTER_API */
    
    /** @ingroup MAX7456_REGISTER_API */
    __INLINE  uint8_t stat(void)      { return read(0xA0); }
    
    /** @ingroup MAX7456_REGISTER_API */
    __INLINE  bool    los(void) { return (bool)!(stat() & (1 << 2)); }
    
    /** @ingroup MAX7456_REGISTER_API */
    __INLINE  uint8_t osdbl(void)   { return (uint8_t)read(OSDBL); }
    /** @ingroup MAX7456_REGISTER_API */
    __INLINE  void    osdbl(bool b) { uint8_t t = osdbl(); if (b) osdbl(t & ~(1 << 4)); else osdbl(t | (1 << 4)); }
    
    /** @ingroup MAX7456_REGISTER_API */
    __INLINE  void    RowBrightness(RowBrightnessReg r, uint8_t i) { write(r, i); }
    /** @ingroup MAX7456_REGISTER_API */
    __INLINE  uint8_t RowBrightness(RowBrightnessReg r) { return read (r); }
    
protected:
    void init(PinName mosi, PinName miso, PinName sclk, const char *name, PinName cs, PinName rst, PinName vsync = NC);
    void write(unsigned char address, unsigned char byte);
    int  read(unsigned char address);
    
    SPI         *_ssp;
    DigitalOut  *_cs;
    DigitalOut  *_rst;
    InterruptIn *_vsync;
    FunctionPointer _vsync_callback;   
};

#endif