-
Notifications
You must be signed in to change notification settings - Fork 0
/
ThreeWire.h
99 lines (77 loc) · 2.62 KB
/
ThreeWire.h
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
#pragma once
//ThreeWire command Read/Write flag
const uint8_t THREEWIRE_READFLAG = 0x01;
class ThreeWire
{
public:
ThreeWire(uint8_t ioPin, uint8_t clkPin, uint8_t cePin) :
_ioPin(ioPin),
_clkPin(clkPin),
_cePin(cePin)
{
}
void begin() {
resetPins();
}
void end() {
resetPins();
}
void beginTransmission(uint8_t command) {
digitalWrite(_cePin, LOW); // default, not enabled
pinMode(_cePin, OUTPUT);
digitalWrite(_clkPin, LOW); // default, clock low
pinMode(_clkPin, OUTPUT);
pinMode(_ioPin, OUTPUT);
digitalWrite(_cePin, HIGH); // start the session
delayMicroseconds(4); // tCC = 4us
write(command, (command & THREEWIRE_READFLAG) == THREEWIRE_READFLAG);
}
void endTransmission() {
digitalWrite(_cePin, LOW);
delayMicroseconds(4); // tCWH = 4us
}
void write(uint8_t value, bool isDataRequestCommand = false) {
for (uint8_t bit = 0; bit < 8; bit++) {
digitalWrite(_ioPin, value & 0x01);
delayMicroseconds(1); // tDC = 200ns
// clock up, data is read by DS1302
digitalWrite(_clkPin, HIGH);
delayMicroseconds(1); // tCH = 1000ns, tCDH = 800ns
// for the last bit before a read
// Set IO line for input before the clock down
if (bit == 7 && isDataRequestCommand) {
pinMode(_ioPin, INPUT);
}
digitalWrite(_clkPin, LOW);
delayMicroseconds(1); // tCL=1000ns, tCDD=800ns
value >>= 1;
}
}
uint8_t read() {
uint8_t value = 0;
for (uint8_t bit = 0; bit < 8; bit++) {
// first bit is present on io pin, so only clock the other
// bits
value |= (digitalRead(_ioPin) << bit);
// Clock up, prepare for next
digitalWrite(_clkPin, HIGH);
delayMicroseconds(1);
// Clock down, value is ready after some time.
digitalWrite(_clkPin, LOW);
delayMicroseconds(1); // tCL=1000ns, tCDD=800ns
}
return value;
}
private:
const uint8_t _ioPin;
const uint8_t _clkPin;
const uint8_t _cePin;
void resetPins() {
// just making sure they are in a default low power use state
// as required state is set when transmissions are started
// three wire devices have internal pull downs so they will be low
pinMode(_clkPin, INPUT);
pinMode(_ioPin, INPUT);
pinMode(_cePin, INPUT);
}
};