11static uint8_t
prom_crc(
const uint16_t prom[8]) {
12 uint16_t remainder = 0;
13 for (uint8_t
byte = 0;
byte < 16; ++
byte) {
14 uint16_t word = prom[
byte / 2];
18 remainder ^= (
byte & 1U) ? (word & 0xFFU) : (word >> 8);
19 for (uint8_t bit = 0; bit < 8; ++bit) {
20 remainder = (uint16_t)((remainder << 1) ^
21 ((remainder & 0x8000U) ? 0x3000U : 0U));
24 return (uint8_t)((remainder >> 12) & 0xFU);
28 uint8_t attempt, uint32_t now_ms,
31 uint8_t mode = 0,
count = 1, expected = 0, response_index = 1;
32 uint32_t max_hz = 10000000U;
54 frames[0].
tx[0] = 0x8F;
62 for (uint8_t i = 0; i <
count; ++i) {
63 frames[i].
tx[0] = (uint8_t)(0xA0U + 2U * i);
69 frames[0].
tx[1] = 0x39;
77 frames[0].
tx[0] = 0xC0;
79 frames[1].
tx[0] = 0x17;
86 devices->io_context, device_id, mode, max_hz, frames,
count, budget_ms);
92 bool zero =
true, ones =
true;
93 for (uint8_t i = 0; i < 8; ++i) {
95 (uint16_t)(((uint16_t)frames[i].rx[1] << 8) | frames[i].rx[2]);
96 zero = zero && prom[i] == 0;
97 ones = ones && prom[i] == 0xFFFFU;
102 uint8_t expected_crc = (uint8_t)(prom[7] & 0xFU);
103 uint8_t actual_crc =
prom_crc(prom);
104 if (expected_crc != actual_crc) {
106 (actual_crc << 4) | expected_crc);
109 for (uint8_t i = 0; i <
count; ++i) {
110 uint8_t status = frames[i].
rx[1];
111 uint8_t chip_mode = (status >> 4) & 7U;
112 uint8_t command_status = (status >> 1) & 7U;
113 if (chip_mode < 2 || chip_mode > 6 ||
114 (command_status >= 3 && command_status <= 5)) {
120 (uint16_t)(((uint16_t)frames[1].rx[2] << 8) | frames[1].rx[3]);
124 }
else if (frames[0].rx[response_index] != expected) {