-
Notifications
You must be signed in to change notification settings - Fork 0
/
sensor_task.h
403 lines (337 loc) · 15.2 KB
/
sensor_task.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
/*
* sensor_task.h
*
* Copyright (c) 2024, W. M. Keck Observatory
* All rights reserved.
*
* Author: Paul Richards
*
*/
#ifndef SENSOR_TASK_H_
#define SENSOR_TASK_H_
#include "includes.h"
/* Only instantiate variables if we are the .c routine for this header file. */
#ifndef SENSOR_TASK_C_
#define EXTERN extern
#else
#define EXTERN
#endif
/* -----------------------------------------------------------------------------
* Timer values.
*/
/* Attempt to re-initialize the sensor once a second */
#define SENSOR_INIT_TIMEOUT_MS 1000
/* Timeout value for the ready signal from the sensor */
#define SENSOR_READY_TIMEOUT_MS 500
/* Attempt to read and/or init the temp+humidity sensor every 10 seconds */
#define TH_TIMEOUT_MS 10000
/* -----------------------------------------------------------------------------
* PCA9536 - Relay driver to switch sensor between LBL and Kona configuration
*/
#define PCA9536_ADDR 0x41
#define PCA9536_OUT_PORT_REG 0x01
#define PCA9536_OUT_PORT_RESET 0x00
#define PCA9536_OUT_PORT_KONA 0x05
#define PCA9536_OUT_PORT_LBL 0x0A
#define PCA9536_CONFIG_REG 0x03
#define PCA9536_CONFIG_ALL_OUTPUT 0x00
/* -----------------------------------------------------------------------------
* SI7020 Temperature / Humidity sensor
*/
#define SI7020_ADDR 0x40
#define SI7020_HUM_HOLD 0xE5
#define SI7020_HUM_NO_HOLD 0xF5
#define SI7020_TMP_HOLD 0xE3
#define SI7020_TMP_NO_HOLD 0xF3
#define SI7020_TMP_PREVIOUS 0xF0
#define SI7020_RESET 0xFE
#define SI7020_WRITE_USER_1 0xE6
#define SI7020_WRITE_USER_2 0x51
#define SI7020_READ_HEATER 0x11
/* 2 byte register addresses to read the ESN */
#define SI7020_READ_ESN1_1 0xFA
#define SI7020_READ_ESN1_2 0x0F
#define SI7020_READ_ESN2_1 0xFC
#define SI7020_READ_ESN2_2 0xC9
/* Offsets into the buffers from the ESN reads to get the individual
* bytes of the ESN. They do not arrive sequentially. See Si7020
* spec, page 24. */
#define SI7020_SNA_0 6
#define SI7020_SNA_1 4
#define SI7020_SNA_2 2
#define SI7020_SNA_3 0
#define SI7020_SNB_0 4
#define SI7020_SNB_1 3
#define SI7020_SNB_2 1
#define SI7020_SNB_3 0
#define SI7013_ID 0x0D
#define SI7020_ID 0x14
#define SI7021_ID 0x15
/*
* Si7020 temperature is calculated from two bytes, t0 and t1.
* T = (T0 << 8 + T1) * 175.72 / 65536-46.85
*
* Humidity is expressed as:
* H = (H0 << 8 + H1) * 125 / 65536 - 6
*
* When the sensor is disconnected, we want to read back invalid values, such as a
* temperatures of 999C and humidity of 0%. Back calculate the values to return
* when this is the case.
*
*/
/* 99C is equal to 54396 (decimal) */
#define SI7020_INVALID_TH 0xD4
#define SI7020_INVALID_TL 0x7C
/* 0% RH is equal to 3146 (decimal) */
#define SI7020_INVALID_HH 0x0C
#define SI7020_INVALID_HL 0x4A
/* -----------------------------------------------------------------------------
* AD7746 - Capacitance sensor
*/
/* Base address of device on I2C bus */
#define AD7746_ADDR 0x48
/* Commands */
#define AD7746_WRITE 0x00
#define AD7746_READ 0x01
/* Registers and their definitions */
#define AD7746_RESET_REG 0xBF
#define AD7746_STATUS_REG 0x00
/* Capacitance setup register definitions (spec pg 16)
*
* Bit 7: CAPEN (1 = enables capacitive channel for single conversion, continuous conversion, or calibration)
* Bit 6: CIN2 (1 = switches the internal multiplexer to the second capacitive input on the AD7746)
* Bit 5: CAPDIFF (1 = sets differential mode on the selected capacitive input)
* Bit 4-1: Set to 0.
* Bit 0: CAPCHOP (1 = approximately doubles the capacitive channel conversion times and slightly improves the
capacitive channel noise performance for the longest conversion times)
*/
#define AD7746_CAP_SETUP_REG 0x07
#define AD7746_CAP_DIFFERENTIAL 0b11100000 // 0xE0 = CIN2, DIFF=1 (differential capacitance only)
#define AD7746_CAP_CAP1 0b10000000 // 0x80 = CIN1, DIFF=0 (capacitor 1 only)
#define AD7746_CAP_CAP2 0b11000000 // 0xC0 = CIN2, DIFF=0 (capacitor 2 only)
/* Voltage setup register definitions (spec pg 16)
*
* Bit 7: VTEN (1 = enables voltage/temperature channel for single conversion)
* Bit 6-5: VTMD1, VTMD0 Channel Input (00 = Internal temperature sensor)
* Bit 4: EXTREF (0 = select the on-chip internal reference)
* Bit 3-2: (00 - These bits must be 0 for proper operation)
* Bit 1: VTSHORT (0 = disable internal short of the voltage/temperature channel input for test purposes)
* Bit 0 VTCHOP (1 = sets internal chopping on the voltage/temperature channel / must be set to 1 for the specified voltage/temperature channel performance)
*/
#define AD7746_VT_SETUP_REG 0x08
#define AD7746_VT_SETUP_DISABLE 0x00
#define AD7746_VT_SETUP_INT_TEMP 0b10000001 // 0x81 = VTEN=1, VTCHOP=1
/* Excitation setup register definitions (spec pg 17)
* Bit 7: CLKCTRL (0 = default, 1 = decrease frequencies by factor of 2)
* Bit 6: EXCON (1 = excitation signal present on output during cap channel conversion AND during voltage/temp conversion)
* Bit 5: EXCB (0 = disable EXCB pin as the excitation output)
* Bit 4: NOTEXCB (0 = disable EXCB pin as the inverted excitation output)
* Bit 3: EXCA (1 = enable EXCA pin as the excitation output)
* Bit 2: NOTEXCA (0 = disable EXCA pin as the inverted excitation output)
* Bit 1,0: EXCLV1 EXCLV0 (excitation voltage level)
* 11 = Voltage on cap = (+/- Vdd)/2
* EXC Pin Low Level = 0
* EXC Pin High Level = Vdd
*/
#define AD7746_EXC_SETUP_REG 0x09
#define AD7746_EXC_SET_A 0b01001011 // EXCON=1, EXCA=1, EXCLV=1, EXCLV0=1
/* Configuration register (spec page 18)
* Bit 7: VTF1
* Bit 6: VTF0 (00 = default digital filter setup)
* Bit 5: CAPF2
* Bit 4: CAPF1
* Bit 3: CAPF0 (001 = 11.9ms conversion time, 011 = 38.0ms, 111 = 109.6ms)
* Bit 2: MD2
* Bit 1: MD1
* Bit 0: MD0 (010 = single conversion, 000 = idle)
*/
#define AD7746_CFG_REG 0x0A
#define AD7746_CFG_C_11MS_SINGLE 0b00001010 // 0x0A = 11ms single cap convert
#define AD7746_CFG_C_38MS_SINGLE 0b00011010 // 0x1A = 38ms single cap convert
#define AD7746_CFG_C_109MS_SINGLE 0b00111010 // 0x3A = 109.6ms single cap convert
#define AD7746_CFG_T_20MS_SINGLE 0b00000010 // 0x02 = 20ms single temp convert
#define AD7746_CFG_T_32MS_SINGLE 0b01000010 // 0x42 = 32ms single temp convert
#define AD7746_CFG_T_62MS_SINGLE 0b10000010 // 0x82 = 62ms single temp convert
#define AD7746_CFG_T_DEFAULT AD7746_CFG_T_32MS_SINGLE
#define AD7746_TEMP_TRIGGER_RATE 10 // Trigger one temperature read every 10 cap reads
/* -----------------------------------------------------------------------------
* PCA9536 - Relay driver to switch back to old ACS connection
*/
#define PCA9536_ADDR 0x41
#define PCA9536_OUT_PORT_REG 0x01
#define PCA9536_OUT_PORT_RESET 0x00
#define PCA9536_OUT_PORT_NEW_ACS 0x05
#define PCA9536_OUT_PORT_OLD_ACS 0x0A
#define PCA9536_CONFIG_REG 0x03
#define PCA9536_CONFIG_ALL_OUTPUT 0x00
/* -----------------------------------------------------------------------------
* Task state machine discrete states, separate for each sensor
*/
typedef enum {
STATE_POR = 0,
STATE_IDLE = 1,
STATE_RESET = 2,
STATE_INIT = 3,
STATE_TRIGGER_CAP = 4,
STATE_TRIGGER_CAP_WAIT = 5,
STATE_TRIGGER_TEMPERATURE = 6,
STATE_TRIGGER_TEMP_WAIT = 7,
STATE_READ_TH = 8,
STATE_MAX
} sensor_state_t;
/* -----------------------------------------------------------------------------
* PCA9536 state, sets the LBL or Kona relay positions
*/
typedef enum {
RELAY_LBL = 0,
RELAY_KONA = 1
} relay_position_t;
/* -----------------------------------------------------------------------------
* Single / differential capacitance, or temperature, selection choices
*/
typedef enum {
MODE_C_DIFFERENTIAL = 0,
MODE_C_CAP1 = 1,
MODE_C_CAP2 = 2,
MODE_TEMPERATURE = 3
} sensor_mode_t;
/* -----------------------------------------------------------------------------
* Capacitance conversion times selection
*/
typedef enum {
CONVERT_TIME_109MS = 0, // Default
CONVERT_TIME_38MS = 1,
CONVERT_TIME_11MS = 2
} sensor_conversion_time_t;
/* -----------------------------------------------------------------------------
* Identity device / serial number defines
*/
#define SERIAL_NUMBER_SIZE 6
#ifdef SENSOR_TASK_C_
const char serial_number_default[SERIAL_NUMBER_SIZE] = {0, 0, 0, 0, 0, 0};
const char serial_number_invalid[SERIAL_NUMBER_SIZE] = {0x1D, 0xDE, 0xAD, 0, 0, 0};
#else
extern const char serial_number_default[SERIAL_NUMBER_SIZE];
extern const char serial_number_invalid[SERIAL_NUMBER_SIZE];
#endif
#define UC24AA02UID_OP_WRITE 0x50
#define UC24AA02UID_OP_READ 0x51
#define UC24AA02UID_SN_BASE 0xFA
/* -----------------------------------------------------------------------------
* Maxim MAX7310 port expander device - for use only with the capacitance sensor
* test set.
*/
#define MAX7310_ADDR_WRITE 0x18 //0x30
#define MAX7310_ADDR_READ 0x19 //0x31
#define MAX7310_INPUT_REG 0x00
#define MAX7310_OUTPUT_REG 0x01
#define MAX7310_CFG_REG 0x03
#define MAX7310_CFG_SET_OUTPUTS 0
#define MAX7310_TIMEOUT_REG 0x04
#define MAX7310_TIMEOUT_DISABLE 0
#define MAX7310_HOLD_TIME 4 // ms
/* A set of bit masks for the various outputs.
*
* On the drawing, the relays are setup to connect pins on one side (pins 3 and 6)
* to a selected set of pins on the other side (either 7 and 2, or 5 and 4). We will
* refer to these modes as "6-7 and 3-2 mode" versus "6-5 and 3-4 mode" which are
* two distinct settings of the relays that are selected by writing a 1 to IO pin 8
* and a 0 to IO pin 1. To achieve the other selection, write a 0 to IO8 and a 1 to
* IO1. Hold this for 4ms to let the relay switch.
*
* U4A and B control the sense side of the AD7746. Pin mode 6-7/3-2 enables the sense
* side connection.
*
* U5A and B control the excitation side of the AD7746. Pin mode 6-5/3-4 enables the
* excitation. (Yes, it's backwards compared to the other side.)
*
* U8A and B control the capacitors that are connected to the differential
* inputs. When in the pin 6-7 and 3-2 mode, the C8 (fixed) and C9 (variable)
* caps are connected. When in the pin 6-5 and 3-4 mode, the C10 (fixed) and
* C11 (fixed) are connected.
*
* For this to make more sense, look at the NB_Testset.pdf drawing sheet 3.
*/
#define CAP_RELAY_RESET 0b00000000
/* Define the connections between the relay pins and the MAX7310 IO lines.
* IOs 0 and 1 are not used. */
#define CAP_RELAY_U4_PIN1 0b01000000 // IO6
#define CAP_RELAY_U4_PIN8 0b10000000 // IO7
#define CAP_RELAY_U5_PIN1 0b00000100 // IO2
#define CAP_RELAY_U5_PIN8 0b00001000 // IO3
#define CAP_RELAY_U8_PIN1 0b00010000 // IO4
#define CAP_RELAY_U8_PIN8 0b00100000 // IO5
/* Assert the PIN8 value to connect 6-7 and 3-2
* Assert the PIN1 value to connect 6-5 and 3-4 */
#define CAP_RELAY_U4_67_32 CAP_RELAY_U4_PIN8
#define CAP_RELAY_U4_65_34 CAP_RELAY_U4_PIN1
#define CAP_RELAY_U5_67_32 CAP_RELAY_U5_PIN8
#define CAP_RELAY_U5_65_34 CAP_RELAY_U5_PIN1
#define CAP_RELAY_U8_67_32 CAP_RELAY_U8_PIN8
#define CAP_RELAY_U8_65_34 CAP_RELAY_U8_PIN1
/* Relay selection choices */
typedef enum {
CAP_RELAY_SET_UNKNOWN = 0,
CAP_RELAY_SET_67_32 = 1,
CAP_RELAY_SET_65_34 = 2
} cap_relay_position_t;
/* -----------------------------------------------------------------------------
* This structure contains the sensor state and latest values of the capacitance,
* temperature, humidity, and chip temperature. *
*/
typedef struct {
/* State machine */
sensor_state_t state;
/* Enabled for use flag. Not all sensors need to be connected, some
* mirror segments have fewer than 6 sensors on them. Note that this
* is called "disabled" instead of "enabled" so that the default value
* will be to enable all the sensors, and the node box software can
* selectively disable sensors as needed. */
bool enabled;
/* Connection status */
bool ad7746_connected;
/* Timers for the device */
timer_t timer_init;
timer_t timer_ready;
/* LBL-Kona Sensor switching */
relay_position_t relay_position, relay_position_previous;
/* Capacitor/temperature selection mode */
sensor_mode_t mode;
sensor_mode_t next_mode;
sensor_mode_t last_mode;
/* Flag that enables retrieving single-ended caps alongside differential;
* used only for debugging because it runs the differential cap retrieval
* at one third the usual sampling rate. */
bool enable_c1_c2;
/* Capacitor conversion time */
sensor_conversion_time_t conversion_time;
/* Capacitor conversion cycles, used to interleave temperature measurements */
uint8_t conversions;
/* Si7020 temperature+humidity sensing control */
bool si7020_connected;
uint8_t si7020_esn[8];
timer_t si7020_timer;
/* 24AA02UID serial EEPROM support with 6 bytes of a device serial number */
uint8_t serial_number[SERIAL_NUMBER_SIZE];
/* Capacitance test set relay positions */
bool max7310_connected;
bool max7310_configured;
cap_relay_position_t relay_u4_position, relay_u4_position_previous;
cap_relay_position_t relay_u5_position, relay_u5_position_previous;
cap_relay_position_t relay_u8_position, relay_u8_position_previous;
} sensor_control_t;
EXTERN sensor_control_t sensor_control[MAX_SENSORS];
/* -----------------------------------------------------------------------------
* Function prototypes
*/
EXTERN bool Relay_Init(sensor_name_t sensor);
EXTERN bool TH_Sensor_Init(sensor_name_t sensor);
EXTERN bool TH_Sensor_Read(sensor_name_t sensor);
EXTERN bool Sensor_Reset(sensor_name_t sensor);
EXTERN bool Sensor_Init(sensor_name_t sensor);
EXTERN bool Sensor_Trigger(sensor_name_t sensor, sensor_mode_t cap_mode);
EXTERN bool Sensor_Read(sensor_name_t sensor, sensor_mode_t cap_mode);
EXTERN void Sensor_Process(sensor_name_t sensor);
EXTERN uint32_t Sensor_Task_Init(void);
#undef EXTERN
#endif // SENSOR_TASK_H_