Committer:
Wimpie
Date:
Sun Apr 17 17:26:10 2011 +0000
Revision:
3:704f87be7993
Parent:
2:1c5dea5d8783

        

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Wimpie 0:9218cf335f9b 1 /* mbed I2CTextLCD Library
Wimpie 0:9218cf335f9b 2 * Copyright (c) 2007-2009 sford
Wimpie 0:9218cf335f9b 3 * Copyright (c) 2010 Wim De Roeve changed to work with I2C PCF8575
Wimpie 0:9218cf335f9b 4 * Released under the MIT License: http://mbed.org/license/mit
Wimpie 0:9218cf335f9b 5 */
Wimpie 0:9218cf335f9b 6
Wimpie 0:9218cf335f9b 7 #include "I2CTextLCD.h"
Wimpie 0:9218cf335f9b 8 #include "mbed.h"
Wimpie 0:9218cf335f9b 9 #include "error.h"
Wimpie 0:9218cf335f9b 10
Wimpie 0:9218cf335f9b 11 using namespace mbed;
Wimpie 0:9218cf335f9b 12
Wimpie 0:9218cf335f9b 13 /*
Wimpie 0:9218cf335f9b 14 * useful info found at http://www.a-netz.de/lcd.en.php
Wimpie 0:9218cf335f9b 15 *
Wimpie 0:9218cf335f9b 16 *
Wimpie 0:9218cf335f9b 17 * Initialisation
Wimpie 0:9218cf335f9b 18 * ==============
Wimpie 0:9218cf335f9b 19 *
Wimpie 0:9218cf335f9b 20 * After attaching the supply voltage/after a reset, the display needs to be brought in to a defined state
Wimpie 0:9218cf335f9b 21 *
Wimpie 0:9218cf335f9b 22 * - wait approximately 15 ms so the display is ready to execute commands
Wimpie 0:9218cf335f9b 23 * - Execute the command 0x30 ("Display Settings") three times (wait 1,64ms after each command, the busy flag cannot be queried now).
Wimpie 0:9218cf335f9b 24 * - The display is in 8 bit mode, so if you have only connected 4 data pins you should only transmit the higher nibble of each command.
Wimpie 0:9218cf335f9b 25 * - If you want to use the 4 bit mode, now you can execute the command to switch over to this mode now.
Wimpie 0:9218cf335f9b 26 * - Execute the "clear display" command
Wimpie 0:9218cf335f9b 27 *
Wimpie 0:9218cf335f9b 28 * Timing
Wimpie 0:9218cf335f9b 29 * ======
Wimpie 0:9218cf335f9b 30 *
Wimpie 0:9218cf335f9b 31 * Nearly all commands transmitted to the display need 40us for execution.
Wimpie 0:9218cf335f9b 32 * Exceptions are the commands "Clear Display and Reset" and "Set Cursor to Start Position"
Wimpie 0:9218cf335f9b 33 * These commands need 1.64ms for execution. These timings are valid for all displays working with an
Wimpie 0:9218cf335f9b 34 * internal clock of 250kHz. But I do not know any displays that use other frequencies. Any time you
Wimpie 0:9218cf335f9b 35 * can use the busy flag to test if the display is ready to accept the next command.
Wimpie 0:9218cf335f9b 36 *
Wimpie 0:9218cf335f9b 37 */
Wimpie 0:9218cf335f9b 38
Wimpie 2:1c5dea5d8783 39 I2CTextLCD::I2CTextLCD(PinName sda, PinName scl, int i2cAddress , int columns, int rows,
Wimpie 2:1c5dea5d8783 40 bool backlight) : _i2c(sda, scl) {
Wimpie 0:9218cf335f9b 41
Wimpie 0:9218cf335f9b 42 _i2cAddress = i2cAddress;
Wimpie 0:9218cf335f9b 43 _columns = columns;
Wimpie 0:9218cf335f9b 44 _rows = rows;
Wimpie 2:1c5dea5d8783 45 _backlight=backlight;
Wimpie 2:1c5dea5d8783 46
Wimpie 0:9218cf335f9b 47
Wimpie 0:9218cf335f9b 48 // Should theoretically wait 15ms, but most things will be powered up pre-reset
Wimpie 0:9218cf335f9b 49 // so i'll disable that for the minute. If implemented, could wait 15ms post reset
Wimpie 0:9218cf335f9b 50 // instead
Wimpie 0:9218cf335f9b 51 // wait(0.015);
Wimpie 0:9218cf335f9b 52
Wimpie 0:9218cf335f9b 53 // send "Display Settings" 3 times (Only top nibble of 0x30 as we've got 4-bit bus)
Wimpie 0:9218cf335f9b 54
Wimpie 0:9218cf335f9b 55 for (int i=0; i<3; i++) {
Wimpie 3:704f87be7993 56 writeNibble(EIGHT_BITMODE,false);
Wimpie 0:9218cf335f9b 57 wait(0.00164); // this command takes 1.64ms, so wait for it
Wimpie 0:9218cf335f9b 58 }
Wimpie 3:704f87be7993 59 writeNibble(FOUR_BITMODE,false); // 4-bit mode
Wimpie 0:9218cf335f9b 60
Wimpie 0:9218cf335f9b 61 writeCommand(0x28); // Function set 001 BW N F - -
Wimpie 0:9218cf335f9b 62 writeCommand(0x0C);
Wimpie 0:9218cf335f9b 63 writeCommand(0x6); // Cursor Direction and Display Shift : 0000 01 CD S (CD 0-left, 1-right S(hift) 0-no, 1-yes
Wimpie 0:9218cf335f9b 64
Wimpie 0:9218cf335f9b 65 cls();
Wimpie 2:1c5dea5d8783 66
Wimpie 2:1c5dea5d8783 67
Wimpie 0:9218cf335f9b 68 }
Wimpie 0:9218cf335f9b 69
Wimpie 0:9218cf335f9b 70 int I2CTextLCD::_putc(int value) {
Wimpie 0:9218cf335f9b 71 if (value == '\n') {
Wimpie 0:9218cf335f9b 72 newline();
Wimpie 0:9218cf335f9b 73 } else {
Wimpie 0:9218cf335f9b 74 writeData(value);
Wimpie 0:9218cf335f9b 75 }
Wimpie 0:9218cf335f9b 76 return value;
Wimpie 0:9218cf335f9b 77 }
Wimpie 0:9218cf335f9b 78
Wimpie 0:9218cf335f9b 79 int I2CTextLCD::_getc() {
Wimpie 0:9218cf335f9b 80 return 0;
Wimpie 0:9218cf335f9b 81 }
Wimpie 0:9218cf335f9b 82
Wimpie 2:1c5dea5d8783 83 void I2CTextLCD::backlight(bool status) {
Wimpie 2:1c5dea5d8783 84 _backlight=status;
Wimpie 2:1c5dea5d8783 85 if (_backlight)
Wimpie 3:704f87be7993 86 writeI2CByte(BACKLIGHT_ON | E1_ON);
Wimpie 2:1c5dea5d8783 87 else
Wimpie 3:704f87be7993 88 writeI2CByte(E1_ON);
Wimpie 1:0eb3365ec819 89 }
Wimpie 1:0eb3365ec819 90
Wimpie 1:0eb3365ec819 91
Wimpie 0:9218cf335f9b 92 void I2CTextLCD::newline() {
Wimpie 0:9218cf335f9b 93 _column = 0;
Wimpie 0:9218cf335f9b 94 _row++;
Wimpie 0:9218cf335f9b 95 if (_row >= _rows) {
Wimpie 0:9218cf335f9b 96 _row = 0;
Wimpie 0:9218cf335f9b 97 }
Wimpie 0:9218cf335f9b 98 locate(_column, _row);
Wimpie 0:9218cf335f9b 99 }
Wimpie 0:9218cf335f9b 100
Wimpie 0:9218cf335f9b 101 void I2CTextLCD::locate(int column, int row) {
Wimpie 0:9218cf335f9b 102 if (column < 0 || column >= _columns || row < 0 || row >= _rows) {
Wimpie 0:9218cf335f9b 103 error("locate(%d,%d) out of range on %dx%d display", column, row, _columns, _rows);
Wimpie 0:9218cf335f9b 104 return;
Wimpie 0:9218cf335f9b 105 }
Wimpie 0:9218cf335f9b 106
Wimpie 0:9218cf335f9b 107 _row = row;
Wimpie 0:9218cf335f9b 108 _column = column;
Wimpie 0:9218cf335f9b 109 int address = 0x80 + (_row * 40) + _column; // memory starts at 0x80, and is 40 chars long per row
Wimpie 0:9218cf335f9b 110 // pc_LCD.traceOut("locate %dx%d\r\n", column, row);
Wimpie 0:9218cf335f9b 111 writeCommand(address);
Wimpie 0:9218cf335f9b 112 }
Wimpie 0:9218cf335f9b 113
Wimpie 0:9218cf335f9b 114 void I2CTextLCD::cls() {
Wimpie 0:9218cf335f9b 115 writeCommand(0x01); // Clear Display
Wimpie 0:9218cf335f9b 116 wait(0.00164f); // This command takes 1.64 ms
Wimpie 0:9218cf335f9b 117 locate(0, 0);
Wimpie 0:9218cf335f9b 118 }
Wimpie 0:9218cf335f9b 119
Wimpie 0:9218cf335f9b 120 void I2CTextLCD::reset() {
Wimpie 0:9218cf335f9b 121 cls();
Wimpie 0:9218cf335f9b 122 }
Wimpie 0:9218cf335f9b 123
Wimpie 0:9218cf335f9b 124 void I2CTextLCD::writeNibble(int data, bool rs) {
Wimpie 0:9218cf335f9b 125
Wimpie 0:9218cf335f9b 126 data = (data & 0xF);
Wimpie 0:9218cf335f9b 127
Wimpie 1:0eb3365ec819 128
Wimpie 1:0eb3365ec819 129 if (_backlight)
Wimpie 1:0eb3365ec819 130 data= data | BACKLIGHT_ON;
Wimpie 1:0eb3365ec819 131
Wimpie 0:9218cf335f9b 132 if (rs) {
Wimpie 0:9218cf335f9b 133 data = data | RS_ON; // set rs bit
Wimpie 0:9218cf335f9b 134 }
Wimpie 0:9218cf335f9b 135
Wimpie 3:704f87be7993 136 writeI2CByte(data | E1_ON); // E=1
Wimpie 0:9218cf335f9b 137
Wimpie 0:9218cf335f9b 138 wait(0.000040f);
Wimpie 2:1c5dea5d8783 139 writeI2CByte(data); // E=0
Wimpie 0:9218cf335f9b 140
Wimpie 0:9218cf335f9b 141 wait(0.000040f);
Wimpie 3:704f87be7993 142 writeI2CByte(data | E1_ON); // E=1
Wimpie 0:9218cf335f9b 143 }
Wimpie 0:9218cf335f9b 144
Wimpie 0:9218cf335f9b 145 void I2CTextLCD::writeByte(int data, bool rs) {
Wimpie 0:9218cf335f9b 146 writeNibble(data >> 4 , rs);
Wimpie 0:9218cf335f9b 147 writeNibble(data >> 0 , rs);
Wimpie 0:9218cf335f9b 148 }
Wimpie 0:9218cf335f9b 149
Wimpie 0:9218cf335f9b 150 void I2CTextLCD::writeCommand(int command) {
Wimpie 3:704f87be7993 151 // RS = 0;
Wimpie 0:9218cf335f9b 152 writeByte(command,false);
Wimpie 0:9218cf335f9b 153 }
Wimpie 0:9218cf335f9b 154
Wimpie 0:9218cf335f9b 155 void I2CTextLCD::writeData(int data) {
Wimpie 3:704f87be7993 156 //RS = 1
Wimpie 0:9218cf335f9b 157 writeByte(data,true);
Wimpie 0:9218cf335f9b 158
Wimpie 0:9218cf335f9b 159 _column++;
Wimpie 0:9218cf335f9b 160 if (_column >= _columns) {
Wimpie 0:9218cf335f9b 161 newline();
Wimpie 0:9218cf335f9b 162 }
Wimpie 0:9218cf335f9b 163 }
Wimpie 0:9218cf335f9b 164
Wimpie 0:9218cf335f9b 165 void I2CTextLCD::writeI2CByte(int data) {
Wimpie 0:9218cf335f9b 166 char cmd[2];
Wimpie 0:9218cf335f9b 167 cmd[0] = (data & 0xFF);
Wimpie 0:9218cf335f9b 168 cmd[1] = (data >> 8);
Wimpie 0:9218cf335f9b 169 _i2c.write(_i2cAddress, cmd, 2);
Wimpie 0:9218cf335f9b 170 }
Wimpie 1:0eb3365ec819 171
Wimpie 1:0eb3365ec819 172
Wimpie 2:1c5dea5d8783 173
Wimpie 2:1c5dea5d8783 174
Wimpie 2:1c5dea5d8783 175