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