AMU Library 3.0
C/C++ library for communicating with AMU (Aerospace Measurement Unit) devices
Loading...
Searching...
No Matches
scpi.c
Go to the documentation of this file.
1
8
9#include "scpi.h"
10#include "amu_device.h"
11#include "amu_regs.h"
12#include "amu_config_internal.h"
13
15static volatile amu_device_t* scpi_amu_dev;
16
17
18#ifdef __AMU_USE_SCPI__
21#endif
22
23static scpi_t scpi_context;
24static scpi_interface_t scpi_interface;
25
26static size_t o_count = 1;
27
28#define SCPI_Param_amu_pid_t(c, v, b) SCPI_ParamArrayFloat(c, v, 3, &o_count, SCPI_FORMAT_ASCII, b)
29#define SCPI_Result_amu_pid_t(c, v) SCPI_ResultArrayFloat(c, (float *)&(v), 3, SCPI_FORMAT_ASCII)
30
31#define SCPI_Param_amu_coeff_t(c, v, b) SCPI_ParamArrayFloat(c, v, 4, &o_count, SCPI_FORMAT_ASCII, b)
32#define SCPI_Result_amu_coeff_t(c, v) SCPI_ResultArrayFloat(c, (float *)&(v), 4, SCPI_FORMAT_ASCII)
33
34#define SCPI_Param_amu_notes_t(c, v, b) SCPI_ParamCopyText(c, v, AMU_NOTES_SIZE, &o_count, b)
35#define SCPI_Result_amu_notes_t(c, v) SCPI_ResultText(c, (char *)v)
36
37#define SCPI_Param_ss_angle_t(c, v, b) SCPI_ParamArrayFloat(c, v, 6, &o_count, SCPI_FORMAT_ASCII, b)
38#define SCPI_Result_ss_angle_t(c, v) SCPI_ResultArrayFloat(c, (float *)&(v), 6, SCPI_FORMAT_ASCII)
39
40#define SCPI_Param_press_data_t(c, v, b) SCPI_ParamArrayFloat(c, v, 4, &o_count, SCPI_FORMAT_ASCII, b)
41#define SCPI_Result_press_data_t(c, v) SCPI_ResultArrayFloat(c, (float *)&(v), 4, SCPI_FORMAT_ASCII)
42
43#define SCPI_Param_amu_int_volt_t(c, v, b) SCPI_ParamArrayFloat(c, v, 4, &o_count, SCPI_FORMAT_ASCII, b)
44#define SCPI_Result_amu_int_volt_t(c, v) SCPI_ResultArrayFloat(c, (float *)&(v), 4, SCPI_FORMAT_ASCII)
45
46#define SCPI_Param_amu_meas_t(c, v, b) SCPI_ParamArrayFloat(c, v, 2, &o_count, SCPI_FORMAT_ASCII, b)
47#define SCPI_Result_amu_meas_t(c, v) SCPI_ResultArrayFloat(c, (float *)&(v), 2, SCPI_FORMAT_ASCII)
48
50
51
52#define SCPI_CMD_RW(TYPE) \
53scpi_result_t scpi_cmd_rw_##TYPE(scpi_t *context) { \
54 \
55 int32_t channel = -1; \
56 \
57 memset((void *)scpi_amu_dev->transfer_reg, 0, sizeof(TYPE)); \
58 \
59 SCPI_CommandNumbers(context, &channel, 1, -1); \
60 \
61 scpi_amu_dev->transfer_reg[0] = channel; \
62 \
63 if(!context->query) { \
64 if(channel >= 0) { \
65 if( !SCPI_Param_##TYPE(context, (void *)&scpi_amu_dev->transfer_reg[1], TRUE)) return SCPI_RES_ERR; \
66 } \
67 else { \
68 channel = 0; \
69 if( !SCPI_Param_##TYPE(context, (void *)scpi_amu_dev->transfer_reg, TRUE)) return SCPI_RES_ERR; \
70 } \
71 } \
72 else \
73 channel = 0; \
74 \
75 _scpi_get_channelList(context); \
76 \
77 for(uint8_t *device = scpi_channel_list; *device != AMU_DEVICE_END_LIST; device++) { \
78 if(context->query) { \
79 if( SCPI_CmdTag(context) >= CMD_I2C_USB ) \
80 _amu_route_command(*device, (SCPI_CmdTag(context) | CMD_READ), sizeof(TYPE), true); \
81 else \
82 _amu_route_command(*device, SCPI_CmdTag(context), sizeof(TYPE), true); \
83 \
84 TYPE *data = (TYPE *)scpi_amu_dev->transfer_reg; \
85 SCPI_Result_##TYPE(context, *data); \
86 } \
87 else { \
88 _amu_route_command(*device, SCPI_CmdTag(context), sizeof(TYPE), false); \
89 } \
90 } \
91 \
92 return SCPI_RES_OK; \
93} \
94
96SCPI_CMD_RW(uint16_t)
97SCPI_CMD_RW(uint32_t)
107
108#define SCPI_CMD_EXEC_QRY(TYPE) \
109scpi_result_t scpi_cmd_exec_qry_##TYPE(scpi_t *context) { \
110 \
111 int32_t channel = -1; \
112 \
113 memset((void *)scpi_amu_dev->transfer_reg, 0, sizeof(TYPE)); \
114 \
115 SCPI_CommandNumbers(context, &channel, 1, -1); \
116 \
117 scpi_amu_dev->transfer_reg[0] = channel; \
118 \
119 _scpi_get_channelList(context); \
120 \
121 for(uint8_t *device = scpi_channel_list; *device != AMU_DEVICE_END_LIST; device++) { \
122 if(context->query) { \
123 if( SCPI_CmdTag(context) >= CMD_I2C_USB ) \
124 _amu_route_command(*device, (SCPI_CmdTag(context) | CMD_READ), sizeof(TYPE), true); \
125 else \
126 _amu_route_command(*device, SCPI_CmdTag(context), sizeof(TYPE), true); \
127 \
128 TYPE *data = (TYPE *)scpi_amu_dev->transfer_reg; \
129 SCPI_Result_##TYPE(context, *data); \
130 } \
131 else { \
132 if( channel == -1) \
133 _amu_route_command(*device, SCPI_CmdTag(context), 0, false); \
134 else \
135 _amu_route_command(*device, SCPI_CmdTag(context), 1, false); \
136 } \
137 } \
138 \
139 return SCPI_RES_OK; \
140} \
141
146
147// If commmand number exists, it's placed in the first byte of the transfer register
148// NO parameters, otherwise error is thrown.
150
151 int32_t* commandNumber = (int32_t*)scpi_amu_dev->transfer_reg;
152
153 SCPI_CommandNumbers(context, commandNumber, 1, -1);
154
155 _scpi_get_channelList(context);
156
157 for (uint8_t* device = scpi_channel_list; *device != AMU_DEVICE_END_LIST; device++) {
158 if (*commandNumber == -1)
159 _amu_route_command(*device, SCPI_CmdTag(context), 0, false);
160 else
161 _amu_route_command(*device, SCPI_CmdTag(context), 1, false);
162 }
163 return SCPI_RES_OK;
164}
165
167
168 uint8_t numPoints;
169
170 _scpi_get_channelList(context);
171
172 for (uint8_t* device = scpi_channel_list; *device != AMU_DEVICE_END_LIST; device++) {
173
175 numPoints = scpi_amu_dev->transfer_reg[0];
176
177 switch ((AMU_REG_DATA_PTR_t)SCPI_CmdTag(context)) {
179 _amu_route_command(*device, SCPI_CmdTag(context), numPoints * sizeof(uint32_t), true);
180 SCPI_ResultArrayUInt32(context, (uint32_t*)&scpi_amu_dev->transfer_reg[0], numPoints, SCPI_FORMAT_ASCII);
181 break;
186 _amu_route_command(*device, SCPI_CmdTag(context), numPoints * sizeof(float), true);
187 SCPI_ResultArrayFloat(context, (float*)&scpi_amu_dev->transfer_reg[0], numPoints, SCPI_FORMAT_ASCII);
188 break;
190 _amu_route_command(*device, SCPI_CmdTag(context), sizeof(ivsweep_config_t), true);
191 SCPI_ResultArrayUInt8(context, (uint8_t*)&scpi_amu_dev->transfer_reg[0], 8, SCPI_FORMAT_ASCII);
192 SCPI_ResultArrayFloat(context, (float*)&scpi_amu_dev->transfer_reg[8], 2, SCPI_FORMAT_ASCII);
193 break;
195 _amu_route_command(*device, SCPI_CmdTag(context), sizeof(ivsweep_meta_t), true);
196 SCPI_ResultArrayFloat(context, (float*)&scpi_amu_dev->transfer_reg[0], 10, SCPI_FORMAT_ASCII);
197 SCPI_ResultArrayUInt32(context, (uint32_t*)&scpi_amu_dev->transfer_reg[40], 2, SCPI_FORMAT_ASCII);
198 break;
200 _amu_route_command(*device, SCPI_CmdTag(context), sizeof(ss_angle_t), true);
201 SCPI_ResultArrayFloat(context, (float*)&scpi_amu_dev->transfer_reg[0], 2, SCPI_FORMAT_ASCII);
202 break;
204 _amu_route_command(*device, SCPI_CmdTag(context), sizeof(press_data_t), true);
205 SCPI_ResultArrayFloat(context, (float*)&scpi_amu_dev->transfer_reg[0], 4, SCPI_FORMAT_ASCII);
206 break;
207 default: break;
208 }
209
210 }
211
212 return SCPI_RES_OK;
213}
214
216
217 if (!SCPI_ParamArrayFloat(context, (void*)scpi_amu_dev->transfer_reg, AMU_TRANSFER_REG_SIZE / sizeof(float), &o_count, SCPI_FORMAT_ASCII, TRUE)) return SCPI_RES_ERR;
218
219 _scpi_get_channelList(context);
220
221 for (uint8_t* device = scpi_channel_list; *device != AMU_DEVICE_END_LIST; device++) {
223 _amu_route_command(*device, SCPI_CmdTag(context), (o_count * sizeof(float)), false);
224 else
225 return SCPI_RES_ERR;
226 }
227
228 return SCPI_RES_OK;
229}
230
232
233 uint32_t sweepSettingsUint32_t[8];
234 uint8_t* sweepSettings = (uint8_t*)scpi_amu_dev->transfer_reg;
235 float* am0 = (float*)&scpi_amu_dev->transfer_reg[8];
236 float* area = (float*)&scpi_amu_dev->transfer_reg[12];
237
238 if (!SCPI_ParamArrayUInt32(context, sweepSettingsUint32_t, 8, &o_count, SCPI_FORMAT_ASCII, TRUE)) return SCPI_RES_ERR;
239 if (!SCPI_ParamFloat(context, am0, TRUE)) return SCPI_RES_ERR;
240 if (!SCPI_ParamFloat(context, area, TRUE)) return SCPI_RES_ERR;
241
242 _scpi_get_channelList(context);
243
244 //Convert uint32_t values to uint8_t and move them into the transfer register
245 for (uint8_t i = 0; i < 8; i++) {
246 sweepSettings[i] = (uint8_t)sweepSettingsUint32_t[i];
247 }
248
249 for (uint8_t* device = scpi_channel_list; *device != AMU_DEVICE_END_LIST; device++) {
250 _amu_route_command(*device, SCPI_CmdTag(context), sizeof(ivsweep_config_t), context->query);
251 }
252
253 return SCPI_RES_OK;
254}
255
257
258 if (!SCPI_ParamArrayFloat(context, (void*)scpi_amu_dev->transfer_reg, 9, &o_count, SCPI_FORMAT_ASCII, TRUE)) return SCPI_RES_ERR;
259 if (!SCPI_ParamUInt32(context, (void*)&scpi_amu_dev->transfer_reg[36], TRUE)) return SCPI_RES_ERR;
260
261 _scpi_get_channelList(context);
262
263 for (uint8_t* device = scpi_channel_list; *device != AMU_DEVICE_END_LIST; device++) {
264 _amu_route_command(*device, SCPI_CmdTag(context), sizeof(ivsweep_meta_t), context->query);
265 }
266
267 return SCPI_RES_OK;
268}
269
270scpi_result_t _scpi_cmd_led(scpi_t* context) {
271
272 if (!SCPI_ParamUInt32(context, (void*)scpi_amu_dev->transfer_reg, TRUE)) return SCPI_RES_ERR;
273
274 _scpi_get_channelList(context);
275
276 for (uint8_t* device = scpi_channel_list; *device != AMU_DEVICE_END_LIST; device++) {
277 _amu_route_command(*device, (CMD_t)(SCPI_CmdTag(context) + scpi_amu_dev->transfer_reg[0]), sizeof(uint8_t), false);
278 }
279
280 return SCPI_RES_OK;
281}
282
284
285 int32_t channel = -1;
286
287 memset((void*)scpi_amu_dev->transfer_reg, 0, 4);
288
289 SCPI_CommandNumbers(context, &channel, 1, -1);
290
291 if (channel == -1)
292 channel = SCPI_CmdTag(context) & 0x0F; // So instead, use the tag
293 else
294 scpi_amu_dev->transfer_reg[0] = channel;
295
296 if (channel > 15)
297 return SCPI_RES_ERR;
298
299 if (!context->query) {
300 return SCPI_RES_ERR;
301 }
302
303 _scpi_get_channelList(context);
304
305 for (uint8_t* device = scpi_channel_list; *device != AMU_DEVICE_END_LIST; device++) {
306
307 if (SCPI_CmdTag(context) >= CMD_I2C_USB)
308 _amu_route_command(*device, (SCPI_CmdTag(context) | CMD_READ), 4, true);
309 else
310 _amu_route_command(*device, SCPI_CmdTag(context), 4, true);
311
312
313 if (strstr(context->param_list.cmd_raw.data, "RAW"))
314 SCPI_ResultUInt32Base(context, scpi_amu_dev->amu_regs->adc_raw.channel[channel], 16);
315 else
317 }
318
319 return SCPI_RES_OK;
320}
321
323
324 _scpi_get_channelList(context); // Get the list of channels to act on
325
326 uint16_t* activeChannels = (uint16_t*)scpi_amu_dev->transfer_reg;
327 uint8_t numChannels = 0;
328
329 for (uint8_t* device = scpi_channel_list; *device != AMU_DEVICE_END_LIST; device++) {
330
331 _amu_route_command(*device, AMU_REG_SYSTEM_ADC_ACTIVE_CHANNELS, sizeof(uint16_t), true);
332
333 for (uint16_t i = 0; i < 16; i++) {
334 if (*activeChannels & (1 << i))
335 numChannels++;
336 }
337
338 _amu_route_command(*device, SCPI_CmdTag(context), numChannels * 4, false);
339
340 if (numChannels > 0) {
341 SCPI_ResultArrayFloat(context, (float*)scpi_amu_dev->transfer_reg, numChannels, SCPI_FORMAT_ASCII);
342 }
343 }
344
345 return SCPI_RES_OK;
346}
347
349
350 _scpi_get_channelList(context); // Get the list of channels to act on
351
352 for (uint8_t* device = scpi_channel_list; *device != AMU_DEVICE_END_LIST; device++) {
353
354 _amu_route_command(*device, SCPI_CmdTag(context), 12, true);
355
356 SCPI_ResultArrayFloat(context, (float*)scpi_amu_dev->transfer_reg, 3, SCPI_FORMAT_ASCII);
357 }
358
359 return SCPI_RES_OK;
360}
361
363
364 if (!context->query) {
365 if (!SCPI_ParamCopyText(context, (void*)scpi_amu_dev->transfer_reg, AMU_TRANSFER_REG_SIZE, &o_count, TRUE)) return SCPI_RES_ERR;
366 }
367
368 _scpi_get_channelList(context); // Get the list of channels to act on
369
370 for (uint8_t* device = scpi_channel_list; *device != AMU_DEVICE_END_LIST; device++) {
371
372 if (context->query) {
373 if (SCPI_CmdTag(context) >= CMD_I2C_USB) {
374 switch (SCPI_CmdTag(context)) {
375 case CMD_SYSTEM_FIRMWARE: _amu_route_command(*device, (SCPI_CmdTag(context) | CMD_READ), AMU_FIRMWARE_STR_LEN, true); break;
376 case CMD_SYSTEM_SERIAL_NUM: _amu_route_command(*device, (SCPI_CmdTag(context) | CMD_READ), AMU_SERIALNUM_STR_LEN, true); break;
377 case CMD_DUT_MANUFACTURER: _amu_route_command(*device, (SCPI_CmdTag(context) | CMD_READ), sizeof(scpi_amu_dev->amu_regs->dut.manufacturer), true); break;
378 case CMD_DUT_MODEL: _amu_route_command(*device, (SCPI_CmdTag(context) | CMD_READ), sizeof(scpi_amu_dev->amu_regs->dut.model), true); break;
379 case CMD_DUT_TECHNOLOGY: _amu_route_command(*device, (SCPI_CmdTag(context) | CMD_READ), sizeof(scpi_amu_dev->amu_regs->dut.technology), true); break;
380 case CMD_DUT_SERIAL_NUMBER: _amu_route_command(*device, (SCPI_CmdTag(context) | CMD_READ), sizeof(scpi_amu_dev->amu_regs->dut.serial), true); break;
381 case CMD_DUT_NOTES: _amu_route_command(*device, (SCPI_CmdTag(context) | CMD_READ), AMU_NOTES_SIZE, true); break;
382 default: _amu_route_command(*device, (SCPI_CmdTag(context) | CMD_READ), AMU_TRANSFER_REG_SIZE, true); break;
383 }
384 }
385 else {
386 switch (SCPI_CmdTag(context)) {
387 default: _amu_route_command(*device, (SCPI_CmdTag(context)), sizeof(scpi_amu_dev->transfer_reg), true); break;
388 case AMU_REG_DUT_MANUFACTURER: _amu_route_command(*device, (SCPI_CmdTag(context)), sizeof(scpi_amu_dev->amu_regs->dut.manufacturer), true); break;
389 case AMU_REG_DUT_MODEL: _amu_route_command(*device, (SCPI_CmdTag(context)), sizeof(scpi_amu_dev->amu_regs->dut.model), true); break;
390 case AMU_REG_DUT_TECHNOLOGY: _amu_route_command(*device, (SCPI_CmdTag(context)), sizeof(scpi_amu_dev->amu_regs->dut.technology), true); break;
391 case AMU_REG_DUT_SERIAL_NUMBER: _amu_route_command(*device, (SCPI_CmdTag(context)), sizeof(scpi_amu_dev->amu_regs->dut.serial), true); break;
392 }
393 }
394
395 SCPI_ResultText(context, (const char*)scpi_amu_dev->transfer_reg);
396 }
397 else {
398 if (SCPI_CmdTag(context) >= CMD_I2C_USB) {
399 switch (SCPI_CmdTag(context)) {
400 case CMD_SYSTEM_FIRMWARE: _amu_route_command(*device, (SCPI_CmdTag(context)), AMU_FIRMWARE_STR_LEN, false); break;
401 case CMD_SYSTEM_SERIAL_NUM: _amu_route_command(*device, (SCPI_CmdTag(context)), AMU_SERIALNUM_STR_LEN, false); break;
402 case CMD_DUT_MANUFACTURER: _amu_route_command(*device, (SCPI_CmdTag(context)), sizeof(scpi_amu_dev->amu_regs->dut.manufacturer), false); break;
403 case CMD_DUT_MODEL: _amu_route_command(*device, (SCPI_CmdTag(context)), sizeof(scpi_amu_dev->amu_regs->dut.model), false); break;
404 case CMD_DUT_TECHNOLOGY: _amu_route_command(*device, (SCPI_CmdTag(context)), sizeof(scpi_amu_dev->amu_regs->dut.technology), false); break;
405 case CMD_DUT_SERIAL_NUMBER: _amu_route_command(*device, (SCPI_CmdTag(context)), sizeof(scpi_amu_dev->amu_regs->dut.serial), false); break;
406 case CMD_DUT_NOTES: _amu_route_command(*device, (SCPI_CmdTag(context)), AMU_NOTES_SIZE, false); break;
407 default: _amu_route_command(*device, (SCPI_CmdTag(context)), AMU_TRANSFER_REG_SIZE, false); break;
408 }
409 }
410 }
411 }
412
413 return SCPI_RES_OK;
414}
415
417
418 int32_t* commandNumber = (int32_t*)scpi_amu_dev->transfer_reg;
419
420 SCPI_CommandNumbers(context, commandNumber, 1, -1);
421
422 _scpi_get_channelList(context);
423
424 for (uint8_t* device = scpi_channel_list; *device != AMU_DEVICE_END_LIST; device++) {
425 if (*device == AMU_THIS_DEVICE) {
426 _amu_route_command(*device, SCPI_CmdTag(context), sizeof(uint8_t), context->query);
428 for (uint8_t i = 0; i < amu_get_num_devices(); i++) {
429 if (i == AMU_THIS_DEVICE)
430 SCPI_ResultUInt8(context, scpi_amu_dev->twi_address);
431 else
433 }
434 }
435 }
436 return SCPI_RES_OK;
437}
438
439static size_t SCPI_Write(scpi_t* context, const char* data, size_t len) {
440 (void)context;
441 return scpi_amu_dev->scpi_dev.write_cmd(data, len);
442}
443
445
446 char buffer[32];
447
448if (ctrl == 1) {
449
450#if defined(HAVE_SNPRINTF)
451 snprintf(buffer, sizeof(buffer), "**SRQ: 0x%X", val);
452 context->interface->write(context, buffer, sizeof(buffer));
453#else
454 context->interface->write(context, "**SRQ: 0x", 10);
455 context->interface->write(context, itoa(val, buffer, 16), sizeof(buffer));
456#endif
457 context->interface->write(context, SCPI_LINE_ENDING, sizeof(SCPI_LINE_ENDING));
458 }
459 else {
460
461#if defined(HAVE_SNPRINTF)
462 snprintf(buffer, sizeof(buffer), "**CTRL: 0x%X: 0x%X", ctrl, val);
463 context->interface->write(context, buffer, sizeof(buffer));
464#else
465 context->interface->write(context, "**CTRL: 0x", 11);
466 context->interface->write(context, itoa(ctrl, buffer, 16), sizeof(buffer));
467 context->interface->write(context, ": 0x", 5);
468 context->interface->write(context, itoa(val, buffer, 16), sizeof(buffer));
469#endif
470 context->interface->write(context, SCPI_LINE_ENDING, sizeof(SCPI_LINE_ENDING));
471 }
472
473 return SCPI_RES_OK;
474}
475
476static scpi_result_t SCPI_Reset(scpi_t* context) {
477 if (scpi_amu_dev->scpi_dev.reset_cmd)
478 scpi_amu_dev->scpi_dev.reset_cmd();
479 return SCPI_RES_OK;
480}
481
482static scpi_result_t SCPI_Flush(scpi_t* context) {
483 if (scpi_amu_dev->scpi_dev.flush_cmd)
484 scpi_amu_dev->scpi_dev.flush_cmd();
485 return SCPI_RES_OK;
486}
487
488
489// This is difficult to read, but necessary in order to place SCPI strings in program memory, otherwise, we use up ~3K of SRAM or ~40%
490// First SCPI_COMMAND def applies above, (SCPI_COMMANDS hasn't been called yet, so we can define it after)
491// The first call creates program memory char[] pointers for every command as a variable which looks like i.e. scpi_amu_heater_CMD_WRITE_HEATER_PID
492// After defining all the areas, we redefine SCPI_COMMAND to place these arrays into the scpi_commands[] array, with the corresponding function and tag calls
493
494#ifdef __AMU_USE_SCPI__
495
496#ifndef SCPI_COMMAND
497#ifdef SCPI_USE_PROGMEM
498 #define SCPI_COMMAND(P, C, T) static const char C ## _ ## T ## _pattern[] PROGMEM = P;
499#else
500 #define SCPI_COMMAND(P, C, T) static const char C ## _ ## T ## _pattern[] = P;
501#endif
502#endif
503
504
505#ifdef __AMU_LOW_MEMORY__
507#else
510#endif
511
512#undef SCPI_COMMAND
513
514#define SCPI_COMMAND(P, C, T) {C ## _ ## T ## _pattern, C, T},
515#ifdef __AMU_SCPI_USE_PROGMEM__
516 static const scpi_command_t scpi_def_commands[] PROGMEM = {
517#else
518 static const scpi_command_t scpi_def_commands[] = {
519#endif
520
521#ifdef __AMU_LOW_MEMORY__
524#else
528#endif
529};
530
531#endif
532
533#undef SCPI_COMMAND
534
535void amu_scpi_init(volatile amu_device_t* dev, const char* idn1, const char* idn2, const char* idn3, const char* idn4) {
536
537 scpi_amu_dev = dev;
538
539 scpi_interface.error = NULL;
544
545#ifdef __AMU_USE_SCPI__
547 scpi_def_commands,
550 idn1,
551 idn2,
552 idn3,
553 idn4,
556#endif
557
558}
559
560void amu_scpi_update(const char incomingByte) {
561#ifdef __AMU_USE_SCPI__
562 SCPI_Input(&scpi_context, &incomingByte, 1);
563#endif
564}
565
566void amu_scpi_update_buffer(const char* buffer, size_t len) {
567#ifdef __AMU_USE_SCPI__
568 SCPI_Input(&scpi_context, buffer, len);
569#endif
570}
571
572void amu_scpi_add_aux_commands(const scpi_command_t* aux_cmd_list) {
573#ifdef __AMU_USE_SCPI__
574 scpi_context.aux_cmdlist = aux_cmd_list;
575#endif
576}
577
578void amu_scpi_list_commands(void) {
579
580 int32_t i;
581
582#ifdef __AMU_SCPI_USE_PROGMEM__
583
584 char cmd_pattern[SCPI_MAX_CMD_PATTERN_SIZE];
585
586 PGM_P pattern = (PGM_P)pgm_read_word(&(scpi_context.def_cmdlist[0].pattern));
587 strncpy_P(cmd_pattern, pattern, SCPI_MAX_CMD_PATTERN_SIZE);
588 scpi_context.interface->write(&scpi_context, cmd_pattern, strlen(cmd_pattern));
589
590 for (i = 1; (pattern = (PGM_P)pgm_read_word(&(scpi_context.def_cmdlist[i].pattern))) != 0; i++) {
591 strncpy_P(cmd_pattern, pattern, SCPI_MAX_CMD_PATTERN_SIZE);
592 scpi_context.interface->write(&scpi_context, cmd_pattern, strlen(cmd_pattern));
593 }
594
595 if (scpi_context.aux_cmdlist != NULL) {
596 PGM_P pattern = (PGM_P)pgm_read_word(&(scpi_context.aux_cmdlist[0].pattern));
597 strncpy_P(cmd_pattern, pattern, SCPI_MAX_CMD_PATTERN_SIZE);
598 scpi_context.interface->write(&scpi_context, cmd_pattern, strlen(cmd_pattern));
599
600 for (i = 1; (pattern = (PGM_P)pgm_read_word(&(scpi_context.aux_cmdlist[i].pattern))) != 0; i++) {
601 strncpy_P(cmd_pattern, pattern, SCPI_MAX_CMD_PATTERN_SIZE);
602 scpi_context.interface->write(&scpi_context, cmd_pattern, strlen(cmd_pattern));
603 }
604 }
605
606#else
607
608 char* cmd_pattern;
609
610 char message[] = "SCPI Commands:\n";
611 scpi_context.interface->write(&scpi_context, message, sizeof(message) - 1);
612
613 // if( scpi_context.def_cmdlist == NULL ) {
614 // scpi_context.interface->write(&scpi_context, "No commands defined", 19);
615 // scpi_context.interface->write(&scpi_context, SCPI_LINE_ENDING, sizeof(SCPI_LINE_ENDING));
616 // return;
617 // }
618
619 // // Debug: Check first command
620 // if( scpi_context.def_cmdlist[0].pattern == NULL ) {
621 // scpi_context.interface->write(&scpi_context, "First command pattern is NULL", 29);
622 // scpi_context.interface->write(&scpi_context, SCPI_LINE_ENDING, sizeof(SCPI_LINE_ENDING));
623 // return;
624 // }
625
626 for (i = 0; (cmd_pattern = (char*)scpi_context.def_cmdlist[i].pattern) != 0; i++) {
627 scpi_context.interface->write(&scpi_context, cmd_pattern, strlen(cmd_pattern));
628 scpi_context.interface->write(&scpi_context, ",", 1);
629 }
630
631
632 if (scpi_context.aux_cmdlist != NULL) {
633 for (i = 0; (cmd_pattern = (char*)scpi_context.aux_cmdlist[i].pattern) != 0; i++) {
634 scpi_context.interface->write(&scpi_context, cmd_pattern, strlen(cmd_pattern));
635 scpi_context.interface->write(&scpi_context, ",", 1);
636 }
637 }
638
639#endif
640
642
643}
644
645
646
647int16_t _scpi_get_channelList(scpi_t* context) {
648
649 scpi_parameter_t channel_list_param;
650 uint8_t scpi_list_iterator = 0;
651
652 //Checks for any parameter
653 if (SCPI_Parameter(context, &channel_list_param, FALSE)) {
654
655 scpi_bool_t is_range;
656 size_t dimensions;
657
658 /* the next statement is valid usage and it gets only real number of dimensions for the first item (index 0) */
659 if (!SCPI_ExprChannelListEntry(context, &channel_list_param, 0, &is_range, NULL, NULL, 0, &dimensions)) {
660
661 size_t param_idx = 0; /* index for channel list */
662 int8_t direction = 1; /* direction of counter for rows, +/-1 */
663 int32_t address_start = 0;
664 int32_t address_end = 0;
665
666
667 while (SCPI_EXPR_OK == SCPI_ExprChannelListEntry(context, &channel_list_param, param_idx, &is_range, &address_start, &address_end, 1, &dimensions)) {
668
669 if ((dimensions != 1) | (address_start > 63)) {
670 scpi_channel_list[scpi_list_iterator] = AMU_DEVICE_END_LIST;
671 return FALSE;
672 }
673
674 if (is_range) {
675
676 if (address_end > 63) {
677 scpi_channel_list[scpi_list_iterator] = AMU_DEVICE_END_LIST;
678 return FALSE;
679 }
680
681 for ((address_start > address_end) ? (direction = -1) : (direction = 1); address_start != address_end; address_start += direction)
682 scpi_channel_list[scpi_list_iterator++] = address_start;
683
684 scpi_channel_list[scpi_list_iterator++] = address_start;
685
686 }
687 else {
688 scpi_channel_list[scpi_list_iterator++] = address_start;
689 }
690
691 /* increase index */
692 param_idx++;
693 }
694 }
695 }
696 else { //No parameter list
697 scpi_channel_list[scpi_list_iterator++] = 0;
698 }
699
700 scpi_channel_list[scpi_list_iterator] = AMU_DEVICE_END_LIST;
701
702 return TRUE;
703}
#define CMD_I2C_USB
TODO.
#define CMD_READ
CMD_t
uint8_t amu_get_device_address(uint8_t deviceNum)
Device addresses are used for TODO.
Definition amu_device.c:224
int8_t amu_get_num_devices()
Definition amu_device.c:210
uint8_t _amu_route_command(uint8_t deviceNum, CMD_t cmd, size_t transferLen, bool query)
TODO.
Definition amu_device.c:242
#define AMU_SERIALNUM_STR_LEN
Definition amu_device.h:28
#define AMU_FIRMWARE_STR_LEN
Definition amu_device.h:29
#define AMU_MAX_CONNECTED_DEVICES
Definition amu_device.h:21
static float transfer_read_float(void)
Definition amu_device.h:107
@ AMU_REG_SYSTEM_ADC_ACTIVE_CHANNELS
Definition amu_regs.h:43
AMU_REG_DATA_PTR_t
Definition amu_regs.h:137
@ AMU_REG_DATA_PTR_VOLTAGE
Definition amu_regs.h:140
@ AMU_REG_DATA_PTR_PRESSURE
Definition amu_regs.h:147
@ AMU_REG_DATA_PTR_SWEEP_CONFIG
Definition amu_regs.h:144
@ AMU_REG_DATA_PTR_SS_YAW
Definition amu_regs.h:142
@ AMU_REG_DATA_PTR_CURRENT
Definition amu_regs.h:141
@ AMU_REG_DATA_PTR_TIMESTAMP
Definition amu_regs.h:139
@ AMU_REG_DATA_PTR_SWEEP_META
Definition amu_regs.h:145
@ AMU_REG_DATA_PTR_SS_PITCH
Definition amu_regs.h:143
@ AMU_REG_DATA_PTR_SUNSENSOR
Definition amu_regs.h:146
@ AMU_REG_SWEEP_CONFIG_NUM_POINTS
Definition amu_regs.h:107
@ AMU_REG_DUT_MODEL
Definition amu_regs.h:55
@ AMU_REG_DUT_SERIAL_NUMBER
Definition amu_regs.h:57
@ AMU_REG_DUT_TECHNOLOGY
Definition amu_regs.h:56
@ AMU_REG_DUT_MANUFACTURER
Definition amu_regs.h:54
char amu_notes_t[128]
Definition amu_types.h:174
#define AMU_NOTES_SIZE
Definition amu_types.h:26
#define IVSWEEP_MAX_POINTS
Definition amu_types.h:29
#define AMU_TRANSFER_REG_SIZE
Definition amu_types.h:30
#define AMU_THIS_DEVICE
Definition amu_types.h:24
#define AMU_DEVICE_END_LIST
Definition amu_types.h:22
#define SCPI_MAX_CMD_PATTERN_SIZE
Definition config.h:46
#define SCPI_LINE_ENDING
Definition config.h:54
scpi_expr_result_t SCPI_ExprChannelListEntry(scpi_t *context, scpi_parameter_t *param, int index, scpi_bool_t *isRange, int32_t *valuesFrom, int32_t *valuesTo, size_t length, size_t *dimensions)
Definition expression.c:266
@ SCPI_EXPR_OK
Definition expression.h:46
@ CMD_DUT_MANUFACTURER
Sets or queries DUT manufacturer name.
@ CMD_DUT_MODEL
Sets or queries DUT model/part number.
@ CMD_DUT_TECHNOLOGY
Sets or queries DUT semiconductor technology.
@ CMD_DUT_SERIAL_NUMBER
Sets or queries DUT serial number.
@ CMD_DUT_NOTES
Sets or queries DUT documentation notes.
@ CMD_SYSTEM_FIRMWARE
Returns firmware version string.
@ CMD_SYSTEM_SERIAL_NUM
Returns unique device serial number.
scpi_bool_t SCPI_ParamFloat(scpi_t *context, void *value, scpi_bool_t mandatory)
Definition parser.c:1032
uint16_t SCPI_CmdTag(scpi_t *context)
Definition parser.c:1593
scpi_bool_t SCPI_CommandNumbers(scpi_t *context, int32_t *numbers, size_t len, int32_t default_value)
Definition parser.c:1606
scpi_bool_t SCPI_ParamArrayFloat(scpi_t *context, float *data, size_t i_count, size_t *o_count, scpi_array_format_t format, scpi_bool_t mandatory)
Definition parser.c:1903
scpi_bool_t SCPI_Parameter(scpi_t *context, scpi_parameter_t *parameter, scpi_bool_t mandatory)
Definition parser.c:774
scpi_bool_t SCPI_ParamArrayUInt32(scpi_t *context, uint32_t *data, size_t i_count, size_t *o_count, scpi_array_format_t format, scpi_bool_t mandatory)
Definition parser.c:1864
size_t SCPI_ResultText(scpi_t *context, const char *data)
Definition parser.c:600
size_t SCPI_ResultUInt32Base(scpi_t *context, uint32_t val, int8_t base)
Definition parser.c:538
size_t SCPI_ResultArrayUInt8(scpi_t *context, const uint8_t *array, size_t count, scpi_array_format_t format)
Definition parser.c:1728
scpi_bool_t SCPI_Input(scpi_t *context, const char *data, int len)
Definition parser.c:394
scpi_bool_t SCPI_ParamUInt32(scpi_t *context, void *value, scpi_bool_t mandatory)
Definition parser.c:1169
size_t SCPI_ResultArrayUInt32(scpi_t *context, const uint32_t *array, size_t count, scpi_array_format_t format)
Definition parser.c:1776
size_t SCPI_ResultArrayFloat(scpi_t *context, const float *array, size_t count, scpi_array_format_t format)
Definition parser.c:1812
size_t SCPI_ResultFloat(scpi_t *context, float val)
Definition parser.c:568
scpi_bool_t SCPI_ParamCopyText(scpi_t *context, char *buffer, size_t buffer_len, size_t *copy_len, scpi_bool_t mandatory)
Definition parser.c:1263
void SCPI_Init(scpi_t *context, const scpi_command_t *def_cmds, scpi_interface_t *interface, const scpi_unit_def_t *units, const char *idn1, const char *idn2, const char *idn3, const char *idn4, char *input_buffer, size_t input_buffer_length, scpi_error_t *error_queue_data, int16_t error_queue_size)
Definition parser.c:337
#define SCPI_ResultUInt8(c, v)
Definition parser.h:63
#define SCPI_ResultInt8(c, v)
Definition parser.h:64
static scpi_interface_t scpi_interface
Definition scpi.c:24
scpi_result_t _scpi_write_config_ptr(scpi_t *context)
Definition scpi.c:231
scpi_result_t scpi_cmd_execute(scpi_t *context)
Definition scpi.c:149
static size_t o_count
Definition scpi.c:26
scpi_result_t _scpi_cmd_measure_channel(scpi_t *context)
Definition scpi.c:283
static scpi_error_t scpi_error_queue_data[16]
Definition scpi.c:20
static scpi_result_t SCPI_Write_Control(scpi_t *context, scpi_ctrl_name_t ctrl, scpi_reg_val_t val)
Definition scpi.c:444
static uint8_t scpi_channel_list[16+1]
Definition scpi.c:14
scpi_result_t _scpi_cmd_measure_tsensors(scpi_t *context)
Definition scpi.c:348
scpi_result_t _scpi_cmd_led(scpi_t *context)
Definition scpi.c:270
scpi_result_t _scpi_write_meta_ptr(scpi_t *context)
Definition scpi.c:256
scpi_result_t _scpi_cmd_query_str(scpi_t *context)
Definition scpi.c:362
scpi_result_t _scpi_cmd_measure_active_ch(scpi_t *context)
Definition scpi.c:322
scpi_result_t _scpi_cmd_twi_scan(scpi_t *context)
Definition scpi.c:416
scpi_result_t _scpi_read_ptr(scpi_t *context)
Definition scpi.c:166
#define SCPI_CMD_RW(TYPE)
Definition scpi.c:52
static scpi_result_t SCPI_Reset(scpi_t *context)
Definition scpi.c:476
amu_notes_t * notes_ptr
Definition scpi.c:49
int16_t _scpi_get_channelList(scpi_t *context)
Definition scpi.c:647
static char scpi_input_buffer[1024]
Definition scpi.c:19
static size_t SCPI_Write(scpi_t *context, const char *data, size_t len)
Definition scpi.c:439
static scpi_result_t SCPI_Flush(scpi_t *context)
Definition scpi.c:482
#define SCPI_CMD_EXEC_QRY(TYPE)
Definition scpi.c:108
static scpi_t scpi_context
Definition scpi.c:23
static volatile amu_device_t * scpi_amu_dev
Definition scpi.c:15
scpi_result_t _scpi_write_sweep_ptr(scpi_t *context)
Definition scpi.c:215
SCPI library include file.
void amu_scpi_init(volatile amu_device_t *dev, const char *idn1, const char *idn2, const char *idn3, const char *idn4)
void amu_scpi_update(const char incomingByte)
void amu_scpi_add_aux_commands(const scpi_command_t *aux_cmd_list)
#define AMULIBC_SCPI_INPUT_BUFFER_LENGTH
Definition scpi.h:23
#define __AMU_EXTENDED_CMD_LIST__
Definition scpi.h:236
void amu_scpi_update_buffer(const char *buffer, size_t len)
#define __AMU_DEFAULT_CMD_LIST__
Definition scpi.h:92
void amu_scpi_list_commands(void)
#define AMULIBC_SCPI_ERROR_QUEUE_SIZE
Definition scpi.h:27
bool scpi_bool_t
Definition types.h:67
@ SCPI_RES_ERR
Definition types.h:111
@ SCPI_RES_OK
Definition types.h:110
uint16_t scpi_reg_val_t
Definition types.h:106
#define SCPI_CMD_LIST_END
Definition types.h:117
#define TRUE
Definition types.h:63
#define FALSE
Definition types.h:60
enum _scpi_result_t scpi_result_t
Definition types.h:113
enum _scpi_ctrl_name_t scpi_ctrl_name_t
Definition types.h:104
@ SCPI_FORMAT_ASCII
Definition types.h:401
scpi_token_t scpi_parameter_t
Definition types.h:362
const scpi_unit_def_t scpi_units_def[]
Definition units.c:65