111 lines
3.6 KiB
C++
111 lines
3.6 KiB
C++
/*
|
|
* CLI_I2C_Commands.cpp - CLI library for Arduino/ESP8266 - I2C Commands implementation
|
|
*
|
|
* Version 1.0, latest version, documentation and bugtracker available at:
|
|
* https://gitlab.lindenaar.net/arduino/CLI
|
|
*
|
|
* Copyright (c) 2019 Frederik Lindenaar
|
|
*
|
|
* This library is free software: you can redistribute it and/or modify it under
|
|
* the terms of version 3 of the GNU General Public License as published by the
|
|
* Free Software Foundation, or (at your option) a later version of the license.
|
|
*
|
|
* This code 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, visit <http://www.gnu.org/licenses/> to download it.
|
|
*/
|
|
|
|
#include <CLI.h>
|
|
#include <Wire.h>
|
|
|
|
I2C_Scan_Command::I2C_Scan_Command(CLI & cli) : CLI_Command(cli,
|
|
PSTR("i2c_scan"), PSTR("Scan I2C bus for slave devices")) { };
|
|
|
|
bool I2C_Scan_Command::setparams(const char *params) {
|
|
_address = _found = 0;
|
|
return !params;
|
|
}
|
|
|
|
bool I2C_Scan_Command::execute(CLI &cli) {
|
|
if (_address < 127) {
|
|
if (_address == 0) cli.println(F("Scanning I2C..."));
|
|
Wire.beginTransmission(_address);
|
|
uint8_t error = Wire.endTransmission();
|
|
|
|
if (error == 0) {
|
|
cli.print(F("I2C device found at address 0x"));
|
|
if (_address < 0x10) cli.print("0");
|
|
cli.println(_address, HEX);
|
|
_found++;
|
|
} else if (error == 4) {
|
|
cli.print(F("Unknown error at address 0x"));
|
|
if (_address < 0x10) cli.print("0");
|
|
cli.println(_address, HEX);
|
|
}
|
|
_address++;
|
|
return true;
|
|
} else {
|
|
if (_found == 0)
|
|
cli.print_P(PSTR("No I2C devices found"));
|
|
return false;
|
|
}
|
|
}
|
|
|
|
|
|
I2C_Dump_Command::I2C_Dump_Command(CLI & cli) : CLI_Command(cli,
|
|
PSTR("i2c_dump"), PSTR("Display I2C EEPROM/Memory in HEX and ASCII"),
|
|
PSTR("Usage: i2c_dump 0x<id> <size> [<skip>] [single]\n"
|
|
"where:\t<id>\tHEX I2C device ID\n"
|
|
"\t<size>\tsize of memory\n"
|
|
"\t<skip>\t(optional) start offset\n"
|
|
"\tsingle\tto enforce 1-byte addressing")) { };
|
|
|
|
bool I2C_Dump_Command::setparams(const char *params) {
|
|
if (params && *(params++) == '0' && *(params++) == 'x') {
|
|
if ((params = CLI_STR_parse_HEX_byte(params, _address)) && *params == ' ') {
|
|
if(params = CLI_STR_parseInt(CLI_STR_skipSep(params), (int &)_length)) {
|
|
_offset = 0;
|
|
_large = _length > 0xff;
|
|
if (*params == ' ') {
|
|
params = CLI_STR_skipSep(params);
|
|
if(const char *p = CLI_STR_parseInt(params, (int &)_offset))
|
|
params = CLI_STR_skipSep(p);
|
|
if (strcmp_P(params, PSTR("single")) == 0) {
|
|
if (_large) return false;
|
|
params += 6;
|
|
}
|
|
}
|
|
return *params == 0;
|
|
}
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
bool I2C_Dump_Command::execute(CLI &cli) {
|
|
uint8_t buffer[16], len = 0;
|
|
|
|
Wire.beginTransmission(_address);
|
|
if (_large) Wire.write((uint8_t)(_offset >> 8)); // MSB
|
|
Wire.write((uint8_t)(_offset & 0xff)); // LSB
|
|
if (Wire.endTransmission() != 0) {
|
|
cli.print(F("No I2C device at 0x"));
|
|
cli.print(_address, HEX);
|
|
cli.println();
|
|
return false;
|
|
}
|
|
|
|
if (_offset == 0) cli.println(F("I2C EEPROM/Memory: "));
|
|
|
|
Wire.requestFrom(_address, (uint8_t) (_length - _offset < sizeof(buffer)) ? _length - _offset : sizeof(buffer));
|
|
while (Wire.available() && len < sizeof(buffer)) buffer[len++] = Wire.read();
|
|
|
|
cli.print_mem(_offset, buffer, len);
|
|
_offset += len;
|
|
return _offset < _length;
|
|
}
|
|
|