forked from OpenSprinkler/OpenSprinkler-Firmware
-
Notifications
You must be signed in to change notification settings - Fork 6
/
hunter.cpp
221 lines (194 loc) · 5.65 KB
/
hunter.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
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
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
#include "hunter.h"
/////////////////////////////////////////////////////////////////////////////
// Function: HunterBitfield
// Description: Set a value with an arbitrary bit width to a bit position
// within a blob
// Arguments: bits - blob to write the value to
// pos - bit position within the blob
// val - value to write
// len - len in bits of the value
/////////////////////////////////////////////////////////////////////////////
void HunterBitfield(vector <byte>& bits, byte pos, byte val, byte len)
{
while (len > 0)
{
if (val & 0x1)
{
bits[pos / 8] = bits[pos / 8] | 0x80 >> (pos % 8);
}
else
{
bits[pos / 8] = bits[pos / 8] & ~(0x80 >> (pos % 8));
}
len--;
val = val >> 1;
pos++;
}
}
/////////////////////////////////////////////////////////////////////////////
// Function: HunterLow
// Description: writes a low bit on the bus
// Arguments: none
/////////////////////////////////////////////////////////////////////////////
void HunterLow(void)
{
digitalWrite(HUNTER_PIN, HUNTER_ONE);
delayMicroseconds(SHORT_INTERVAL); //microseconds
digitalWrite(HUNTER_PIN, HUNTER_ZERO);
delayMicroseconds(LONG_INTERVAL); //microseconds
}
/////////////////////////////////////////////////////////////////////////////
// Function: HunterHigh
// Description: writes a high bit on the bus
// Arguments: none
/////////////////////////////////////////////////////////////////////////////
void HunterHigh(void)
{
digitalWrite(HUNTER_PIN, HUNTER_ONE);
delayMicroseconds(LONG_INTERVAL); //microseconds
digitalWrite(HUNTER_PIN, HUNTER_ZERO);
delayMicroseconds(SHORT_INTERVAL); //microseconds
}
/////////////////////////////////////////////////////////////////////////////
// Function: HunterWrite
// Description: Write the bit sequence out of the bus
// Arguments: buffer - blob containing the bits to transmit
// extrabit - if true, then write an extra 1 bit
/////////////////////////////////////////////////////////////////////////////
void HunterWrite(vector<byte> buffer, bool extrabit)
{
// Bus start sequence
//_flexwire.invert(false);
//delay(325);
//_flexwire.invert(true);
//delay(65);
// Resetimpulse
digitalWrite(HUNTER_PIN, HUNTER_ONE);
delay(325); //milliseconds
digitalWrite(HUNTER_PIN, HUNTER_ZERO);
delay(65); //milliseconds
// Write the start pulse
//_flexwire.invert(false);
//udelay(900);
//_flexwire.invert(true);
// Startimpulse
digitalWrite(HUNTER_PIN, HUNTER_ONE);
delayMicroseconds(START_INTERVAL); //microseconds
digitalWrite(HUNTER_PIN, HUNTER_ZERO);
delayMicroseconds(SHORT_INTERVAL); //microseconds
// Write the bits out
//_flexwire.write(buffer);
for (auto &sendByte : buffer)
{
for (byte inner = 0; inner < 8; inner++)
{
// Send high order bits first
if (sendByte & 0x80)
{
HunterHigh();
}
else
{
HunterLow();
}
sendByte <<= 1;
}
}
// Include an extra 1 bit
if (extrabit)
{
//_flexwire.writebit(true);
HunterHigh();
}
// Write the stop pulse
//_flexwire.writebit(false);
HunterLow();
}
/////////////////////////////////////////////////////////////////////////////
// Function: start
// Description: Start a zone
// Arguments: zone - zone number (1-48)
// time - time in minutes (0-240)
/////////////////////////////////////////////////////////////////////////////
void HunterStart(byte zone, byte time)
{
DEBUG_PRINT("X-Core Hunter start zone ");
DEBUG_PRINT(zone);
DEBUG_PRINT(" for ");
DEBUG_PRINT(time);
DEBUG_PRINTLN(" min");
// Start out with a base frame
vector<byte> buffer = {0xff,0x00,0x00,0x00,0x10,0x00,0x00,0x04,0x00,0x00,0x01,0x00,0x01,0xb8,0x3f};
if (zone < 1 || zone > 48)
{
DEBUG_PRINTLN("invalid zone");
return;
}
if (time < 0 || time > 240)
{
DEBUG_PRINTLN("invalid time");
return;
}
// The bus protocol is a little bizzare, not sure why
// Bits 9:10 are 0x1 for zones > 12 and 0x2 otherwise
if (zone > 12)
{
HunterBitfield(buffer, 9, 0x1, 2);
}
else
{
HunterBitfield(buffer, 9, 0x2, 2);
}
// Zone + 0x17 is at bits 23:29 and 36:42
HunterBitfield(buffer, 23, zone + 0x17, 7);
HunterBitfield(buffer, 36, zone + 0x17, 7);
// Zone + 0x23 is at bits 49:55 and 62:68
HunterBitfield(buffer, 49, zone + 0x23, 7);
HunterBitfield(buffer, 62, zone + 0x23, 7);
// Zone + 0x2f is at bits 75:81 and 88:94
HunterBitfield(buffer, 75, zone + 0x2f, 7);
HunterBitfield(buffer, 88, zone + 0x2f, 7);
// Time is encoded in three places and broken up by nibble
// Low nibble: bits 31:34, 57:60, and 83:86
// High nibble: bits 44:47, 70:73, and 96:99
HunterBitfield(buffer, 31, time, 4);
HunterBitfield(buffer, 44, time >> 4, 4);
HunterBitfield(buffer, 57, time, 4);
HunterBitfield(buffer, 70, time >> 4, 4);
HunterBitfield(buffer, 83, time, 4);
HunterBitfield(buffer, 96, time >> 4, 4);
// Bottom nibble of zone - 1 is at bits 109:112
HunterBitfield(buffer, 109, zone - 1, 4);
// Write the bits out of the bus
HunterWrite(buffer, true);
}
/////////////////////////////////////////////////////////////////////////////
// Function: stop
// Description: Stop all zones
// Arguments: None
/////////////////////////////////////////////////////////////////////////////
void HunterStop(byte zone)
{
DEBUG_PRINT("X-Core Hunter stop zone ");
DEBUG_PRINT(zone);
DEBUG_PRINT(" = ");
HunterStart(zone, 0);
}
/////////////////////////////////////////////////////////////////////////////
// Function: program
// Description: Run a program
// Arguments: num - program number (1-4)
/////////////////////////////////////////////////////////////////////////////
void HunterProgram(byte num)
{
// Start with a basic program frame
vector<byte> buffer = {0xff, 0x40, 0x03, 0x96, 0x09 ,0xbd ,0x7f};
if (num < 1 || num > 4)
{
DEBUG_PRINTLN("invalid program");
return;
}
// Program number - 1 is at bits 31:32
HunterBitfield(buffer, 31, num - 1, 2);
HunterWrite(buffer, false);
}