STAR
Cal STAR — firmware, DAQ server, and engine design
Loading...
Searching...
No Matches
sense_p.cpp
Go to the documentation of this file.
1
// #include <ADS126X.h>
2
// #include <SPI.h>
3
// #include <Arduino.h>
4
// #include "board_pins.h"
5
// #include "adcs.h"
6
7
// #include "freertos/FreeRTOS.h"
8
// #include "freertos/stream_buffer.h"
9
10
// // 1 = ASCII voltages for the Python calibration script
11
// // 0 = binary sweep packets
12
// #define TEXT_OUTPUT 0
13
// #define PT_NUM_START 0
14
// #define NUM_PTS 10
15
16
// static inline void flushPacketIfNeeded(bool force);
17
// static void sendSweepIfNeeded(const adcs::AllResults& sweep);
18
19
// // Sentinals
20
21
// static constexpr uint8_t PAD_CH = 0xFF; // "no channel"
22
// static constexpr int32_t SENT_I32 = INT32_MIN; // "missing" for signed 32
23
// static constexpr uint32_t SENT_U32 = 0xFFFFFFFFu; // "missing" for unsigned
24
// 32
25
26
// // --- Buffer settings ---
27
// static const size_t PKT_MAX = 1024; // packet size in bytes
28
29
// static uint8_t pktA[PKT_MAX];
30
// static uint8_t pktB[PKT_MAX];
31
// static uint8_t* active = pktA;
32
// static uint8_t* standby = pktB;
33
34
// static const uint32_t FLUSH_MS = 10; // flush every ~10 ms
35
// static size_t used = 0;
36
// static uint32_t lastFlushMs = 0;
37
38
// // ===== Sweep packet format =====
39
// // Little endian
40
41
// #pragma pack(push,1)
42
// struct PacketHeader {
43
// char magic[4]; // "AD26"
44
// uint8_t version; // 2 (new format)
45
// uint8_t flags; // bit0 = per-record t_us present
46
// uint16_t count; // number of records in this sweep
47
// uint16_t failures; // from readAll
48
// uint32_t total_time_us; // total sweep time
49
// uint32_t packet_time_us; // FULL micros() when this packet is sent
50
// };
51
52
// struct Rec18 {
53
// uint8_t ch; // channel id
54
// uint8_t ok; // 0 or 1
55
// int32_t raw;
56
// int32_t sample_time; // ADC code
57
// uint32_t read_time_dur; // per read()
58
// uint32_t conv_time_dur; // wait for DRDY
59
// };
60
// #pragma pack(pop)
61
62
// // ===== CRC32 (poly 0xEDB88320, init 0xFFFFFFFF, final XOR 0xFFFFFFFF) =====
63
// static uint32_t crc32_le(const uint8_t* data, size_t len) {
64
// uint32_t crc = 0xFFFFFFFFu;
65
// for (size_t i = 0; i < len; ++i) {
66
// crc ^= data[i];
67
// for (int k = 0; k < 8; ++k) {
68
// uint32_t mask = -(crc & 1u);
69
// crc = (crc >> 1) ^ (0xEDB88320u & mask);
70
71
// }
72
// }
73
74
// return crc ^ 0xFFFFFFFFu;
75
// }
76
77
// static void sendSweepPacket(const adcs::AllResults& sweep) {
78
// uint32_t packet_time = micros();
79
80
// const size_t header_sz = sizeof(PacketHeader);
81
// const size_t rec_sz = sizeof(Rec18);
82
// const size_t n_fixed = 10;
83
// const size_t payload_no_crc = header_sz + n_fixed * rec_sz;
84
// const size_t total_len = payload_no_crc + sizeof(uint32_t);
85
86
// if (total_len > PKT_MAX) {
87
// // With n_fixed=10 this should not happen.
88
// return;
89
// }
90
91
// // Build packet into the small scratch buffer (reuse your existing
92
// “active”) uint8_t* buf = standby; // use standby as a scratch area so we
93
// don't disturb "active" size_t off = 0;
94
95
// PacketHeader h;
96
// memcpy(h.magic, "AD26", 4);
97
// h.version = 2;
98
// h.flags = 0x01;
99
// h.count = n_fixed;
100
// h.failures = sweep.failures + static_cast<uint16_t>((n_fixed >
101
// sweep.count) ? (n_fixed - sweep.count) : 0); h.total_time_us =
102
// sweep.total_time; h.packet_time_us = packet_time; memcpy(buf + off, &h,
103
// sizeof(h)); off += sizeof(h);
104
105
// const size_t n_real = (sweep.count <= n_fixed) ? sweep.count : n_fixed;
106
// for (size_t i = 0; i < n_real; ++i) {
107
// const auto& s = sweep.samples[i];
108
// Rec18 r;
109
// r.ch = s.channel;
110
// r.ok = s.result.ok ? 1u : 0u;
111
// r.raw = s.result.raw;
112
// r.sample_time = s.result.sample_time;
113
// r.read_time_dur = s.result.read_time_dur;
114
// r.conv_time_dur = s.result.conv_time_dur;
115
// memcpy(buf + off, &r, sizeof(r)); off += sizeof(r);
116
// }
117
118
// for (size_t i = n_real; i < n_fixed; ++i) {
119
// Rec18 r;
120
// r.ch = PAD_CH;
121
// r.ok = 0;
122
// r.raw = SENT_I32;
123
// r.sample_time = SENT_I32;
124
// r.read_time_dur = SENT_U32;
125
// r.conv_time_dur = SENT_U32;
126
// memcpy(buf + off, &r, sizeof(r)); off += sizeof(r);
127
// }
128
129
// const uint32_t crc = crc32_le(buf, off);
130
// memcpy(buf + off, &crc, sizeof(crc)); off += sizeof(crc);
131
132
// // Append the completed sweep packet into the large outgoing buffer.
133
// // If it won’t fit, flush first, then append.
134
// if (used + off > PKT_MAX) {
135
// flushPacketIfNeeded(true);
136
// }
137
// memcpy(active + used, buf, off);
138
// used += off;
139
140
// // Do not Serial.write here. Let the timed flush handle it.
141
// }
142
143
// void setup() {
144
// Serial.begin(230400);
145
// SPI.begin(SCLK, MISOp, MOSIp, CS);
146
147
// if (!adcs::init()) { while (1) { delay(1000); } }
148
// if (!adcs::configure()){ while (1) { delay(1000); } }
149
// }
150
151
// void loop() {
152
// // One sweep
153
// adcs::AllResults sweep = adcs::readAll(channels, num_channels);
154
155
// if (TEXT_OUTPUT) {
156
// // ASCII volts for calibration scripts
157
// for (size_t i = 0; i < sweep.count; ++i) {
158
// const auto& s = sweep.samples[i];
159
// float volts = (float)s.result.raw * vRef / adcScale;
160
// Serial.print(volts, 6);
161
// if (i + 1 < sweep.count) Serial.print(' ');
162
// }
163
// Serial.print("\r\n");
164
// } else {
165
// sendSweepPacket(sweep);
166
// flushPacketIfNeeded(false); // flush by time
167
// }
168
// }
169
170
// static inline void flushPacketIfNeeded(bool force = false) {
171
// uint32_t now = millis();
172
// if (force || (used > 0 && (now - lastFlushMs >= FLUSH_MS))) {
173
// Serial.write(active, used);
174
// // optional delimiter: Serial.println();
175
// uint8_t* tmp = active; active = standby; standby = tmp;
176
// used = 0;
177
// lastFlushMs = now;
178
// }
179
// }
firmware
ADC_Testing
Noise_Characterization
test
Old
sense_p.cpp
Generated by
1.15.0