Skip to content

Commit 901a83a

Browse files
committed
Add Zigbee chip delect (beta)
1 parent abcccb5 commit 901a83a

11 files changed

+568
-50
lines changed

bin/UZG-01.bin

2.88 KB
Binary file not shown.
Binary file not shown.

src/CC26XX_detect.cpp

+357
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,357 @@
1+
#include <Arduino.h>
2+
#include "CC26XX_detect.h"
3+
4+
CommandInterface::CommandInterface(Stream &serial) : _stream(serial) {}
5+
6+
7+
bool CommandInterface::_sendSynch()
8+
{
9+
const u_int32_t cmd = 0x55;
10+
11+
_stream.flush();
12+
13+
_stream.write(cmd); // # send U
14+
_stream.write(cmd); // # send U
15+
return _wait_for_ack(2);
16+
}
17+
18+
bool CommandInterface::_wait_for_ack(unsigned long timeout = 1)
19+
{
20+
unsigned long startMillis = millis();
21+
while (millis() - startMillis < timeout * 1000)
22+
{
23+
if (_stream.available() >= 1)
24+
{
25+
uint8_t received = _stream.read();
26+
if (received == ACK_BYTE)
27+
{
28+
// Serial.println("ACK received");
29+
return true;
30+
}
31+
else if (received == NACK_BYTE)
32+
{
33+
// Serial.println("NACK received");
34+
return false;
35+
}
36+
}
37+
}
38+
Serial.println("Timeout waiting for ACK/NACK");
39+
return false;
40+
}
41+
42+
uint32_t CommandInterface::_cmdGetChipId()
43+
{
44+
const u_int32_t cmd = 0x28;
45+
const u_int32_t lng = 3;
46+
47+
_stream.write(lng); // # send size
48+
_stream.write(cmd); // # send checksum
49+
_stream.write(cmd); // # send data
50+
if (_wait_for_ack())
51+
{
52+
// 4 byte answ, the 2 LSB hold chip ID
53+
byte *version = _receivePacket();
54+
// Serial.println("size " + String(sizeof(version)));
55+
if (_checkLastCmd())
56+
{
57+
58+
uint32_t value = 0;
59+
value |= uint32_t(version[3]) << 0; // Least significant byte
60+
value |= uint32_t(version[2]) << 8;
61+
value |= uint32_t(version[1]) << 16;
62+
value |= uint32_t(version[0]) << 24; // Most significant byte
63+
// Serial.print("ChipId ");
64+
// Serial.println(value, HEX);
65+
66+
if (sizeof(version) != 4)
67+
{
68+
Serial.println("Unreasonable chip. Looks upper"); // repr(version) ?
69+
return uint32_t(0);
70+
}
71+
72+
uint32_t chip_id = (version[0] << 8) | (version[1]);
73+
74+
return chip_id;
75+
}
76+
}
77+
return uint32_t(0);
78+
}
79+
80+
byte *CommandInterface::_cmdGetStatus()
81+
{
82+
const u_int32_t cmd = 0x23;
83+
const u_int32_t lng = 3;
84+
85+
_stream.write(lng); // # send size
86+
_stream.write(cmd); // # send checksum
87+
_stream.write(cmd); // # send data
88+
89+
// mdebug(10, "*** GetStatus command (0x23)")
90+
if (_wait_for_ack())
91+
{
92+
byte *stat = _receivePacket();
93+
return stat;
94+
}
95+
Serial.print("Error _cmdGetStatus");
96+
return nullptr;
97+
}
98+
99+
bool CommandInterface::_checkLastCmd()
100+
{
101+
102+
byte *stat = _cmdGetStatus();
103+
if (stat == nullptr)
104+
{
105+
Serial.println("No response from target on status request.");
106+
Serial.println("(Did you disable the bootloader?)");
107+
return 0;
108+
}
109+
else
110+
{
111+
if (stat[0] == COMMAND_RET_SUCCESS)
112+
{
113+
// Serial.println("Command Successful");
114+
return 1;
115+
}
116+
else
117+
{
118+
const char *stat_str = _getStatusString(stat[0]);
119+
if (stat_str == "Unknown")
120+
{
121+
Serial.println("Warning: unrecognized status returned 0x" + String(stat[0]));
122+
}
123+
else
124+
{
125+
Serial.println("Target returned: 0x" + String(stat[0]) + " " + String(stat_str));
126+
}
127+
return 0;
128+
}
129+
}
130+
return 0;
131+
}
132+
133+
void CommandInterface::_sendAck()
134+
{
135+
const u_int32_t cmd1 = 0x00;
136+
const u_int32_t cmd2 = 0xCC;
137+
_stream.write(cmd1);
138+
_stream.write(cmd2);
139+
}
140+
141+
void CommandInterface::_sendNAck()
142+
{
143+
const u_int32_t cmd1 = 0x00;
144+
const u_int32_t cmd2 = 0x33;
145+
_stream.write(cmd1);
146+
_stream.write(cmd2);
147+
}
148+
149+
byte *CommandInterface::_cmdMemRead(uint32_t address)
150+
{
151+
const u_int32_t cmd = 0x2A;
152+
const u_int32_t lng = 9;
153+
154+
byte addrBytes[4];
155+
_encodeAddr(address, addrBytes);
156+
157+
_stream.write(lng); // # send length
158+
_stream.write(_calcChecks(cmd, address, 2)); // # send checksum
159+
_stream.write(cmd); // # send cmd
160+
_stream.write(addrBytes[0]); // # send addr
161+
_stream.write(addrBytes[1]); // # send addr
162+
_stream.write(addrBytes[2]); // # send addr
163+
_stream.write(addrBytes[3]); // # send addr
164+
_stream.write(1); // # send width, 4 bytes
165+
_stream.write(1); // # send number of reads
166+
167+
// Serial.println("*** Mem Read (0x2A)");
168+
if (_wait_for_ack())
169+
{
170+
byte *data = _receivePacket();
171+
if (_checkLastCmd())
172+
{
173+
return data;
174+
}
175+
}
176+
return 0;
177+
}
178+
179+
byte *CommandInterface::_receivePacket()
180+
{
181+
byte got[2];
182+
// Read the initial 2 bytes which contain size and checksum
183+
// The _read function should be defined elsewhere to read bytes from a communication interface.
184+
_stream.readBytes(got, 2);
185+
186+
byte size = got[0]; // rcv size
187+
byte chks = got[1]; // rcv checksum
188+
byte *data = new byte[size - 2]; // Allocate buffer for the data
189+
190+
// Now read the rest of the packet
191+
if (!_stream.readBytes(data, size - 2))
192+
{
193+
// Handle read error
194+
delete[] data; // Remember to free the memory if an error occurs
195+
return nullptr;
196+
}
197+
198+
// Debugging output, might use Serial.print in Arduino
199+
// Serial.print(F("*** received "));
200+
// Serial.print(size, HEX);
201+
// Serial.println(F(" bytes"));
202+
203+
// Calculate checksum
204+
byte calculatedChks = 0;
205+
for (int i = 0; i < size - 2; i++)
206+
{
207+
calculatedChks += data[i];
208+
}
209+
calculatedChks &= 0xFF;
210+
211+
// Check the checksum
212+
if (chks == calculatedChks)
213+
{
214+
_sendAck(); // This function needs to be implemented
215+
return data;
216+
}
217+
else
218+
{
219+
_sendNAck(); // This function needs to be implemented
220+
delete[] data; // Free the memory
221+
// Handle checksum error
222+
// You could set an error flag or return a null pointer.
223+
return nullptr;
224+
}
225+
}
226+
227+
void CommandInterface::_encodeAddr(unsigned long addr, byte encodedAddr[4])
228+
{
229+
encodedAddr[3] = (byte)((addr >> 0) & 0xFF);
230+
encodedAddr[2] = (byte)((addr >> 8) & 0xFF);
231+
encodedAddr[1] = (byte)((addr >> 16) & 0xFF);
232+
encodedAddr[0] = (byte)((addr >> 24) & 0xFF);
233+
}
234+
235+
// Функция для декодирования адреса из массива байтов
236+
unsigned long CommandInterface::_decodeAddr(byte byte0, byte byte1, byte byte2, byte byte3)
237+
{
238+
return ((unsigned long)byte3 << 24) | ((unsigned long)byte2 << 16) | ((unsigned long)byte1 << 8) | byte0;
239+
}
240+
241+
// Функция для расчета контрольной суммы
242+
byte CommandInterface::_calcChecks(byte cmd, unsigned long addr, unsigned long size)
243+
{
244+
byte addrBytes[4];
245+
byte sizeBytes[4];
246+
_encodeAddr(addr, addrBytes);
247+
_encodeAddr(size, sizeBytes);
248+
249+
unsigned long sum = 0;
250+
for (int i = 0; i < 4; i++)
251+
{
252+
sum += addrBytes[i];
253+
sum += sizeBytes[i];
254+
}
255+
sum += cmd;
256+
257+
return (byte)(sum & 0xFF);
258+
}
259+
260+
CC26XX_detect::CC26XX_detect(Stream &serial) : CommandInterface(serial) {}
261+
262+
bool CC26XX_detect::begin(int CC_RST_PIN, int CC_BSL_PIN, int BSL_MODE)
263+
{
264+
_CC_RST_PIN = CC_RST_PIN;
265+
_CC_BSL_PIN = CC_BSL_PIN;
266+
_BSL_MODE = BSL_MODE;
267+
268+
pinMode(_CC_RST_PIN, OUTPUT);
269+
pinMode(_CC_BSL_PIN, OUTPUT);
270+
271+
_enterBSLMode();
272+
if (!_sendSynch())
273+
{
274+
// Serial.print("begin NOT ok");
275+
return false;
276+
}
277+
278+
279+
return true;
280+
}
281+
282+
void CC26XX_detect::_enterBSLMode()
283+
{
284+
if (_BSL_MODE == 0)
285+
{
286+
digitalWrite(_CC_RST_PIN, LOW);
287+
digitalWrite(_CC_BSL_PIN, LOW);
288+
delay(250);
289+
digitalWrite(_CC_RST_PIN, HIGH);
290+
delay(2000);
291+
digitalWrite(_CC_BSL_PIN, HIGH);
292+
delay(1000);
293+
//Serial.println("enter bsl mode...");
294+
}
295+
296+
// Другие режимы BSL_MODE могут быть добавлены здесь в будущем
297+
}
298+
299+
String CC26XX_detect::detectChipInfo()
300+
{
301+
uint32_t chip_id = _cmdGetChipId();
302+
303+
// Serial.println(chip_id, HEX);
304+
// Serial.println(chip_id_2, HEX);
305+
// String chip_id_str = _getChipIdString(chip_id);
306+
307+
// Serial.println(chip_id_str);
308+
309+
// if (chip_id == 0xF000)
310+
//{
311+
// Serial.println("2652");
312+
// String chip_id_str_2 = _getChipIdString2652(chip_id_2);
313+
// Serial.println(chip_id_str_2);
314+
315+
byte *device_id = _cmdMemRead(ICEPICK_DEVICE_ID);
316+
// Serial.println(sizeof(device_id));
317+
uint32_t wafer_id = (((device_id[3] & 0x0F) << 16) +
318+
(device_id[2] << 8) +
319+
(device_id[1] & 0xF0)) >>
320+
4;
321+
uint32_t pg_rev = (device_id[3] & 0xF0) >> 4;
322+
323+
// We can now detect the exact device
324+
325+
// Serial.print("wafer_id: ");
326+
// Serial.println(wafer_id, HEX);
327+
// Serial.print("pg_rev: ");
328+
// Serial.println(pg_rev, HEX);
329+
330+
byte *user_id = _cmdMemRead(FCFG_USER_ID);
331+
332+
// Serial.println("Packege: " + _getPackage(user_id[2]));
333+
334+
byte protocols = user_id[1] >> 4;
335+
// Serial.print("protocols: ");
336+
// Serial.println(protocols, HEX);
337+
338+
String chip_str = "";
339+
if (protocols & PROTO_MASK_IEEE == PROTO_MASK_IEEE)
340+
{
341+
if (chip_id == 0x1202 && wafer_id == 0xBB77 && pg_rev == 0x1)
342+
{
343+
chip_str = "CC2652P7";
344+
}
345+
else if (chip_id == 0x3202 && wafer_id == 0xBB41 && pg_rev == 0x3)
346+
{
347+
chip_str = "CC2652P2";
348+
}
349+
else
350+
{
351+
chip_str = "Unknown ( " + String(chip_id, HEX) + " " + String(wafer_id, HEX) + " " + String(pg_rev, HEX) + " )";
352+
}
353+
// Serial.println(chip_str);
354+
}
355+
return chip_str;
356+
}
357+

0 commit comments

Comments
 (0)