Tscope5
serialport.c
Go to the documentation of this file.
1 ////////////////////////////////////////////////////////////////////////////////
2 //
3 // __ ______
4 // / /_______________ ____ ___ / ____/
5 // / __/ ___/ ___/ __ \/ __ \/ _ \ /___ )
6 // / /_(__ ) /__/ /_/ / /_/ / __/ ____/ /
7 // \__/____/\___/\____/ .___/\___/ /_____/
8 // /_/
9 //
10 /// \file serialport.c
11 /// Definitions of serial port functions.
12 /// \example serialport01.c
13 /// \example serialport02.c
14 /// \example serialport03.c
15 /// \example config_serialport.c
16 ////////////////////////////////////////////////////////////////////////////////
17 
18 
19 #include "../include/tscope5/serialport.h"
20 #include "../include/tscope5/timer.h"
21 #include "../include/tscope5/serialport_internal.h"
22 #include "../include/tscope5/system_internal.h"
23 
24 
25 ////////////////////////////////////////////////////////////////////////////////
26 /// @name Response registration
27 /// Serialports can be used as response devices.
28 /// See timer.c for more information about response registration.
29 //@{
30 ////////////////////////////////////////////////////////////////////////////////
31 
32 
33 ////////////////////////////////////////////////////////////////////////////////
34 /// Define a serial port as a response input device
35 ///
36 /// \param portname Name of the serial port
37 /// (COM1, ... on Windows, /etc/tty... on Posix systems).
38 ///
39 /// \return The device number of the port
40 /// (the first serial port opened by Tscope5 gets number 1, etc.).
41 ////////////////////////////////////////////////////////////////////////////////
43 {
44  ts5_check_serialport("ts5_define_serialport_response_input");
45 
46  int portnum = ts5_check_serialport2("ts5_define_serialport_response_input",
47  portname);
48 
49  ts5_log(TS5_LOGLEVEL_3, "ts5_define_serialport_response_input(%s)\n",
50  portname);
51 
52  _ts5_status.timer.serialport_is_response_device = 1;
53 
54  return portnum+1;
55 }
56 
57 
58 ////////////////////////////////////////////////////////////////////////////////
59 /// Define a serial port button as a response button.
60 ///
61 /// \param device Number of the serial port (devices are numbered from 1).
62 /// \param button Number of the button (buttons are counted from 1).
63 ///
64 /// \return The reponse number associated with the button.
65 ///
66 /// Currently serial ports only support button press events,
67 /// no button release events.
68 ////////////////////////////////////////////////////////////////////////////////
69 int ts5_define_serialport_button(int device, int button)
70 {
71  ts5_check_serialport("ts5_define_serialport_button");
72  ts5_log(TS5_LOGLEVEL_3, "ts5_define_serialport_button(%d,%d)\n", device, button);
73 
74  if (device<1 || device>_ts5_status.timer.num_serialports) {
75  ts5_fatal("%s: %s %d, %s %d\n", "ts5_define_serialport_button",
76  "device argument is", device, "number of serialportes is",
77  _ts5_status.timer.num_serialports);
78  }
79 
80  if (button==0) {
81  ts5_fatal("%s: %s\n", "ts5_define_serialport_button",
82  "button argument is 0, response buttons are numbered from 1");
83  }
84 
85  if (button<0) {
86  ts5_fatal("%s: %s %s %s\n", "ts5_define_serialport_button",
87  "button argument is negative.",
88  "button releases are currently not supported",
89  "for serial ports");
90  }
91 
92  if (button>_ts5_status.timer.serialport[device-1].num_buttons) {
93  ts5_fatal("%s: %s %d, %s %d is %d\n", "ts5_define_serialport_button",
94  "button argument is ", button,
95  "number of serialport buttons for device", device,
96  _ts5_status.timer.serialport[device-1].num_buttons);
97  }
98 
99  if (button>0 && _ts5_status.timer.serialport[device-1]
100  .button_press_defined[button-1] !=0) {
101  ts5_fatal("%s: %s %d %s\n", "ts5_define_serialport_button",
102  "button press", button, "is already defined");
103  }
104 
105  _ts5_status.timer.serialport_is_response_device = 1;
106  _ts5_status.timer.num_defined_buttons++;
107  _ts5_status.timer.num_active_buttons++;
108  _ts5_status.timer.serialport[device-1].num_defined_buttons++;
109  _ts5_status.timer.serialport[device-1].num_active_buttons++;
110 
111  _ts5_status.timer.serialport[device-1]
112  .button_press_defined[button-1] =
113  _ts5_status.timer.num_defined_buttons;
114 
115  _ts5_status.timer.serialport[device-1]
116  .button_press_active[button-1] =
117  _ts5_status.timer.num_defined_buttons;
118 
119  return _ts5_status.timer.num_defined_buttons;
120 }
121 
122 
123 ////////////////////////////////////////////////////////////////////////////////
124 /// Get the number of serial ports that are connected to the system.
125 ///
126 /// \return The number of serial ports that are connected to the system.
127 ////////////////////////////////////////////////////////////////////////////////
129 {
130  ts5_check_serialport("ts5_get_num_serialports");
131  ts5_log(TS5_LOGLEVEL_4, "ts5_get_num_serialports()\n");
132 
133  return _ts5_status.timer.num_serialports;
134 }
135 
136 
137 ////////////////////////////////////////////////////////////////////////////////
138 /// Get the number of buttons available on a serial port.
139 ///
140 /// \param device Number of the serial port (devices are numbered from 1).
141 ///
142 /// \return The number of buttons on the serial port.
143 ////////////////////////////////////////////////////////////////////////////////
145 {
146  ts5_check_serialport("ts5_get_num_serialport_buttons");
147  ts5_log(TS5_LOGLEVEL_4, "ts5_get_num_serialport_buttons(%d)\n", device);
148 
149  if (device<1 || device>_ts5_status.timer.num_serialports) {
150  ts5_fatal("%s: %s %d, %s %d\n", "ts5_get_num_serialport_buttons",
151  "device argument is", device, "number of serialports is",
152  _ts5_status.timer.num_serialports);
153  }
154 
155  return _ts5_status.timer.serialport[device-1].num_buttons;
156 }
157 
158 
159 ////////////////////////////////////////////////////////////////////////////////
160 //@}
161 ////////////////////////////////////////////////////////////////////////////////
162 
163 
164 ////////////////////////////////////////////////////////////////////////////////
165 /// @name Trigger input/output
166 /// The serial ports can be used as trigger input/output devices.
167 /// See timer.c for more information about trigger input/output.
168 //@{
169 ////////////////////////////////////////////////////////////////////////////////
170 
171 
172 ////////////////////////////////////////////////////////////////////////////////
173 /// Define a serial port as a trigger input device
174 ///
175 /// \param portname Name of the serial port
176 /// (COM1, ... on Windows, /etc/tty... on Posix systems).
177 ///
178 /// \return The device number of the port
179 /// (the first serial port opened by Tscope5 gets number 1, etc.).
180 ////////////////////////////////////////////////////////////////////////////////
182 {
183  ts5_check_serialport("ts5_define_serialport_trigger_input");
184 
185  int portnum = ts5_check_serialport2("ts5_define_serialport_trigger_input",
186  portname);
187 
188  ts5_log(TS5_LOGLEVEL_3, "ts5_define_serialport_trigger_input(%s)\n",
189  portname);
190 
191  _ts5_status.timer.serialport_is_trigger_device = 1;
192  _ts5_status.timer.serialport[portnum].is_trigger_input_device = 1;
193 
194  return portnum+1;
195 }
196 
197 
198 ////////////////////////////////////////////////////////////////////////////////
199 /// Turn on serial port input simulation.
200 ///
201 /// \param device Number of the serial port.
202 /// \param value Input value that has to be simulated
203 /// (0-255, 0 turns the simulation off).
204 /// \param interval Interval in seconds between two triggers.
205 ////////////////////////////////////////////////////////////////////////////////
206 void ts5_simulate_serialport_trigger_input(int device, unsigned char value,
207  double interval)
208 {
209  ts5_check_serialport("ts5_simulate_serialport_trigger_input");
210  ts5_log(TS5_LOGLEVEL_3, "ts5_simulate_serialport_trigger_input(%d,%d,%f)\n",
211  device, value, interval);
212 
213  if (device<1 || device>_ts5_status.timer.num_serialports) {
214  ts5_fatal("%s: %s %d, %s %d\n", "ts5_simulate_serialport_trigger_input",
215  "device argument is", device,
216  "number of serial ports is",
217  _ts5_status.timer.num_serialports);
218  }
219 
220  _ts5_status.timer.serialport[device-1].simulate_trigger_input =
221  value;
222 
223  _ts5_status.timer.serialport[device-1].trigger_simulation_interval =
224  interval;
225 }
226 
227 
228 ////////////////////////////////////////////////////////////////////////////////
229 /// Define a serial port as a trigger output device
230 ///
231 /// \param portname Name of the serial port
232 /// (COM1, ... on Windows, /etc/tty... on Posix systems).
233 ///
234 /// \return The device number of the port
235 /// (the first serial port opened by Tscope5 gets number 1, etc.).
236 ////////////////////////////////////////////////////////////////////////////////
238 {
239  ts5_check_serialport("ts5_define_serialport_trigger_output");
240 
241  int portnum = ts5_check_serialport2("ts5_define_serialport_trigger_output",
242  portname);
243 
244  ts5_log(TS5_LOGLEVEL_3, "ts5_define_serialport_trigger_output(%s)\n",
245  portname);
246 
247  _ts5_status.timer.serialport_is_trigger_device = 1;
248  _ts5_status.timer.serialport[portnum].is_trigger_output_device = 1;
249  return portnum+1;
250 }
251 
252 
253 ////////////////////////////////////////////////////////////////////////////////
254 /// Send a trigger trough a serial port
255 ///
256 /// \param device Number of the serial port (devices are numbered from 1).
257 /// \param value The trigger value that has to be sent (0-255).
258 ////////////////////////////////////////////////////////////////////////////////
259 void ts5_send_serialport_trigger(int device, unsigned char value)
260 {
261  ts5_check_serialport("ts5_send_serialport_trigger");
262  ts5_log(TS5_LOGLEVEL_3, "ts5_send_serialport_trigger(%d,%d)\n",
263  device, value);
264 
265  if (device<1 || device>_ts5_status.timer.num_serialports) {
266  ts5_fatal("%s: %s %d, %s %d\n", "ts5_send_serialport_trigger",
267  "device argument is", device,
268  "number of serial ports is",
269  _ts5_status.timer.num_serialports);
270  }
271 
272  char serial_buff[TS5_MAX_CHAR];
273  sprintf(serial_buff, "%c", value);
274 
275  #ifdef TS5_WINDOWS
276 
277  unsigned long bytes_to_write = strlen(serial_buff);
278  unsigned long bytes_written;
279 
280  if (!WriteFile(*(_ts5_status.timer.serialport[device-1].port),
281  serial_buff, bytes_to_write, &bytes_written, NULL)) {
282  ts5_fatal("ts5_send_serialport_trigger: write error 1\n");
283  }
284 
285  if (bytes_written != bytes_to_write) {
286  ts5_fatal("ts5_send_serialport_trigger: write error 2\n");
287  }
288 
289 
290  #else
291 
292  unsigned int bytes_to_write = strlen(serial_buff);
293  unsigned int bytes_written;
294 
295  bytes_written =
296  write(*(_ts5_status.timer.serialport[device-1].port),
297  serial_buff, bytes_to_write);
298 
299  if (bytes_written != bytes_to_write) {
300  ts5_fatal("ts5_send_serialport_trigger: write error\n");
301  }
302 
303 
304  #endif
305 }
306 
307 
308 ////////////////////////////////////////////////////////////////////////////////
309 /// Get a pointer to a serial port
310 ///
311 /// \param device Number of the serial port (devices are numbered from 1).
312 ///
313 /// \return pointer to the serial port.
314 ////////////////////////////////////////////////////////////////////////////////
315 TS5_SERIALPORT* ts5_get_serialport(int device)
316 {
317  ts5_check_serialport("ts5_get_serialport");
318  ts5_log(TS5_LOGLEVEL_3, "ts5_get_serialport(%d)\n", device);
319 
320  if (device < 1 || device>_ts5_status.timer.num_serialports) {
321  ts5_fatal("%s: %s %d, %s %d\n", ts5_get_serialport,
322  "device argument is", device,
323  "number of opened serial ports is",
324  _ts5_status.timer.num_serialports);
325  }
326  return _ts5_status.timer.serialport[device-1].port;
327 }
328 
329 
330 
331 ////////////////////////////////////////////////////////////////////////////////
332 //@}
333 ////////////////////////////////////////////////////////////////////////////////
void ts5_simulate_serialport_trigger_input(int device, unsigned char value, double interval)
Turn on serial port input simulation.
Definition: serialport.c:206
int ts5_get_num_serialport_buttons(int device)
Get the number of buttons available on a serial port.
Definition: serialport.c:144
int ts5_define_serialport_button(int device, int button)
Define a serial port button as a response button.
Definition: serialport.c:69
int ts5_define_serialport_response_input(char *portname)
Define a serial port as a response input device.
Definition: serialport.c:42
int ts5_define_serialport_trigger_output(char *portname)
Define a serial port as a trigger output device.
Definition: serialport.c:237
TS5_SERIALPORT * ts5_get_serialport(int device)
Get a pointer to a serial port.
Definition: serialport.c:315
void ts5_send_serialport_trigger(int device, unsigned char value)
Send a trigger trough a serial port.
Definition: serialport.c:259
int ts5_get_num_serialports()
Get the number of serial ports that are connected to the system.
Definition: serialport.c:128
void ts5_check_serialport(char *calling_function)
Do some checks at the start of each serialport function.
void ts5_log(const unsigned int level, const char *format,...)
Send info to a logging window.
Definition: system.c:45
int ts5_define_serialport_trigger_input(char *portname)
Define a serial port as a trigger input device.
Definition: serialport.c:181
void ts5_fatal(const char *format,...)
Exit safely with an error message.
Definition: system.c:533
int ts5_check_serialport2(char *calling_function, char *portname)
Do some checks at the start of each serialport function.