STAR
Cal STAR — firmware, DAQ server, and engine design
Loading...
Searching...
No Matches
test_sd_spi.c
Go to the documentation of this file.
1#include <stdio.h>
2#include <stdlib.h>
3#include <string.h>
4
5#include "sd_spi.h"
6
7#define CHECK(condition) \
8 do { \
9 if (!(condition)) { \
10 fprintf(stderr, "%s:%d: %s\n", __FILE__, __LINE__, #condition); \
11 exit(1); \
12 } \
13 } while (0)
14
15/* CMD0 ...95 and CMD8 ...87 are the published constants every SD driver
16 * hard-codes; the rest were computed with an independent CRC7 in Python. */
17static void test_command_frames(void) {
18 static const struct {
19 uint8_t index;
20 uint32_t arg;
21 uint8_t frame[6];
22 } cases[] = {
23 {SD_CMD0_GO_IDLE, 0, {0x40, 0x00, 0x00, 0x00, 0x00, 0x95}},
26 {0x48, 0x00, 0x00, 0x01, 0xAA, 0x87}},
27 {SD_CMD55_APP_CMD, 0, {0x77, 0x00, 0x00, 0x00, 0x00, 0x65}},
30 {0x69, 0x40, 0x00, 0x00, 0x00, 0x77}},
31 {SD_CMD58_READ_OCR, 0, {0x7A, 0x00, 0x00, 0x00, 0x00, 0xFD}},
32 {SD_CMD10_SEND_CID, 0, {0x4A, 0x00, 0x00, 0x00, 0x00, 0x1B}},
33 };
34 for (size_t i = 0; i < sizeof(cases) / sizeof(cases[0]); ++i) {
35 uint8_t out[6];
36 sd_command_frame(out, cases[i].index, cases[i].arg);
37 CHECK(memcmp(out, cases[i].frame, 6) == 0);
38 }
39}
40
41static void test_r1(void) {
42 CHECK(!sd_is_r1(0xFF));
44 CHECK(sd_is_r1(0x00));
46}
47
48static void test_r7(void) {
49 const uint8_t good[4] = {0x00, 0x00, 0x01, 0xAA};
50 const uint8_t wrong_pattern[4] = {0x00, 0x00, 0x01, 0x55};
51 const uint8_t wrong_voltage[4] = {0x00, 0x00, 0x02, 0xAA};
52 CHECK(sd_r7_ok(good));
53 CHECK(!sd_r7_ok(wrong_pattern));
54 CHECK(!sd_r7_ok(wrong_voltage));
55}
56
57static void test_cid(void) {
58 /* Well-formed CID body; last byte B7 computed independently. */
59 uint8_t cid[16] = {0x03, 0x53, 0x44, 0x53, 0x55, 0x31, 0x36, 0x47,
60 0x80, 0x12, 0x34, 0x56, 0x78, 0x01, 0x4A, 0xB7};
61 CHECK(sd_cid_ok(cid));
62 for (int i = 0; i < 16; ++i) {
63 uint8_t bad[16];
64 memcpy(bad, cid, 16);
65 bad[i] ^= 0x10;
66 CHECK(!sd_cid_ok(bad));
67 }
68 /* A dead bus reads all 0xFF or all 0x00: neither is a valid CID. All
69 * 0xFF satisfies the CRC7 by coincidence, so this needs its own rule. */
70 uint8_t ff[16], zero[16];
71 memset(ff, 0xFF, 16);
72 memset(zero, 0x00, 16);
73 CHECK(!sd_cid_ok(ff));
74 CHECK(!sd_cid_ok(zero));
75}
76
77int main(void) {
79 test_r1();
80 test_r7();
81 test_cid();
82 puts("sd_spi: all tests passed");
83 return 0;
84}
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_R1_ILLEGAL_COMMAND
Definition sd_spi.h:28
#define SD_CMD10_SEND_CID
Definition sd_spi.h:19
#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
int main()
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 void test_cid(void)
Definition test_sd_spi.c:57
#define CHECK(condition)
Definition test_sd_spi.c:7
static void test_r7(void)
Definition test_sd_spi.c:48
static void test_r1(void)
Definition test_sd_spi.c:41
static void test_command_frames(void)
Definition test_sd_spi.c:17