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

Revision:
0:d7cd54ad4c3d
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/MAX7456.cpp	Tue Nov 16 10:47:25 2010 +0000
@@ -0,0 +1,303 @@
+/*
+    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.
+*/
+
+#include "mbed.h"
+#include "MAX7456.h"
+
+#ifdef MAX7456_DEBUG
+#include "IOMACROS.h"
+extern Serial pc;
+#endif
+
+#define CS_ASSERT   _cs->write(0)
+#define CS_DEASSERT _cs->write(1)
+
+// This header should only be included once here in this
+// file as it compiles inline directly. Include within
+// the library namespace.
+#include "MAX7456CHARS.h"
+
+/* Map ASCII table to the MAX7456 character map.
+   Note, the MAX7456 in-built character map is no where near the ascii
+   table mapping and very few characters are available to map. Where 
+   possible we create new characters for those we need that are missing
+   from the MAX7456 that we want to use and also we create some special
+   characters of our own that are not ASCII chars (crosshair for example).
+   These additional character definitions are listed below the table. 
+   Character maps we have create can be found in MAX7456CHARS.h */
+const unsigned char MAX7456_ascii[256] = {
+
+    /* Regular ASCII table. */
+    /*         00    01    02    03    04    05    06    07     08    09    0A    0B    0C    0D    0E    0F  */  
+    /* 00 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+    /* 10 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+    /* 20 */ 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x00, 0x46,  0x3F, 0x40, 0x00, 0x4d, 0x45, 0x49, 0x41, 0x47, 
+    /* 30 */ 0x0A, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,  0x08, 0x09, 0x44, 0x43, 0x4A, 0x00, 0x4B, 0x42,
+    /* 40 */ 0x4C, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11,  0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 
+    /* 50 */ 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0x21,  0x22, 0x23, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 
+    /* 60 */ 0x46, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B,  0x2C, 0x2D, 0x2E, 0x2F, 0x30, 0x31, 0x32, 0x33,
+    /* 70 */ 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B,  0x3C, 0x3D, 0x3E, 0x00, 0x00, 0x00, 0x00, 0x00, 
+    
+    /* Extended ASCII table. */
+    /*         00    01    02    03    04    05    06    07     08    09    0A    0B    0C    0D    0E    0F  */  
+    /* 80 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+    /* 90 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+    /* A0 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+    /* B0 */ 0xB0, 0x00, 0x00, 0xB3, 0xB4, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xBF,   
+    /* C0 */ 0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+    /* D0 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  0x00, 0xD9, 0xDA, 0x00, 0x00, 0x00, 0x00, 0x00, 
+    /* E0 */ 0xe0, 0xe1, 0xe2, 0x00, 0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+    /* F0 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00     
+};
+
+MAX7456::MAX7456(PinName mosi, PinName miso, PinName sclk, const char *name, PinName cs, PinName rst, PinName vsync)
+{
+    init(mosi, miso, sclk, name, cs, rst, vsync);
+}
+
+MAX7456::MAX7456(PinName mosi, PinName miso, PinName sclk, PinName cs, PinName rst, PinName vsync)
+{
+    init(mosi, miso, sclk, NULL, cs, rst, vsync);
+}
+
+MAX7456::~MAX7456()
+{
+    delete(_ssp);
+    delete(_cs);
+    delete(_rst);
+    delete(_vsync);
+}
+
+void
+MAX7456::init(PinName mosi, PinName miso, PinName sclk, const char *name, PinName cs, PinName rst, PinName vsync)
+{
+    _ssp = new SPI(mosi, miso, sclk, name);
+    _cs  = new DigitalOut(cs);
+    _rst = new DigitalOut(rst);    
+    if (vsync != NC) {
+        _vsync = new InterruptIn(vsync);
+        _vsync->fall(this, &MAX7456::vsync_isr);   
+    }
+    
+    // Set default output signals.
+    CS_DEASSERT;
+    _rst->write(1);
+   
+    // Setup the SSP.
+    _ssp->format(8,0);
+    _ssp->frequency(25000000);
+    
+    // Reset the MAX7456
+    reset();
+    
+    /* Write the custom CM map. */
+    write(0, read(0) & 0xF7);
+    for (int index = 0; custom_chars[index].ascii != 0; index++) {
+        write_char_map(custom_chars[index].ascii, custom_chars[index].map);
+    }
+    
+    wait_us(100000);
+    
+    /* Change the vertical offset. */
+    vos(0x16);
+    
+    /* Set the blink rate. */
+    //vm1((3 << 2) | 3);
+    
+    /* Enable display of OSD image. */
+    vm0(0x48);
+}
+
+void 
+MAX7456::write(unsigned char address, unsigned char byte) 
+{
+    CS_ASSERT;
+ 
+    /* MAX7456 addresses are always less than 0x80 so if the
+       address is > 0x7F then the caller is requesting an direct
+       8bit data transfer. */
+    if (address < 0x80) { _ssp->write(address); }
+    
+    _ssp->write(byte);
+    CS_DEASSERT;
+}
+
+int 
+MAX7456::read(unsigned char address) 
+{
+    int data;
+    address |= 0x80;
+    CS_ASSERT;
+    _ssp->write(address);
+    data = _ssp->write(0xFF);
+    CS_DEASSERT;
+    return data;
+}
+
+void
+MAX7456::reset(void)
+{
+    _rst->write(0); 
+    wait_us(100000);
+    _rst->write(1);  
+    wait_us(100000);
+}
+
+void
+MAX7456::clear_display(void)
+{
+    dmm(1 << 2);
+    while(dmm() & (1 << 2));
+}
+
+void 
+MAX7456::cursor(int x, int y) 
+{
+    uint16_t pos = (y * 30) + x;
+    dmah((pos >> 8) & 0x1);
+    dmal(pos & 0xFF);    
+}
+
+void 
+MAX7456::convert_string(char *s) 
+{
+    while(*(s)) {
+        *(s) = MAX7456_ascii[*(s)];
+        s++;
+    }
+}
+
+int
+MAX7456::string(char *s) 
+{
+    int len = 0;
+    dmm(1 | (1 << 6)); /* Enable 8bit write */    
+    while(*(s)) {
+        write(0x80, MAX7456_ascii[*s++]);        
+        len++;
+    }
+    write(0x80, 0xFF);
+    return len;
+}
+
+void
+MAX7456::attributes_xyl(int x, int y, char *s, int len)
+{
+    uint16_t pos = (y * 30) + x;
+    dmah(((pos >> 8) & 0x1) | (1 << 1));
+    dmdi(pos & 0xFF);    
+    dmm(1 | (1 << 6)); /* Enable 8bit write */    
+    while (len--) {
+        write(0x80, *s++);
+    }
+    write(0x80, 0xFF);
+}
+
+int
+MAX7456::stringxy(int x, int y, char *s) 
+{
+    cursor(x, y);
+    return string(s);
+}
+
+int
+MAX7456::stringxy(int x, int y, char *s, uint8_t a) 
+{
+    char *q = NULL;
+    int len;
+    cursor(x, y);
+    len = string(s);
+    q = (char *)malloc(len);
+    if (!q) {
+        return -1;
+    }
+    memset(q, a, len);
+    attributes_xyl(x, y, q, len);
+    free(q);
+    return len;
+}
+
+int
+MAX7456::stringxy(int x, int y, char *s, char *a) 
+{
+    int len;
+    cursor(x, y);
+    len = string(s);
+    attributes_xyl(x, y, a, 30);
+    return len;
+}
+
+void 
+MAX7456::stringl(int x, int y, char *s, int len) 
+{
+    cursor(x, y);            
+    dmm(1); /* Enable 8bit write */    
+    while(len--) {
+        if (*s == '\0') break;
+        write(0x80, MAX7456_ascii[*s++]);
+    }
+    write(0x80, 0xFF);
+}
+
+void 
+MAX7456::read_char_map(unsigned char address, unsigned char *data54) 
+{
+    cmah((uint8_t)address);
+    cmm(0x50);
+    for (uint8_t index = 0; index < 54; index++) {
+        cmal(index);
+        wait_us(1000);        
+        *(data54 + index) = read(0xC0);
+    }
+}
+
+void 
+MAX7456::write_char_map(unsigned char address, const unsigned char *data54) 
+{
+    unsigned char index, c, match = 1;
+    
+    write(CMAH, address);
+    write(CMM, 0x50);
+    wait_us(20000);
+    for (index = 0; index < 54; index++) {
+        write(CMAL, index);
+        c = read(0xC0);
+        if (c != data54[index]) {
+            match = 0;            
+            break;
+        }
+    }
+    
+    if (!match) {   
+        write(CMAH, address);
+        for (index = 0; index < 0x36; index++) {
+            write(CMAL, index);
+            write(CMDI, data54[index]);
+        }
+        write(CMM, 0xA0);
+        wait_us(20000);
+        while ((read(0xA0) & 0x20) != 0x00);    
+    }
+}
+
+
+