I2C_Commands.cpp
3.64 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
/*
* 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;
}