Sanyo LC75711 VFD controller/driver for upto 16 Dot Matrix Characters
The component page is here.
LC75711.cpp
- Committer:
- wim
- Date:
- 2017-09-13
- Revision:
- 1:bcf010fcacae
- Parent:
- 0:5eb5fee234e8
- Child:
- 2:cb6f2b7930c8
File content as of revision 1:bcf010fcacae:
/* mbed LC75710 Library, for Sanyo LC7571X VFD controller * Note: The LC75710, LC75711 and LC75712 differ only in the built-in character ROM * * Copyright (c) 2017, v01: WH, Initial version * 2017, v02: WH, Cleaned up docs * * 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 "LC75711.h" #include "LC75711_UDC.inc" /** Constructor for class for driving Sanyo LC75711 VFD controller * * @brief Supports upto 16 Grids of 35 matrix segments. Also supports 3-8 additional segments (depending on number of grids). * SPI bus interface device. * @param PinName mosi, sclk, cs SPI bus pins * @param Mode selects number of Grids and Segments (default 11 Grids, 35 matrix segments, 8 additional segments) */ LC75711::LC75711(PinName mosi, PinName sclk, PinName cs, Mode mode) : _spi(mosi,NC,sclk), _cs(cs), _mode(mode) { _init(); } /** Init the LC75711 interface and the controller * * @param none * @return none */ void LC75711::_init(){ //init SPI _cs=0; _spi.format(8,0); //LC75711 uses mode 0 (Clock Low on Idle, Data latched on first (=rising) edge) // _spi.frequency(100000); _spi.frequency(250000); //init controller // Set number of Grids _writeCmd((LC75711_GRID_REG | _mode), // B16..B23, Command register & value 0x00, // B8..B15, Dummy 0x00, // B0..B7, Dummy LC75711_GRID_DLY); // Command Delay _setAddress(0, 0); // No shift setBlink(false); // No Blink setBrightness(LC75711_BRT_DEF); // Default Brightness // Clear the DCRAM (undefined at Reset) cls(); // Clear the UDC RAM (undefined at Reset) const char udc_none[] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00}; for (int idx=0; idx < LC75711_NR_UDC; idx++) { setUDC(idx, (char *)udc_none); } setDisplay(true); // Display On } /** Clear the screen and locate to 0 * * @param none * @return none */ void LC75711::cls() { for (int cnt=0; cnt<LC75711_DISPLAY_MEM; cnt++) { writeData(char (' '), cnt); // data // writeData(0x00, cnt); // data } for (int cnt=0; cnt<LC75711_ADD_MEM; cnt++) { writeData(0x00, cnt); // adata } } /** Set the Blink mode * * @param bool Blink mode * @param int grids selected grids for Blinking enable/disable (default = all) * @return none */ void LC75711::setBlink(bool on, int grids) { // Sanity check and update of local shadow if (on) { _blink = _blink | (grids & LC75711_GR_MSK); // Set grid bits } else { _blink = _blink & ~(grids & LC75711_GR_MSK); // Clr grid bits } _writeCmd((LC75711_BLNK_REG | LC75711_BLNK_ON), // B16..B23, Command register & value ((_blink >> 8) & 0xFF), // B8..B15, GR8..GR16 ( _blink & 0xFF), // B0..B7, GR1..GR7 LC75711_BLNK_DLY); // Command Delay } /** Set Brightness * * @param char brightness (8 significant bits, valid range 0..239 (dutycycle linked to number of grids) * @return none */ void LC75711::setBrightness(char brightness){ //Sanity check brightness = brightness & LC75711_BRT_MSK; // mask invalid bits if (brightness > 239) {brightness = 239;} _writeCmd((LC75711_BRT_REG), // B16..B23, Command register brightness, // B8..B15, Brightness 0x00, // B0..B7, Dummy LC75711_BRT_DLY); // Command Delay } /** Set the Display mode On/off * * @param bool display mode * @return none */ void LC75711::setDisplay(bool on) { char display; if (on) { display = LC75711_DSPL_ON; } else { display = LC75711_DSPL_OFF; } _writeCmd((LC75711_DSPL_REG | display), // B16..B23, Command register & value 0xFF, // B8..B15, GR8..GR16 0xFF, // B0..B7, GR1..GR7 LC75711_DSPL_DLY); // Command Delay } /** Set User Defined Characters (UDC) * * @param unsigned char udc_idx The Index of the UDC (0..7) * @param UDCData_t udc_data The bitpattern for the UDC (7 bytes) * @return none */ void LC75711::setUDC(unsigned char udc_idx, UDCData_t udc_data) { char data; //Sanity check udc_idx = udc_idx & LC75711_UDC_MSK; // mask invalid bits _cs=0; // Prepare to send Address wait_us(1); _spi.write(_flip(LC75711_ADDRESS)); // Address _cs=1; // Latch Address, Prepare to send Command & Params wait_us(1); data = ((udc_data[1] & 0x07) << 5) | ((udc_data[0] & 0x1F) << 0); _spi.write(_flip(data)); // B0..B7, AM1-AM8 data = ((udc_data[3] & 0x01) << 7) | ((udc_data[2] & 0x1F) << 2) | ((udc_data[1] & 0x18) >> 3); _spi.write(_flip(data)); // B8..B15, AM9-AM16 data = ((udc_data[4] & 0x0F) << 4) | ((udc_data[3] & 0x1E) >> 1); _spi.write(_flip(data)); // B16..B23, AM17-AM24 data = ((udc_data[6] & 0x03) << 6) | ((udc_data[5] & 0x1F) << 1) | ((udc_data[4] & 0x10) >> 4); _spi.write(_flip(data)); // B24..B31, AM25-AM32 data = ((udc_data[6] & 0x1C) >> 2); _spi.write(_flip(data)); // B32..B39, AM32-AM35 _spi.write(_flip(udc_idx)); // B40..B47, CA0-CA7 _spi.write(_flip(LC75711_UDC_REG)); // B48..B55, Command register wait_us(1); _cs=0; // Latch Command & Params wait_us(LC75711_UDC_DLY); // Command Delay } /** Write Data to LC75711 * * @param char data Character code * @param char address Parameter for data * @return none */ void LC75711::writeData(char data, char address){ //Sanity check address = address & LC75711_DADR_MSK; // mask invalid bits _writeCmd((LC75711_DATA_REG), // B16..B23, Command register address, // B8..B15, DCRAM address data, // B0..B7, Character code LC75711_DATA_DLY); // Command Delay } /** Write Additional Data to LC75711 * * @param char adata Additional code (annunciator) * @param char address Parameter for data * @return none */ void LC75711::writeAData(char adata, char address){ //Sanity check address = address & LC75711_AADR_MSK; // mask invalid bits _writeCmd((LC75711_ADAT_REG | address), // B16..B23, Command register & ADRAM address adata, // B8..B15, ADATA 0x00, // B0..B7, Dummy LC75711_ADAT_DLY); // Command Delay } /** Set Address * * @param char RAM address for data displayed at Grid1 (0..63) * @param char RAM address for adata displayed at Grid1 (0..15) * @return none * * Note that a Shift (L/R) command will change the Address of data displayed at Grid1 */ void LC75711::_setAddress(char data_addr, char adata_addr){ //Sanity check data_addr = data_addr & LC75711_DADR_MSK; // mask invalid bits adata_addr = adata_addr & LC75711_AADR_MSK; // mask invalid bits _writeCmd((LC75711_AC_REG | adata_addr), // B16..B23, Command register & ADRAM address data_addr, // B8..B15, DCRAM address 0x00, // B0..B7, Dummy LC75711_AC_DLY); // Command Delay } /** Write command and parameters to LC75711 * * @param char cmd Command byte * @param char data1 Parameters for command * @param char data0 Parameters for command * @param char delay Delay for command execution * @return none */ void LC75711::_writeCmd(char cmd, char data1, char data0, char delay){ _cs=0; // Prepare to send Address wait_us(1); _spi.write(_flip(LC75711_ADDRESS)); // Address _cs=1; // Latch Address, Prepare to send Command & Params wait_us(1); _spi.write(_flip(data0)); // B0..B7 _spi.write(_flip(data1)); // B8..B15 _spi.write(_flip(cmd)); // B16..B23, Command register & value wait_us(1); _cs=0; // Latch Command & Params wait_us(delay); // Command Delay } /** Helper to reverse all command or databits. The LC75711 expects LSB first, whereas SPI is MSB first * * @param char data * @return bitreversed data */ char LC75711::_flip(char data) { char value=0; if (data & 0x01) {value |= 0x80;} ; if (data & 0x02) {value |= 0x40;} ; if (data & 0x04) {value |= 0x20;} ; if (data & 0x08) {value |= 0x10;} ; if (data & 0x10) {value |= 0x08;} ; if (data & 0x20) {value |= 0x04;} ; if (data & 0x40) {value |= 0x02;} ; if (data & 0x80) {value |= 0x01;} ; return value; } #if (ASTON_TEST == 1) /** Constructor for class for Sanyo LC75711 VFD controller as used in ASTON * * @brief Supports 10 Grids of 35 Segments without additional Segments and uses Grid 11 for Icon segments. * * @param PinName mosi, miso, sclk, cs SPI bus pins */ LC75711_ASTON::LC75711_ASTON(PinName mosi, PinName sclk, PinName cs) : LC75711(mosi, sclk, cs, Grid11_Add8) { _column = 0; _columns = ASTON_NR_DIGITS; // Clear the _udc_icon (should be cleared at Reset) // for (int idx=0; idx < 7; idx++) { // _udc_icon = 0x00; // } } /** Locate cursor to a screen column * * @param column The horizontal position from the left, indexed from 0 * @return none */ void LC75711_ASTON::locate(int column) { //sanity check if (column < 0) {column = 0;} if (column > (_columns - 1)) {column = _columns - 1;} _column = column; } /** Number of screen columns * * @param none * @return columns */ int LC75711_ASTON::columns() { return _columns; } /** Clear the screen and locate to 0 * * @param bool clrAll Clear Icons also (default = false) * @return none */ void LC75711_ASTON::cls(bool clrAll) { for (int cnt=0; cnt<ASTON_NR_DIGITS; cnt++) { writeData(char (' '), cnt); // data } if (clrAll) { for (int cnt=0; cnt<ASTON_NR_DIGITS; cnt++) { writeAData(0x00, cnt); // adata } //Clear Icons // } _column = 0; } /** Set Icon * * @param Icon Enums Icon Encodes UDC_0 byte index in 8 MSBs and encodes Icon bit/segment in 8 LSBs * @return none */ void LC75711_ASTON::setIcon(Icon icon){ int byte_idx, bits; byte_idx = (icon >> 8) & 0x07; // Decode byte index and sanity mask bits = (1 << (icon & 0x07)) & 0x1F; // Decode bits and sanity mask //Set the segment bit for the Icon _udc_icon[byte_idx] |= bits; //Update UDC_0 used to display the Icons at Grid 11 setUDC(0, _udc_icon); } /** Clr Icon * * @param Icon Enums Icon Encodes UDC_0 byte index in 8 MSBs and encodes Icon bit/segment in 8 LSBs * @return none */ void LC75711_ASTON::clrIcon(Icon icon) { int byte_idx, bits; byte_idx = (icon >> 8) & 0x07; // Decode byte index and sanity mask bits = (1 << (icon & 0x07)) & 0x1F; // Decode bits and sanity mask //Clear the segment bit for the Icon _udc_icon[byte_idx] &= ~bits; //Update UDC_0 used to display the Icons at Grid 11 setUDC(0, _udc_icon); } /** Write a single character (Stream implementation) * * @param value char to print * @return value; */ int LC75711_ASTON::_putc(int value) { int addr; if ((value == '\n') || (value == '\r')) { //No character to write //Update Cursor _column = 0; } else if ((value >= 0) && (value < 192)) { //Character to write //Translate between _column and displaybuffer entries //Note that the ASTON has 1 digit/grids. //_column == 0 => Grid10 => addr = 9 //_column == 1 => Grid9 => addr = 8 // .... //_column == 9 => Grid1 => addr = 0 addr = (9 - _column); // 1 Byte for every Grid; writeData(value, addr); //Update Cursor _column++; if (_column > (ASTON_NR_DIGITS - 1)) { _column = 0; } } // if validChar return value; } /** Get a single character (Stream implementation) * * @param none * @return -1 */ int LC75711_ASTON::_getc() { return -1; } #endif