ESP32-PaxCounter/src/i2c.cpp

133 lines
4.0 KiB
C++
Raw Normal View History

2019-09-02 16:53:39 +02:00
// Basic config
#include "globals.h"
2019-10-16 21:14:34 +02:00
#include "i2c.h"
2019-09-02 16:53:39 +02:00
// Local logging tag
static const char TAG[] = __FILE__;
2020-10-14 10:29:13 +02:00
void i2c_init(void) { Wire.begin(MY_DISPLAY_SDA, MY_DISPLAY_SCL, 100000); }
2019-10-16 21:14:34 +02:00
void i2c_deinit(void) { Wire.~TwoWire(); }
2019-10-16 21:14:34 +02:00
2020-10-14 10:29:13 +02:00
void i2c_scan(void) {
// parts of the code in this function were taken from:
//
// Copyright (c) 2019 BitBank Software, Inc.
// Written by Larry Bank
// email: bitbank@pobox.com
// Project started 25/02/2019
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
BBI2C bbi2c;
const char *szNames[] = {
"Unknown", "SSD1306", "SH1106", "VL53L0X", "BMP180", "BMP280",
"BME280", "MPU-60x0", "MPU-9250", "MCP9808", "LSM6DS3", "ADXL345",
"ADS1115", "MAX44009", "MAG3110", "CCS811", "HTS221", "LPS25H",
"LSM9DS1", "LM8330", "DS3231", "LIS3DH", "LIS3DSH", "INA219",
"SHT3X", "HDC1080", "MPU6886", "BME680", "AXP202", "AXP192",
"24AA02XEXX", "DS1307"};
2019-09-02 16:53:39 +02:00
ESP_LOGI(TAG, "Starting I2C bus scan...");
2019-09-09 12:06:23 +02:00
// block i2c bus access
if (I2C_MUTEX_LOCK()) {
2019-09-02 16:53:39 +02:00
2020-10-14 10:29:13 +02:00
memset(&bbi2c, 0, sizeof(bbi2c));
bbi2c.bWire = 1; // use wire library, no bitbanging
bbi2c.iSDA = MY_DISPLAY_SDA;
bbi2c.iSCL = MY_DISPLAY_SCL;
I2CInit(&bbi2c, 100000L); // Scan at 100KHz low speed
delay(100); // allow devices to power up
uint8_t map[16];
uint8_t i;
int iDevice, iCount;
I2CScan(&bbi2c, map); // get bitmap of connected I2C devices
if (map[0] == 0xfe) // something is wrong with the I2C bus
{
ESP_LOGI(TAG, "I2C pins are not correct or the bus is being pulled low "
"by a bad device; unable to run scan");
} else {
iCount = 0;
for (i = 1; i < 128; i++) // skip address 0 (general call address) since
// more than 1 device can respond
{
if (map[i >> 3] & (1 << (i & 7))) // device found
{
iCount++;
iDevice = I2CDiscoverDevice(&bbi2c, i);
ESP_LOGI(TAG, "Device found at 0x%X, type = %s", i,
szNames[iDevice]); // show the device name as a string
2019-09-09 12:06:23 +02:00
}
2020-10-14 10:29:13 +02:00
} // for i
ESP_LOGI(TAG, "%u I2C device(s) found", iCount);
}
2019-10-13 16:59:03 +02:00
2019-09-09 12:06:23 +02:00
I2C_MUTEX_UNLOCK(); // release i2c bus access
} else
2020-10-14 10:29:13 +02:00
ESP_LOGE(TAG, "I2C bus busy - scan error");
}
// mutexed functions for i2c r/w access
2021-01-30 17:54:34 +01:00
int i2c_readBytes(uint8_t addr, uint8_t reg, uint8_t *data, uint8_t len) {
if (I2C_MUTEX_LOCK()) {
uint8_t ret = 0;
Wire.beginTransmission(addr);
Wire.write(reg);
Wire.endTransmission(false);
uint8_t cnt = Wire.requestFrom(addr, (uint8_t)len, (uint8_t)1);
if (!cnt)
ret = 0xFF;
uint16_t index = 0;
while (Wire.available()) {
if (index > len) {
ret = 0xFF;
goto finish;
}
data[index++] = Wire.read();
}
finish:
I2C_MUTEX_UNLOCK(); // release i2c bus access
return ret;
} else {
ESP_LOGW(TAG, "[%0.3f] i2c mutex lock failed", _seconds());
return 0xFF;
}
}
2021-01-30 17:54:34 +01:00
int i2c_writeBytes(uint8_t addr, uint8_t reg, uint8_t *data, uint8_t len) {
if (I2C_MUTEX_LOCK()) {
uint8_t ret = 0;
Wire.beginTransmission(addr);
Wire.write(reg);
for (uint16_t i = 0; i < len; i++) {
Wire.write(data[i]);
}
ret = Wire.endTransmission();
I2C_MUTEX_UNLOCK(); // release i2c bus access
return ret ? ret : 0xFF;
} else {
ESP_LOGW(TAG, "[%0.3f] i2c mutex lock failed", _seconds());
return 0xFF;
}
}