0
mirror of https://gitlab.com/hyperglitch/jellyfish.git synced 2026-02-10 21:42:16 +00:00

336 lines
10 KiB
C

/*-
* Copyright (c) 2015 Lutz Hoerl, Thorlabs GmbH
*
* All Rights Reserved
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @file main.c
* @date Thu Nov 15 10:58:45 UTC 2012
*
* @brief SCPI parser test with a little GUI built with NI-CVI (Lutz Hoerl, Thorlabs)
* You can build this example using CVI 2012SP1, an eval version is available here:
* ftp://ftp.ni.com/evaluation/labview/ekit/other/downloader/NILWCVI2012SP1.exe
* Size is about 550 MB
*
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#include "scpi/scpi.h"
#include "../common/scpi-def.h"
/* NI-CVI specific stuff */
#include <cvirte.h>
#include <userint.h>
#include "TestLibscpi.h" /* this is the include for the GUI constants */
/* GLOBAL VARIABLES */
static int panelHandle;
/* PROTOTYPES */
void gui_updateSTB(uint8_t newSTB);
void gui_updateSRE(uint8_t newSTB);
void gui_updateESR(uint8_t newSTB);
void gui_updateESE(uint8_t newSTB);
void updateSSCPIRegister(void);
void updateSTB(void);
void updateSRE(void);
void updateESR(void);
void updateESE(void);
/* a global output buffer to collect output data until it will be 'flushed' */
#define SCPI_OUPUT_BUFFER_SIZE (256)
char SCPI_outputBuffer[SCPI_OUPUT_BUFFER_SIZE];
unsigned int SCPI_outputBuffer_idx = 0;
/* helper function to remove <LF> and <CR> from the end of a string */
/* this is needed only here for the GUI, there is a 'insert line to a text box' function */
/* that automatically adds a new line, so this prohibits double line feeds for the GUI */
void removeTrailingEndcodes(char *buf) {
int len;
len = strlen(buf);
while (len > 0) {
len--;
switch (buf[len]) {
case '\n':
case '\r':
buf[len] = '\0';
break;
default:
len = 0; /* stop loop */
break;
}
}
}
/* wrapper for debugging output, collects debug output until a <LF> */
/* is received, then removes the <LF> and outputs the line on the GUI */
void debug_output(char *buf) {
static char pbuf[512];
static int pos = 0;
int len;
len = strlen(buf);
if (buf[len - 1] == '\n') {
buf[len - 1] == '\0';
len--;
memcpy(&pbuf[pos], buf, len);
pos = 0;
InsertTextBoxLine(panelHandle, PANEL_OUTPUTDEBUG, -1, pbuf);
} else {
memcpy(&pbuf[pos], buf, len);
pos += len;
}
}
size_t SCPI_Write(scpi_t * context, const char * data, size_t len) {
if ((SCPI_outputBuffer_idx + len) > (SCPI_OUPUT_BUFFER_SIZE - 1)) {
len = (SCPI_OUPUT_BUFFER_SIZE - 1) - SCPI_outputBuffer_idx; /* limit length to left over space */
/* apparently there is no mechanism to cope with buffers that are too small */
}
memcpy(&SCPI_outputBuffer[SCPI_outputBuffer_idx], data, len);
SCPI_outputBuffer_idx += len;
SCPI_outputBuffer[SCPI_outputBuffer_idx] = '\0';
/* return fwrite(data, 1, len, stdout); */
return len;
}
scpi_result_t SCPI_Flush(scpi_t * context) {
/* fwrite(SCPI_outputBuffer, 1, SCPI_outputBuffer_idx, stdout); */
removeTrailingEndcodes(SCPI_outputBuffer);
InsertTextBoxLine(panelHandle, PANEL_OUTPUT, -1, SCPI_outputBuffer);
SCPI_outputBuffer_idx = 0;
return SCPI_RES_OK;
}
int SCPI_Error(scpi_t * context, int_fast16_t err) {
char buf[512];
/* fprintf(stderr, "**ERROR: %d, \"%s\"\r\n", (int16_t) err, SCPI_ErrorTranslate(err)); */
sprintf(buf, "**ERROR: %d, \"%s\"", (int16_t) err, SCPI_ErrorTranslate(err));
InsertTextBoxLine(panelHandle, PANEL_OUTPUTERR, -1, buf);
return 0;
}
scpi_result_t SCPI_Control(scpi_t * context, scpi_ctrl_name_t ctrl, scpi_reg_val_t val) {
if (SCPI_CTRL_SRQ == ctrl) {
/* fprintf(stderr, "**SRQ: 0x%X (%d)\r\n", val, val); */
SetCtrlVal(panelHandle, PANEL_LEDSRQ, 1);
} else {
fprintf(stderr, "**CTRL %02x: 0x%X (%d)\r\n", ctrl, val, val);
}
return SCPI_RES_OK;
}
scpi_result_t SCPI_Reset(scpi_t * context) {
char buf[256];
/* fprintf(stderr, "**Reset\r\n"); */
sprintf(buf, "**Reset\r\n");
debug_output(buf);
return SCPI_RES_OK;
}
scpi_result_t SCPI_SystemCommTcpipControlQ(scpi_t * context) {
return SCPI_RES_ERR;
}
/*
*
*/
int main(int argc, char** argv) {
int result;
SCPI_Init(&scpi_context,
scpi_commands,
&scpi_interface,
scpi_units_def,
SCPI_IDN1, SCPI_IDN2, SCPI_IDN3, SCPI_IDN4,
scpi_input_buffer, SCPI_INPUT_BUFFER_LENGTH,
scpi_error_queue_data, SCPI_ERROR_QUEUE_SIZE);
if (InitCVIRTE(0, argv, 0) == 0)
return -1; /* out of memory */
if ((panelHandle = LoadPanel(0, "TestLibscpi.uir", PANEL)) < 0)
return -1;
DisplayPanel(panelHandle);
updateSSCPIRegister();
RunUserInterface();
DiscardPanel(panelHandle);
return (EXIT_SUCCESS);
}
void updateSSCPIRegister(void) {
updateSTB();
updateSRE();
updateESR();
updateESE();
}
void updateSTB(void) {
scpi_reg_val_t regVal;
regVal = SCPI_RegGet(&scpi_context, SCPI_REG_STB);
gui_updateSTB((uint8_t) (0x00FF & regVal));
}
void updateESR(void) {
scpi_reg_val_t regVal;
regVal = SCPI_RegGet(&scpi_context, SCPI_REG_ESR);
gui_updateESR((uint8_t) (0x00FF & regVal));
}
void updateESE(void) {
scpi_reg_val_t regVal;
regVal = SCPI_RegGet(&scpi_context, SCPI_REG_ESE);
gui_updateESE((uint8_t) (0x00FF & regVal));
}
void updateSRE(void) {
scpi_reg_val_t regVal;
regVal = SCPI_RegGet(&scpi_context, SCPI_REG_SRE);
gui_updateSRE((uint8_t) (0x00FF & regVal));
}
/*
* The CALLBACK functions below are called from the CVI runtime engine when
* user clicks on buttons, inputs data on the GUI etc.
*/
int CVICALLBACK cb_scpi_input(int panel, int control, int event,
void *callbackData, int eventData1, int eventData2) {
char buf[256];
int len;
switch (event) {
case EVENT_COMMIT:
GetCtrlVal(panel, control, buf);
/* we have to add a endcode to make SCPI accept the string, here a <LF> is added */
len = strlen(buf);
buf[len] = '\n';
len++;
SCPI_Input(&scpi_context, buf, len);
updateSSCPIRegister();
break;
}
return 0;
}
int CVICALLBACK cb_quit(int panel, int control, int event,
void *callbackData, int eventData1, int eventData2) {
switch (event) {
case EVENT_COMMIT:
QuitUserInterface(0);
break;
}
return 0;
}
/*
* Helper functions for GUI
*/
void gui_updateSTB(uint8_t newSTB) {
char buf[5];
sprintf(buf, "0x%02X", newSTB);
SetCtrlVal(panelHandle, PANEL_STBHEX, buf);
SetCtrlVal(panelHandle, PANEL_STB0, (newSTB & 0x01));
SetCtrlVal(panelHandle, PANEL_STB1, (newSTB & 0x02));
SetCtrlVal(panelHandle, PANEL_STB2, (newSTB & 0x04));
SetCtrlVal(panelHandle, PANEL_STB3, (newSTB & 0x08));
SetCtrlVal(panelHandle, PANEL_STB4, (newSTB & 0x10));
SetCtrlVal(panelHandle, PANEL_STB5, (newSTB & 0x20));
SetCtrlVal(panelHandle, PANEL_STB6, (newSTB & 0x40));
SetCtrlVal(panelHandle, PANEL_STB7, (newSTB & 0x80));
if (0x00 == (newSTB & 0x40)) SetCtrlVal(panelHandle, PANEL_LEDSRQ, 0);
}
void gui_updateESR(uint8_t newESR) {
char buf[5];
sprintf(buf, "0x%02X", newESR);
SetCtrlVal(panelHandle, PANEL_ESRHEX, buf);
SetCtrlVal(panelHandle, PANEL_ESR0, (newESR & 0x01));
SetCtrlVal(panelHandle, PANEL_ESR1, (newESR & 0x02));
SetCtrlVal(panelHandle, PANEL_ESR2, (newESR & 0x04));
SetCtrlVal(panelHandle, PANEL_ESR3, (newESR & 0x08));
SetCtrlVal(panelHandle, PANEL_ESR4, (newESR & 0x10));
SetCtrlVal(panelHandle, PANEL_ESR5, (newESR & 0x20));
SetCtrlVal(panelHandle, PANEL_ESR6, (newESR & 0x40));
SetCtrlVal(panelHandle, PANEL_ESR7, (newESR & 0x80));
}
void gui_updateESE(uint8_t newESE) {
char buf[5];
sprintf(buf, "0x%02X", newESE);
SetCtrlVal(panelHandle, PANEL_ESEHEX, buf);
SetCtrlVal(panelHandle, PANEL_ESE0, (newESE & 0x01));
SetCtrlVal(panelHandle, PANEL_ESE1, (newESE & 0x02));
SetCtrlVal(panelHandle, PANEL_ESE2, (newESE & 0x04));
SetCtrlVal(panelHandle, PANEL_ESE3, (newESE & 0x08));
SetCtrlVal(panelHandle, PANEL_ESE4, (newESE & 0x10));
SetCtrlVal(panelHandle, PANEL_ESE5, (newESE & 0x20));
SetCtrlVal(panelHandle, PANEL_ESE6, (newESE & 0x40));
SetCtrlVal(panelHandle, PANEL_ESE7, (newESE & 0x80));
}
void gui_updateSRE(uint8_t newSRE) {
char buf[5];
sprintf(buf, "0x%02X", newSRE);
SetCtrlVal(panelHandle, PANEL_SREHEX, buf);
SetCtrlVal(panelHandle, PANEL_SRE0, (newSRE & 0x01));
SetCtrlVal(panelHandle, PANEL_SRE1, (newSRE & 0x02));
SetCtrlVal(panelHandle, PANEL_SRE2, (newSRE & 0x04));
SetCtrlVal(panelHandle, PANEL_SRE3, (newSRE & 0x08));
SetCtrlVal(panelHandle, PANEL_SRE4, (newSRE & 0x10));
SetCtrlVal(panelHandle, PANEL_SRE5, (newSRE & 0x20));
SetCtrlVal(panelHandle, PANEL_SRE6, (newSRE & 0x40));
SetCtrlVal(panelHandle, PANEL_SRE7, (newSRE & 0x80));
}