14 #include "../include/tscope5/serialport_internal.h"
15 #include "../include/tscope5/system_internal.h"
16 #include "../include/tscope5/timer_internal.h"
19 #include <sys/types.h>
20 #include <sys/ioctl.h>
42 ts5_log(TS5_LOGLEVEL_6,
"%s: ts5_check_serialport\n", calling_function);
62 ts5_log(TS5_LOGLEVEL_6,
"%s: ts5_check_serialport2(%s)\n",
63 calling_function, portname);
69 for (i=0; i<_ts5_status.timer.num_serialports; i++) {
70 if (!strcmp(portname, _ts5_status.timer.serialport[i].portname)) {
79 port = (TS5_SERIALPORT *)al_malloc(
sizeof(TS5_SERIALPORT));
82 *port = CreateFile(portname,
83 GENERIC_READ | GENERIC_WRITE,
84 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
91 if (*port == INVALID_HANDLE_VALUE) {
92 ts5_fatal(
"%s: could not open serial port %s\n",
93 calling_function, portname);
97 *port = open(portname, O_RDWR | O_NOCTTY | O_NDELAY);
100 ts5_fatal(
"%s: could not open serial port %s\n",
101 calling_function, portname);
105 if (ioctl(*port, TIOCEXCL) == -1) {
106 ts5_fatal(
"%s: could not get exclusivity on serial port %s\n",
107 calling_function, portname);
112 _ts5_status.timer.num_serialports++;
113 portnum = _ts5_status.timer.num_serialports - 1;
116 TS5_SERIALPORT_STATUS *serialport_status;
117 serialport_status = al_realloc(_ts5_status.timer.serialport,
118 _ts5_status.timer.num_serialports *
sizeof(TS5_SERIALPORT_STATUS));
120 if (serialport_status == NULL) {
122 "failed to allocate memory for serial port settings");
125 _ts5_status.timer.serialport =
126 (TS5_SERIALPORT_STATUS *) serialport_status;
129 strcpy(_ts5_status.timer.serialport[portnum].portname, portname);
130 _ts5_status.timer.serialport[portnum].port = port;
132 _ts5_status.timer.serialport[portnum].num_buttons = 127;
133 _ts5_status.timer.serialport[portnum].num_defined_buttons = 0;
134 _ts5_status.timer.serialport[portnum].num_active_buttons = 0;
136 _ts5_status.timer.serialport[portnum].button_press_defined =
137 (
int *)al_malloc(
sizeof(
int)
138 * _ts5_status.timer.serialport[portnum].num_buttons);
140 _ts5_status.timer.serialport[portnum].button_press_active =
141 (
int *)al_malloc(
sizeof(
int)
142 * _ts5_status.timer.serialport[portnum].num_buttons);
144 _ts5_status.timer.serialport[portnum].button_release_defined =
145 (
int *)al_malloc(
sizeof(
int)
146 * _ts5_status.timer.serialport[portnum].num_buttons);
148 _ts5_status.timer.serialport[portnum].button_release_active =
149 (
int *)al_malloc(
sizeof(
int)
150 * _ts5_status.timer.serialport[portnum].num_buttons);
153 for (j=0; j<_ts5_status.timer.serialport[portnum].num_buttons; j++) {
154 _ts5_status.timer.serialport[portnum].button_press_defined[j] = 0;
155 _ts5_status.timer.serialport[portnum].button_press_active[j] = 0;
156 _ts5_status.timer.serialport[portnum].button_release_defined[j] = 0;
157 _ts5_status.timer.serialport[portnum].button_release_active[j] = 0;
160 _ts5_status.timer.serialport[portnum].is_trigger_input_device = 0;
161 _ts5_status.timer.serialport[portnum].is_trigger_output_device = 0;
162 _ts5_status.timer.serialport[portnum].simulate_trigger_input = 0;
163 _ts5_status.timer.serialport[portnum].trigger_simulation_interval = 2.0;
164 _ts5_status.timer.serialport[portnum].last_trigger_simulation =
192 ts5_log(TS5_LOGLEVEL_1,
"%s: Installing Tscope5 serialport\n",
196 al_init_user_event_source(
197 &_ts5_data.timer.serialport_response_event_source);
199 al_init_user_event_source(
200 &_ts5_data.timer.serialport_trigger_event_source);
203 al_register_event_source(_ts5_data.timer.response_queue,
204 &_ts5_data.timer.serialport_response_event_source);
206 al_register_event_source(_ts5_data.timer.trigger_queue,
207 &_ts5_data.timer.serialport_trigger_event_source);
209 al_register_event_source(_ts5_data.timer.trigger_log,
210 &_ts5_data.timer.serialport_trigger_event_source);
213 _ts5_data.timer.serialport_thread =
216 al_start_thread(_ts5_data.timer.serialport_thread);
232 ts5_log(TS5_LOGLEVEL_1,
"Uninstalling Tscope5 serialport\n");
235 al_join_thread(_ts5_data.timer.serialport_thread, NULL);
236 al_destroy_thread(_ts5_data.timer.serialport_thread);
239 al_unregister_event_source(_ts5_data.timer.response_queue,
240 &_ts5_data.timer.serialport_response_event_source);
242 al_unregister_event_source(_ts5_data.timer.trigger_queue,
243 &_ts5_data.timer.serialport_trigger_event_source);
245 al_unregister_event_source(_ts5_data.timer.trigger_log,
246 &_ts5_data.timer.serialport_trigger_event_source);
249 al_destroy_user_event_source(
250 &_ts5_data.timer.serialport_response_event_source);
252 al_destroy_user_event_source(
253 &_ts5_data.timer.serialport_trigger_event_source);
257 for (i=0; i<_ts5_status.timer.num_serialports; i++) {
260 if (!CloseHandle(*(_ts5_status.timer.serialport[i].port))) {
261 ts5_log(TS5_LOGLEVEL_1,
"%s %s %d\n",
262 "ts5_uninstall_serialport",
263 "could not uninstall serial port", i);
267 tcdrain(*(_ts5_status.timer.serialport[i].port));
269 if (close(*(_ts5_status.timer.serialport[i].port)) == -1) {
270 ts5_log(TS5_LOGLEVEL_1,
"%s %s %d\n",
271 "ts5_uninstall_serialport",
272 "could not uninstall serial port", i);
277 al_free(_ts5_status.timer.serialport[i].button_press_defined);
278 _ts5_status.timer.serialport[i].button_press_defined = NULL;
280 al_free(_ts5_status.timer.serialport[i].button_press_active);
281 _ts5_status.timer.serialport[i].button_press_active = NULL;
283 al_free(_ts5_status.timer.serialport[i].button_release_defined);
284 _ts5_status.timer.serialport[i].button_release_defined = NULL;
286 al_free(_ts5_status.timer.serialport[i].button_release_active);
287 _ts5_status.timer.serialport[i].button_release_active = NULL;
289 al_free(_ts5_status.timer.serialport[i].port);
292 al_free(_ts5_status.timer.serialport);
293 _ts5_status.timer.serialport = NULL;
294 _ts5_status.timer.num_serialports = 0;
295 _ts5_status.timer.serialport_is_response_device = 0;
296 _ts5_status.timer.serialport_is_trigger_device = 0;
311 ALLEGRO_EVENT serialport_event;
312 double previous_time;
313 double current_time = al_get_time();
325 while (!al_get_thread_should_stop(_ts5_data.timer.serialport_thread)) {
328 for (i=0; i<_ts5_status.timer.num_serialports; i++) {
332 if (_ts5_status.timer.serialport[i].num_defined_buttons ||
333 _ts5_status.timer.serialport[i].is_trigger_input_device) {
335 char serial_buff[TS5_MAX_CHAR];
339 unsigned long bytes_to_read = 1;
340 unsigned long bytes_read = 0;
342 if (!ReadFile(*(_ts5_status.timer.serialport[i].port),
343 serial_buff, bytes_to_read, &bytes_read, NULL)) {
344 ts5_fatal(
"ts5_serialport_threadfunc: read error\n");
347 num_bytes = bytes_read;
350 unsigned int bytes_to_read = 1;
351 unsigned int bytes_read = 0;
353 bytes_read = read(*(_ts5_status.timer.serialport[i].port),
354 serial_buff, bytes_to_read);
356 if ((
int)bytes_read == -1) {
357 ts5_fatal(
"ts5_serialport_threadfunc: read error\n");
360 num_bytes = bytes_read;
366 serialport_event.user.data1 = i;
367 serialport_event.user.data2 = serial_buff[0];
368 serialport_event.user.data3 =
369 (intptr_t)((current_time-previous_time)*1000000.0);
371 if (_ts5_status.timer.serialport[i].num_defined_buttons) {
372 serialport_event.user.type = TS5_EVENT_SERIALPORT_BUTTON_DOWN;
374 &_ts5_data.timer.serialport_response_event_source,
375 &serialport_event, NULL);
378 if (_ts5_status.timer.serialport[i].is_trigger_input_device) {
380 serialport_event.user.type = TS5_EVENT_SERIALPORT_TRIGGER;
382 &_ts5_data.timer.serialport_trigger_event_source,
383 &serialport_event, NULL);
390 if (_ts5_status.timer.serialport[i].simulate_trigger_input) {
392 if (current_time - _ts5_status.timer.serialport[i]
393 .last_trigger_simulation
394 >= _ts5_status.timer.serialport[i]
395 .trigger_simulation_interval) {
397 serialport_event.user.type = TS5_EVENT_SERIALPORT_TRIGGER;
399 serialport_event.user.data1 = i;
401 serialport_event.user.data2 =
402 _ts5_status.timer.serialport[i].simulate_trigger_input;
404 serialport_event.user.data3 =
405 (intptr_t)((current_time-previous_time)*1000000.0);
408 &_ts5_data.timer.serialport_trigger_event_source,
409 &serialport_event, NULL);
411 _ts5_status.timer.serialport[i].last_trigger_simulation =
417 previous_time = current_time;
418 current_time = al_get_time();
423 }
while (al_get_time() - current_time < 0.00005);
int _ts5_is_timer_installed
Is the timer subsystem installed?
void * ts5_serialport_threadfunc()
Serial port thread function.
void ts5_uninstall_serialport()
Uninstall the serialport subsystem.
void ts5_install_serialport(char *calling_function)
Install the serialport subsystem.
int _ts5_is_serialport_installed
Is the serialport subsystem installed?
void ts5_check_serialport(char *calling_function)
Do some checks at the start of each serialport function.
void ts5_install_timer(char *calling_function)
Install the timer subsystem.
void ts5_log(const unsigned int level, const char *format,...)
Send info to a logging window.
void ts5_fatal(const char *format,...)
Exit safely with an error message.
int ts5_check_serialport2(char *calling_function, char *portname)
Do some checks at the start of each serialport function.