Committer:
Wimpie
Date:
Sat Dec 18 20:06:14 2010 +0000
Revision:
0:9218cf335f9b
Child:
1:0eb3365ec819

        

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 0:9218cf335f9b 39 I2CTextLCD::I2CTextLCD(PinName sda, PinName scl, int i2cAddress , int columns, int rows) :
Wimpie 0:9218cf335f9b 40 _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 0:9218cf335f9b 45
Wimpie 0:9218cf335f9b 46
Wimpie 0:9218cf335f9b 47 // Should theoretically wait 15ms, but most things will be powered up pre-reset
Wimpie 0:9218cf335f9b 48 // so i'll disable that for the minute. If implemented, could wait 15ms post reset
Wimpie 0:9218cf335f9b 49 // instead
Wimpie 0:9218cf335f9b 50 // wait(0.015);
Wimpie 0:9218cf335f9b 51
Wimpie 0:9218cf335f9b 52 // send "Display Settings" 3 times (Only top nibble of 0x30 as we've got 4-bit bus)
Wimpie 0:9218cf335f9b 53
Wimpie 0:9218cf335f9b 54 for (int i=0; i<3; i++) {
Wimpie 0:9218cf335f9b 55 writeNibble(0x3,false);
Wimpie 0:9218cf335f9b 56 wait(0.00164); // this command takes 1.64ms, so wait for it
Wimpie 0:9218cf335f9b 57 }
Wimpie 0:9218cf335f9b 58 writeNibble(0x2,false); // 4-bit mode
Wimpie 0:9218cf335f9b 59
Wimpie 0:9218cf335f9b 60 writeCommand(0x28); // Function set 001 BW N F - -
Wimpie 0:9218cf335f9b 61 writeCommand(0x0C);
Wimpie 0:9218cf335f9b 62 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 63
Wimpie 0:9218cf335f9b 64 cls();
Wimpie 0:9218cf335f9b 65 }
Wimpie 0:9218cf335f9b 66
Wimpie 0:9218cf335f9b 67 int I2CTextLCD::_putc(int value) {
Wimpie 0:9218cf335f9b 68 if (value == '\n') {
Wimpie 0:9218cf335f9b 69 newline();
Wimpie 0:9218cf335f9b 70 } else {
Wimpie 0:9218cf335f9b 71 writeData(value);
Wimpie 0:9218cf335f9b 72 }
Wimpie 0:9218cf335f9b 73 return value;
Wimpie 0:9218cf335f9b 74 }
Wimpie 0:9218cf335f9b 75
Wimpie 0:9218cf335f9b 76 int I2CTextLCD::_getc() {
Wimpie 0:9218cf335f9b 77 return 0;
Wimpie 0:9218cf335f9b 78 }
Wimpie 0:9218cf335f9b 79
Wimpie 0:9218cf335f9b 80 void I2CTextLCD::newline() {
Wimpie 0:9218cf335f9b 81 _column = 0;
Wimpie 0:9218cf335f9b 82 _row++;
Wimpie 0:9218cf335f9b 83 if (_row >= _rows) {
Wimpie 0:9218cf335f9b 84 _row = 0;
Wimpie 0:9218cf335f9b 85 }
Wimpie 0:9218cf335f9b 86 locate(_column, _row);
Wimpie 0:9218cf335f9b 87 }
Wimpie 0:9218cf335f9b 88
Wimpie 0:9218cf335f9b 89 void I2CTextLCD::locate(int column, int row) {
Wimpie 0:9218cf335f9b 90 if (column < 0 || column >= _columns || row < 0 || row >= _rows) {
Wimpie 0:9218cf335f9b 91 error("locate(%d,%d) out of range on %dx%d display", column, row, _columns, _rows);
Wimpie 0:9218cf335f9b 92 return;
Wimpie 0:9218cf335f9b 93 }
Wimpie 0:9218cf335f9b 94
Wimpie 0:9218cf335f9b 95 _row = row;
Wimpie 0:9218cf335f9b 96 _column = column;
Wimpie 0:9218cf335f9b 97 int address = 0x80 + (_row * 40) + _column; // memory starts at 0x80, and is 40 chars long per row
Wimpie 0:9218cf335f9b 98 // pc_LCD.traceOut("locate %dx%d\r\n", column, row);
Wimpie 0:9218cf335f9b 99 writeCommand(address);
Wimpie 0:9218cf335f9b 100 }
Wimpie 0:9218cf335f9b 101
Wimpie 0:9218cf335f9b 102 void I2CTextLCD::cls() {
Wimpie 0:9218cf335f9b 103 writeCommand(0x01); // Clear Display
Wimpie 0:9218cf335f9b 104 wait(0.00164f); // This command takes 1.64 ms
Wimpie 0:9218cf335f9b 105 locate(0, 0);
Wimpie 0:9218cf335f9b 106 }
Wimpie 0:9218cf335f9b 107
Wimpie 0:9218cf335f9b 108 void I2CTextLCD::reset() {
Wimpie 0:9218cf335f9b 109 cls();
Wimpie 0:9218cf335f9b 110 }
Wimpie 0:9218cf335f9b 111
Wimpie 0:9218cf335f9b 112 void I2CTextLCD::writeNibble(int data, bool rs) {
Wimpie 0:9218cf335f9b 113
Wimpie 0:9218cf335f9b 114 data = (data & 0xF);
Wimpie 0:9218cf335f9b 115
Wimpie 0:9218cf335f9b 116 if (rs) {
Wimpie 0:9218cf335f9b 117 data = data | RS_ON; // set rs bit
Wimpie 0:9218cf335f9b 118 }
Wimpie 0:9218cf335f9b 119
Wimpie 0:9218cf335f9b 120 writeI2CByte(data | E_ON); // E=1
Wimpie 0:9218cf335f9b 121
Wimpie 0:9218cf335f9b 122 wait(0.000040f);
Wimpie 0:9218cf335f9b 123 writeI2CByte(data ); // E=0
Wimpie 0:9218cf335f9b 124
Wimpie 0:9218cf335f9b 125 wait(0.000040f);
Wimpie 0:9218cf335f9b 126 writeI2CByte(data | E_ON); // E=1
Wimpie 0:9218cf335f9b 127 }
Wimpie 0:9218cf335f9b 128
Wimpie 0:9218cf335f9b 129 void I2CTextLCD::writeByte(int data, bool rs) {
Wimpie 0:9218cf335f9b 130 writeNibble(data >> 4 , rs);
Wimpie 0:9218cf335f9b 131 writeNibble(data >> 0 , rs);
Wimpie 0:9218cf335f9b 132 }
Wimpie 0:9218cf335f9b 133
Wimpie 0:9218cf335f9b 134 void I2CTextLCD::writeCommand(int command) {
Wimpie 0:9218cf335f9b 135 //command ^= RS_ON; // RS = 0;
Wimpie 0:9218cf335f9b 136 writeByte(command,false);
Wimpie 0:9218cf335f9b 137 }
Wimpie 0:9218cf335f9b 138
Wimpie 0:9218cf335f9b 139 void I2CTextLCD::writeData(int data) {
Wimpie 0:9218cf335f9b 140 // data = data | RS_ON; //RS = 1
Wimpie 0:9218cf335f9b 141 writeByte(data,true);
Wimpie 0:9218cf335f9b 142
Wimpie 0:9218cf335f9b 143 _column++;
Wimpie 0:9218cf335f9b 144 if (_column >= _columns) {
Wimpie 0:9218cf335f9b 145 newline();
Wimpie 0:9218cf335f9b 146 }
Wimpie 0:9218cf335f9b 147 }
Wimpie 0:9218cf335f9b 148
Wimpie 0:9218cf335f9b 149 void I2CTextLCD::writeI2CByte(int data) {
Wimpie 0:9218cf335f9b 150 char cmd[2];
Wimpie 0:9218cf335f9b 151 cmd[0] = (data & 0xFF);
Wimpie 0:9218cf335f9b 152 cmd[1] = (data >> 8);
Wimpie 0:9218cf335f9b 153 _i2c.write(_i2cAddress, cmd, 2);
Wimpie 0:9218cf335f9b 154 }