minilab 1.0.0-mswin32

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (128) hide show
  1. data/.document +2 -0
  2. data/CHANGES +2 -0
  3. data/LICENSE +19 -0
  4. data/README +107 -0
  5. data/Rakefile +145 -0
  6. data/config/environment.rb +15 -0
  7. data/config/objects.yml +22 -0
  8. data/lib/analog_io.rb +30 -0
  9. data/lib/digital_auxport_io.rb +49 -0
  10. data/lib/digital_configuration.rb +66 -0
  11. data/lib/digital_port_io.rb +68 -0
  12. data/lib/extension/extconf.rb +4 -0
  13. data/lib/extension/minilab_hardware.c +235 -0
  14. data/lib/extension/minilab_hardware.so +0 -0
  15. data/lib/library_translator.rb +48 -0
  16. data/lib/minilab.rb +149 -0
  17. data/lib/minilab_context.rb +39 -0
  18. data/lib/result_verifier.rb +14 -0
  19. data/test/integration/analog_input_output_test.rb +43 -0
  20. data/test/integration/connect_to_hardware_test.rb +13 -0
  21. data/test/integration/digital_input_output_test.rb +114 -0
  22. data/test/integration/integration_test.rb +53 -0
  23. data/test/integration/require_minilab_test.rb +9 -0
  24. data/test/system/analog_input.test +3 -0
  25. data/test/system/analog_output.test +37 -0
  26. data/test/system/digital_port_input.test +5 -0
  27. data/test/system/digital_port_output.test +39 -0
  28. data/test/system/digital_port_read_byte.test +26 -0
  29. data/test/system/digital_screw_terminals_input.test +2 -0
  30. data/test/system/digital_screw_terminals_output.test +11 -0
  31. data/test/system/minilab_driver.rb +85 -0
  32. data/test/test_helper.rb +11 -0
  33. data/test/unit/analog_io_test.rb +87 -0
  34. data/test/unit/digital_auxport_io_test.rb +114 -0
  35. data/test/unit/digital_configuration_test.rb +136 -0
  36. data/test/unit/digital_port_io_test.rb +117 -0
  37. data/test/unit/library_translator_test.rb +100 -0
  38. data/test/unit/minilab_context_test.rb +82 -0
  39. data/test/unit/minilab_hardware_test.rb +83 -0
  40. data/test/unit/minilab_test.rb +131 -0
  41. data/test/unit/result_verifier_test.rb +33 -0
  42. data/vendor/behaviors/lib/behaviors.rb +50 -0
  43. data/vendor/behaviors/tasks/behaviors_tasks.rake +140 -0
  44. data/vendor/behaviors/test/behaviors_tasks_test.rb +71 -0
  45. data/vendor/behaviors/test/behaviors_test.rb +50 -0
  46. data/vendor/behaviors/test/tasks_test/Rakefile +16 -0
  47. data/vendor/behaviors/test/tasks_test/doc/behaviors.html +55 -0
  48. data/vendor/behaviors/test/tasks_test/lib/user.rb +2 -0
  49. data/vendor/behaviors/test/tasks_test/test/user_test.rb +17 -0
  50. data/vendor/constructor/Rakefile +44 -0
  51. data/vendor/constructor/config/environment.rb +12 -0
  52. data/vendor/constructor/lib/constructor.rb +132 -0
  53. data/vendor/constructor/test/constructor_test.rb +366 -0
  54. data/vendor/constructor/test/helper.rb +3 -0
  55. data/vendor/diy/README +26 -0
  56. data/vendor/diy/Rakefile +18 -0
  57. data/vendor/diy/lib/constructor.rb +114 -0
  58. data/vendor/diy/lib/diy.rb +329 -0
  59. data/vendor/diy/proto/context.rb +117 -0
  60. data/vendor/diy/proto/context.yml +20 -0
  61. data/vendor/diy/test/diy_test.rb +370 -0
  62. data/vendor/diy/test/files/broken_construction.yml +7 -0
  63. data/vendor/diy/test/files/cat/cat.rb +4 -0
  64. data/vendor/diy/test/files/cat/extra_conflict.yml +5 -0
  65. data/vendor/diy/test/files/cat/heritage.rb +2 -0
  66. data/vendor/diy/test/files/cat/needs_input.yml +3 -0
  67. data/vendor/diy/test/files/cat/the_cat_lineage.rb +1 -0
  68. data/vendor/diy/test/files/dog/dog_model.rb +4 -0
  69. data/vendor/diy/test/files/dog/dog_presenter.rb +4 -0
  70. data/vendor/diy/test/files/dog/dog_view.rb +2 -0
  71. data/vendor/diy/test/files/dog/file_resolver.rb +2 -0
  72. data/vendor/diy/test/files/dog/other_thing.rb +2 -0
  73. data/vendor/diy/test/files/dog/simple.yml +11 -0
  74. data/vendor/diy/test/files/donkey/foo.rb +8 -0
  75. data/vendor/diy/test/files/donkey/foo/bar/qux.rb +7 -0
  76. data/vendor/diy/test/files/fud/objects.yml +13 -0
  77. data/vendor/diy/test/files/fud/toy.rb +15 -0
  78. data/vendor/diy/test/files/gnu/objects.yml +14 -0
  79. data/vendor/diy/test/files/gnu/thinger.rb +8 -0
  80. data/vendor/diy/test/files/goat/base.rb +8 -0
  81. data/vendor/diy/test/files/goat/can.rb +6 -0
  82. data/vendor/diy/test/files/goat/goat.rb +6 -0
  83. data/vendor/diy/test/files/goat/objects.yml +12 -0
  84. data/vendor/diy/test/files/goat/paper.rb +6 -0
  85. data/vendor/diy/test/files/goat/plane.rb +8 -0
  86. data/vendor/diy/test/files/goat/shirt.rb +6 -0
  87. data/vendor/diy/test/files/goat/wings.rb +8 -0
  88. data/vendor/diy/test/files/horse/holder_thing.rb +4 -0
  89. data/vendor/diy/test/files/horse/objects.yml +7 -0
  90. data/vendor/diy/test/files/yak/core_model.rb +4 -0
  91. data/vendor/diy/test/files/yak/core_presenter.rb +4 -0
  92. data/vendor/diy/test/files/yak/core_view.rb +1 -0
  93. data/vendor/diy/test/files/yak/data_source.rb +1 -0
  94. data/vendor/diy/test/files/yak/fringe_model.rb +4 -0
  95. data/vendor/diy/test/files/yak/fringe_presenter.rb +4 -0
  96. data/vendor/diy/test/files/yak/fringe_view.rb +1 -0
  97. data/vendor/diy/test/files/yak/my_objects.yml +21 -0
  98. data/vendor/diy/test/test_helper.rb +40 -0
  99. data/vendor/hardmock/CHANGES +8 -0
  100. data/vendor/hardmock/LICENSE +7 -0
  101. data/vendor/hardmock/README +48 -0
  102. data/vendor/hardmock/Rakefile +100 -0
  103. data/vendor/hardmock/TODO +7 -0
  104. data/vendor/hardmock/config/environment.rb +12 -0
  105. data/vendor/hardmock/homepage/demo.rb +21 -0
  106. data/vendor/hardmock/homepage/hardmock_sample.png +0 -0
  107. data/vendor/hardmock/homepage/index.html +65 -0
  108. data/vendor/hardmock/init.rb +3 -0
  109. data/vendor/hardmock/lib/hardmock.rb +634 -0
  110. data/vendor/hardmock/lib/method_cleanout.rb +14 -0
  111. data/vendor/hardmock/rcov.rake +18 -0
  112. data/vendor/hardmock/test/functional/assert_error_test.rb +52 -0
  113. data/vendor/hardmock/test/functional/auto_verify_test.rb +192 -0
  114. data/vendor/hardmock/test/functional/direct_mock_usage_test.rb +396 -0
  115. data/vendor/hardmock/test/functional/hardmock_test.rb +380 -0
  116. data/vendor/hardmock/test/test_helper.rb +23 -0
  117. data/vendor/hardmock/test/unit/expectation_builder_test.rb +18 -0
  118. data/vendor/hardmock/test/unit/expector_test.rb +56 -0
  119. data/vendor/hardmock/test/unit/method_cleanout_test.rb +35 -0
  120. data/vendor/hardmock/test/unit/mock_control_test.rb +172 -0
  121. data/vendor/hardmock/test/unit/mock_test.rb +273 -0
  122. data/vendor/hardmock/test/unit/simple_expectation_test.rb +345 -0
  123. data/vendor/hardmock/test/unit/trapper_test.rb +60 -0
  124. data/vendor/hardmock/test/unit/verify_error_test.rb +34 -0
  125. data/vendor/systir/systir.rb +403 -0
  126. data/vendor/systir/test/unit/ui/xml/testrunner.rb +192 -0
  127. data/vendor/systir/test/unit/ui/xml/xmltestrunner.xslt +109 -0
  128. metadata +235 -0
@@ -0,0 +1,68 @@
1
+ require 'constructor'
2
+
3
+ class DigitalPortIo #:nodoc:
4
+ constructor :minilab_hardware, :result_verifier, :digital_configuration, :library_translator
5
+
6
+ def get_valid_ports
7
+ @digital_configuration.get_valid_ports
8
+ end
9
+
10
+ def configure_input_port(port)
11
+ @digital_configuration.configure_port_for_input(port)
12
+ end
13
+
14
+ def configure_output_port(port)
15
+ @digital_configuration.configure_port_for_output(port)
16
+ end
17
+
18
+ def read_digital(pin)
19
+ check_pin_configuration(pin, :input)
20
+ pin = get_library_pin_number(pin)
21
+
22
+ access_hardware(:read_digital_pin, pin)
23
+ end
24
+
25
+ def write_digital(pin, value)
26
+ check_pin_configuration(pin, :output)
27
+ pin = get_library_pin_number(pin)
28
+
29
+ access_hardware(:write_digital_pin, pin, value)
30
+ true
31
+ end
32
+
33
+ def read_port(port)
34
+ raise "#{port} is an invalid port." unless get_valid_ports.include?(port)
35
+
36
+ if !@digital_configuration.is_port_configured_for_input?(port)
37
+ raise "Digital port #{port} is not configured for input."
38
+ end
39
+
40
+ access_hardware("read_port", get_library_port(port))
41
+ end
42
+
43
+ private
44
+ def get_port(pin)
45
+ @library_translator.get_port_for_pin(pin)
46
+ end
47
+
48
+ def get_library_pin_number(pin)
49
+ @library_translator.get_library_pin_number(pin)
50
+ end
51
+
52
+ def get_library_port(port)
53
+ @library_translator.get_library_port(port)
54
+ end
55
+
56
+ def check_pin_configuration(pin, type)
57
+ port = get_port(pin)
58
+ if !@digital_configuration.send("is_port_configured_for_#{type}?", port)
59
+ raise "Digital port #{port} for pin #{pin} is not configured for #{type}."
60
+ end
61
+ end
62
+
63
+ def access_hardware(method, *args)
64
+ result = @minilab_hardware.send(method, *args)
65
+ @result_verifier.verify(result)
66
+ result[:value]
67
+ end
68
+ end
@@ -0,0 +1,4 @@
1
+ require 'mkmf'
2
+
3
+ have_library('cbw32')
4
+ create_makefile('minilab_hardware')
@@ -0,0 +1,235 @@
1
+ #include "ruby.h"
2
+ #include "stdio.h"
3
+ #include "cbw.h"
4
+
5
+ #define BOARD_NUM 0
6
+
7
+ static void define_constants();
8
+ static VALUE create_error_and_value_hash(int error, VALUE the_value);
9
+ static VALUE create_error_hash(int error);
10
+ static VALUE setup_error_handling(VALUE self, VALUE error_reporting, VALUE error_handling);
11
+ static VALUE declare_revision(VALUE self, VALUE revision);
12
+ static VALUE get_revision(VALUE self);
13
+ static VALUE get_error_string(VALUE self, VALUE error);
14
+ static VALUE configure_auxport(VALUE self, VALUE optz);
15
+ static VALUE configure_port(VALUE self, VALUE optz);
16
+ static VALUE read_analog(VALUE self, VALUE channel);
17
+ static VALUE read_digital_pin(VALUE self, VALUE pin);
18
+ static VALUE read_auxport(VALUE self, VALUE pin);
19
+ static VALUE read_port(VALUE self, VALUE port);
20
+ static VALUE write_analog(VALUE self, VALUE channel, VALUE volts);
21
+ static VALUE write_digital_pin(VALUE self, VALUE pin, VALUE data);
22
+ static VALUE write_auxport(VALUE self, VALUE pin, VALUE data);
23
+
24
+ VALUE MinilabHardware;
25
+
26
+ /* :nodoc: */
27
+ void Init_minilab_hardware()
28
+ {
29
+ define_constants();
30
+
31
+ MinilabHardware = rb_define_class("MinilabHardware", rb_cObject);
32
+ rb_define_method(MinilabHardware, "setup_error_handling", setup_error_handling, 2);
33
+ rb_define_method(MinilabHardware, "declare_revision", declare_revision, 1);
34
+ rb_define_method(MinilabHardware, "get_revision", get_revision, 0);
35
+ rb_define_method(MinilabHardware, "get_error_string", get_error_string, 1);
36
+ rb_define_method(MinilabHardware, "configure_auxport", configure_auxport, 1);
37
+ rb_define_method(MinilabHardware, "configure_port", configure_port, 1);
38
+ rb_define_method(MinilabHardware, "read_analog", read_analog, 1);
39
+ rb_define_method(MinilabHardware, "read_digital_pin", read_digital_pin, 1);
40
+ rb_define_method(MinilabHardware, "read_auxport", read_auxport, 1);
41
+ rb_define_method(MinilabHardware, "read_port", read_port, 1);
42
+ rb_define_method(MinilabHardware, "write_analog", write_analog, 2);
43
+ rb_define_method(MinilabHardware, "write_digital_pin", write_digital_pin, 2);
44
+ rb_define_method(MinilabHardware, "write_auxport", write_auxport, 2);
45
+ }
46
+
47
+ /* :nodoc: */
48
+ static void define_constants()
49
+ {
50
+ VALUE minilab_constants = rb_define_module("MinilabConstants");
51
+ rb_define_const(minilab_constants, "DONTPRINT", INT2NUM(DONTPRINT));
52
+ rb_define_const(minilab_constants, "STOPALL", INT2NUM(STOPALL));
53
+ rb_define_const(minilab_constants, "CURRENTREVNUM", INT2NUM(CURRENTREVNUM));
54
+ rb_define_const(minilab_constants, "DIGITALIN", INT2NUM(DIGITALIN));
55
+ rb_define_const(minilab_constants, "DIGITALOUT", INT2NUM(DIGITALOUT));
56
+ rb_define_const(minilab_constants, "FIRSTPORTA", INT2NUM(FIRSTPORTA));
57
+ rb_define_const(minilab_constants, "FIRSTPORTB", INT2NUM(FIRSTPORTB));
58
+ rb_define_const(minilab_constants, "FIRSTPORTCL", INT2NUM(FIRSTPORTCL));
59
+ rb_define_const(minilab_constants, "FIRSTPORTCH", INT2NUM(FIRSTPORTCH));
60
+ }
61
+
62
+ // Public functions.
63
+ // Setup stuff
64
+ static VALUE setup_error_handling(VALUE self, VALUE error_reporting, VALUE error_handling)
65
+ {
66
+ int error = cbErrHandling(error_reporting, error_handling);
67
+ return create_error_hash(error);
68
+ }
69
+
70
+ static VALUE declare_revision(VALUE self, VALUE revision)
71
+ {
72
+ float the_revision = NUM2DBL(revision);
73
+ int error = cbDeclareRevision(&the_revision);
74
+ return create_error_hash(error);
75
+ }
76
+
77
+ static VALUE get_revision(VALUE self)
78
+ {
79
+ float dll_revision_number;
80
+ float vxd_revision_number;
81
+ int error;
82
+
83
+ error = cbGetRevision(&dll_revision_number, &vxd_revision_number);
84
+
85
+ return create_error_and_value_hash(error, rb_float_new(dll_revision_number));
86
+ }
87
+
88
+ static VALUE get_error_string(VALUE self, VALUE error)
89
+ {
90
+ int new_error;
91
+ char message[ERRSTRLEN];
92
+
93
+ new_error = cbGetErrMsg(error, message);
94
+ if (new_error)
95
+ return create_error_hash(error);
96
+
97
+ return rb_str_new2(message);
98
+ }
99
+
100
+ static VALUE configure_auxport(VALUE self, VALUE optz)
101
+ {
102
+ int error;
103
+ VALUE pin;
104
+ VALUE direction;
105
+
106
+ pin = rb_hash_aref(optz, ID2SYM(rb_intern("pin")));
107
+ if (NIL_P(pin) != 0) {
108
+ rb_raise(rb_eRuntimeError, ":pin is a required parameter");
109
+ }
110
+
111
+ direction = rb_hash_aref(optz, ID2SYM(rb_intern("direction")));
112
+ if (NIL_P(direction) != 0) {
113
+ rb_raise(rb_eRuntimeError, ":direction is a required parameter");
114
+ }
115
+
116
+ error = cbDConfigBit(BOARD_NUM, AUXPORT, NUM2UINT(pin), NUM2UINT(direction));
117
+
118
+ return create_error_hash(error);
119
+ }
120
+
121
+ static VALUE configure_port(VALUE self, VALUE optz)
122
+ {
123
+ int error;
124
+ VALUE port;
125
+ VALUE direction;
126
+
127
+ port = rb_hash_aref(optz, ID2SYM(rb_intern("port")));
128
+ if (NIL_P(port) != 0) {
129
+ rb_raise(rb_eRuntimeError, ":port is a required parameter");
130
+ }
131
+
132
+ direction = rb_hash_aref(optz, ID2SYM(rb_intern("direction")));
133
+ if (NIL_P(direction) != 0) {
134
+ rb_raise(rb_eRuntimeError, ":direction is a required parameter");
135
+ }
136
+
137
+ error = cbDConfigPort(BOARD_NUM, NUM2UINT(port), NUM2UINT(direction));
138
+
139
+ return create_error_hash(error);
140
+ }
141
+
142
+ // IO functions
143
+ static VALUE read_analog(VALUE self, VALUE channel)
144
+ {
145
+ unsigned short raw_data;
146
+ float voltage;
147
+ int error;
148
+
149
+ error = cbAIn(BOARD_NUM, NUM2UINT(channel), BIP10VOLTS, &raw_data);
150
+ if (error)
151
+ return create_error_hash(error);
152
+
153
+ error = cbToEngUnits(BOARD_NUM, BIP10VOLTS, raw_data, &voltage);
154
+
155
+ return create_error_and_value_hash(error, rb_float_new(voltage));
156
+ }
157
+
158
+ static VALUE read_digital_pin(VALUE self, VALUE pin)
159
+ {
160
+ unsigned short data;
161
+ int error;
162
+
163
+ error = cbDBitIn(BOARD_NUM, FIRSTPORTA, NUM2UINT(pin), &data);
164
+
165
+ return create_error_and_value_hash(error, UINT2NUM(data));
166
+ }
167
+
168
+ static VALUE read_auxport(VALUE self, VALUE pin)
169
+ {
170
+ unsigned short data;
171
+ int error;
172
+
173
+ error = cbDBitIn(BOARD_NUM, AUXPORT, NUM2UINT(pin), &data);
174
+
175
+ return create_error_and_value_hash(error, UINT2NUM(data));
176
+ }
177
+
178
+ static VALUE read_port(VALUE self, VALUE port)
179
+ {
180
+ unsigned short data;
181
+ int error;
182
+
183
+ error = cbDIn(BOARD_NUM, NUM2UINT(port), &data);
184
+ return create_error_and_value_hash(error, UINT2NUM(data));
185
+ }
186
+
187
+ static VALUE write_analog(VALUE self, VALUE channel, VALUE volts)
188
+ {
189
+ unsigned short raw_data;
190
+ int error;
191
+
192
+ error = cbFromEngUnits(BOARD_NUM, UNI5VOLTS, NUM2DBL(volts), &raw_data);
193
+ if (error)
194
+ return create_error_hash(error);
195
+
196
+ error = cbAOut(BOARD_NUM, NUM2UINT(channel), UNI5VOLTS, raw_data);
197
+
198
+ return create_error_hash(error);
199
+ }
200
+
201
+ static VALUE write_digital_pin(VALUE self, VALUE pin, VALUE data)
202
+ {
203
+ int error;
204
+
205
+ error = cbDBitOut(BOARD_NUM, FIRSTPORTA, NUM2UINT(pin), NUM2UINT(data));
206
+
207
+ return create_error_hash(error);
208
+ }
209
+
210
+ static VALUE write_auxport(VALUE self, VALUE pin, VALUE data)
211
+ {
212
+ int error;
213
+
214
+ error = cbDBitOut(BOARD_NUM, AUXPORT, NUM2UINT(pin), NUM2UINT(data));
215
+
216
+ return create_error_hash(error);
217
+ }
218
+
219
+ // Helpers
220
+ static VALUE create_error_and_value_hash(int error, VALUE the_value)
221
+ {
222
+ VALUE result = rb_hash_new();
223
+
224
+ if (error)
225
+ rb_hash_aset(result, ID2SYM(rb_intern("error")), INT2NUM(error));
226
+ else
227
+ rb_hash_aset(result, ID2SYM(rb_intern("value")), the_value);
228
+
229
+ return result;
230
+ }
231
+
232
+ static VALUE create_error_hash(int error)
233
+ {
234
+ return create_error_and_value_hash(error, Qtrue);
235
+ }
@@ -0,0 +1,48 @@
1
+ require 'extension/minilab_hardware'
2
+
3
+ class LibraryTranslator #:nodoc:
4
+ include MinilabConstants
5
+
6
+ def get_port_for_pin(pin)
7
+ case pin
8
+ when 30..37
9
+ :porta
10
+ when 3..10
11
+ :portb
12
+ when 26..29
13
+ :portcl
14
+ when 22..25
15
+ :portch
16
+ else
17
+ raise "Pin #{pin} does not map to a known minilab DB37 port."
18
+ end
19
+ end
20
+
21
+ def get_library_pin_number(pin)
22
+ case pin
23
+ when 30..37 # port a pins
24
+ 7 - (pin - 30)
25
+ when 3..10 # port b pins
26
+ 15 - (pin - 3)
27
+ when 26..29 # port cl pins
28
+ 19 - (pin - 26)
29
+ when 22..25 # port ch pins
30
+ 23 - (pin - 22)
31
+ else
32
+ raise "Pin #{pin} does not map to a minilab library pin number."
33
+ end
34
+ end
35
+
36
+ def get_library_port(port)
37
+ port_to_library_port_mapping = {
38
+ :porta => FIRSTPORTA,
39
+ :portb => FIRSTPORTB,
40
+ :portcl => FIRSTPORTCL,
41
+ :portch => FIRSTPORTCH
42
+ }
43
+
44
+ library_port = port_to_library_port_mapping[port]
45
+ return library_port unless library_port.nil?
46
+ raise "Port #{port} is not a valid port."
47
+ end
48
+ end
@@ -0,0 +1,149 @@
1
+ require File.expand_path(File.dirname(__FILE__)) + "/../config/environment.rb"
2
+ require 'extension/minilab_hardware'
3
+ require 'minilab_context'
4
+ require 'analog_io'
5
+ require 'digital_auxport_io'
6
+ require 'digital_port_io'
7
+ require 'result_verifier'
8
+ require 'constructor'
9
+
10
+ # The main interface to the minilab library. Create one of these objects
11
+ # using the +build+ class method. After you've created a minilab object,
12
+ # use the +connect+ method to establish the connection to the device.
13
+ # Minilab objects are not usable until they've been connected.
14
+ class Minilab
15
+ include MinilabConstants
16
+ constructor :minilab_hardware, :result_verifier, :analog_io,
17
+ :digital_auxport_io, :digital_port_io
18
+
19
+ # Use this method to construct Minilab objects. The object will not yet
20
+ # be connected to the device.
21
+ def self.build
22
+ MinilabContext.new.build[:minilab]
23
+ end
24
+
25
+ # Connect to the device. There are two side effects of connecting.
26
+ # * Error reporting from MCC's universal library is set to print
27
+ # errors to standard out instead of popping up a Windows dialog.
28
+ # * Each of the DB37 digital ports is setup for input.
29
+ def connect
30
+ result = @minilab_hardware.setup_error_handling(DONTPRINT, STOPALL)
31
+ @result_verifier.verify(result, "setup_error_handling")
32
+
33
+ result = @minilab_hardware.declare_revision(CURRENTREVNUM)
34
+ @result_verifier.verify(result, "declare_revision")
35
+
36
+ @connected = true
37
+
38
+ @digital_port_io.get_valid_ports.each do |port|
39
+ configure_input_port(port)
40
+ end
41
+ end
42
+
43
+ # Read from one of the eight analog channels (0 - 7) on top of the device.
44
+ #
45
+ # Single-ended mode is the only analog mode supported.
46
+ #
47
+ # An error is raised if an invalid channel number is given.
48
+ def read_analog(channel)
49
+ ensure_connected_to_device
50
+ @analog_io.read_analog(channel)
51
+ end
52
+
53
+ # Output a voltage on one of the eight analog channels. The output voltage
54
+ # must be in the range of 0.0 - 5.0 volts.
55
+ #
56
+ # Single-ended mode is the only analog mode supported.
57
+ #
58
+ # An error is raised if an invalid channel number or an out-of-range
59
+ # voltage is given.
60
+ def write_analog(channel, volts)
61
+ ensure_connected_to_device
62
+ @analog_io.write_analog(channel, volts)
63
+ end
64
+
65
+ # Configure one of the DB37 ports for input.
66
+ #
67
+ # Specify _port_ as a symbol. The available ports are <tt>:porta</tt>,
68
+ # <tt>:portb</tt>, <tt>:portcl</tt>, and <tt>:portch</tt>. An error is
69
+ # raised if an invalid port is given.
70
+ def configure_input_port(port)
71
+ ensure_connected_to_device
72
+ @digital_port_io.configure_input_port(port)
73
+ end
74
+
75
+ # Configure one of the DB37 ports for output.
76
+ #
77
+ # Specify _port_ as a symbol. The available ports are <tt>:porta</tt>,
78
+ # <tt>:portb</tt>, <tt>:portcl</tt>, and <tt>:portch</tt>. An error is
79
+ # raised if an invalid port is given.
80
+ def configure_output_port(port)
81
+ ensure_connected_to_device
82
+ @digital_port_io.configure_output_port(port)
83
+ end
84
+
85
+ # Read a single bit from one of the digital pins.
86
+ #
87
+ # If you'd like to read from one of the pins on the top of the device (the
88
+ # auxport pins), then specify the pin as a string with its label (e.g.
89
+ # read_digital("DIO1")). Alternatively, if you'd like to read from one of
90
+ # the DB37 pins, specify the pin as the number it's labeled with (e.g.
91
+ # read_digital(13)).
92
+ #
93
+ # An error is raised if you specify a pin that doesn't exist or if you
94
+ # try to read from a DB37 pin on a port that is not configured for input.
95
+ # The digital pins on the top of the device do not need to be configured.
96
+ def read_digital(pin)
97
+ ensure_connected_to_device
98
+ perform_digital_op(pin, :read, pin)
99
+ end
100
+
101
+ # Write a single bit to one of the digital pins. _value_ must be an integer
102
+ # 1 or 0.
103
+ #
104
+ # If you'd like to write to one of the pins on the top of the device (the
105
+ # auxport pins), then specify the pin as a string with its label (e.g.
106
+ # write_digital("DIO2", 0)). Alternatively, if you'd like to write to one
107
+ # of the DB37 pins, specify the pin as the number it's labeled with (e.g.
108
+ # write_digital(17, 1)).
109
+ #
110
+ # An error is raised if you specify a pin that doesn't exist or if you
111
+ # try to write to a DB37 pin on a port that is not configured for output.
112
+ # The digital pins on the top of the device do not need to be configured.
113
+ #
114
+ # Values above 1 are interpreted as 1; negative values raise an error.
115
+ def write_digital(pin, value)
116
+ ensure_connected_to_device
117
+ perform_digital_op(pin, :write, pin, value)
118
+ end
119
+
120
+ # Read a byte from one of the DB37 ports.
121
+ #
122
+ # Specify _port_ as a symbol. The available ports are <tt>:porta</tt>,
123
+ # <tt>:portb</tt>, <tt>:portcl</tt>, and <tt>:portch</tt>.
124
+ #
125
+ # An error is raised if an invalid port is given.
126
+ def read_digital_byte(port)
127
+ ensure_connected_to_device
128
+ @digital_port_io.read_port(port)
129
+ end
130
+
131
+ private
132
+ def setup
133
+ @connected = false
134
+ end
135
+
136
+ def perform_digital_op(pin, op, *args)
137
+ method = "#{op.to_s}_digital"
138
+ case pin
139
+ when String
140
+ @digital_auxport_io.send(method,*args)
141
+ when Fixnum
142
+ @digital_port_io.send(method,*args)
143
+ end
144
+ end
145
+
146
+ def ensure_connected_to_device
147
+ raise "Cannot use any minilab methods without calling 'connect' first." unless @connected
148
+ end
149
+ end