This module provides a simple API to the Maxim MAX7456 on-screen display chip
MAX7456.cpp
- 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. */ #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); } }