STAR
Cal STAR — firmware, DAQ server, and engine design
Loading...
Searching...
No Matches
board_bringup.c
Go to the documentation of this file.
1#include "board_bringup.h"
2
3#include "board.h"
4#include "board_adc.h"
5#include "board_spi.h"
6#include "board_time.h"
7#include "board_uart9.h"
8#include "cmsis_os2.h"
9#include "gnss_frame.h"
10#include "main.h"
11#include "sd_spi.h"
12
14extern MMC_HandleTypeDef hmmc1;
15
16static void enable(board_bringup_t* b, uint16_t device_id) {
17 b->devices.configured_mask |= SELF_TEST_DEVICE_ENABLED(device_id);
18}
19
20/* Sleep until at least ms after reset (the HAL tick starts at reset). */
21static void wait_since_boot(uint32_t ms) {
22 uint32_t now = board_now_ms();
23 if (now < ms) {
24 osDelay(ms - now);
25 }
26}
27
28/*
29 * MS5611 reset (0x1E), required once after power-on so the calibration PROM
30 * is loaded (datasheet p.10, "Reset sequence"). Figure 5 holds CSB low through
31 * the 2.8 ms reload; osDelay(4) guarantees >= 3 ms on a 1 kHz tick.
32 */
33static bool ms5611_reset(void) {
34 static const uint8_t reset_cmd = 0x1E;
35 uint32_t deadline = board_now_ms() + 50U;
36 if (board_spi_lock(BOARD_SPI_BARO, deadline) != BOARD_SPI_OK) {
37 return false;
38 }
41 board_spi_shift(BOARD_SPI_BARO, &reset_cmd, NULL, 1, deadline);
42 if (st == BOARD_SPI_OK) {
43 osDelay(4);
44 }
47 return st == BOARD_SPI_OK;
48}
49
51 self_test_reply_t r = {result, diag};
52 return r;
53}
54
55static bool uart9_set_baud(uint32_t baud) {
56 if (huart9.Init.BaudRate == baud) {
57 return true;
58 }
59 return board_uart9_apply_baud(baud); /* keeps the FIFO on */
60}
61
62/*
63 * MAX-M10S on UART9 (PD14 RX <- GPS TXD, PD15 TX -> GPS RXD; schematic p.10).
64 * Out of the box it sends NMEA at 1 Hz, so listening is enough: PASS on one
65 * complete frame with a valid checksum (NMEA or UBX). No fix is required
66 * (#137). The startup baud is still open (38400 per the M10 defaults and the
67 * .ioc; 9600 per the R03 datasheet), so attempts alternate: 1 and 3 listen at
68 * 38400, 2 at 9600. Nothing is sent to the module.
69 */
71 uint32_t budget_ms) {
72 if (!b->gnss_powered) {
74 }
75 uint32_t baud = (attempt % 2U == 0U) ? 9600U : 38400U;
76 if (!uart9_set_baud(baud)) {
77 return reply(SELF_TEST_FAIL, 0);
78 }
79 uint32_t listen =
80 budget_ms < BOARD_GNSS_LISTEN_MS ? budget_ms : BOARD_GNSS_LISTEN_MS;
81 uint32_t deadline = board_now_ms() + listen;
86 while (!board_deadline_passed(deadline)) {
87 uint32_t left = board_ms_left(deadline);
88 uint8_t byte;
89 if (HAL_UART_Receive(&huart9, &byte, 1, left < 20U ? left : 20U) ==
90 HAL_OK) {
91 if (gnss_frame_feed(&parser, byte) != GNSS_FRAME_NONE) {
92 return reply(SELF_TEST_PASS, (int32_t)baud);
93 }
94 } else {
95 /* an overrun stalls reception until cleared */
98 }
99 }
100 bool antenna_short = HAL_GPIO_ReadPin(GPS_ANT_STATUS_GPIO_Port,
103 antenna_short ? BOARD_GNSS_DIAG_ANTENNA_SHORT : 0);
104}
105
106/*
107 * One SD command in SPI mode, CS low for the whole exchange: the 6-byte
108 * frame, up to 8 bytes of 0xFF until R1 (bit 7 clear) appears, then
109 * extra_len more bytes (R7/OCR). CS high and 8 more clocks afterwards.
110 * Caller holds the SPI4 lock.
111 */
112static board_spi_status_t sd_command(uint8_t index, uint32_t arg, uint8_t* r1,
113 uint8_t* extra, uint8_t extra_len,
114 uint32_t deadline) {
115 uint8_t frame[6];
116 sd_command_frame(frame, index, arg);
117 *r1 = 0xFF;
121 for (uint8_t i = 0; st == BOARD_SPI_OK && i < 8 && !sd_is_r1(*r1); ++i) {
122 st = board_spi_shift(BOARD_SPI_NAND, NULL, r1, 1, deadline);
123 }
124 if (st == BOARD_SPI_OK && sd_is_r1(*r1) && extra_len) {
125 st = board_spi_shift(BOARD_SPI_NAND, NULL, extra, extra_len, deadline);
126 }
128 if (st == BOARD_SPI_OK) {
129 st = board_spi_shift(BOARD_SPI_NAND, NULL, NULL, 1, deadline);
130 }
131 return st;
132}
133
134/* CMD10: R1, then wait for the 0xFE data token, then 16 CID bytes + CRC16. */
135static board_spi_status_t sd_read_cid(uint8_t* r1, uint8_t cid[16],
136 uint32_t deadline) {
137 uint8_t frame[6], token = 0xFF, crc16[2];
139 *r1 = 0xFF;
143 for (uint8_t i = 0; st == BOARD_SPI_OK && i < 8 && !sd_is_r1(*r1); ++i) {
144 st = board_spi_shift(BOARD_SPI_NAND, NULL, r1, 1, deadline);
145 }
146 if (st == BOARD_SPI_OK && *r1 == 0x00U) {
147 for (uint16_t i = 0;
148 st == BOARD_SPI_OK && i < 512 && token != SD_DATA_TOKEN; ++i) {
149 st = board_spi_shift(BOARD_SPI_NAND, NULL, &token, 1, deadline);
150 }
151 if (st == BOARD_SPI_OK && token == SD_DATA_TOKEN) {
152 st = board_spi_shift(BOARD_SPI_NAND, NULL, cid, 16, deadline);
153 if (st == BOARD_SPI_OK) {
154 st = board_spi_shift(BOARD_SPI_NAND, NULL, crc16, 2, deadline);
155 }
156 } else if (st == BOARD_SPI_OK) {
157 *r1 = 0xFF; /* no data token: treat as no answer */
158 }
159 }
161 if (st == BOARD_SPI_OK) {
162 st = board_spi_shift(BOARD_SPI_NAND, NULL, NULL, 1, deadline);
163 }
164 return st;
165}
166
167static self_test_reply_t sd_fail(board_spi_status_t st, int stage, uint8_t r1) {
168 int32_t diag = (int32_t)((stage << 8) | r1);
169 if (st == BOARD_SPI_TIMEOUT) {
170 return reply(SELF_TEST_TIMEOUT, diag);
171 }
172 return reply(SELF_TEST_FAIL, diag);
173}
174
175/*
176 * ZDSD01GLGEAG SD NAND (U10) on SPI4, SD SPI mode, read-only: wake clocks,
177 * CMD0, CMD8, ACMD41 (initialize), CMD58 (OCR), CMD10 (CID). Nothing is
178 * written. SPI4 stays at 250 kHz, inside the 400 kHz init limit.
179 */
180static self_test_reply_t sd_nand_probe(uint32_t budget_ms) {
181 uint32_t deadline = board_now_ms() + budget_ms;
182 uint8_t r1 = 0xFF, r7[4], ocr[4], cid[16];
184 if (st != BOARD_SPI_OK) {
185 return sd_fail(st, 0, 0xFF);
186 }
188 /* >= 74 clocks with CS high put the card in a known state. */
189 st = board_spi_idle_clocks(BOARD_SPI_NAND, 10, deadline);
190 if (st == BOARD_SPI_OK) {
191 st = sd_command(SD_CMD0_GO_IDLE, 0, &r1, NULL, 0, deadline);
192 }
193 if (st != BOARD_SPI_OK || r1 != SD_R1_IDLE) {
195 goto done;
196 }
197 st = sd_command(SD_CMD8_SEND_IF_COND, SD_CMD8_ARG, &r1, r7, 4, deadline);
198 if (st != BOARD_SPI_OK || r1 != SD_R1_IDLE || !sd_r7_ok(r7)) {
200 goto done;
201 }
202 uint32_t init_deadline = board_now_ms() + BOARD_SD_INIT_MS;
203 if ((int32_t)(init_deadline - deadline) > 0) {
204 init_deadline = deadline;
205 }
206 do {
207 st = sd_command(SD_CMD55_APP_CMD, 0, &r1, NULL, 0, deadline);
208 if (st == BOARD_SPI_OK && (r1 & ~SD_R1_IDLE) == 0U) {
210 0, deadline);
211 }
212 if (st != BOARD_SPI_OK || r1 == 0x00U) {
213 break;
214 }
215 osDelay(10);
216 } while (!board_deadline_passed(init_deadline));
217 if (st != BOARD_SPI_OK || r1 != 0x00U) {
220 goto done;
221 }
222 st = sd_command(SD_CMD58_READ_OCR, 0, &r1, ocr, 4, deadline);
223 if (st != BOARD_SPI_OK || r1 != 0x00U) {
225 goto done;
226 }
227 st = sd_read_cid(&r1, cid, deadline);
228 if (st != BOARD_SPI_OK || r1 != 0x00U || !sd_cid_ok(cid)) {
230 goto done;
231 }
232 {
233 uint32_t ocr_word = ((uint32_t)ocr[0] << 24) |
234 ((uint32_t)ocr[1] << 16) | ((uint32_t)ocr[2] << 8) |
235 ocr[3];
236 result =
238 (int32_t)(cid[0] | ((ocr_word & SD_OCR_CCS) ? 0x100U : 0U)));
239 }
240done:
242 return result;
243}
244
245/*
246 * THGBMTG5D1LBAIL eMMC (U9) on SDMMC1, 4-bit. Runs CubeMX's own
247 * MX_SDMMC1_MMC_Init() (not called from main(), see board.h) with
248 * Error_Handler() made non-fatal. A successful HAL_MMC_Init() has completed
249 * the full identification (CMD0/1/2/3, CSD, EXT_CSD) and switched to 4-bit
250 * with CMD6, which writes the bus-width setting but no stored data. Then the
251 * CID is read and the card must be in the transfer state.
252 *
253 * Exactly once per power-up: the datasheet warns that repeated CMD0/CMD1
254 * initialization causes read disturb (THGBMTG5D1LBAIL rev 1.0, p.28), so
255 * self-test retries report the first result instead of initializing again.
256 * hmmc1 is left READY for the eMMC log adapter (emmc_stm32.c), which owns
257 * every transfer after this. The HAL's command timeouts bound the init.
258 */
261 return reply(SELF_TEST_FAIL, (int32_t)(hmmc1.ErrorCode & 0x7FFFFFFFU));
262 }
263 HAL_MMC_CardCIDTypeDef cid;
264 if (HAL_MMC_GetCardCID(&hmmc1, &cid) != HAL_OK) {
265 return reply(SELF_TEST_FAIL, (int32_t)(hmmc1.ErrorCode & 0x7FFFFFFFU));
266 }
267 HAL_MMC_CardStateTypeDef state = HAL_MMC_GetCardState(&hmmc1);
268 if (state != HAL_MMC_CARD_TRANSFER) {
269 return reply(SELF_TEST_FAIL,
270 (int32_t)(BOARD_EMMC_DIAG_STATE | (state & 0xFFU)));
271 }
272 return reply(SELF_TEST_PASS, (int32_t)cid.ManufacturerID);
273}
274
276 if (!b->emmc_reset_released) {
278 }
279 if (!b->emmc_init_attempted) {
280 b->emmc_init_attempted = true;
281 b->emmc_result = emmc_identify();
282 }
283 return b->emmc_result;
284}
285
287 b->devices.exchange = board_spi_self_test_exchange;
288 b->devices.io_context = NULL;
289 b->devices.configured_mask = 0;
290 b->gnss_powered = false;
291 b->emmc_reset_released = false;
292 b->emmc_init_attempted = false;
293 /* µs timebase first: everything after this is stamped with it. */
294 b->time_ok = board_time_start();
295 /* ADC1: offset + linearity calibration once, before any conversion. */
296 b->adc_ready = board_adc_init();
297 if (!board_spi_init()) {
298 return; /* no bus locks: no SPI device is enabled */
299 }
300
301 /* ISM330DHCX (U4): on the always-on 3V3 rail. Its boot sequence takes
302 * about 10 ms after power-up; 20 ms gives margin. SPI needs no setup: CS
303 * is driven high by MX_GPIO_Init and goes low only for a transfer. */
304 wait_since_boot(20);
306
307 /* H3LIS100DL (U3), high-g: same rail and bus as the IMU. At power-up it
308 * loads its trimming from internal flash (DocID027504 p.27); no separate
309 * boot time is specified, and the 20 ms above covers it. It starts in
310 * power-down (CTRL_REG1 = 0x07), which still answers WHO_AM_I. */
312
313 /* MS5611 (U5), barometer: same rail and bus. Its PROM check is only
314 * meaningful after the power-on reset, so the check is enabled only if
315 * the reset command went out. */
316 if (ms5611_reset()) {
318 }
319
320 /* W5500 (U6), Ethernet: held in reset by ETH_RST (PE13), which
321 * MX_GPIO_Init drives low. RSTn low >= 500 us (TRC), then the internal
322 * PLL locks <= 1 ms after RSTn rises (TPL) (datasheet v1.0.2 p.61).
323 * It has been low since boot; osDelay(3) guarantees >= 2 ms. */
325 osDelay(3);
327
328 /* Wio-SX1262 (U8), LoRa: held in reset by RADIO_NRST (PB0), driven low
329 * by MX_GPIO_Init. NRESET low typ. 100 us (SX1262 DS 8.1, p.50); after
330 * release BUSY (PC5) stays high through STARTUP and falls once the chip
331 * is in STDBY_RC and accepts commands (8.2.2, 9.1). Wait up to 50 ms.
332 * The check is enabled either way: board_spi waits on BUSY before every
333 * radio command, so a radio that never starts reports TIMEOUT instead of
334 * being hidden as "not configured". RF_SW (PB1) stays low; nothing here
335 * transmits. */
337 uint32_t radio_deadline = board_now_ms() + 50U;
339 GPIO_PIN_SET &&
340 !board_deadline_passed(radio_deadline)) {
341 osDelay(1);
342 }
344
345 /* MAX-M10S (MD1), GNSS: its 3V3A rail comes from the 3V6 buck (U15) and
346 * LP5907 LDO (U16), off until REG_3V6_EN (PE11) goes high (#137 power
347 * tree). GPS_RST (PD11, open drain) is already released by MX_GPIO_Init.
348 * 10 ms covers both regulators' start-up; the module then needs up to a
349 * second before its first sentence, which the probe's listen window
350 * covers. */
352 osDelay(10);
353 b->gnss_powered = true;
354
355 /* THGBMTG5D1LBAIL (U9), eMMC: EMMC_RST (PA8) is driven low by
356 * MX_GPIO_Init. Release it and allow 1 ms; HAL_MMC_Init then sends the
357 * >= 74 init clocks itself. The init runs in the probe, so a retry can
358 * start from scratch and a dead part is a reported FAIL, not a halt. */
360 osDelay(2);
361 b->emmc_reset_released = true;
362}
363
364self_test_battery_t board_bringup_read_battery(void* context, uint32_t now_ms,
365 uint32_t budget_ms) {
366 board_bringup_t* b = context;
368 uint16_t counts = 0;
369 if (!b || !b->adc_ready) {
371 return battery;
372 }
373 /* Average 16 conversions (~0.1 ms each at 387.5 cycles): the 16-bit
374 * reading of a 2 V node carries a few counts of noise. Each read gets
375 * the remaining budget, so the whole batch stays inside budget_ms. */
376 uint32_t start = board_now_ms(), sum = 0;
377 for (unsigned i = 0; i < 16U; ++i) {
378 uint32_t used = board_now_ms() - start;
379 if (used >= budget_ms ||
380 !board_adc_read(BOARD_ADC_VBAT, &counts, budget_ms - used)) {
381 battery.reply = reply(SELF_TEST_FAIL, 0);
382 return battery;
383 }
384 sum += counts;
385 }
386 battery.reply = reply(SELF_TEST_PASS, 0);
387 battery.valid = true;
388 battery.raw_counts = (sum + 8U) / 16U;
389 battery.sampled_at_ms = now_ms;
390 return battery;
391}
392
394 /* TPS2121 ST, pulled up by R65: HIGH = IN1 (battery), LOW = IN2 (USB);
395 * schematic p.12, TPS2121 datasheet p.21. */
397}
398
399self_test_reply_t board_bringup_probe(void* context, uint16_t device_id,
400 uint8_t attempt, uint32_t now_ms,
401 uint32_t budget_ms) {
402 board_bringup_t* b = context;
403 if (!b) {
405 return r;
406 }
407 switch (device_id) {
409 return gnss_probe(b, attempt, budget_ms);
411 /* 3V3 rail; CS has a 100k pull-up and is driven high since boot;
412 * the SD power-up wait (>= 1 ms) has long passed. */
413 return sd_nand_probe(budget_ms);
415 return emmc_probe(b);
416 default:
417 /* SPI identity checks (IMU, high-g, baro, Ethernet, radio). */
418 return self_test_devices_probe(&b->devices, device_id, attempt,
419 now_ms, budget_ms);
420 }
421}
uint8_t byte
Minimal Arduino.h stub for native unit tests.
Definition Arduino.h:16
#define RADIO_NRST_Pin
Definition main.h:107
void MX_SDMMC1_MMC_Init(void)
SDMMC1 Initialization Function.
Definition main.c:456
#define RADIO_BUSY_GPIO_Port
Definition main.h:106
#define REG_3V6_EN_GPIO_Port
Definition main.h:117
#define GPS_ANT_STATUS_GPIO_Port
Definition main.h:130
#define ETH_RST_Pin
Definition main.h:118
#define RADIO_BUSY_Pin
Definition main.h:105
#define SW_ST_GPIO_Port
Definition main.h:115
#define EMMC_RST_Pin
Definition main.h:145
#define GPS_ANT_STATUS_Pin
Definition main.h:129
#define REG_3V6_EN_Pin
Definition main.h:116
#define RADIO_NRST_GPIO_Port
Definition main.h:108
#define SW_ST_Pin
Definition main.h:114
#define ETH_RST_GPIO_Port
Definition main.h:119
#define EMMC_RST_GPIO_Port
Definition main.h:146
uint32_t board_now_ms(void)
Definition board.c:24
bool board_soft_init(void(*init)(void))
Definition board.c:16
static bool board_deadline_passed(uint32_t deadline_ms)
Definition board.h:42
static uint32_t board_ms_left(uint32_t deadline_ms)
Definition board.h:47
bool board_adc_read(board_adc_input_t input, uint16_t *counts, uint32_t timeout_ms)
Definition board_adc.c:28
bool board_adc_init(void)
Definition board_adc.c:19
@ BOARD_ADC_VBAT
Definition board_adc.h:19
static self_test_reply_t emmc_identify(void)
static self_test_reply_t sd_fail(board_spi_status_t st, int stage, uint8_t r1)
static board_spi_status_t sd_command(uint8_t index, uint32_t arg, uint8_t *r1, uint8_t *extra, uint8_t extra_len, uint32_t deadline)
static void wait_since_boot(uint32_t ms)
bool board_bringup_on_usb(void)
static bool ms5611_reset(void)
static self_test_reply_t emmc_probe(board_bringup_t *b)
static self_test_reply_t gnss_probe(board_bringup_t *b, uint8_t attempt, uint32_t budget_ms)
static board_spi_status_t sd_read_cid(uint8_t *r1, uint8_t cid[16], uint32_t deadline)
static self_test_reply_t reply(self_test_result_t result, int32_t diag)
static self_test_reply_t sd_nand_probe(uint32_t budget_ms)
self_test_battery_t board_bringup_read_battery(void *context, uint32_t now_ms, uint32_t budget_ms)
static void enable(board_bringup_t *b, uint16_t device_id)
static bool uart9_set_baud(uint32_t baud)
self_test_reply_t board_bringup_probe(void *context, uint16_t device_id, uint8_t attempt, uint32_t now_ms, uint32_t budget_ms)
void board_bringup_power_up(board_bringup_t *b)
#define BOARD_SD_STAGE_CMD10
#define BOARD_EMMC_DIAG_STATE
#define BOARD_GNSS_LISTEN_MS
#define BOARD_SD_STAGE_ACMD41
#define BOARD_SD_INIT_MS
#define BOARD_GNSS_DIAG_ANTENNA_SHORT
#define BOARD_SD_STAGE_CMD8
#define BOARD_SD_STAGE_CMD0
#define BOARD_SD_STAGE_CMD58
board_spi_status_t board_spi_idle_clocks(board_spi_device_t device, uint16_t len, uint32_t deadline_ms)
Definition board_spi.c:210
self_test_reply_t board_spi_self_test_exchange(void *context, uint16_t device_id, uint8_t mode, uint32_t max_hz, self_test_spi_frame_t *frames, uint8_t count, uint32_t budget_ms)
Definition board_spi.c:243
bool board_spi_init(void)
Definition board_spi.c:56
void board_spi_deselect(board_spi_device_t device)
Definition board_spi.c:195
board_spi_status_t board_spi_lock(board_spi_device_t device, uint32_t deadline_ms)
Definition board_spi.c:94
void board_spi_unlock(board_spi_device_t device)
Definition board_spi.c:108
board_spi_status_t board_spi_shift(board_spi_device_t device, const uint8_t *tx, uint8_t *rx, uint16_t len, uint32_t deadline_ms)
Definition board_spi.c:201
void board_spi_select(board_spi_device_t device)
Definition board_spi.c:189
@ BOARD_SPI_NAND
Definition board_spi.h:32
@ BOARD_SPI_BARO
Definition board_spi.h:29
board_spi_status_t
Definition board_spi.h:36
@ BOARD_SPI_TIMEOUT
Definition board_spi.h:38
@ BOARD_SPI_OK
Definition board_spi.h:37
bool board_time_start(void)
Definition board_time.c:27
bool board_uart9_apply_baud(uint32_t baud)
Definition board_uart9.c:23
osStatus_t osDelay(uint32_t ticks)
Wait for Timeout (Time Delay).
Definition cmsis_os2.c:1094
static ActuatorControllerState state
Definition main.cpp:57
gnss_frame_kind_t gnss_frame_feed(gnss_frame_parser_t *p, uint8_t byte)
Definition gnss_frame.c:57
static void start(gnss_frame_parser_t *p, uint8_t byte)
Definition gnss_frame.c:45
void gnss_frame_init(gnss_frame_parser_t *parser)
Definition gnss_frame.c:35
@ GNSS_FRAME_NONE
Definition gnss_frame.h:22
GPIO_PinState HAL_GPIO_ReadPin(const GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin)
void HAL_GPIO_WritePin(GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin, GPIO_PinState PinState)
@ GPIO_PIN_SET
@ GPIO_PIN_RESET
HAL_StatusTypeDef HAL_UART_Receive(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size, uint32_t Timeout)
#define __HAL_UART_CLEAR_FLAG(__HANDLE__, __FLAG__)
Clear the specified UART pending flag.
struct __UART_HandleTypeDef UART_HandleTypeDef
UART handle Structure definition.
#define UART_CLEAR_FEF
Framing Error Clear Flag.
#define UART_CLEAR_OREF
Overrun Error Clear Flag.
#define UART_CLEAR_PEF
Parity Error Clear Flag.
#define UART_CLEAR_NEF
Noise Error detected Clear Flag.
#define NULL
Definition usbd_def.h:44
*brief create JSON pointer *sa reference_tokens const string_t const string_t & b
Definition json.hpp:13878
*brief create a new JSON pointer by appending the unescaped token at the end of the JSON pointer *sa string_t token
Definition json.hpp:13937
json_pointer result
Definition json.hpp:14064
MMC_HandleTypeDef hmmc1
Definition main.c:54
UART_HandleTypeDef huart9
Definition main.c:65
bool sd_r7_ok(const uint8_t r7[4])
Definition sd_spi.c:26
void sd_command_frame(uint8_t out[6], uint8_t index, uint32_t argument)
Definition sd_spi.c:17
bool sd_cid_ok(const uint8_t cid[16])
Definition sd_spi.c:31
#define SD_CMD8_ARG
Definition sd_spi.h:24
#define SD_CMD8_SEND_IF_COND
Definition sd_spi.h:18
#define SD_CMD58_READ_OCR
Definition sd_spi.h:21
#define SD_R1_IDLE
Definition sd_spi.h:27
#define SD_ACMD41_HCS
Definition sd_spi.h:25
#define SD_CMD55_APP_CMD
Definition sd_spi.h:20
#define SD_CMD0_GO_IDLE
Definition sd_spi.h:17
#define SD_OCR_CCS
Definition sd_spi.h:30
#define SD_CMD10_SEND_CID
Definition sd_spi.h:19
#define SD_DATA_TOKEN
Definition sd_spi.h:29
#define SD_ACMD41_SD_SEND_OP_COND
Definition sd_spi.h:22
static bool sd_is_r1(uint8_t byte)
Definition sd_spi.h:39
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)
@ SELF_TEST_DEVICE_ETHERNET
@ SELF_TEST_DEVICE_IMU
@ SELF_TEST_DEVICE_GNSS
@ SELF_TEST_DEVICE_HIGH_G
@ SELF_TEST_DEVICE_NAND
@ SELF_TEST_DEVICE_RADIO
@ SELF_TEST_DEVICE_BAROMETER
@ SELF_TEST_DEVICE_EMMC
#define SELF_TEST_DEVICE_ENABLED(id)
self_test_result_t
@ SELF_TEST_FAIL
@ SELF_TEST_NOT_CONFIGURED
@ SELF_TEST_PASS
@ SELF_TEST_TIMEOUT
@ HAL_OK
static boot_report_t r
static std::vector< uint8_t > frame(uint8_t hi, uint8_t lo, size_t payload_len, uint8_t fill)
One wire packet: len(4, LE) then len bytes of body, where the first 4 body bytes are ty/packet_id(2)/...
static self_test_battery_t battery(void *context, uint32_t now_ms, uint32_t budget_ms)