// 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);
}
}
}