MHVLib  20111011
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 
00089 MHV_Display_HD44780_Direct_Connect::MHV_Display_HD44780_Direct_Connect(
00090                 volatile uint8_t *dataDir, volatile uint8_t *dataOut, volatile uint8_t *dataIn, uint8_t dataPin, int8_t dataPinchangeInterrupt,
00091                 volatile uint8_t *controlDir, volatile uint8_t *controlOut, volatile uint8_t *controlIn, uint8_t controlPin, int8_t controlPinchangeInterrupt,
00092                 volatile uint8_t *visualDir, volatile uint8_t *visualOut, volatile uint8_t *visualIn, uint8_t visualPin, int8_t visualPinchangeInterrupt,
00093                 uint8_t colCount, uint16_t rowCount, MHV_RingBuffer *txBuffers) :
00094                 MHV_Display_HD44780(colCount, rowCount, txBuffers) {
00095         _dataDir = dataDir;
00096         _dataOut = dataOut;
00097         _dataIn = dataIn;
00098         _dataPin = dataPin;
00099         _controlOut = controlOut;
00100         _controlPin = controlPin;
00101         _visualOut = visualOut;
00102         _visualPin = visualPin;
00103 
00104 // Set pins as output
00105         _dataMask = 0x0f << _dataPin;
00106         *_dataDir |= _dataMask;
00107         *_dataOut &= ~(_dataMask);
00108 
00109         uint8_t mask = 0x07 << _controlPin;
00110         *controlDir |= mask;
00111         *_controlOut &= ~mask;
00112 
00113         mask = 0x03 << _visualPin;
00114         *visualDir |= mask;
00115         *_visualOut &= ~(mask);
00116 
00117         _brightness = 5;
00118         _contrast = 6;
00119 }
00120 
00139 MHV_Display_HD44780_Direct_Connect::MHV_Display_HD44780_Direct_Connect(
00140                 volatile uint8_t *dataDir, volatile uint8_t *dataOut, volatile uint8_t *dataIn, uint8_t dataPin, int8_t dataPinchangeInterrupt,
00141                 volatile uint8_t *controlDir, volatile uint8_t *controlOut, volatile uint8_t *controlIn, uint8_t controlPin, int8_t controlPinchangeInterrupt,
00142                 uint8_t colCount, uint16_t rowCount, MHV_RingBuffer *txBuffers) :
00143                 MHV_Display_HD44780(colCount, rowCount, txBuffers) {
00144         _dataDir = dataDir;
00145         _dataOut = dataOut;
00146         _dataIn = dataIn;
00147         _dataPin = dataPin;
00148         _controlOut = controlOut;
00149         _controlPin = controlPin;
00150 
00151 // Set pins as output
00152         _dataMask = 0x0f << _dataPin;
00153         *_dataDir |= _dataMask;
00154         *_dataOut &= ~(_dataMask);
00155 
00156         uint8_t mask = 0x07 << _controlPin;
00157         *controlDir |= mask;
00158         *_controlOut &= ~mask;
00159 }
00160 
00161 
00167 void MHV_Display_HD44780_Direct_Connect::writeByte(uint8_t byte, bool rs) {
00168         // Write high order nibble
00169         writeNibble(byte >> 4, rs);
00170         // Write low order nibble
00171         writeNibble(byte & 0x0f, rs);
00172 }
00173 
00179 void MHV_Display_HD44780_Direct_Connect::writeNibble(uint8_t nibble, bool rs) {
00180         uint8_t oldPort = *_dataOut & ~(_dataMask);
00181         *_controlOut &= ~(HD44780_RW);
00182         if (rs) {
00183                 *_controlOut |= HD44780_RS;
00184         }
00185 
00186         *_dataOut = oldPort | ((nibble << _dataPin) & _dataMask);
00187 
00188         _delay_loop_1(HD44780_TSU1);
00189         *_controlOut |= HD44780_E;
00190         _delay_loop_1(HD44780_TW);
00191         *_controlOut &= ~HD44780_E & ~HD44780_RS;
00192         _delay_loop_1(HD44780_TW);
00193 }
00194 
00195 
00200 uint8_t MHV_Display_HD44780_Direct_Connect::readByte(bool rs) {
00201         char character = readNibble(rs) << 4;
00202         // Read low order nibble
00203         character |= readNibble(rs);
00204 
00205         return character;
00206 }
00207 
00212 uint8_t MHV_Display_HD44780_Direct_Connect::readNibble(bool rs) {
00213         *_controlOut |= HD44780_RW;
00214         if (rs) {
00215                 *_controlOut |= HD44780_RS;
00216         }
00217 
00218         *_dataDir &= ~_dataMask;
00219         _delay_loop_1(HD44780_TSU1);
00220         *_controlOut |= HD44780_E;
00221         _delay_loop_1(HD44780_TW);
00222         uint8_t data = *_dataIn;
00223         *_controlOut &= ~HD44780_E & ~HD44780_RS;
00224         *_dataDir |= _dataMask;
00225         _delay_loop_1(HD44780_TW);
00226 
00227         return data >> _dataPin;
00228 }
00229 
00234 bool MHV_Display_HD44780_Direct_Connect::isBusy() {
00235         *_dataDir &= ~(HD44780_DB7);
00236         *_dataOut &= ~(HD44780_DB7); // turn off pullup
00237         *_controlOut |= HD44780_RW;
00238         _delay_loop_1(HD44780_TSU1);
00239         *_controlOut |= HD44780_E;
00240         _delay_loop_1(HD44780_TW);
00241 
00242         bool busy = *_dataIn & HD44780_DB7;
00243         *_controlOut &= ~(HD44780_E | HD44780_RW);
00244         *_dataDir |= HD44780_DB7;
00245 
00246         _mustDelay = true;
00247 
00248         return busy;
00249 }
00250 
00255 void MHV_Display_HD44780_Direct_Connect::setBacklight(uint8_t value) {
00256         if (value > 15) {
00257                 value = 15;
00258         }
00259         _brightness = value;
00260 }
00261 
00266 void MHV_Display_HD44780_Direct_Connect::setContrast(uint8_t value) {
00267         if (value > 15) {
00268                 value = 15;
00269         }
00270         value = 15 - value;
00271 
00272         _contrast = value;
00273 }
00274 
00278 void MHV_Display_HD44780_Direct_Connect::tickPWM() {
00279         if (0 == _ticks % 16) {
00280                 *_visualOut |= HD44780_LED;
00281                 *_visualOut |= HD44780_CONTRAST;
00282         }
00283 
00284         if (_brightness == _ticks % 16) {
00285                 *_visualOut &= ~HD44780_LED;
00286         }
00287 
00288         if (_contrast == _ticks % 16) {
00289                 *_visualOut &= ~HD44780_CONTRAST;
00290         }
00291 
00292         _ticks++;
00293 }
00294 
00299 void MHV_Display_HD44780_Direct_Connect::delay(MHV_HD44780_COMMAND command) {
00300         return;
00301 }
00302 
00312 void MHV_Display_HD44780_Direct_Connect::init(bool multiLine, bool bigFont, bool cursorOn, bool cursorBlink,
00313                                 bool left2right, bool scroll) {
00314         MHV_Display_HD44780::init(false, multiLine, bigFont, cursorOn, cursorBlink, left2right, scroll);
00315 }
00316