MHVLib  20111011
An efficiency oriented runtime library for AVR microcontrollers
A:/eclipse/mhvlib/MHV_Display_HD44780.cpp
Go to the documentation of this file.
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 }