MHVLib  20111227
An efficiency oriented runtime library for AVR microcontrollers
A:/eclipse/mhvlib/MHV_Display_HD44780_Direct_Connect.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_Direct_Connect.h>
00029 
00030 #define HD44780_DB4                     (1 << _dataPin)
00031 #define HD44780_DB5                     (1 << (_dataPin + 1))
00032 #define HD44780_DB6                     (1 << (_dataPin + 2))
00033 #define HD44780_DB7                     (1 << (_dataPin + 3))
00034 #define HD44780_RS                      (1 << _controlPin)
00035 #define HD44780_RW                      (1 << (_controlPin + 1))
00036 #define HD44780_E                       (1 << (_controlPin + 2))
00037 #define HD44780_CONTRAST        (1 << _visualPin)
00038 #define HD44780_LED                     (1 << (_visualPin + 1))
00039 
00040 /* Delay times in iterations of delay_loop_1 - note that each pass of delay_loop_1 is 3 clocks
00041  */
00042 #define HD44780_TC              (1000 * 1000000 / F_CPU / 3 + 1)
00043 #define HD44780_TSU1    (60 * 1000000 / F_CPU / 3 + 1)
00044 #define HD44780_TSU2    (195 * 1000000 / F_CPU / 3 + 1)
00045 #define HD44780_TDH             (5 * 1000000 / F_CPU / 3 + 1)
00046 #define HD44780_TW              (450 * 1000000 / F_CPU / 3 + 1)
00047 #define HD44780_TINIT   300             // ms
00048 #define HD44780_TCLEAR  1530    // us
00049 #define HD44780_TINSTR  39              // us
00050 #define HD44780_TRAM    430             // us
00051 
00077 MHV_Display_HD44780_Direct_Connect::MHV_Display_HD44780_Direct_Connect(
00078                 MHV_DECLARE_PIN(data),
00079                 MHV_DECLARE_PIN(control),
00080                 MHV_DECLARE_PIN(visual),
00081                 uint8_t colCount, uint16_t rowCount, MHV_RingBuffer &txBuffers) :
00082                 MHV_Display_HD44780(colCount, rowCount, txBuffers) {
00083         _dataDir = dataDir;
00084         _dataOut = dataOut;
00085         _dataIn = dataIn;
00086         _dataPin = dataPin;
00087         _controlOut = controlOut;
00088         _controlPin = controlPin;
00089         _visualOut = visualOut;
00090         _visualPin = visualPin;
00091 
00092 // Set pins as output
00093         _dataMask = 0x0f << _dataPin;
00094         *_dataDir |= _dataMask;
00095         *_dataOut &= ~(_dataMask);
00096 
00097         uint8_t mask = 0x07 << _controlPin;
00098         *controlDir |= mask;
00099         *_controlOut &= ~mask;
00100 
00101         mask = 0x03 << _visualPin;
00102         *visualDir |= mask;
00103         *_visualOut &= ~(mask);
00104 
00105         _brightness = 5;
00106         _contrast = 6;
00107 }
00108 
00119 MHV_Display_HD44780_Direct_Connect::MHV_Display_HD44780_Direct_Connect(
00120                 MHV_DECLARE_PIN(data),
00121                 MHV_DECLARE_PIN(control),
00122                 uint8_t colCount, uint16_t rowCount, MHV_RingBuffer &txBuffers) :
00123                 MHV_Display_HD44780(colCount, rowCount, txBuffers) {
00124         _dataDir = dataDir;
00125         _dataOut = dataOut;
00126         _dataIn = dataIn;
00127         _dataPin = dataPin;
00128         _controlOut = controlOut;
00129         _controlPin = controlPin;
00130 
00131 // Set pins as output
00132         _dataMask = 0x0f << _dataPin;
00133         *_dataDir |= _dataMask;
00134         *_dataOut &= ~(_dataMask);
00135 
00136         uint8_t mask = 0x07 << _controlPin;
00137         *controlDir |= mask;
00138         *_controlOut &= ~mask;
00139 }
00140 
00141 
00147 void MHV_Display_HD44780_Direct_Connect::writeByte(uint8_t byte, bool rs) {
00148         // Write high order nibble
00149         writeNibble(byte >> 4, rs);
00150         // Write low order nibble
00151         writeNibble(byte & 0x0f, rs);
00152 }
00153 
00159 void MHV_Display_HD44780_Direct_Connect::writeNibble(uint8_t nibble, bool rs) {
00160         uint8_t oldPort = *_dataOut & ~(_dataMask);
00161         *_controlOut &= ~(HD44780_RW);
00162         if (rs) {
00163                 *_controlOut |= HD44780_RS;
00164         }
00165 
00166         *_dataOut = oldPort | ((nibble << _dataPin) & _dataMask);
00167 
00168         _delay_loop_1(HD44780_TSU1);
00169         *_controlOut |= HD44780_E;
00170         _delay_loop_1(HD44780_TW);
00171         *_controlOut &= ~HD44780_E & ~HD44780_RS;
00172         _delay_loop_1(HD44780_TW);
00173 }
00174 
00175 
00180 uint8_t MHV_Display_HD44780_Direct_Connect::readByte(bool rs) {
00181         char character = readNibble(rs) << 4;
00182         // Read low order nibble
00183         character |= readNibble(rs);
00184 
00185         return character;
00186 }
00187 
00192 uint8_t MHV_Display_HD44780_Direct_Connect::readNibble(bool rs) {
00193         *_controlOut |= HD44780_RW;
00194         if (rs) {
00195                 *_controlOut |= HD44780_RS;
00196         }
00197 
00198         *_dataDir &= ~_dataMask;
00199         _delay_loop_1(HD44780_TSU1);
00200         *_controlOut |= HD44780_E;
00201         _delay_loop_1(HD44780_TW);
00202         uint8_t data = *_dataIn;
00203         *_controlOut &= ~HD44780_E & ~HD44780_RS;
00204         *_dataDir |= _dataMask;
00205         _delay_loop_1(HD44780_TW);
00206 
00207         return data >> _dataPin;
00208 }
00209 
00214 bool MHV_Display_HD44780_Direct_Connect::isBusy() {
00215         *_dataDir &= ~(HD44780_DB7);
00216         *_dataOut &= ~(HD44780_DB7); // turn off pullup
00217         *_controlOut |= HD44780_RW;
00218         _delay_loop_1(HD44780_TSU1);
00219         *_controlOut |= HD44780_E;
00220         _delay_loop_1(HD44780_TW);
00221 
00222         bool busy = *_dataIn & HD44780_DB7;
00223         *_controlOut &= ~(HD44780_E | HD44780_RW);
00224         *_dataDir |= HD44780_DB7;
00225 
00226         _mustDelay = true;
00227 
00228         return busy;
00229 }
00230 
00235 void MHV_Display_HD44780_Direct_Connect::setBacklight(uint8_t value) {
00236         if (value > 15) {
00237                 value = 15;
00238         }
00239         _brightness = value;
00240 }
00241 
00246 void MHV_Display_HD44780_Direct_Connect::setContrast(uint8_t value) {
00247         if (value > 15) {
00248                 value = 15;
00249         }
00250         value = 15 - value;
00251 
00252         _contrast = value;
00253 }
00254 
00258 void MHV_Display_HD44780_Direct_Connect::tickPWM() {
00259         if (0 == _ticks % 16) {
00260                 *_visualOut |= HD44780_LED;
00261                 *_visualOut |= HD44780_CONTRAST;
00262         }
00263 
00264         if (_brightness == _ticks % 16) {
00265                 *_visualOut &= ~HD44780_LED;
00266         }
00267 
00268         if (_contrast == _ticks % 16) {
00269                 *_visualOut &= ~HD44780_CONTRAST;
00270         }
00271 
00272         _ticks++;
00273 }
00274 
00279 void MHV_Display_HD44780_Direct_Connect::delay(MHV_HD44780_COMMAND command) {
00280         return;
00281 }
00282 
00292 void MHV_Display_HD44780_Direct_Connect::init(bool multiLine, bool bigFont, bool cursorOn, bool cursorBlink,
00293                                 bool left2right, bool scroll) {
00294         MHV_Display_HD44780::init(false, multiLine, bigFont, cursorOn, cursorBlink, left2right, scroll);
00295 }
00296