-
Notifications
You must be signed in to change notification settings - Fork 0
/
I2Cmanager.cpp
103 lines (93 loc) · 3.27 KB
/
I2Cmanager.cpp
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
#include "I2Cmanager.h"
#include "console.h"
I2C_manager::I2C_manager(int _port, int _numDevices, int _baseAddress) {
console->section("I2Cmanager",CORE_PREFIX);
port = _port ;
numDevices = _numDevices ;
baseAddress = _baseAddress;
switch (port) {
case 0:
Wire.begin();
console->println("started wire");
wire = &Wire;
break;
case 1:
Wire1.begin();
console->println("started wire1");
wire = &Wire1;
break;
case 2:
Wire2.begin();
console->println("started wire2");
wire = &Wire2;
break;
}
for (int i=0; i< numDevices; i++) {
devices.push_back((signed)(baseAddress+i));
}
console->sectionEnd("I2Cmanager initialised",CORE_PREFIX);
}
void I2C_manager::write(std::vector<int> bytes, int device) {
console->println("start I2C write");
console->println(device);
wire->beginTransmission((signed)devices[device]);
for (int deviceNo : devices) {
console->println(deviceNo);
}
console->println(devices[0]);
for (int byte : bytes) {
wire->write(byte);
console->printByte(byte);
}
wire->endTransmission();
console->println("finish I2C write");
}
int I2C_manager::read(int device) {
if (wire->available() > 0) {
return wire->read();
} else {
return 0;
}
}
portExpander::portExpander(int _port, int _numDevices) : expanders(_port,_numDevices,baseAddress) {
console->section("portExpander",CORE_PREFIX);
port = _port;
numDevices = _numDevices;
for (int i = 0; i < numDevices; i++) {
expanders.write({0x00,0x00},i); // A register set to output
expanders.write({0x01,0x00},i); // B register set to output
console->println("I2C device configured");
regA.push_back(0); // sets stored pin states to 0
regB.push_back(0);
//console->println("reg modified");
}
//instantiateI2C(); // instantiates the "expanders" object
console->sectionEnd("portExpander initialised",CORE_PREFIX);
}
/*
void portExpander::instantiateI2C()
: expanders(port,numDevices,baseAddress)
{}
*/
void portExpander::write(int data, int device) {
expanders.write({data},device);
}
//writes to a pin on a specific expander
void portExpander::writeToPin(int pin, int state, int expander) {
int reg;
if (pin < 8) { // if in register A
reg = 0x12; //set register address
regA[expander] ^= (-state ^ regA[expander]) & (1UL << pin); // updates byte containing states using individual bit changing method from https://stackoverflow.com/questions/47981/how-do-you-set-clear-and-toggle-a-single-bit
expanders.write({reg,regA[expander]},expander); // writes byte to register
} else {
reg = 0x13;
regB[expander] ^= (-state ^ regA[expander]) & (1UL << (pin-8));
expanders.write({reg,regB[expander]},expander);
}
}
// writes to expanders as if they are combined together
void portExpander::writeToPinCombined(int pin, int state) {
int device = pin/16; // finds device number
int devicePin = (pin-device*16); // finds the pin on the specific expander
writeToPin(devicePin, state, device); // writes to the relevant pin
}