Repository navigation
Expand file tree
/
Copy pathSBS.cpp
More file actions
135 lines (126 loc) · 5.08 KB
/
Copy pathSBS.cpp
File metadata and controls
135 lines (126 loc) · 5.08 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
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
#include "SBS.h"
SBS::SBS(uint8_t address, int sda, int scl) {
// Slave Function Address,Writable?, byte count
commands[0] = {"ManufacturerAccess", 0x00, true, 1, "word"};
commands[1] = {"RemainingCapacityAlarm", 0x01, true, 2, "mAh"};
commands[2] = {"RemainingTimeAlarm", 0x02, true, 2, "minutes"};
commands[3] = {"BatteryMode", 0x03, true, 2, "bit flags"};
commands[4] = {"AtRate", 0x04, true, 2, "mA"};
commands[5] = {"AtRateTimeToFull", 0x05, false, 2, "minutes"};
commands[6] = {"AtRateTimeToEmpty", 0x06, false, 2, "minutes"};
commands[7] = {"AtRateOK", 0x07, false, 1, "Boolean"};
commands[8] = {"Temperature", 0x08, false, 2, "0.1K"};
commands[9] = {"Voltage", 0x09, false, 2, "mV"};
commands[10] = {"Current", 0x0a, false, 2, "mA"};
commands[11] = {"AverageCurrent", 0x0b, false, 2, "mA"};
commands[12] = {"MaxError", 0x0c, false, 2, "percent"};
commands[13] = {"RelativeStateOfCharge", 0x0d, false, 2, "percent"};
commands[14] = {"AbsoluteStateOfCharge", 0x0e, false, 2, "percent"};
commands[15] = {"RemainingCapacity", 0x0f, false, 2, "mAh"};
commands[16] = {"FullChargeCapacity", 0x10, false, 2, "mAh"};
commands[17] = {"RunTimeToEmpty", 0x11, false, 2, "minutes"};
commands[18] = {"AverageTimeToEmpty", 0x12, false, 2, "minutes"};
commands[19] = {"AverageTimeToFull", 0x13, false, 2, "minutes"};
commands[20] = {"ChargingCurrent", 0x14, false, 2, "mA"};
commands[21] = {"ChargingVoltage", 0x15, false, 2, "mV"};
commands[22] = {"BatteryStatus", 0x16, false, 2, "bit flags"};
commands[23] = {"CycleCount", 0x17, false, 2, "count"};
commands[24] = {"DesignCapacity", 0x18, false, 2, "mAh"};
commands[25] = {"DesignVoltage", 0x19, false, 2, "mV"};
commands[26] = {"SpecificationInfo", 0x1a, false, 2, "unsigned int"};
commands[27] = {"ManufactureDate", 0x1b, false, 2, "unsigned int"};
commands[28] = {"SerialNumber", 0x1c, false, 2, "number"};
//reserved 0x1d - 0x1f
commands[29] = {"ManufacturerName", 0x20, false, 0, "string"};
commands[30] = {"DeviceName", 0x21, false, 1, "string"};
commands[31] = {"DeviceChemistry", 0x22, false, 1, "string"};
commands[32] = {"ManufacturerData", 0x23, false, 1, "data"};
commands[33] = {"OptionalMfgFunction5", 0x2f, false, 1, "data"};
commands[34] = {"VoltageCellFour", 0x3c, false, 1, "mV"};
commands[35] = {"VoltageCellThree", 0x3d, false, 1, "mV"};
commands[36] = {"VoltageCellTwo", 0x3e, false, 1, "mV"};
commands[37] = {"VoltageCellOne", 0x3f, false, 1, "mV"};
smbusAddress = address;
Wire.begin(sda, scl);
Wire.setClockStretchLimit(35000);
Wire.setClock(40000);
}
byte SBS::sbsReadByte(uint8_t command) {
byte b = 0;
Wire.beginTransmission(smbusAddress);
Wire.write(command);
if(Wire.endTransmission(false) == 0) {
Wire.requestFrom((int)smbusAddress, 1, (int)true);
if(Wire.available()) {
b = Wire.read();
}
}
return b;
}
uint16_t SBS::sbsReadWord(uint8_t command) {
uint16_t b1 = 0, b2 = 0;
Wire.beginTransmission(smbusAddress);
Wire.write(command);
if(Wire.endTransmission(false) == 0) {
Wire.requestFrom((int)smbusAddress, 2, (int)true);
if(Wire.available() >= 2) {
b1 = Wire.read();
b2 = Wire.read();
return b1 | (b2 << 8);
}
}
return 0;
}
int16_t SBS::sbsReadInt(uint8_t command) {
return (int16_t)sbsReadWord(command);
}
void SBS::sbsReadString(char str[], uint8_t command) {
str[0] = 0;
int n = 0;
Wire.beginTransmission(smbusAddress);
Wire.write(command);
if(Wire.endTransmission(false) == 0) {
Wire.requestFrom((int)smbusAddress, 33, (int)true); // request max possible size (32 + 1 length byte)
if(Wire.available()) {
n = Wire.read(); // SMBus string read sends length as first byte
if(n > 32) n = 32; // prevent buffer overflow
for(int i = 0; i < n; i++) {
if(Wire.available()) {
str[i] = (char)Wire.read();
} else {
n = i; // stop if no more data
break;
}
}
str[n] = 0; // null terminate
}
}
}
int SBS::sbsReadBlock(uint8_t command, uint8_t* data, uint8_t max_len) {
int n = 0;
Wire.beginTransmission(smbusAddress);
Wire.write(command);
if(Wire.endTransmission(false) == 0) {
Wire.requestFrom((int)smbusAddress, max_len + 1, (int)true);
if(Wire.available()) {
n = Wire.read(); // length byte
if(n > max_len) n = max_len;
for(int i = 0; i < n; i++) {
if(Wire.available()) {
data[i] = Wire.read();
} else {
n = i;
break;
}
}
}
}
return n;
}
void SBS::sbsWriteWord(uint8_t command, uint16_t data) {
Wire.beginTransmission(smbusAddress);
Wire.write(command);
Wire.write(data & 0xFF); // Lower byte first for SBS Word Protocol
Wire.write((data >> 8) & 0xFF); // Upper byte second
Wire.endTransmission();
}