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);
113 _ts5_status.timer.num_serialports++;
114 portnum = _ts5_status.timer.num_serialports - 1;
117 TS5_SERIALPORT_STATUS *serialport_status;
118 serialport_status = al_realloc(_ts5_status.timer.serialport,
119 _ts5_status.timer.num_serialports *
sizeof(TS5_SERIALPORT_STATUS));
121 if (serialport_status == NULL) {
123 "failed to allocate memory for serial port settings");
126 _ts5_status.timer.serialport =
127 (TS5_SERIALPORT_STATUS *) serialport_status;
130 strcpy(_ts5_status.timer.serialport[portnum].portname, portname);
131 _ts5_status.timer.serialport[portnum].port = port;
132 _ts5_status.timer.serialport[portnum].is_trigger_input_device = 0;
133 _ts5_status.timer.serialport[portnum].is_trigger_output_device = 0;
134 _ts5_status.timer.serialport[portnum].simulate_trigger_input = 0;
135 _ts5_status.timer.serialport[portnum].trigger_simulation_interval = 2.0;
136 _ts5_status.timer.serialport[portnum].last_trigger_simulation =
162 ts5_log(TS5_LOGLEVEL_1,
"%s: Installing Tscope5 serialport\n",
165 al_init_user_event_source(
166 &_ts5_data.timer.serialport_trigger_event_source);
168 al_register_event_source(_ts5_data.timer.trigger_queue,
169 &_ts5_data.timer.serialport_trigger_event_source);
171 al_register_event_source(_ts5_data.timer.trigger_log,
172 &_ts5_data.timer.serialport_trigger_event_source);
174 _ts5_data.timer.serialport_thread =
177 al_start_thread(_ts5_data.timer.serialport_thread);
193 ts5_log(TS5_LOGLEVEL_1,
"Uninstalling Tscope5 serialport\n");
196 al_join_thread(_ts5_data.timer.serialport_thread, NULL);
197 al_destroy_thread(_ts5_data.timer.serialport_thread);
200 al_unregister_event_source(_ts5_data.timer.trigger_queue,
201 &_ts5_data.timer.serialport_trigger_event_source);
203 al_unregister_event_source(_ts5_data.timer.trigger_log,
204 &_ts5_data.timer.serialport_trigger_event_source);
207 al_destroy_user_event_source(
208 &_ts5_data.timer.serialport_trigger_event_source);
212 for (i=0; i<_ts5_status.timer.num_serialports; i++) {
215 if (!CloseHandle(*(_ts5_status.timer.serialport[i].port))) {
216 ts5_log(TS5_LOGLEVEL_1,
"%s %s %d\n",
217 "ts5_uninstall_serialport",
218 "could not uninstall serial port", i);
222 tcdrain(*(_ts5_status.timer.serialport[i].port));
224 if (close(*(_ts5_status.timer.serialport[i].port)) == -1) {
225 ts5_log(TS5_LOGLEVEL_1,
"%s %s %d\n",
226 "ts5_uninstall_serialport",
227 "could not uninstall serial port", i);
232 al_free(_ts5_status.timer.serialport[i].port);
235 al_free(_ts5_status.timer.serialport);
237 _ts5_status.timer.serialport_is_trigger_device = 0;
252 ALLEGRO_EVENT serialport_event;
253 double previous_time;
254 double current_time = al_get_time();
266 while (!al_get_thread_should_stop(_ts5_data.timer.serialport_thread)) {
269 for (i=0; i<_ts5_status.timer.num_serialports; i++) {
272 if (_ts5_status.timer.serialport[i].is_trigger_input_device) {
274 char serial_buff[TS5_MAX_CHAR];
278 unsigned long bytes_to_read = 1;
279 unsigned long bytes_read = 0;
281 if (!ReadFile(*(_ts5_status.timer.serialport[i].port),
282 serial_buff, bytes_to_read, &bytes_read, NULL)) {
283 ts5_fatal(
"ts5_serialport_threadfunc: read error\n");
286 num_bytes = bytes_read;
289 unsigned int bytes_to_read = 1;
290 unsigned int bytes_read = 0;
292 bytes_read = read(*(_ts5_status.timer.serialport[i].port),
293 serial_buff, bytes_to_read);
295 if ((
int)bytes_read == -1) {
296 ts5_fatal(
"ts5_serialport_threadfunc: read error\n");
299 num_bytes = bytes_read;
305 serialport_event.user.type = TS5_EVENT_SERIALPORT_TRIGGER;
307 serialport_event.user.data1 = i;
308 serialport_event.user.data2 = serial_buff[0];
309 serialport_event.user.data3 =
310 (intptr_t)((current_time-previous_time)*1000000.0);
313 &_ts5_data.timer.serialport_trigger_event_source,
314 &serialport_event, NULL);
319 if (_ts5_status.timer.serialport[i].simulate_trigger_input) {
321 if (current_time - _ts5_status.timer.serialport[i]
322 .last_trigger_simulation
323 >= _ts5_status.timer.serialport[i]
324 .trigger_simulation_interval) {
326 serialport_event.user.type = TS5_EVENT_SERIALPORT_TRIGGER;
328 serialport_event.user.data1 = i;
330 serialport_event.user.data2 =
331 _ts5_status.timer.serialport[i].simulate_trigger_input;
333 serialport_event.user.data3 =
334 (intptr_t)((current_time-previous_time)*1000000.0);
337 &_ts5_data.timer.serialport_trigger_event_source,
338 &serialport_event, NULL);
340 _ts5_status.timer.serialport[i].last_trigger_simulation =
346 previous_time = current_time;
347 current_time = al_get_time();
352 }
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.