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