-
Notifications
You must be signed in to change notification settings - Fork 3
Expand file tree
/
Copy pathsy7t609-uart-protocol.cpp
More file actions
195 lines (145 loc) · 4.45 KB
/
Copy pathsy7t609-uart-protocol.cpp
File metadata and controls
195 lines (145 loc) · 4.45 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
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
#include "sy7t609-uart-protocol.h"
#include <Arduino.h>
#include "sy7t609.h"
#define SSI_HEADER (0xAA)
#define SSI_DEFAULT_FRAME_SIZE (3)
#define SSI_MAX_PAYLOAD_SIZE (7)
#define SSI_READ_PAYLOAD_SIZE (4)
#define SSI_REPLY_PAYLOAD_SIZE (3)
#define SSI_WRITE_PAYLOAD_SIZE (7)
#define CMD_CLEAR_ADDRESS (0xA0)
#define CMD_SELECT_REGISTER_ADDRESS (0xA3)
#define CMD_READ_REGITSTER_3BYTES (0xE3)
#define CMD_WRITE_RETISTER_3BYTES (0xD3)
enum sy7t609_reply_code {
REPLY_ACK_WITH_DATA = 0xAA,
REPLY_AUTO_REPORTING_HEADER = 0xAE,
REPLY_ACK_WITHOUT_DATA = 0xAD,
REPLY_NEGATIVE_ACK = 0xB0,
REPLY_COMMAND_NOT_IMPLEMENTED = 0xBC,
REPLY_CHECKSUM_FAILED = 0xBD,
REPLY_BUFFER_OVERFLOW = 0xBF
};
typedef struct ssi_command_packet_frame {
uint8_t header;
uint8_t byte_count;
uint8_t payload[SSI_MAX_PAYLOAD_SIZE];
uint8_t checksum;
} ssi_command_packet_frame_t;
typedef struct ssi_reply_packet_frame {
uint8_t reply_code;
uint8_t byte_count;
uint8_t payload[SSI_REPLY_PAYLOAD_SIZE];
uint8_t checksum;
} ssi_reply_packet_frame_t;
static uint8_t getChecksumForCommand(ssi_command_packet_frame_t packet);
static uint8_t getChecksumForCommand(ssi_command_packet_frame_t packet) {
uint8_t data;
uint8_t checksum = 0;
data = packet.header;
checksum += data;
data = packet.byte_count;
checksum += data;
uint8_t i;
uint8_t len = packet.byte_count - SSI_DEFAULT_FRAME_SIZE;
for (i = 0; i < len; i++) {
data = packet.payload[i];
checksum += data;
}
checksum = ~checksum + 1;
return checksum;
}
static uint8_t getChecksumForReply(ssi_reply_packet_frame_t packet) {
uint8_t data;
uint8_t checksum = 0;
data = packet.reply_code;
checksum += data;
data = packet.byte_count;
checksum += data;
uint8_t i;
uint8_t len = SSI_REPLY_PAYLOAD_SIZE;
for (i = 0; i < len; i++) {
data = packet.payload[i];
checksum += data;
}
checksum = ~checksum + 1;
return checksum;
}
bool readRegister(uint16_t addr, uint32_t* out_value) {
ssi_command_packet_frame_t packet;
packet.header = SSI_HEADER;
packet.byte_count = SSI_DEFAULT_FRAME_SIZE + SSI_READ_PAYLOAD_SIZE;
packet.payload[0] = CMD_SELECT_REGISTER_ADDRESS;
packet.payload[1] = addr & 0xFF;
packet.payload[2] = (addr >> 8) & 0xFF;
packet.payload[3] = CMD_READ_REGITSTER_3BYTES;
packet.checksum = getChecksumForCommand(packet);
Serial.flush();
Serial.write(packet.header);
Serial.write(packet.byte_count);
uint8_t i;
for (i = 0; i < SSI_READ_PAYLOAD_SIZE; i++) {
Serial.write(packet.payload[i]);
}
Serial.write(packet.checksum);
size_t reply_len = 0;
uint8_t reply_buffer[6];
reply_len = Serial.readBytes(reply_buffer, 6);
if (reply_len != 6) {
// Serial Error
reportErr("readRegister/Serial Error", 0);
return false;
}
if (reply_buffer[0] != REPLY_ACK_WITH_DATA) {
// SSI Error
reportErr("readRegister/SSI Error", reply_buffer[0]);
return false;
}
ssi_reply_packet_frame_t reply_packet;
memcpy(&reply_packet, reply_buffer, sizeof(reply_packet));
uint8_t checksum = getChecksumForReply(reply_packet);
if (reply_packet.checksum != checksum) {
// Checksum Error
reportErr("readRegister/Checksum Error", 0);
return false;
}
*out_value = ((uint32_t)reply_packet.payload[2] << 16) |
((uint32_t)reply_packet.payload[1] << 8) |
(uint32_t)reply_packet.payload[0];
return true;
}
bool writeRegister(uint16_t addr, uint32_t value) {
ssi_command_packet_frame_t packet;
packet.header = SSI_HEADER;
packet.byte_count = SSI_DEFAULT_FRAME_SIZE + SSI_WRITE_PAYLOAD_SIZE;
packet.payload[0] = CMD_SELECT_REGISTER_ADDRESS;
packet.payload[1] = addr & 0xFF;
packet.payload[2] = (addr >> 8) & 0xFF;
packet.payload[3] = CMD_WRITE_RETISTER_3BYTES;
packet.payload[4] = value & 0xFF;
packet.payload[5] = (value >> 8) & 0xFF;
packet.payload[6] = (value >> 16) & 0xFF;
packet.checksum = getChecksumForCommand(packet);
Serial.flush();
Serial.write(packet.header);
Serial.write(packet.byte_count);
uint8_t i;
for (i = 0; i < SSI_WRITE_PAYLOAD_SIZE; i++) {
Serial.write(packet.payload[i]);
}
Serial.write(packet.checksum);
size_t reply_len = 0;
uint8_t reply = 0;
reply_len = Serial.readBytes(&reply, 1);
if (reply_len != 1) {
// Serial Error
reportErr("writeRegister/Serial Error", 0);
return false;
}
if (reply != REPLY_ACK_WITHOUT_DATA) {
// SSI Error
reportErr("writeRegister/SSI Error", reply);
return false;
}
return true;
}