Tscope5
cedrusbox.c
Go to the documentation of this file.
1 ////////////////////////////////////////////////////////////////////////////////
2 //
3 // __ ______
4 // / /_______________ ____ ___ / ____/
5 // / __/ ___/ ___/ __ \/ __ \/ _ \ /___ )
6 // / /_(__ ) /__/ /_/ / /_/ / __/ ____/ /
7 // \__/____/\___/\____/ .___/\___/ /_____/
8 // /_/
9 //
10 /// \file cedrusbox.c
11 /// Definitions of cedrusbox functions
12 /// \example cedrusbox01.c
13 /// \todo SV1 testen
14 ////////////////////////////////////////////////////////////////////////////////
15 
16 
17 #include "../include/tscope5/cedrusbox.h"
18 #include "../include/tscope5/cedrusbox_internal.h"
19 #include "../include/tscope5/system_internal.h"
20 
21 
22 ////////////////////////////////////////////////////////////////////////////////
23 /// @name Response registration
24 /// Cedrus response boxes can only be used as response devices.
25 /// See timer.c for more information about response registration.
26 //@{
27 ////////////////////////////////////////////////////////////////////////////////
28 
29 
30 ////////////////////////////////////////////////////////////////////////////////
31 /// Define a cedrusbox button as a response button.
32 ///
33 /// \param device Number of the cedrusbox (devices are numbered from 1).
34 /// \param button Number of the button (buttons are counted from 1).
35 ///
36 /// \return The reponse number associated with the button.
37 ///
38 /// Give a positive number if you want to monitor button press events,
39 /// a negative number if you want to monitor button release events.
40 ////////////////////////////////////////////////////////////////////////////////
41 int ts5_define_cedrusbox_button(int device, int button)
42 {
43  ts5_check_cedrusbox("ts5_define_cedrusbox_button");
44  ts5_log(TS5_LOGLEVEL_3, "ts5_define_cedrusbox_button(%d,%d)\n", device, button);
45 
46  if (device<1 || device>_ts5_status.timer.num_cedrusboxes) {
47  ts5_fatal("%s: %s %d, %s %d\n", "ts5_define_cedrusbox_button",
48  "device argument is", device, "number of cedrusboxes is",
49  _ts5_status.timer.num_cedrusboxes);
50  }
51 
52  if (button==0) {
53  ts5_fatal("%s: %s\n", "ts5_define_cedrusbox_button",
54  "button argument is 0, response buttons are numbered from 1");
55  }
56 
57  if (abs(button)>_ts5_status.timer.cedrusbox[device-1].num_buttons) {
58  ts5_fatal("%s: %s %d, %s %d is %d\n", "ts5_define_cedrusbox_button",
59  "button argument is ", button,
60  "number of cedrusbox buttons for device", device,
61  _ts5_status.timer.cedrusbox[device-1].num_buttons);
62  }
63 
64  if (button>0 && _ts5_status.timer.cedrusbox[device-1]
65  .button_press_defined[button-1] !=0) {
66  ts5_fatal("%s: %s %d %s\n", "ts5_define_cedrusbox_button",
67  "button press", button, "is already defined");
68  }
69 
70  if (button<0 && _ts5_status.timer.cedrusbox[device-1]
71  .button_release_defined[-button-1]!=0) {
72  ts5_fatal("%s: %s %d %s\n", "ts5_define_cedrusbox_button",
73  "button release", button, "is already defined");
74  }
75 
76  _ts5_status.timer.cedrusbox_is_response_device = 1;
77  _ts5_status.timer.num_defined_buttons++;
78  _ts5_status.timer.num_active_buttons++;
79  _ts5_status.timer.cedrusbox[device-1].num_defined_buttons++;
80  _ts5_status.timer.cedrusbox[device-1].num_active_buttons++;
81 
82  if (button>0) {
83  _ts5_status.timer.cedrusbox[device-1]
84  .button_press_defined[button-1] =
85  _ts5_status.timer.num_defined_buttons;
86 
87  _ts5_status.timer.cedrusbox[device-1]
88  .button_press_active[button-1] =
89  _ts5_status.timer.num_defined_buttons;
90 
91  }
92  else {
93  _ts5_status.timer.cedrusbox[device-1]
94  .button_release_defined[-button-1] =
95  _ts5_status.timer.num_defined_buttons;
96 
97  _ts5_status.timer.cedrusbox[device-1]
98  .button_release_active[-button-1] =
99  _ts5_status.timer.num_defined_buttons;
100  }
101 
102  return _ts5_status.timer.num_defined_buttons;
103 }
104 
105 
106 ////////////////////////////////////////////////////////////////////////////////
107 /// Get then number of cedrusboxes that are connected to the system.
108 ///
109 /// \return The number of cedrusboxes that are connected to the system.
110 ////////////////////////////////////////////////////////////////////////////////
112 {
113  ts5_check_cedrusbox("ts5_get_num_cedrusboxes");
114  ts5_log(TS5_LOGLEVEL_4, "ts5_get_num_cedrusboxes()\n");
115 
116  return _ts5_status.timer.num_cedrusboxes;
117 }
118 
119 
120 ////////////////////////////////////////////////////////////////////////////////
121 /// Get then number of buttons available on a cedrusbox.
122 ///
123 /// \param device Number of the cedrusbox (devices are numbered from 1).
124 ///
125 /// \return The number of buttons on the cedrusbox.
126 ////////////////////////////////////////////////////////////////////////////////
128 {
129  ts5_check_cedrusbox("ts5_get_num_cedrusbox_buttons");
130  ts5_log(TS5_LOGLEVEL_4, "ts5_get_num_cedrusbox_buttons(%d)\n", device);
131 
132  return _ts5_status.timer.cedrusbox[device-1].num_buttons;
133 }
134 
135 
136 ////////////////////////////////////////////////////////////////////////////////
137 /// Set a parameter on a cedrusbox.
138 ///
139 /// \param device Number of the cedrusbox.
140 /// \param parameter Code for the parameter that will be set.
141 /// \param value The value that will be set.
142 ///
143 /// \return The previous value for the parameter.
144 ///
145 /// The available commands for SV1 voice keys are:
146 /// - TS5_CEDRUSBOX_LOCKINGLEVEL:
147 /// can be S5_CEDRUSBOX_LOCK or TS5_CEDRUSBOX_UNLOCK.
148 /// This locks/unlocks the treshold and delay dials on the device.
149 /// - TS5_CEDRUSBOX_TRESHOLD: voice key treshold.
150 /// Should be an integer between the values set with
151 /// TS5_CEDRUSBOX_MIN_TRESHOLD and TS5_CEDRUSBOX_MAX_TRESHOLD.
152 /// - TS5_CEDRUSBOX_MIN_TRESHOLD: minimum voice key treshold that can be set.
153 /// Should be an integer value between 0 and the value set with
154 /// TS5_CEDRUSBOX_MAX_TRESHOLD.
155 /// - TS5_CEDRUSBOX_MAX_TRESHOLD: maximum voice key treshold that can be set.
156 /// Should be an integer value between the value set with
157 /// TS5_CEDRUSBOX_MIN_TRESHOLD and 255.
158 /// - TS5_CEDRUSBOX_RISE_DELAY: voice key rise delay in milliseconds.
159 /// Should be an integer between the values set with
160 /// TS5_CEDRUSBOX_MIN_RISE_DELAY and TS5_CEDRUSBOX_MAX_RISE_DELAY.
161 /// - TS5_CEDRUSBOX_MIN_RISE_DELAY: minimum voice key rise delay
162 /// that can be set. Should be an integer value between 0 and the value set
163 /// with TS5_CEDRUSBOX_MAX_RISE_DELAY.
164 /// - TS5_CEDRUSBOX_MAX_RISE_DELAY: maximum voice key rise delay
165 /// that can be set. Should be an integer value between the value set
166 /// with TS5_CEDRUSBOX_MIN_TRESHOLD and 100.
167 /// - TS5_CEDRUSBOX_DROP_DELAY: voice key drop delay in milliseconds.
168 /// Should be an integer value between 0 and 255.
169 ////////////////////////////////////////////////////////////////////////////////
170 int ts5_cedrusbox_set_parameter(int device, int parameter, int value)
171 {
172  ts5_check_cedrusbox("ts5_cedrusbox_set_parameter");
173  ts5_log(TS5_LOGLEVEL_4, "ts5_cedrusbox_set_parameter(%d,%d,%d)\n",
174  device, parameter, value);
175 
176  if (_ts5_status.timer.cedrusbox[device-1].type!=TS5_CEDRUSBOX_SV1) {
177  ts5_fatal("%s: %s %d %s\n", "ts5_cedrusbox_set_parameter",
178  "device", device, "is not a voice key");
179  }
180 
181  // pause the response thread if necessary
182  int pause_cedrusbox = _ts5_data.timer.cedrusbox_thread &&
183  !_ts5_data.timer.cedrusbox_thread_is_paused;
184 
185  if (pause_cedrusbox) {
186  al_join_thread(_ts5_data.timer.cedrusbox_thread, NULL);
187  _ts5_data.timer.cedrusbox_thread_is_paused = 1;
188  }
189 
190  int port_num = _ts5_status.timer.cedrusbox[device-1].port_num;
191  int retval = ts5_cedrusbox_get_parameter(device, parameter);
192  char command[6];
193 
194  int min, max;
195 
196  switch (parameter) {
197 
198  case TS5_CEDRUSBOX_LOCKINGLEVEL:
199 
200  if (value != TS5_CEDRUSBOX_LOCK && value != TS5_CEDRUSBOX_UNLOCK) {
201  ts5_fatal("%s: %s %s\n", "ts5_cedrusbox_set_parameter",
202  "TS5_CEDRUSBOX_LOCKINGLEVEL should be",
203  "TS5_CEDRUSBOX_LOCK or TS5_CEDRUSBOX_UNLOCK");
204  }
205 
206  sprintf(command, "f2%d", value);
207  break;
208 
209  case TS5_CEDRUSBOX_TRESHOLD:
210 
211  min = ts5_cedrusbox_get_parameter(device, TS5_CEDRUSBOX_MIN_TRESHOLD);
212  max = ts5_cedrusbox_get_parameter(device, TS5_CEDRUSBOX_MAX_TRESHOLD);
213 
214  if (value < min || value > max) {
215  ts5_fatal("%s: %s min (%d) and max(%d)\n",
216  "ts5_cedrusbox_set_parameter",
217  "treshold should be between", min, max);
218  }
219 
220  sprintf(command, "b1%d", value);
221  break;
222 
223  case TS5_CEDRUSBOX_MIN_TRESHOLD:
224 
225  max = ts5_cedrusbox_get_parameter(device, TS5_CEDRUSBOX_MAX_TRESHOLD);
226  if (value < 0 || value > max) {
227  ts5_fatal("%s: %s (%d)\n", "ts5_cedrusbox_set_parameter",
228  "minimum treshold should be between 0 and max", max);
229  }
230 
231  sprintf(command, "b6%d", value);
232  break;
233 
234  case TS5_CEDRUSBOX_MAX_TRESHOLD:
235 
236  min = ts5_cedrusbox_get_parameter(device, TS5_CEDRUSBOX_MIN_TRESHOLD);
237 
238  if (value < min || value > 255) {
239  ts5_fatal("%s: %s min (%d) and 255\n",
240  "ts5_cedrusbox_set_parameter",
241  "maximum treshold should be between", min);
242  }
243 
244  sprintf(command, "b7%d", value);
245  break;
246 
247  case TS5_CEDRUSBOX_RISE_DELAY:
248 
249  min = ts5_cedrusbox_get_parameter(device, TS5_CEDRUSBOX_MIN_RISE_DELAY);
250  max = ts5_cedrusbox_get_parameter(device, TS5_CEDRUSBOX_MAX_RISE_DELAY);
251 
252  if (value < min || value > max) {
253  ts5_fatal("%s: %s min (%d) and max (%d)",
254  "ts5_cedrusbox_set_parameter",
255  "rise delay should be between", min, max);
256  }
257 
258  sprintf(command, "b2%d", value);
259  break;
260 
261  case TS5_CEDRUSBOX_MIN_RISE_DELAY:
262 
263  max = ts5_cedrusbox_get_parameter(device, TS5_CEDRUSBOX_MAX_RISE_DELAY);
264 
265  if (value < 0 || value > max) {
266  ts5_fatal("%s: %s (%d)\n", "ts5_cedrusbox_set_parameter",
267  "minimum rise delay should be between 0 and max", max);
268  }
269 
270  sprintf(command, "b4%d", value);
271  break;
272 
273  case TS5_CEDRUSBOX_MAX_RISE_DELAY:
274 
275  min = ts5_cedrusbox_get_parameter(device, TS5_CEDRUSBOX_MIN_RISE_DELAY);
276 
277  if (value < min || value > 100) {
278  ts5_fatal("%s: %s min (%d) and 100",
279  "ts5_cedrusbox_set_parameter",
280  "maximum rise delay should be between", min);
281  }
282 
283  sprintf(command, "b5%d", value);
284  break;
285 
286  case TS5_CEDRUSBOX_DROP_DELAY:
287 
288  if (value < 0 || value > 255) {
289  ts5_fatal("%s: %s\n", "ts5_cedrusbox_set_parameter",
290  "drop delay should be between 0 and 255\n");
291  }
292 
293  sprintf(command, "b3%d", value);
294  break;
295 
296  default:
297  ts5_fatal("ts5_cedrusbox_set_parameter: unknown parameter value (%d)\n",
298  parameter);
299  }
300 
301  ts5_write_cedrusbox(port_num, command, 4);
302 
303  int newval = ts5_cedrusbox_get_parameter(device, parameter);
304 
305  if (newval != value) {
306  ts5_fatal("%s: %s %d\n", "ts5_cedrusbox_set_parameter",
307  "could not change parameter", parameter);
308  }
309 
310  if (pause_cedrusbox) {
311  al_start_thread(_ts5_data.timer.cedrusbox_thread);
312  _ts5_data.timer.cedrusbox_thread_is_paused = 0;
313  }
314 
315  return retval;
316 }
317 
318 
319 ////////////////////////////////////////////////////////////////////////////////
320 /// Get a parameter on a cedrusbox.
321 ///
322 /// \param device Number of the cedrusbox.
323 /// \param parameter Code for the parameter that will be queried.
324 ///
325 /// \return The value for the parameter.
326 ///
327 /// See ts5_cedrusbox_set_parameter() for the list of parameter values.
328 ////////////////////////////////////////////////////////////////////////////////
329 int ts5_cedrusbox_get_parameter(int device, int parameter)
330 {
331  ts5_check_cedrusbox("ts5_cedrusbox_get_parameter");
332  ts5_log(TS5_LOGLEVEL_4, "ts5_cedrusbox_get_parameter(%d,%d)\n",
333  device, parameter);
334 
335  if (_ts5_status.timer.cedrusbox[device-1].type!=TS5_CEDRUSBOX_SV1) {
336  ts5_fatal("ts5_cedrusbox_get_parameter: device %d is not a voice key\n",
337  device);
338  }
339 
340  int port_num = _ts5_status.timer.cedrusbox[device-1].port_num;
341 
342  char command[4];
343 
344  switch (parameter) {
345 
346  case TS5_CEDRUSBOX_LOCKINGLEVEL:
347  sprintf(command, "_f2");
348  break;
349 
350  case TS5_CEDRUSBOX_TRESHOLD:
351  sprintf(command, "_b1");
352  break;
353 
354  case TS5_CEDRUSBOX_MIN_TRESHOLD:
355  sprintf(command, "_b6");
356  break;
357 
358  case TS5_CEDRUSBOX_MAX_TRESHOLD:
359  sprintf(command, "_b7");
360  break;
361 
362  case TS5_CEDRUSBOX_RISE_DELAY:
363  sprintf(command, "_b2");
364  break;
365 
366  case TS5_CEDRUSBOX_MIN_RISE_DELAY:
367  sprintf(command, "_b4");
368  break;
369 
370  case TS5_CEDRUSBOX_MAX_RISE_DELAY:
371  sprintf(command, "_b5");
372  break;
373 
374  case TS5_CEDRUSBOX_DROP_DELAY:
375  sprintf(command, "_b3");
376  break;
377 
378  default:
379  ts5_fatal("%s: %s (%d)\n", "ts5_cedrusbox_get_parameter",
380  "unknown parameter value", parameter);
381  }
382 
383  // pause the response thread if necessary
384  int pause_cedrusbox = _ts5_data.timer.cedrusbox_thread &&
385  !_ts5_data.timer.cedrusbox_thread_is_paused;
386 
387  if (pause_cedrusbox) {
388  al_join_thread(_ts5_data.timer.cedrusbox_thread, NULL);
389  _ts5_data.timer.cedrusbox_thread_is_paused = 1;
390  }
391 
392  // write command
393  ts5_write_cedrusbox(port_num, command, 3);
394 
395  // wait for response
396  char serial_buff[TS5_MAX_CHAR];
397  serial_buff[0] = '\0';
398  ts5_read_cedrusbox(port_num, serial_buff, 4);
399 
400  int value = 0;
401  value = serial_buff[3];
402 
403  // restart thread if necessary
404  if (pause_cedrusbox) {
405  al_start_thread(_ts5_data.timer.cedrusbox_thread);
406  _ts5_data.timer.cedrusbox_thread_is_paused = 0;
407  }
408 
409  return value;
410 }
411 
412 
413 ////////////////////////////////////////////////////////////////////////////////
414 //@}
415 ////////////////////////////////////////////////////////////////////////////////