Mercurial > hg > fxanalyse
view kk-data-provider.c @ 263:8d9a4c5eb7a4
Fixes to make last changes working in CVI
author | Daniele Nicolodi <daniele.nicolodi@obspm.fr> |
---|---|
date | Tue, 16 Jun 2015 17:19:15 +0200 |
parents | 9b35a2b2c759 |
children |
line wrap: on
line source
/* FXAnalise data provider which directly interfaces with the KK FX80E counter */ #include <ansi_c.h> #include <userint.h> #include <formatio.h> #include <utility.h> #include <inifile.h> #include "config.h" #include "data-provider.h" #include "KKFX80E.h" #define FX_MODE_PI 0x02 #define FX_MODE_LAMBDA 0x03 #define DEFAULT_PORT "COM4:115200" #define DEFAULT_NCHAN 4 #define DEFAULT_MODE FX_MODE_PI #define TIMEOUT 1 /* seconds */ #define MAXRETRY 100 #define strneq(a, b, len) (strncmp((a), (b), (len)) == 0) const char * FX_ModeString(int mode) { const static char *modes[] = { [FX_MODE_PI] = "PI", [FX_MODE_LAMBDA] = "LAMBDA", }; return modes[mode]; } static char * FX_Command(unsigned char cmd, unsigned mask, unsigned value) { char *resp; int rv, retry; unsigned int header; /* send command */ rv = FX_Send(cmd); if (! rv) return NULL; /* wait successfull reply */ for (retry = 0; retry < MAXRETRY; retry++) { rv = FX_Recv(&resp, TIMEOUT); if (! rv) return NULL; header = strtoul(resp, NULL, 16); if ((header & mask) == value) return resp; } /* max retry reached */ return NULL; } int CVICALLBACK KKDataProvider (void *functionData) { int main_thread_id; int rv; char *resp; int nchan = DEFAULT_NCHAN; int mode = DEFAULT_MODE; char port[256]; char buffer[16]; char header[16]; struct event event; /* get main thread id to post messages to it */ main_thread_id = CmtGetMainThreadID(); /* configuration file path */ char path[MAX_PATHNAME_LEN]; GetIniFilePath(path); /* load configuration file */ IniText configuration = Ini_New(TRUE); Ini_ReadFromFile(configuration, path); /* serial port name */ rv = Ini_GetStringIntoBuffer(configuration, "KK", "port", port, sizeof(port)); if (rv < 1) strncpy(port, DEFAULT_PORT, sizeof(port)); /* gate type */ rv = Ini_GetStringIntoBuffer(configuration, "KK", "mode", buffer, sizeof(buffer)); if (rv < 1) mode = DEFAULT_MODE; else if (stricmp(buffer, "PI") == 0) mode = FX_MODE_PI; else if (stricmp(buffer, "LAMBDA") == 0) mode = FX_MODE_LAMBDA; else send_message(main_thread_id, "KK Counter: unrecognised mode parameter '%s'", buffer); /* channel number */ rv = Ini_GetInt(configuration, "KK", "nchan", &nchan); if (rv < 1) nchan = DEFAULT_NCHAN; /* free */ Ini_Dispose(configuration); /* initialize library */ FX_Init(); /* connect to KK FX80E counter */ rv = FX_Open(port); if (! rv) { send_message(main_thread_id, FX_Error()); goto error; } /* get counter hardware version string */ resp = FX_Command(0x81, 0xFFFF, 0x7001); if (! resp) { send_message(main_thread_id, FX_Error()); goto error; } send_message(main_thread_id, "KK Counter: version %s", resp + 4); /* set report interval 1sec */ resp = FX_Command(0x29, 0x0F00, 0x0900); if (! resp) { send_message(main_thread_id, FX_Error()); goto error; } /* set mode */ resp = FX_Command(0x40 + mode, 0x7000, (mode << 12)); if (! resp) { send_message(main_thread_id, FX_Error()); goto error; } send_message(main_thread_id, "KK Counter: set mode %s", FX_ModeString(mode)); /* disable scrambler */ resp = FX_Command(0x50, 0xFFFF, (mode << 12) + 0x0900); if (! resp) { send_message(main_thread_id, FX_Error()); goto error; } /* read nchan channels */ resp = FX_Command(0x30 + nchan, 0xFFFF, (mode << 12) + 0x0900); if (! resp) { send_message(main_thread_id, FX_Error()); goto error; } /* enable synchronization */ resp = FX_Command(0x0F, 0x00, 0x00); if (! resp) { send_message(main_thread_id, FX_Error()); goto error; } /* expected packet header */ snprintf(header, sizeof(header), "%X", (mode << 12) + 0x0900); while (acquiring) { /* receive data from counter */ FX_Recv(&resp, TIMEOUT); if (! resp) { send_message(main_thread_id, FX_Error()); break; } /* data packets */ if (strneq(resp, header, 4)) { /* timestamp */ gettimeofday(&event.time, NULL); /* parse received data */ rv = Scan(resp + 6, "%f; %f; %f; %f; %f; %f; %f; %f", &event.data[0], &event.data[1], &event.data[2], &event.data[3], &event.data[4], &event.data[5], &event.data[6], &event.data[7]); if (rv != nchan) { send_message(main_thread_id, "KK Counter: data conversion error: %d != %d", rv, nchan); goto error; } /* convert from kHz to Hz */ for (int i = 0; i < nchan; i++) event.data[i] *= 1000.0; /* push data into the data queue */ CmtWriteTSQData(dataQueue, &event, 1, TSQ_INFINITE_TIMEOUT, 0); } else if (strneq(resp, "7000", 4)) { /* ignore heart beat packet */ } else if (strneq(resp, "7015", 4)) { /* ignore undocumented packet. it is sent by newer kk counters for each data packet. it probably contains a sample count along with some other information */ } else if (strneq(resp, "7020", 4)) { /* undocumented packet. it probably reports the header for subsequent data packets */ send_message(main_thread_id, "KK Counter: packet header %s", resp + 7); } else if (strneq(resp, "7F51", 4)) { /* measurement interval synchronized */ send_message(main_thread_id, "KK Counter: measurement interval synchronized"); } else { /* send message to the main thread */ send_message(main_thread_id, "KK Counter: %s", resp); } } error: /* close serial port */ FX_Close(); /* free allocated resources */ FX_Free(); return 0; }