using System;
using System.Collections;
using System.Threading;
using Microsoft.SPOT;
using Microsoft.SPOT.Hardware;
namespace _511_
{
//combined class for display and EEPROM
public enum CodePage : byte
{
ROM_A = 0x02,
ROM_B = 0x06,
ROM_C = 0x0A
}
/// <summary>
/// The default config is adress 0x3C and 400kHz. Run Init() first.
/// Defaults are: 4 lines, 20 characters each line, ROM-B (see datasheet)
/// </summary>
public class I2C
{
public int I2C_TIMEOUT = 500;
public int DISPLAY_LINES = 2;
public int DISPLAY_CHARS = 20;
public byte CODEPAGE = (byte)CodePage.ROM_B;
private byte[] Line_Adresses = { 0x80, 0xA0, 0xC0, 0xE0 }; // RAM addresses for line 0-3
public int SendCommand(I2CDevice I2C_DEV, I2CDevice.Configuration I2C_CFG, byte address, byte Command)
{
try
{
I2C_DEV.Config = I2C_CFG;
I2CDevice.I2CTransaction[] Transaction = new I2CDevice.I2CTransaction[1];
Transaction[0] = I2CDevice.CreateWriteTransaction(new byte[] { 0x00, Command });
return I2C_DEV.Execute(Transaction, I2C_TIMEOUT);
}
catch (Exception ex)
{
return 0;
//Debug.Print(ex.ToString());
}
}
public int SendData(I2CDevice SHAREDI2C_DEV, I2CDevice.Configuration I2C_CFG, byte address, byte Data)
{
SHAREDI2C_DEV.Config = I2C_CFG;
I2CDevice.I2CTransaction[] Transaction = new I2CDevice.I2CTransaction[1];
Transaction[0] = I2CDevice.CreateWriteTransaction(new byte[] { address, Data }); //0X40 for display data register
if (SHAREDI2C_DEV.Execute(Transaction, I2C_TIMEOUT) == 1)
{
return 1;
}
else
{
return 0;
}
}
/// <summary>
/// Display a single line, the screen is not clared, so it also can be used to update a single line.
/// </summary>
/// <param name="I2C_DEV"></param>
/// <param name="Line"></param>
/// <param name="LineID"></param>
public void DisplayLine(I2CDevice SHAREDI2C_DEV, I2CDevice.Configuration I2C_CFG, string Line, int LineID)
{
if (LineID >= DISPLAY_LINES || LineID < 0) { LineID = 0; } //Makes sure, the LinID has a valid value
while (Line.Length < DISPLAY_CHARS) { Line = Line + " "; } //Makes sure, the rest of the line is blank, if you use this to update a line.
char[] cha = Line.ToCharArray();
SendCommand(SHAREDI2C_DEV, I2C_CFG, 0x00, Line_Adresses[LineID]);
int CharID = 0;
foreach (char c in cha)
{
if (CharID >= DISPLAY_CHARS) break;
SendData(SHAREDI2C_DEV, I2C_CFG, 0x40, (byte)c);
CharID++;
}
}
/// <summary>
/// Displays a string-array with up to four strings (can be more, but only the first four lines will be displayed).
/// If there are less than four lines, the content is aligned at the top.
/// </summary>
/// <param name="Display"></param>
public void DisplayAll(I2CDevice SHAREDI2C_DEV, I2CDevice.Configuration I2C_CFG, string[] Display)
{
ArrayList AList = new ArrayList();
foreach (string s in Display) { AList.Add((char[])s.ToCharArray()); }
SendCommand(SHAREDI2C_DEV, I2C_CFG, 0x00, 0x01);
int LineID = 0;
foreach (char[] cha in AList)
{
if (LineID >= DISPLAY_LINES) break;
SendCommand(SHAREDI2C_DEV, I2C_CFG, 0x00, Line_Adresses[LineID]);
int CharID = 0;
foreach (char c in cha)
{
if (CharID >= DISPLAY_CHARS) break;
SendData(SHAREDI2C_DEV, I2C_CFG, 0x40, (byte)c);
CharID++;
}
LineID++;
}
}
/// <summary>
/// Initial setup, call this first before using the display.
/// </summary>
/// <param name="I2C_DEV"></param>
public void Init(I2CDevice I2C_DEV, I2CDevice.Configuration I2C_CFG)
{
SendCommand(I2C_DEV, I2C_CFG, 0x00, 0x38); // Function set: extended command set (RE=1), lines #
SendCommand(I2C_DEV, I2C_CFG, 0x00, 0x39); // Function selection A:
SendCommand(I2C_DEV, I2C_CFG, 0x00, 0x14); // enable internal Vdd regulator at 5V I/O mode (def. value) (0x00 for disable, 2.8V I/O)
SendCommand(I2C_DEV, I2C_CFG, 0x00, 0x78); // Function set: fundamental command set (RE=0) (exit from extended command set), lines #
SendCommand(I2C_DEV, I2C_CFG, 0x00, 0x5E); // Display ON/OFF control: display off, cursor off, blink off (default values)
SendCommand(I2C_DEV, I2C_CFG, 0x00, 0x6D); // Function set: extended command set (RE=1), lines #
SendCommand(I2C_DEV, I2C_CFG, 0x00, 0x0C); // Function selection A:
SendCommand(I2C_DEV, I2C_CFG, 0x00, 0x01); // enable internal Vdd regulator at 5V I/O mode (def. value) (0x00 for disable, 2.8V I/O)
SendCommand(I2C_DEV, I2C_CFG, 0x00, 0x06); // Function set: fundamental command set (RE=0) (exit from extended command set), lines #
SendCommand(I2C_DEV, I2C_CFG, 0x00, 0x08); // Extended function set (RE=1): 5-dot font, B/W inverting disabled (def. val.), 1/2 lines
if (DISPLAY_LINES == 2)
Line_Adresses[1] = 0xC0; // DDRAM address for each line of the display (only for 2-line mode)
}
public byte Read(I2CDevice SHAREDI2C_DEV, I2CDevice.Configuration I2C_CFG, int Address)
{
SHAREDI2C_DEV.Config = I2C_CFG;
var Data = new byte[1];
var xActions = new I2CDevice.I2CTransaction[1];
xActions[0] = I2CDevice.CreateWriteTransaction(new byte[] { (byte)(Address >> 8), (byte)(Address & 0xFF) });
Thread.Sleep(5);
if (SHAREDI2C_DEV.Execute(xActions, 1000) == 0)
{
// Debug.Print("Failed to perform I2C transaction");
}
else
{
xActions[0] = I2CDevice.CreateReadTransaction(Data);
Thread.Sleep(5); // Mandatory after each Write transaction !!!
if (SHAREDI2C_DEV.Execute(xActions, 1000) == 0)
{
// Debug.Print("Failed to perform I2C transaction");
}
else
{
// Debug.Print("Register value: " + Data[0].ToString());
return Data[0];
}
}
return 0;
}
public void Write(I2CDevice SHAREDI2C_DEV, I2CDevice.Configuration I2C_CFG, int Address, byte[] data)
{
SHAREDI2C_DEV.Config = I2C_CFG;
byte[] byte1 = new byte[2];
byte1 = new byte[] { (byte)(Address >> 8), (byte)(Address & 0xFF) };
int length = byte1.Length + data.Length;
byte[] payload = new byte[length];
byte1.CopyTo(payload, 0);
data.CopyTo(payload, byte1.Length);
var xActions = new I2CDevice.I2CTransaction[1];
// byte1=[(byte)(Address>>8),(byte)(Address&0xFF)];
xActions[0] = I2CDevice.CreateWriteTransaction(payload);
Thread.Sleep(5);
if (SHAREDI2C_DEV.Execute(xActions, 1000) == 0)
{
Debug.Print("Failed to perform I2C transaction");
}
}
/// <summary>
/// As the function-name tells you, this clears the screen.
/// </summary>
/// <param name="I2C_DEV"></param>
public void ClearScreen(I2CDevice I2C_DEV, I2CDevice.Configuration I2C_CFG)
{
SendCommand(I2C_DEV, I2C_CFG, 0x00, 0x01);
}
}
}