|
MHVLib
20111227
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_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