i2c-devices 0.0.1

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.
@@ -0,0 +1,87 @@
1
+ #!rspec
2
+
3
+
4
+ $LOAD_PATH.unshift "lib"
5
+
6
+ require "tempfile"
7
+
8
+ require "i2c/device/adt7410"
9
+ require "i2c/driver/i2c-dev"
10
+ require "i2c/mocki2cdevice"
11
+
12
+ describe ADT7410 do
13
+ before do
14
+ @mock = MockI2CDevice.new
15
+ File.stub(:open) do
16
+ @mock.open
17
+ end
18
+ @driver = I2CDevice::Driver::I2CDev.new(@mock.path)
19
+ end
20
+
21
+ describe "#calculate_temperature" do
22
+ context "16bit" do
23
+ it "should treat positive fractial value" do
24
+ # status
25
+ @mock.memory[0x02] = 0b00000000
26
+ # temp
27
+ @mock.memory[0x00] = 0b00000000
28
+ @mock.memory[0x01] = 0b00000001
29
+
30
+ device = ADT7410.new(address: 0x50, driver: @driver)
31
+ expect(device.read_configuration).to eq({
32
+ :fault_queue => 1,
33
+ :ct_pin_polarity => false,
34
+ :int_pin_polarity => false,
35
+ :int_ct_mode => :interrupt_mode,
36
+ :operation_mode => :continuous_conversion,
37
+ :resolution => 16
38
+ })
39
+ expect(device.calculate_temperature).to eq(0.0078125)
40
+ end
41
+
42
+ it "should treat negative value" do
43
+ # status
44
+ @mock.memory[0x02] = 0b00000000
45
+ # temp
46
+ @mock.memory[0x00] = 0b10000000
47
+ @mock.memory[0x01] = 0b00000000
48
+
49
+ device = ADT7410.new(address: 0x50, driver: @driver)
50
+ expect(device.calculate_temperature).to eq(-256)
51
+ end
52
+ end
53
+
54
+ context "13bit" do
55
+ it "should treat positive fractial value" do
56
+ # status
57
+ @mock.memory[0x02] = 0b00000000
58
+ # temp
59
+ @mock.memory[0x00] = 0b00000000
60
+ @mock.memory[0x01] = 0b00001000
61
+
62
+ device = ADT7410.new(address: 0x50, driver: @driver)
63
+ device.configuration({
64
+ resolution: 13,
65
+ })
66
+
67
+ expect(device.calculate_temperature).to eq(0.0625)
68
+ end
69
+
70
+ it "should treat negative value" do
71
+ # status
72
+ @mock.memory[0x02] = 0b00000000
73
+ # temp
74
+ @mock.memory[0x00] = 0b11100100
75
+ @mock.memory[0x01] = 0b10000000
76
+
77
+ device = ADT7410.new(address: 0x50, driver: @driver)
78
+ device.configuration({
79
+ resolution: 13,
80
+ })
81
+
82
+ expect(device.calculate_temperature).to eq(-55)
83
+ end
84
+ end
85
+ end
86
+ end
87
+
@@ -0,0 +1,155 @@
1
+ #!rspec
2
+
3
+
4
+ $LOAD_PATH.unshift "lib"
5
+
6
+ require "tempfile"
7
+
8
+ require "i2c/device/hd44780"
9
+ require "i2c/driver/i2c-dev"
10
+
11
+ describe HD44780 do
12
+ before do
13
+ @i2cout = ""
14
+ @i2cin = ""
15
+ @ioctl = nil
16
+
17
+ ioctl = proc do |cmd, arg|
18
+ @ioctl = [ cmd, arg ]
19
+ end
20
+
21
+ syswrite = proc do |str|
22
+ @i2cout << str
23
+ end
24
+
25
+ sysread = proc do |n|
26
+ @i2cin
27
+ end
28
+
29
+ @temp = Tempfile.new("i2c")
30
+ file = nil
31
+ open = File.method(:open)
32
+ File.stub(:open) do
33
+ file = open.call(@temp.path, "r+")
34
+ file.define_singleton_method(:ioctl) {|cmd,arg| ioctl.call(ioctl) }
35
+ file.define_singleton_method(:syswrite) {|str| syswrite.call(str) }
36
+ file.define_singleton_method(:sysread) {|n| sysread.call(n) }
37
+ file
38
+ end
39
+ @driver = I2CDevice::Driver::I2CDev.new(@temp.path)
40
+ end
41
+
42
+ describe "#initialize_lcd" do
43
+ it "should initialize lcd" do
44
+ lcd = HD44780.new(address: 0x10, driver: @driver)
45
+
46
+ expect(@i2cout.unpack("C*")).to eq([
47
+ 0b00000000,
48
+ 0b00111000,
49
+ 0b00000000,
50
+ 0b00111000,
51
+ 0b00000000,
52
+ 0b00111000,
53
+ 0b00000000,
54
+ 0b00111000,
55
+ 0b00000000,
56
+ 0b00001100,
57
+ 0b00000000,
58
+ 0b00000001,
59
+ ])
60
+ end
61
+ end
62
+
63
+ describe "#put_line" do
64
+ it "should be put_line 1/2" do
65
+ lcd = HD44780.new(address: 0x10, driver: @driver)
66
+
67
+ @i2cout.clear
68
+
69
+ lcd.put_line(0, "0123456789abcdef")
70
+
71
+ expect(@i2cout.unpack("C*")).to eq([
72
+ # set_ddram_address
73
+ 0b00000000, 0b10000000,
74
+
75
+ # write commands
76
+ 0b10000000, "0".ord,
77
+ 0b10000000, "1".ord,
78
+ 0b10000000, "2".ord,
79
+ 0b10000000, "3".ord,
80
+ 0b10000000, "4".ord,
81
+ 0b10000000, "5".ord,
82
+ 0b10000000, "6".ord,
83
+ 0b10000000, "7".ord,
84
+ 0b10000000, "8".ord,
85
+ 0b10000000, "9".ord,
86
+ 0b10000000, "a".ord,
87
+ 0b10000000, "b".ord,
88
+ 0b10000000, "c".ord,
89
+ 0b10000000, "d".ord,
90
+ 0b10000000, "e".ord,
91
+ 0b10000000, "f".ord,
92
+ ])
93
+
94
+ @i2cout.clear
95
+
96
+ lcd.put_line(1, "0123456789abcdef")
97
+
98
+ expect(@i2cout.unpack("C*")).to eq([
99
+ # set_ddram_address
100
+ 0b00000000, 0b11000000,
101
+
102
+ # write commands
103
+ 0b10000000, "0".ord,
104
+ 0b10000000, "1".ord,
105
+ 0b10000000, "2".ord,
106
+ 0b10000000, "3".ord,
107
+ 0b10000000, "4".ord,
108
+ 0b10000000, "5".ord,
109
+ 0b10000000, "6".ord,
110
+ 0b10000000, "7".ord,
111
+ 0b10000000, "8".ord,
112
+ 0b10000000, "9".ord,
113
+ 0b10000000, "a".ord,
114
+ 0b10000000, "b".ord,
115
+ 0b10000000, "c".ord,
116
+ 0b10000000, "d".ord,
117
+ 0b10000000, "e".ord,
118
+ 0b10000000, "f".ord,
119
+ ])
120
+ end
121
+ end
122
+
123
+ describe "#define_character" do
124
+ it "should define character" do
125
+ lcd = HD44780.new(address: 0x10, driver: @driver)
126
+
127
+ @i2cout.clear
128
+
129
+ lcd.define_character(0, [
130
+ 0,1,1,1,0,
131
+ 1,0,0,0,1,
132
+ 1,1,0,1,1,
133
+ 1,0,1,0,1,
134
+ 1,1,0,1,1,
135
+ 1,0,0,0,1,
136
+ 1,0,0,0,1,
137
+ 0,1,1,1,0,
138
+ ])
139
+
140
+ expect(@i2cout.unpack("C*")).to eq([
141
+ # set_cgram_address
142
+ 0b00000000, 0b01000000,
143
+
144
+ 0b10000000, 0b00001110,
145
+ 0b10000000, 0b00010001,
146
+ 0b10000000, 0b00011011,
147
+ 0b10000000, 0b00010101,
148
+ 0b10000000, 0b00011011,
149
+ 0b10000000, 0b00010001,
150
+ 0b10000000, 0b00010001,
151
+ 0b10000000, 0b00001110,
152
+ ])
153
+ end
154
+ end
155
+ end
@@ -0,0 +1,514 @@
1
+ #!rspec
2
+
3
+ $LOAD_PATH.unshift "lib"
4
+
5
+ require "i2c"
6
+ require "i2c/driver/gpio"
7
+ require "tempfile"
8
+
9
+ class GPIOTimeline
10
+ attr_reader :events
11
+
12
+ def initialize
13
+ @timeline = {}
14
+ @pins = []
15
+ @events = []
16
+ @defaults = {}
17
+ @watchers = {}
18
+ end
19
+
20
+ def define(pin)
21
+ unless @timeline.include?(pin)
22
+ default(pin, 0)
23
+ @timeline[pin] = []
24
+ @watchers[pin] = []
25
+ @pins << pin
26
+ end
27
+ end
28
+
29
+ def add(pin, state)
30
+ event = {
31
+ time: Time.now,
32
+ state: state,
33
+ pin: pin,
34
+ }
35
+ @events << event
36
+ @timeline[pin] << event
37
+ @watchers[pin].each do |watcher|
38
+ watcher[:count][:total] += 1
39
+ watcher[:count][state.zero?? :low : :high] += 1
40
+ watcher[:block].call(state, watcher[:count])
41
+ end
42
+ end
43
+
44
+ def mark(label, position=:top)
45
+ event = {
46
+ time: Time.now,
47
+ label: label,
48
+ position: position,
49
+ }
50
+ @events << event
51
+ end
52
+
53
+ def default(pin, state=nil)
54
+ unless state.nil?
55
+ @defaults[pin] = state
56
+ end
57
+ @defaults[pin]
58
+ end
59
+
60
+ def state(pin)
61
+ @timeline[pin].last[:state]
62
+ end
63
+
64
+ def watch(pin, &block)
65
+ watcher= {
66
+ pin: pin,
67
+ block: block,
68
+ count: {
69
+ total: 0,
70
+ low: 0,
71
+ high: 0,
72
+ }
73
+ }
74
+ @watchers[pin] << watcher
75
+ unwatch = lambda {
76
+ @watchers[pin].delete(watcher)
77
+ }
78
+ end
79
+
80
+ def dump
81
+ require "cairo"
82
+
83
+ width = 1240
84
+ height = 300
85
+
86
+ surface = Cairo::ImageSurface.new(Cairo::FORMAT_ARGB32, width, height)
87
+ context = Cairo::Context.new(surface)
88
+
89
+ total = @events.last[:time] - @events.first[:time]
90
+ start = @events.first[:time]
91
+ px_per_sec = (width - 20) / total
92
+
93
+ h = 50
94
+
95
+ context.select_font_face("Lucida Console")
96
+ context.line_width = 3
97
+
98
+ @events.select {|i| i[:label] }.each do |event|
99
+ n = event[:time] - start
100
+ label = event[:label]
101
+ context.set_source_rgb(0.7, 0.7, 0.7)
102
+ context.stroke do
103
+ context.move_to(n * px_per_sec, 0)
104
+ context.line_to(n * px_per_sec, height)
105
+ end
106
+ context.set_source_rgb(0.3, 0.3, 0.3)
107
+ context.move_to(n * px_per_sec + 5, event[:position] == :top ? 20 : height - 20)
108
+ context.set_font_size(10)
109
+ context.show_text(label.to_s)
110
+ end
111
+
112
+ context.set_source_rgb(0.3, 0.3, 0.3)
113
+ context.line_width = 2
114
+
115
+ pin_count = 1
116
+ @pins.each do |pin|
117
+ context.save do
118
+ prev = 0
119
+ context.translate(0, 100 * pin_count)
120
+
121
+ context.move_to(0, prev)
122
+ context.line_to(10, prev)
123
+
124
+ context.translate(10, 0)
125
+
126
+ @timeline[pin].each do |event|
127
+ n = event[:time] - start
128
+
129
+ context.line_to(n * px_per_sec, prev * -h)
130
+ context.line_to(n * px_per_sec, event[:state] * -h)
131
+ prev = event[:state]
132
+ end
133
+
134
+ context.line_to(width, prev * -h)
135
+
136
+ context.stroke
137
+ end
138
+ pin_count += 1
139
+ end
140
+
141
+ surface.write_to_png("/tmp/dump.png")
142
+ end
143
+ end
144
+
145
+ describe I2CDevice::Driver::GPIO do
146
+ before do
147
+ @timeline = timeline = GPIOTimeline.new
148
+
149
+ I2CDevice::Driver::GPIO.define_singleton_method(:export) do |pin|
150
+ timeline.define(pin)
151
+ end
152
+
153
+ I2CDevice::Driver::GPIO.define_singleton_method(:unexport) do |pin|
154
+ end
155
+
156
+ I2CDevice::Driver::GPIO.define_singleton_method(:direction) do |pin, direction|
157
+ # p [:direction, pin]
158
+ state = 1
159
+ case direction
160
+ when :in
161
+ state = timeline.default(pin) # pulled-up
162
+ when :out
163
+ state = 0
164
+ when :high
165
+ state = 1
166
+ when :low
167
+ state = 0
168
+ end
169
+ timeline.add(pin, state)
170
+ end
171
+
172
+ I2CDevice::Driver::GPIO.define_singleton_method(:read) do |pin|
173
+ timeline.state(pin)
174
+ end
175
+
176
+ I2CDevice::Driver::GPIO.define_singleton_method(:write) do |pin, val|
177
+ timeline.add(pin, val ? 1 : 0)
178
+ end
179
+
180
+ @driver = I2CDevice::Driver::GPIO.new(
181
+ sda: 23,
182
+ scl: 24,
183
+ speed: 1,
184
+ )
185
+ @timeline.events.clear
186
+ @timeline.default(@driver.scl, 1)
187
+ @timeline.default(@driver.sda, 1)
188
+ end
189
+
190
+ describe "i2c protocol" do
191
+ it "should set start condition correctly" do
192
+ @driver.send(:start_condition)
193
+ expect(@timeline.state(@driver.scl)).to be(1)
194
+ expect(@timeline.state(@driver.sda)).to be(0)
195
+ expect(@timeline.events.map {|i| [i[:pin], i[:state]] }).to eq([[@driver.sda, 1], [@driver.scl, 1], [@driver.scl, 1], [@driver.sda, 0]])
196
+ end
197
+
198
+ it "should throw exception when bus is busy" do
199
+ @timeline.default(@driver.scl, 0)
200
+ expect { @driver.send(:start_condition) }.to raise_error(I2CDevice::I2CBUSBusy)
201
+ end
202
+
203
+ it "should set stop condition correctly" do
204
+ @driver.send(:start_condition)
205
+
206
+ @timeline.events.clear
207
+ @driver.send(:stop_condition)
208
+ expect(@timeline.events.map {|i| [i[:pin], i[:state]] }).to eq([ [@driver.scl, 0], [@driver.sda, 0], [@driver.scl, 1], [@driver.sda, 1] ])
209
+ expect(@timeline.state(@driver.scl)).to be(1)
210
+ expect(@timeline.state(@driver.sda)).to be(1)
211
+ end
212
+
213
+ it "should write 1 byte correctly and receive nack" do
214
+ @timeline.mark(:start)
215
+ @driver.send(:start_condition)
216
+
217
+ @timeline.mark(:write)
218
+ ret = @driver.send(:write, 0b01010011)
219
+ expect(@timeline.events.drop_while {|i| i[:label] != :write }.select {|i| i[:pin] == @driver.scl }.map {|i| i[:state] }).to eq([0, 1] * 9 + [0])
220
+ expect(ret).to be(false)
221
+ expect(@timeline.state(@driver.scl)).to be(0)
222
+
223
+ @timeline.mark(:stop)
224
+ @driver.send(:stop_condition)
225
+ end
226
+
227
+ it "should write 1 byte correctly and receive ack" do
228
+ @timeline.mark(:start)
229
+ @driver.send(:start_condition)
230
+
231
+ unwatch = @timeline.watch(@driver.scl) do |state, count|
232
+ case
233
+ when count[:high] == 8 && state == 0
234
+ # return ack
235
+ @timeline.default(@driver.sda, 0)
236
+ when count[:high] == 9 && state == 1
237
+ @timeline.mark("ack")
238
+ when count[:high] == 9 && state == 0
239
+ @timeline.default(@driver.sda, 1)
240
+ unwatch.call
241
+ end
242
+ end
243
+
244
+ @timeline.mark(:write)
245
+ ret = @driver.send(:write, 0b11111111)
246
+ expect(@timeline.events.drop_while {|i| i[:label] != :write}.select {|i| i[:pin] == @driver.scl }.map {|i| i[:state] }).to eq([0, 1] * 9 + [0])
247
+ expect(ret).to be(true)
248
+ expect(@timeline.state(@driver.scl)).to be(0)
249
+
250
+ @timeline.mark(:stop)
251
+ @driver.send(:stop_condition)
252
+ end
253
+
254
+ it "should read 1 byte correctly and return ack" do
255
+ @timeline.mark(:start)
256
+ @driver.send(:start_condition)
257
+
258
+ send = 0b00000000
259
+ unwatch = @timeline.watch(@driver.scl) do |state, count|
260
+ case
261
+ when count[:high] < 8 && state == 0
262
+ # send bit
263
+ bit = send[ 7 - count[:high] ]
264
+ @timeline.default(@driver.sda, bit)
265
+ @timeline.add(@driver.sda, bit)
266
+ when count[:high] == 9 && state == 1
267
+ # read ack
268
+ @timeline.mark(:ack)
269
+ expect(@timeline.state(@driver.sda)).to be(0)
270
+ unwatch.call
271
+ @timeline.default(@driver.sda, 1)
272
+ end
273
+ end
274
+ @timeline.mark(:read)
275
+ ret = @driver.send(:read, true)
276
+ expect(ret).to be(send)
277
+
278
+ send = 0b01010101
279
+ unwatch = @timeline.watch(@driver.scl) do |state, count|
280
+ case
281
+ when count[:high] < 8 && state == 0
282
+ # send bit
283
+ bit = send[ 7 - count[:high] ]
284
+ @timeline.default(@driver.sda, bit)
285
+ @timeline.add(@driver.sda, bit)
286
+ when count[:high] <= 8 && state == 1
287
+ @timeline.mark("#{8 - count[:high]}", :bottom)
288
+ when count[:high] == 9 && state == 1
289
+ # read ack
290
+ @timeline.mark(:ack)
291
+ expect(@timeline.state(@driver.sda)).to be(0)
292
+ unwatch.call
293
+ @timeline.default(@driver.sda, 1)
294
+ end
295
+ end
296
+ ret = @driver.send(:read, true)
297
+ expect(ret).to be(send)
298
+
299
+ @timeline.mark(:stop)
300
+ @driver.send(:stop_condition)
301
+ end
302
+
303
+ it "should read 1 byte correctly and return nack" do
304
+ @timeline.mark(:start)
305
+ @driver.send(:start_condition)
306
+
307
+ send = 0b01010101
308
+ unwatch = @timeline.watch(@driver.scl) do |state, count|
309
+ case
310
+ when count[:high] < 8 && state == 0
311
+ # send bit
312
+ bit = send[ 7 - count[:high] ]
313
+ @timeline.default(@driver.sda, bit)
314
+ @timeline.add(@driver.sda, bit)
315
+ when count[:high] == 9 && state == 1
316
+ # read ack
317
+ @timeline.mark(:nack)
318
+ expect(@timeline.state(@driver.sda)).to be(1)
319
+ unwatch.call
320
+ @timeline.default(@driver.sda, 1)
321
+ end
322
+ end
323
+ ret = @driver.send(:read, false)
324
+ expect(ret).to be(send)
325
+
326
+ @timeline.mark(:stop)
327
+ @driver.send(:stop_condition)
328
+ end
329
+ end
330
+
331
+ describe "i2c abstract interface:" do
332
+ it "should initialize with sda, scl properties" do
333
+ expect { I2CDevice::Driver::GPIO.new() }.to raise_error(/required/)
334
+ expect { I2CDevice::Driver::GPIO.new(sda: 1) }.to raise_error
335
+ expect { I2CDevice::Driver::GPIO.new(sda: 1, scl: 2) }.not_to raise_error
336
+ end
337
+
338
+ context "unknown slave address:" do
339
+ describe "i2cset" do
340
+ it "should throw exception on unknown slave address" do
341
+ expect { @driver.i2cset(0x20, 0x00) }.to raise_error(I2CDevice::I2CIOError)
342
+
343
+ expect(@timeline.state(@driver.scl)).to be(1)
344
+ expect(@timeline.state(@driver.sda)).to be(1)
345
+ end
346
+ end
347
+
348
+ describe "i2cget" do
349
+ it "should throw exception on unknown slave address" do
350
+ expect { @driver.i2cget(0x20, 0x00) }.to raise_error(I2CDevice::I2CIOError)
351
+
352
+ expect(@timeline.state(@driver.scl)).to be(1)
353
+ expect(@timeline.state(@driver.sda)).to be(1)
354
+ end
355
+ end
356
+ end
357
+
358
+ context "valid slave address:" do
359
+ before do
360
+ @status = :stop
361
+ @received = []
362
+ @memory = [0x00] * 5
363
+ @max_receive = 3
364
+
365
+ unwatch_scl = nil
366
+ @timeline.watch(@driver.sda) do |state, count|
367
+ case
368
+ when @timeline.state(@driver.scl) == 1 && state == 0
369
+ @status = :start
370
+ @timeline.mark(@status)
371
+ address = 0
372
+ data = 0
373
+ rw = nil
374
+ read_address = 0
375
+ ack = 1
376
+ unwatch_scl.call if unwatch_scl
377
+ unwatch_scl = @timeline.watch(@driver.scl) do |state, count|
378
+ # p [@status, state, count]
379
+ case @status
380
+ when :start
381
+ case
382
+ when state == 1 && count[:high] < 8
383
+ @timeline.mark(8 - count[:high], :bottom)
384
+ address = (address << 1) | @timeline.state(@driver.sda)
385
+ when state == 1 && count[:high] == 8
386
+ @timeline.mark('rw', :bottom)
387
+ rw = @timeline.state(@driver.sda)
388
+ # p " 0b%08b == 0b%08b %02x" % [0x20, address, address]
389
+ when state == 0 && count[:high] == 8
390
+ if address == 0x20
391
+ # ack
392
+ @timeline.default(@driver.sda, 0)
393
+ else
394
+ @status = :unkown
395
+ @timeline.mark(@status)
396
+ end
397
+ when state == 1 && count[:high] == 9
398
+ @timeline.mark('ack')
399
+ when state == 0 && count[:high] == 9
400
+ # reset
401
+ count[:high] = 0
402
+ count[:low] = 0
403
+ @timeline.default(@driver.sda, 1)
404
+ if rw.zero?
405
+ @status = :write
406
+ else
407
+ @status = :read
408
+ read_address = @received[0]
409
+ end
410
+ end
411
+ when :write
412
+ case
413
+ when state == 1 && count[:high] <= 8
414
+ @timeline.mark(8 - count[:high], :bottom)
415
+ data = (data << 1) | @timeline.state(@driver.sda)
416
+ when state == 0 && count[:high] == 8
417
+ if @received.size < @max_receive
418
+ @received << data
419
+ # ack
420
+ @timeline.default(@driver.sda, 0)
421
+ end
422
+ when state == 1 && count[:high] == 9
423
+ @timeline.mark(@received.size <= @max_receive ? 'ack' : 'nack')
424
+ when state == 0 && count[:high] == 9
425
+ # reset
426
+ data = 0
427
+ count[:high] = 0
428
+ count[:low] = 0
429
+ @timeline.default(@driver.sda, 1)
430
+ unless @received.size <= @max_receive
431
+ @status = :stop
432
+ end
433
+ end
434
+ when :read
435
+ case
436
+ when state == 0 && count[:high] < 8
437
+ # send bit
438
+ bit = @memory[read_address][ 7 - count[:high] ]
439
+ @timeline.default(@driver.sda, bit)
440
+ @timeline.add(@driver.sda, bit)
441
+ when state == 1 && count[:high] <= 8
442
+ @timeline.mark(8 - count[:high], :bottom)
443
+ when state == 0 && count[:high] == 8
444
+ @timeline.default(@driver.sda, 1)
445
+ when state == 1 && count[:high] == 9
446
+ ack = @timeline.state(@driver.sda)
447
+ if ack == 0
448
+ @timeline.mark("ack")
449
+ else
450
+ @timeline.mark("nack")
451
+ @status = :stop
452
+ end
453
+ when state == 0 && count[:high] == 9
454
+ read_address += 1
455
+ count[:high] = 0
456
+ count[:low] = 0
457
+ end
458
+ end
459
+ end
460
+ when @timeline.state(@driver.scl) == 1 && state == 1
461
+ @status = :stop
462
+ @timeline.mark(@status)
463
+ unwatch_scl.call
464
+ end
465
+ end
466
+ end
467
+
468
+ describe "i2cset" do
469
+ it "should works successfully" do
470
+ wrote = @driver.i2cset(0x20, 0x0f)
471
+ expect(wrote).to be(1)
472
+ expect(@received).to eq([0x0f])
473
+
474
+ expect(@timeline.state(@driver.scl)).to be(1)
475
+ expect(@timeline.state(@driver.sda)).to be(1)
476
+ end
477
+
478
+ it "should write until nack" do
479
+ @max_receive = 3
480
+ wrote = @driver.i2cset(0x20, 0x01, 0x02, 0x03, 0x04, 0x05)
481
+ expect(wrote).to be(3)
482
+ expect(@received).to eq([0x01, 0x02, 0x03])
483
+
484
+ expect(@timeline.state(@driver.scl)).to be(1)
485
+ expect(@timeline.state(@driver.sda)).to be(1)
486
+ end
487
+ end
488
+
489
+ describe "i2cget" do
490
+ it "should works successfully" do
491
+ @max_receive = 1
492
+ @memory = (0..4).to_a
493
+ got = @driver.i2cget(0x20, 0x01)
494
+ expect(got).to eq("\x01")
495
+
496
+ expect(@timeline.state(@driver.scl)).to be(1)
497
+ expect(@timeline.state(@driver.sda)).to be(1)
498
+ end
499
+
500
+ it "should works with length argument" do
501
+ @max_receive = 1
502
+ @memory = (0..4).to_a
503
+ got = @driver.i2cget(0x20, 0x01, 3)
504
+ expect(got).to eq("\x01\x02\x03")
505
+
506
+ expect(@timeline.state(@driver.scl)).to be(1)
507
+ expect(@timeline.state(@driver.sda)).to be(1)
508
+
509
+ @timeline.dump
510
+ end
511
+ end
512
+ end
513
+ end
514
+ end