using System; using System.Text; using System.Threading; using Microsoft.SPOT; using Microsoft.SPOT.Hardware; namespace CPF { public class I2CUartBridge { public static byte RHR =0x0; public static byte THR =0x0; public static byte IER =0x1; public static byte FCR =0x2; public static byte ISR =0x2; public static byte LCR =0x3; public static byte MCR =0x4; public static byte LSR =0x5; public static byte SHR =0x5; // requires EFR bit-4 = 1 public static byte MSR =0x6; public static byte SFR =0x6; // requires EFR bit-4 = 1 public static byte TCR =0x6; public static byte SPR =0x7; // requires SFR bit-0 = 0, FCTR bit-6 = 0 public static byte GPIOLVL =0x7; // requires SFR bit-0 = 1, FCTR bit-6 = 0 public static byte EMSR =0x7; // requires SFR bit-0 = 0, FCTR bit-6 = 1 public static byte FC =0x7; // requires SFR bit-0 = 0, FCTR bit-6 = 1 public static byte DLL =0x0; public static byte DLM =0x1; public static byte DLD =0x2; /* LCR needs to be 0xbf */ public static byte TRIG =0x0; public static byte FCTR =0x1; public static byte EFR =0x2; public static byte XON1 =0x4; public static byte XON2 =0x5; public static byte XOFF1 =0x6; public static byte XOFF2 =0x7; public static byte GPIOINT =0x4; // requires SFR bit-0 = 1 public static byte GPIO3T =0x5; // requires SFR bit-0 = 1 public static byte GPIOINV =0x6; // requires SFR bit-0 = 1 public static byte GPIOSEL =0x7; // requires SFR bit-0 = 1 // create write buffer (we need one byte) public static byte[] RegisterNum = new byte[1] { 0x12 }; // create read buffer to read the register public static byte[] RegisterValue = new byte[1] { 0x00 }; public static byte[] str = new byte[256]; private static StringBuilder strLine = new StringBuilder(128); //number of bytes in read Fifo public static int nb; //public static ushort Bridge1Address = 48; //A1=VCC A0=VCC //public static ushort Bridge2Address = 49; //A1=VCC A0=GND //************************************************************************************************************************************ public static int init(I2CDevice MyI2C) { //initialiaze an EXAR1280 I2C to UART device ONLY. sets up registers in the proper order. //TODO, hook up error checking and return value int ret = 0; RegisterNum[0] = LCR; RegisterValue[0] = 0xBF; //LCR=BF enables access to enhanced reg RegWrite(MyI2C, RegisterNum, RegisterValue); RegisterNum[0] = FCTR; RegisterValue[0] = 0x41; //FCTR=0x41 enables SPR as fifo counter FCTR[6]=1). FCTR[0] = no sleeping! RegWrite(MyI2C, RegisterNum, RegisterValue); RegisterNum[0] = EFR; RegisterValue[0] = 0x10; //EFR[4] = 1 enables shaded bits, access to DLD and flow control RegWrite(MyI2C, RegisterNum, RegisterValue); RegisterNum[0] = LCR; RegisterValue[0] = 0x80; //LCR[7] = 1 enables access to divisors. LCR[1,2] = 0 selects 8N1 RegWrite(MyI2C, RegisterNum, RegisterValue); /* //-------------------------------------------------- //9600, 4x sampling, 14.7456mHz RegisterNum[0] = DLD; RegisterValue[0] = 0x20; //DLD RegWrite(MyI2C, RegisterNum, RegisterValue); RegisterNum[0] = DLM; RegisterValue[0] = 0x01; //DLM RegWrite(MyI2C, RegisterNum, RegisterValue); RegisterNum[0] = DLL; RegisterValue[0] = 0x80; //DLL RegWrite(MyI2C, RegisterNum, RegisterValue); //--------------------------------------------------- */ //-------------------------------------------------- //19200, 4x sampling, 14.7456mHz RegisterNum[0] = DLD; RegisterValue[0] = 0x20; //DLD RegWrite(MyI2C, RegisterNum, RegisterValue); RegisterNum[0] = DLM; RegisterValue[0] = 0x00; //DLM RegWrite(MyI2C, RegisterNum, RegisterValue); RegisterNum[0] = DLL; RegisterValue[0] = 0xC0; //DLL RegWrite(MyI2C, RegisterNum, RegisterValue); //-------------------------------------------------- RegisterNum[0] = LCR; RegisterValue[0] = 0x03; //LCR 8N1 format RegWrite(MyI2C, RegisterNum, RegisterValue); RegisterNum[0] = MCR; RegisterValue[0] = 0x00; //MCR RegWrite(MyI2C, RegisterNum, RegisterValue); RegisterNum[0] = FCR; RegisterValue[0] = 0x01; //FCR RegWrite(MyI2C, RegisterNum, RegisterValue); RegisterNum[0] = SFR; RegisterValue[0] = 0x00; //SFR RegWrite(MyI2C, RegisterNum, RegisterValue); RegisterNum[0] = EMSR; RegisterValue[0] = 0x00; //EMSR[0] makes spr FIFO rx count RegWrite(MyI2C, RegisterNum, RegisterValue); RegisterNum[0] = IER; RegisterValue[0] = 0x01; //IER, only if LCR[7]=0 RegWrite(MyI2C, RegisterNum, RegisterValue); //clear read fifo FifoRead(MyI2C, str); //clear interrupt ClearIRQ(MyI2C); return (ret); //TODO, hook this up } //end init() //************************************************************************************************************************************ public static int FifoRead(I2CDevice MyI2C, byte[] rtstr) { //reads all characters in read fifo and returns in rtstr. //TODO, hook up error RegisterNum[0] = SPR; int nb = RegRead(MyI2C, RegisterNum); if (nb == 0) { //Debug.Print("FIFO EMPTY"); return 0; } //bounds checking if (nb < 1) nb = 0; if (nb > 127) nb = 127; int bytes_read = 0; int j = 0; //Debug.Print("nb=" + nb.ToString()); while ((nb>0) && (j < 3)) { //get nb bytes for (int i = 0; i < nb; i++) { RegisterNum[0] = 0; rtstr[bytes_read] = (byte)RegRead(MyI2C, RegisterNum); bytes_read++; if (bytes_read > 255) { i = nb; }; //bail out //Debug.Print(rtstr[i].ToString()); } //see if any more characters arrived while we were getting above chars RegisterNum[0] = SPR; nb = RegRead(MyI2C, RegisterNum); //bounds checking if (nb < 1) nb = 0; if (nb > 127) nb = 127; j++; }//end while nb>0 return bytes_read; } //end fiforead() //************************************************************************************************************************************ public static int i2cprint(I2CDevice MyI2C, byte[] sndstr, int nb) { //TODO, hook up error condition for (int i = 0; i < nb; i++) { RegisterNum[0] = 0; RegisterValue[0] = sndstr[i]; RegWrite(MyI2C, RegisterNum, RegisterValue); } return nb; //send something reasonable back. just using nb so //the damn compiler stops complaining. } //end i2cprint //************************************************************************************************************************************ public static ushort RegRead(I2CDevice MyI2C, byte[] RegNum) { //TODO, hook up error condition I2CDevice.I2CTransaction[] xActions = new I2CDevice.I2CTransaction[2]; RegNum[0] = (byte)((int)RegNum[0] & 0x0F); RegNum[0] = (byte)((int)RegNum[0] << 3); //RegNum[0] = (byte)((int)RegNum[0] | 0x01); xActions[0] = I2CDevice.CreateWriteTransaction(RegNum); xActions[1] = I2CDevice.CreateReadTransaction(RegNum); // Now we access the I2C bus using a timeout of one second // if the execute command returns zero, the transaction failed (this // is a good check to make sure that you are communicating with the device correctly // and don’t have a wiring issue or other problem with the I2C device) if (MyI2C.Execute(xActions, 1000) == 0) { Debug.Print("RegRead: Write Fail 1: " + RegNum[0].ToString()); if (MyI2C.Execute(xActions, 1000) == 0) { Debug.Print("RegRead: Write Fail 2: " + RegNum[0].ToString()); } } return RegNum[0]; }//end RegRead() //************************************************************************************************************************************ public static ushort RegWrite(I2CDevice MyI2C, byte[] RegNum, byte[] RegVal) { //to do, hook up error condition ushort ret = 0; I2CDevice.I2CTransaction[] xActions = new I2CDevice.I2CTransaction[1]; RegNum[0] = (byte)((int)RegNum[0] & 0x0F); RegNum[0] = (byte)((int)RegNum[0] << 3); //RegNum[0] = (byte)((int)RegNum[0] | 0x01); byte[] snd = new byte[2] { RegNum[0], RegVal[0] }; //Debug.Print("RegWrite: Writing " + snd[1].ToString() + "to reg num " // + snd[0].ToString()); xActions[0] = I2CDevice.CreateWriteTransaction(snd); if (MyI2C.Execute(xActions, 1000) == 0) { Debug.Print("RegWrite: Write Fail 1: " + RegNum[0].ToString()); if (MyI2C.Execute(xActions, 1000) == 0) { Debug.Print("RegWrite: Write Fail 2: " + RegNum[0].ToString()); ret = 1; } } return (ret); }//end RegWrite //************************************************************************************************************************************ public static void ClearIRQ(I2CDevice MyI2C) { RegisterNum[0] = 2; RegRead(MyI2C, RegisterNum); }//end ClearIRQ() //************************************************************************************************************************************ public static StringBuilder get_i2c_buffer(I2CDevice MyI2C) { //StringBuilder returnField; int i = 0; nb = I2CUartBridge.FifoRead(MyI2C, str); if (nb > 0) { //returnField.Append(System.Text.Encoding.UTF8.GetChars(str, 0, nb)); for (i = 0; i < nb; i++) //non printable chars crash program { if (str[i] > 126) str[i] = 0; } strLine.Clear(); strLine.Append(System.Text.Encoding.UTF8.GetChars(str, 0, nb)); if (strLine.Length > 0) { Debug.Print(strLine.ToString()); Program.btConsole.SendLine(strLine); } } return (strLine); } //end //************************************************************************************************************************************ public static void clear_i2c_buffer(I2CDevice MyI2C, int x) { //Debug.Print("clear_buffer " + x.ToString()); //Debug.Print("i2c_flag=" + i2c_flg.ToString()); //Program.I2CBridge.Config = con; nb = I2CUartBridge.FifoRead(MyI2C, str); //I2CInstrument.ClearIRQ(I2CBridge); //i2c_flg &= ~(1 << (x - 1)); //clear the bit //Debug.Print("i2c_flag=" + i2c_flg.ToString()); Debug.Print("Clearing B" + x.ToString() + ":" + nb.ToString()); } //end //************************************************************************************************************************************ } }