You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

173 lines
5.9 KiB

/*
* Copyright (c) 2018 Tlera Corp. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal with the Software without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimers.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimers in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of Tlera Corp, nor the names of its contributors
* may be used to endorse or promote products derived from this Software
* without specific prior written permission.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
* WITH THE SOFTWARE.
*/
#include "Arduino.h"
#include "I2Cdev.h"
I2Cdev::I2Cdev(TwoWire* i2c_bus) // Class constructor
{
_i2c_bus = i2c_bus;
}
I2Cdev::~I2Cdev() // Class destructor
{
}
/**
* @fn: readByte(uint8_t address, uint8_t subAddress)
*
* @brief: Read one byte from an I2C device
*
* @params: I2C slave device address, Register subAddress
* @returns: unsigned short read
*/
uint8_t I2Cdev::readByte(uint8_t address, uint8_t subAddress)
{
uint8_t data = 0; // `data` will store the register data
_i2c_bus->beginTransmission(address); // Initialize the Tx buffer
_i2c_bus->write(subAddress); // Put slave register address in Tx buffer
_i2c_bus->endTransmission(false); // Send the Tx buffer, but send a restart to keep connection alive
_i2c_bus->requestFrom(address, 1); // Read one byte from slave register address
data = _i2c_bus->read(); // Fill Rx buffer with result
return data; // Return data read from slave register
}
/**
* @fn: readBytes(uint8_t address, uint8_t subAddress, uint8_t count, uint8_t * dest)
*
* @brief: Read multiple bytes from an I2C device
*
* @params: I2C slave device address, Register subAddress, number of btes to be read, aray to store the read data
* @returns: void
*/
void I2Cdev::readBytes(uint8_t address, uint8_t subAddress, uint8_t count, uint8_t * dest)
{
_i2c_bus->beginTransmission(address); // Initialize the Tx buffer
_i2c_bus->write(subAddress); // Put slave register address in Tx buffer
_i2c_bus->endTransmission(false); // Send the Tx buffer, but send a restart to keep connection alive
uint8_t i = 0;
_i2c_bus->requestFrom(address, count); // Read bytes from slave register address
while (_i2c_bus->available()) {
dest[i++] = _i2c_bus->read(); } // Put read results in the Rx buffer
}
/**
* @fn: writeByte(uint8_t devAddr, uint8_t regAddr, uint8_t data)
*
* @brief: Write one byte to an I2C device
*
* @params: I2C slave device address, Register subAddress, data to be written
* @returns: void
*/
void I2Cdev::writeByte(uint8_t devAddr, uint8_t regAddr, uint8_t data)
{
_i2c_bus->beginTransmission(devAddr); // Initialize the Tx buffer
_i2c_bus->write(regAddr); // Put slave register address in Tx buffer
_i2c_bus->write(data); // Put data in Tx buffer
_i2c_bus->endTransmission(); // Send the Tx buffer
}
/**
* @fn: writeBytes(uint8_t devAddr, uint8_t regAddr, uint8_t data)
*
* @brief: Write multiple bytes to an I2C device
*
* @params: I2C slave device address, Register subAddress, byte count, data array to be written
* @returns: void
*/
void I2Cdev::writeBytes(uint8_t devAddr, uint8_t regAddr, uint8_t count, uint8_t *dest)
{
uint8_t temp[1 + count];
temp[0] = regAddr;
for (uint8_t ii = 0; ii < count; ii++)
{
temp[ii + 1] = dest[ii];
}
_i2c_bus->beginTransmission(devAddr); // Initialize the Tx buffer
for (uint8_t jj = 0; jj < count + 1; jj++)
{
_i2c_bus->write(temp[jj]); // Put data in Tx buffer
}
_i2c_bus->endTransmission(); // Send the Tx buffer
}
/**
* @fn:I2Cscan()
* @brief: Scan the I2C bus for active I2C slave devices
*
* @params: void
* @returns: void
*/
void I2Cdev::I2Cscan()
{
// Scan for i2c devices
byte error, address;
int nDevices;
Serial.println("Scanning...");
nDevices = 0;
for(address = 1; address < 127; address++ )
{
// The i2c_scanner uses the return value of the Wire.endTransmisstion to see if a device did acknowledge to the address.
_i2c_bus->beginTransmission(address);
error = _i2c_bus->endTransmission();
if (error == 0)
{
Serial.print("I2C device found at address 0x");
if (address<16)
Serial.print("0");
Serial.print(address,HEX);
Serial.println(" !");
nDevices++;
}
else if (error==4)
{
Serial.print("Unknown error at address 0x");
if (address<16)
Serial.print("0");
Serial.println(address,HEX);
}
}
if (nDevices == 0)
Serial.println("No I2C devices found\n");
else
Serial.println("I2C scan complete\n");
}