/* * Abstraction of the counter device. * */ #include "device.h" #include "params.h" #include "sock.h" #include "hware.h" #include #include #include #define HWARE_TEST(functionCall) \ if( hware_failed(error=(functionCall)) ) \ goto Error; \ else void device_send(DEVICE* device, int n) { BUFFER buffer; buffer.length = 0; snprintf(buffer.body, sizeof(buffer.body), "Time: %s, Value: 0x%06X\r\n", make_timestamp(NULL), device->value); buffer.length = strlen(buffer.body); sock_send(n, &buffer); } void device_read(DEVICE* device, int n) { BUFFER buffer; buffer.length = 0; snprintf(buffer.body, sizeof(buffer.body), "READ 0x%06X\r\n", device->value); buffer.length = strlen(buffer.body); sock_send(n, &buffer); } void device_write(DEVICE *device, int n, const char* tp) { unsigned long value; value = strtol(tp, NULL, 16); device->out_value = value; hware_write(device->private_data, value); return; } void device_print(DEVICE* device, FILE* fd) { fprintf(fd, "Time: %s, Value: 0x%06X\r\n", make_timestamp(NULL), device->value); fflush(fd); } /* * Finalise the current sample and move on to the next */ void device_sample(DEVICE* device) { device->sample_timer = device->current_time; } void device_report(DEVICE* device) { dbg_printf(0, "device_report\n"); /* * Set the time for this report */ device->report_timer = device->current_time; BUFFER buffer; char* str = make_timestamp(&device->current_time); snprintf(buffer.body, sizeof(buffer.body), "%s 0x%06X\r\n", str, device->value); buffer.length = strlen(buffer.body); sock_report(&buffer, 1, device); snprintf(buffer.body, sizeof(buffer.body), "REPORT %s 0x%06X\r\n", str, device->value); buffer.length = strlen(buffer.body); sock_report(&buffer, 2, device); } /** * Initialise the counter * * Initialise all of the control data associated with the logical counter. * * Create a 64-bit physical counter and start it. */ int device_init(DEVICE** cpp, char* name) { int error = 0; char errBuff[2048]={'\0'}; DEVICE* device = (DEVICE*) malloc(sizeof(DEVICE)); *cpp = device; memset(device, 0, sizeof(DEVICE)); strncpy(device->name, name, sizeof(device->name)); device->params.poll_period = 100; /* milliseconds between polls */ device->params.sample_period = 5; /* polls between sample calcs */ device->params.report_period = 10; /* samples between reports */ device->state = device_stopped; struct timeval now; gettimeofday(&now, NULL); device->current_time = now; device->previous_time = now; device->sample_timer = now; device->report_timer = now; HWARE_TEST(hware_ctor(name, &device->private_data)); device_sample(device); return 0; Error: hware_errmsg(errBuff, sizeof(errBuff)); printf("DAQmx Error: %s\n", errBuff); return error; return 0; } int device_command(void* dev, const char* command) { // TODO // DEVICE* device = (DEVICE*)(dev); return 0; } static void device_event(DEVICE *device, char* event) { BUFFER buffer; sprintf(buffer.body, "EVENT %s %s\r\n", make_timestamp(&device->current_time), event); buffer.length = strlen(buffer.body); dbg_printf(0, "%s", buffer.body); sock_report(&buffer, 1, device); sock_report(&buffer, 2, device); } /* * poll the physical counter */ int device_poll(DEVICE* device) { char errBuff[2048]={'\0'}; HWARE_VALUE current_local_value; int error=0; #if 0 dbg_printf(0, "%s:-%s %s %4d\n", device->name, make_timestamp(&device->current_time), make_timestamp(&device->report_timer), device_time_to_next_report(device)); #endif /* read the value from the hardware to a temp */ ++device->poll_counter; HWARE_TEST(hware_read(device->private_data, ¤t_local_value)); dbg_printf(0, "device_poll = 0x%06X @ %s\n", current_local_value, make_timestamp(&device->current_time)); if ((current_local_value != device->value) || (current_local_value != device->new_value)) { if (current_local_value != device->new_value) { device->new_value = current_local_value; device->new_count = device->params.sample_period; } else if (--device->new_count <= 0) { char str[100]; snprintf(str, sizeof(str), "changed 0x%06X 0x%06X", current_local_value, device->value); device_event(device, str); device->value = current_local_value; } } /* check if it is time to roll the sample */ if (device_time_to_next_sample(device) <= 0) { /* check if it is time to roll the report */ if (device_time_to_next_report(device) <= 0) { device_report(device); } device_sample(device); } return error; Error: device_errmsg(errBuff, sizeof(errBuff)); printf("DAQmx Error: %s\n", errBuff); return error; } void device_term(DEVICE* device) { if (device->private_data) { hware_dtor(&device->private_data); device->private_data = NULL; } device->state = device_idle; } bool device_fatal(int error) { return hware_failed(error); } void device_errmsg(char* buff, int len) { hware_errmsg(buff, len); } double device_time_to_next_report(DEVICE* device) { uint64 last_report; uint64 timeofday; int timeout; struct timeval now; now = device->current_time; last_report = 1000 * (uint64) device->report_timer.tv_sec; last_report += (uint64) device->report_timer.tv_usec / 1000; timeofday = 1000 * (uint64) now.tv_sec; timeofday += (uint64) now.tv_usec / 1000; timeout = device->params.poll_period * device->params.sample_period * device->params.report_period; if ((last_report / timeout) != (timeofday / timeout)) return 0.0; timeout = timeout - timeofday % timeout; return 0.001 * timeout; } double device_time_to_next_sample(DEVICE* device) { uint64 last_sample; uint64 timeofday; int timeout; struct timeval now; now = device->current_time; last_sample = 1000 * (uint64) device->sample_timer.tv_sec; last_sample += (uint64) device->sample_timer.tv_usec / 1000; timeofday = 1000 * (uint64) now.tv_sec; timeofday += (uint64) now.tv_usec / 1000; timeout = device->params.poll_period * device->params.sample_period; if ((last_sample / timeout) != (timeofday / timeout)) return 0.0; timeout = timeout - timeofday % timeout; return 0.001 * timeout; }