STAR
Cal STAR — firmware, DAQ server, and engine design
Loading...
Searching...
No Matches
self_test_devices.c
Go to the documentation of this file.
1#include "self_test_devices.h"
2
3#include <string.h>
4
5static self_test_reply_t reply(self_test_result_t result, int32_t diagnostic) {
6 self_test_reply_t value = {result, diagnostic};
7 return value;
8}
9
10/* MS56xx AN520: consume high byte first and clear the entire CRC byte. */
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];
15 if (byte / 2 == 7) {
16 word &= 0xFF00U;
17 }
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));
22 }
23 }
24 return (uint8_t)((remainder >> 12) & 0xFU);
25}
26
27self_test_reply_t self_test_devices_probe(void* context, uint16_t device_id,
28 uint8_t attempt, uint32_t now_ms,
29 uint32_t budget_ms) {
31 uint8_t mode = 0, count = 1, expected = 0, response_index = 1;
32 uint32_t max_hz = 10000000U;
33 (void)attempt;
34 (void)now_ms;
35 if (device_id > SELF_TEST_DEVICE_RADIO) {
37 }
38 if (!devices ||
39 !(devices->configured_mask & SELF_TEST_DEVICE_ENABLED(device_id))) {
41 }
42 if (!devices->exchange) {
44 }
45 if (!budget_ms) {
46 return reply(SELF_TEST_TIMEOUT, 0);
47 }
48 memset(devices->frames, 0, sizeof(devices->frames));
49 self_test_spi_frame_t* frames = devices->frames;
50 switch (device_id) {
53 mode = 3;
54 frames[0].tx[0] = 0x8F;
55 frames[0].length = 2;
56 expected = device_id == SELF_TEST_DEVICE_IMU ? 0x6B : 0x32;
57 break;
59 mode = 3; /* Shared SPI3 with the IMU and high-g accelerometer. */
60 max_hz = 20000000U;
61 count = 8;
62 for (uint8_t i = 0; i < count; ++i) {
63 frames[i].tx[0] = (uint8_t)(0xA0U + 2U * i);
64 frames[i].length = 3;
65 }
66 break;
68 max_hz = 80000000U;
69 frames[0].tx[1] = 0x39;
70 frames[0].length = 4;
71 response_index = 3;
72 expected = 0x04;
73 break;
75 max_hz = 16000000U;
76 count = 2;
77 frames[0].tx[0] = 0xC0; /* GetStatus */
78 frames[0].length = 2;
79 frames[1].tx[0] = 0x17; /* GetDeviceErrors; do not clear errors. */
80 frames[1].length = 4;
81 break;
82 default:
84 }
85 self_test_reply_t transport = devices->exchange(
86 devices->io_context, device_id, mode, max_hz, frames, count, budget_ms);
87 if (transport.result != SELF_TEST_PASS) {
88 return transport;
89 }
90 if (device_id == SELF_TEST_DEVICE_BAROMETER) {
91 uint16_t prom[8];
92 bool zero = true, ones = true;
93 for (uint8_t i = 0; i < 8; ++i) {
94 prom[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;
98 }
99 if (zero || ones) {
101 }
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);
107 }
108 } else if (device_id == SELF_TEST_DEVICE_RADIO) {
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)) {
115 return reply(SELF_TEST_FAIL,
117 }
118 }
119 uint16_t errors =
120 (uint16_t)(((uint16_t)frames[1].rx[2] << 8) | frames[1].rx[3]);
121 if (errors) {
123 }
124 } else if (frames[0].rx[response_index] != expected) {
125 return reply(SELF_TEST_FAIL,
126 SELF_TEST_DIAG_IDENTITY | frames[0].rx[response_index]);
127 }
128 return reply(SELF_TEST_PASS, 0);
129}
uint8_t byte
Minimal Arduino.h stub for native unit tests.
Definition Arduino.h:16
static board_spi_device_t devices[BOARD_SPI_COUNT]
Definition board_devbus.c:7
static volatile uint32_t errors
Definition board_uart9.c:13
size_type count(const key_type &key) const
Definition json.hpp:19264
json_pointer result
Definition json.hpp:14064
static self_test_reply_t reply(self_test_result_t result, int32_t diagnostic)
static uint8_t prom_crc(const uint16_t prom[8])
self_test_reply_t self_test_devices_probe(void *context, uint16_t device_id, uint8_t attempt, uint32_t now_ms, uint32_t budget_ms)
#define SELF_TEST_DIAG_IDENTITY
@ SELF_TEST_DEVICE_ETHERNET
@ SELF_TEST_DEVICE_IMU
@ SELF_TEST_DEVICE_HIGH_G
@ SELF_TEST_DEVICE_RADIO
@ SELF_TEST_DEVICE_BAROMETER
#define SELF_TEST_DIAG_PROM_CRC
#define SELF_TEST_DIAG_RADIO_ERRORS
#define SELF_TEST_DIAG_RADIO_STATUS
#define SELF_TEST_DIAG_BLANK_PROM
#define SELF_TEST_DEVICE_ENABLED(id)
self_test_result_t
@ SELF_TEST_FAIL
@ SELF_TEST_NOT_CONFIGURED
@ SELF_TEST_NOT_IMPLEMENTED
@ SELF_TEST_PASS
@ SELF_TEST_TIMEOUT
self_test_result_t result