// Abstract interface for an I2C bus controller // Copyright (C)2017-2018-2023, Philip Munts dba Munts Technologies. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // // * Redistributions of source code must retain the above copyright notice, // this list of conditions and the following disclaimer. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE // POSSIBILITY OF SUCH DAMAGE. using System; namespace IO.Interfaces.I2C { /// /// I2C bus speed constants. /// public static class Speeds { /// /// Standard Mode /// public const int StandardMode = 100000; /// /// Fast Mode /// public const int FastMode = 400000; /// /// Fast Mode Plus /// public const int FastModePlus = 1000000; } /// /// I2C utility functions. /// public static class Utils { /// /// Prompt the operator to enter an I2C slave address, /// with rigorous error checking. Failure raises an exception. /// /// Prompt string. /// I2C slave address. public static int GetAddress(string prompt) { System.Console.Write(prompt); var inbuf = System.Console.ReadLine(); if (inbuf == null) { throw new Exception("prompt parameter is null"); } byte addr; try { if (inbuf.Substring(0, 2).ToLower().Equals("0x")) addr = System.Convert.ToByte(inbuf, 16); else addr = System.Convert.ToByte(inbuf); } catch { throw new Exception("I2C slave address string is invalid"); } if (addr > 127) { throw new Exception("I2C slave address is out of range"); } return addr; } } /// /// Abstract interface for I2C bus controllers. /// public interface Bus { /// /// Read bytes from an I2C slave device. /// /// I2C slave address. /// Response buffer. /// Number of bytes to read. void Read(int slaveaddr, byte[] resp, int resplen); /// /// Write bytes to an I2C slave device. /// /// I2C slave address. /// Command buffer. /// Number of bytes to write. void Write(int slaveaddr, byte[] cmd, int cmdlen); /// /// Write and read bytes to and from an I2C slave device. /// /// I2C slave address. /// Command buffer. /// Number of bytes to write. /// Response buffer. /// Number of bytes to read. /// Delay in microseconds between the I2C /// write and read cycles. Allowed values are 0 to 65535 microseconds. void Transaction(int slaveaddr, byte[] cmd, int cmdlen, byte[] resp, int resplen, int delayus = 0); } /// /// Encapsulates a single I2C slave device. /// public class Device { private readonly Bus bus; private readonly int addr; /// /// Create an I2C slave device. /// /// I2C bus controller object. /// I2C slave address. public Device(Bus bus, int slaveaddr) { if ((slaveaddr < 0) || (slaveaddr > 127)) { throw new System.Exception("Invalid slave address"); } this.bus = bus; this.addr = slaveaddr; } /// /// Read bytes from an I2C slave device. /// /// Response buffer. /// Number of bytes to read. public void Read(byte[] resp, int resplen) { this.bus.Read(this.addr, resp, resplen); } /// /// Write bytes to an I2C slave device. /// /// Command buffer. /// Number of bytes to write. public void Write(byte[] cmd, int cmdlen) { this.bus.Write(this.addr, cmd, cmdlen); } /// /// Write and read bytes to and from an I2C slave device. /// /// Command buffer. /// Number of bytes to write. /// Response buffer. /// Number of bytes to read. /// Delay in microseconds between the I2C /// write and read cycles. Allowed values are 0 to 65535 microseconds. public void Transaction(byte[] cmd, int cmdlen, byte[] resp, int resplen, int delayus = 0) { this.bus.Transaction(this.addr, cmd, cmdlen, resp, resplen, delayus); } } }