MHVLib
20111011
An efficiency oriented runtime library for AVR microcontrollers
|
00001 /* Copyright (c) 2011, Make, Hack, Void Inc 00002 * All rights reserved. 00003 * 00004 * Redistribution and use in source and binary forms, with or without 00005 * modification, are permitted provided that the following conditions are met: 00006 * * Redistributions of source code must retain the above copyright 00007 * notice, this list of conditions and the following disclaimer. 00008 * * Redistributions in binary form must reproduce the above copyright 00009 * notice, this list of conditions and the following disclaimer in the 00010 * documentation and/or other materials provided with the distribution. 00011 * * Neither the name of the Make, Hack, Void nor the 00012 * names of its contributors may be used to endorse or promote products 00013 * derived from this software without specific prior written permission. 00014 * 00015 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 00016 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 00017 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 00018 * DISCLAIMED. IN NO EVENT SHALL MAKE, HACK, VOID BE LIABLE FOR ANY 00019 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 00020 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 00021 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 00022 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 00023 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 00024 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00025 */ 00026 00027 #include <util/delay.h> 00028 #include <MHV_Display_HD44780.h> 00029 00030 #define HD44780_TINIT 300 // ms 00031 00054 MHV_Display_HD44780::MHV_Display_HD44780(uint8_t colCount, uint16_t rowCount, MHV_RingBuffer *txBuffers) : 00055 MHV_Display_Character(colCount, rowCount, txBuffers) { 00056 _ticks = 0; 00057 _animateTicks = 64; 00058 _mustDelay = false; 00059 } 00060 00065 void MHV_Display_HD44780::_writeChar(char character) { 00066 while (isBusy()) {}; 00067 writeByte(character, true); 00068 delay(MHV_44780_WRITE_CHAR); 00069 } 00070 00075 char MHV_Display_HD44780::_readChar() { 00076 while (isBusy()) {}; 00077 return readByte(true); 00078 } 00079 00086 void MHV_Display_HD44780::_setCursor(uint16_t col, uint16_t row) { 00087 _setCursor((uint8_t)col, (uint8_t)row); 00088 } 00089 00090 00091 static const uint8_t mhv_hd44780AddressTable[] PROGMEM = { 00092 64+20, 20, 64, 0 00093 }; 00094 00101 void MHV_Display_HD44780::_setCursor(uint8_t col, uint8_t row) { 00102 uint8_t address; 00103 00104 if (4 == _rowCount && 20 == _colCount) { 00105 address = pgm_read_byte(mhv_hd44780AddressTable + row); 00106 } else { 00107 // Display type unsupported - assume 2 line display 00108 address = pgm_read_byte(mhv_hd44780AddressTable + row + 2); 00109 } 00110 00111 address += col; 00112 00113 while (isBusy()) {}; 00114 00115 addressDDRAM(address); 00116 } 00117 00121 void MHV_Display_HD44780::writeCommand(MHV_HD44780_COMMAND command, uint8_t data) { 00122 uint8_t byte = command | data; 00123 00124 if (_mustDelay) { 00125 _delay_us(19); 00126 _mustDelay = false; 00127 } 00128 00129 writeByte(byte, false); 00130 00131 delay(command); 00132 } 00133 00137 void MHV_Display_HD44780::clear() { 00138 while (isBusy()) {}; 00139 00140 writeCommand(MHV_44780_CMD_CLEAR, 0); 00141 _currentRow = _rowCount - 1; 00142 _currentCol = 0; 00143 } 00144 00150 void MHV_Display_HD44780::entryMode(bool left2Right, bool scroll) { 00151 uint8_t data = left2Right << 1 | scroll; 00152 00153 while (isBusy()) {}; 00154 00155 writeCommand(MHV_44780_CMD_SET_ENTRY_MODE, data); 00156 } 00157 00164 void MHV_Display_HD44780::control(bool displayOn, bool cursorOn, bool cursorBlink) { 00165 uint8_t data = displayOn << 2 | cursorOn << 1 | cursorBlink; 00166 00167 while (isBusy()) {}; 00168 00169 writeCommand(MHV_44780_CMD_SET_DISPLAY_MODE, data); 00170 } 00171 00178 void MHV_Display_HD44780::function(bool byteMode, bool multiLine, bool bigFont) { 00179 uint8_t data = byteMode << 4 | multiLine << 3 | bigFont << 2; 00180 00181 if (!byteMode) { 00182 // Set 4 bit transfer 00183 writeByte(0b00100010, false); 00184 _delay_ms(4.1); 00185 } 00186 00187 writeCommand(MHV_44780_CMD_SET_FUNCTION, data); 00188 } 00189 00194 void MHV_Display_HD44780::addressCGRAM(uint8_t address) { 00195 while (isBusy()) {}; 00196 00197 writeCommand(MHV_44780_CMD_SET_CG_ADDR, address); 00198 } 00199 00204 void MHV_Display_HD44780::addressDDRAM(uint8_t address) { 00205 while (isBusy()) {}; 00206 00207 writeCommand(MHV_44780_CMD_SET_DD_ADDR, address); 00208 } 00209 00210 00221 void MHV_Display_HD44780::init(bool byteMode, bool multiLine, bool bigFont, bool cursorOn, bool cursorBlink, 00222 bool left2right, bool scroll) { 00223 /* Assume the worst case, we are called immediately after poweron 00224 * Also assume that the MCU init takes 0 time 00225 */ 00226 _delay_ms(HD44780_TINIT); 00227 00228 // hardware initialization always set 8 bits mode 00229 _byteMode = true; 00230 uint8_t resetData = 1 << 4 | multiLine << 3 | bigFont << 2 | 1; 00231 writeCommand(MHV_44780_CMD_SET_FUNCTION, resetData); 00232 writeCommand(MHV_44780_CMD_SET_FUNCTION, resetData); 00233 writeCommand(MHV_44780_CMD_SET_FUNCTION, resetData); 00234 00235 _byteMode = byteMode; 00236 00237 00238 function(byteMode, multiLine, bigFont); 00239 _delay_us(39); 00240 control(true, cursorOn, cursorBlink); 00241 clear(); 00242 entryMode(left2right, scroll); 00243 _currentRow = _rowCount - 1; 00244 _currentCol = 0; 00245 }