lignite 0.2.0 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (44) hide show
  1. checksums.yaml +4 -4
  2. data/.rspec +1 -0
  3. data/.rubocop.yml +12 -0
  4. data/NEWS.md +5 -1
  5. data/README.md +2 -2
  6. data/Rakefile +1 -1
  7. data/VERSION +1 -1
  8. data/bin/ev3tool +111 -104
  9. data/examples/bobbee.rb +7 -7
  10. data/examples/hello.rb +2 -0
  11. data/examples/hello.yml +4 -0
  12. data/examples/light-sensor.rb +2 -0
  13. data/examples/light-sensor.yml +3 -0
  14. data/examples/lights.rb +7 -7
  15. data/examples/lights.yml +4 -0
  16. data/examples/sys_list_files.rb +4 -2
  17. data/examples/sys_list_files.yml +9 -0
  18. data/lib/lignite.rb +5 -1
  19. data/lib/lignite/assembler.rb +6 -6
  20. data/lib/lignite/body_compiler.rb +4 -0
  21. data/lib/lignite/connection.rb +59 -1
  22. data/lib/lignite/connection/bluetooth.rb +7 -1
  23. data/lib/lignite/connection/replay.rb +57 -0
  24. data/lib/lignite/connection/tap.rb +45 -0
  25. data/lib/lignite/connection/usb.rb +10 -7
  26. data/lib/lignite/direct_commands.rb +56 -5
  27. data/lib/lignite/message.rb +8 -5
  28. data/lib/lignite/motors.rb +5 -5
  29. data/lib/lignite/op_compiler.rb +19 -18
  30. data/lib/lignite/rbf_object.rb +1 -1
  31. data/lib/lignite/system_commands.rb +30 -2
  32. data/lib/lignite/variables.rb +2 -2
  33. data/lignite.gemspec +14 -4
  34. data/rubocop-suse.yml +74 -0
  35. data/spec/connection_usb_spec.rb +42 -0
  36. data/spec/data/ColorReadout.rb +11 -12
  37. data/spec/data/HelloWorld-subop.rb +1 -1
  38. data/spec/data/HelloWorld.rb +1 -1
  39. data/spec/data/NoDebug.rb +1 -1
  40. data/spec/data/VernierReadout.rb +4 -4
  41. data/spec/direct_commands_spec.rb +25 -0
  42. data/spec/system_commands_spec.rb +22 -0
  43. metadata +28 -3
  44. data/lib/lignite/message_sender.rb +0 -94
@@ -6,10 +6,10 @@ module Lignite
6
6
  # do the DCs spawn independent threads??
7
7
  # must run ready in the same block?
8
8
 
9
- attr :layer
10
- attr :nos
9
+ attr_reader :layer
10
+ attr_reader :nos
11
11
  # @return [Lignite::DirectCommands]
12
- attr :dc
12
+ attr_reader :dc
13
13
 
14
14
  # 0x02 | 0x04 | 0x08 -> [1, 2, 3]
15
15
  def nos_as_indices
@@ -24,7 +24,7 @@ module Lignite
24
24
  @dc = dc
25
25
  end
26
26
 
27
- # TODO filter out support: official: no
27
+ # TODO: filter out support: official: no
28
28
 
29
29
  # the type is an OUT param so the VM SETs and we GET to learn the type?
30
30
  def set_type
@@ -62,7 +62,7 @@ module Lignite
62
62
  end
63
63
 
64
64
  def start
65
- dc.output_start(layer, nos) # apparently not
65
+ dc.output_start(layer, nos) # apparently not
66
66
  end
67
67
 
68
68
  # ATTR ~polarity
@@ -119,7 +119,7 @@ module Lignite
119
119
  end
120
120
 
121
121
  enums = yml["enums"]
122
- enums.each do |ename, edata|
122
+ enums.each_value do |edata|
123
123
  edata["members"].each do |mname, mdata|
124
124
  load_const(mname, mdata["value"])
125
125
  end
@@ -177,29 +177,30 @@ module Lignite
177
177
  end
178
178
 
179
179
  def make_lc(n, bytes = nil)
180
- bytes ||= if (-31 .. 31).include? n
181
- 0
182
- elsif (-127 .. 127).include? n
183
- 1
184
- elsif (-32767 .. 32767).include? n
185
- 2
186
- else
187
- 4
188
- end
180
+ bytes ||= if (-31..31).cover? n
181
+ 0
182
+ elsif (-127..127).cover? n
183
+ 1
184
+ elsif (-32767..32767).cover? n
185
+ 2
186
+ else
187
+ 4
188
+ end
189
189
  make_lcn(n, bytes)
190
190
  end
191
191
 
192
192
  def make_v(n, local_or_global)
193
193
  vartag = PRIMPAR_VARIABEL | local_or_global
194
- if (0 .. 31).include? n
195
- return [vartag | (n & PRIMPAR_VALUE)]
196
- elsif (0 .. 255).include? n
197
- return [vartag | PRIMPAR_LONG | PRIMPAR_1_BYTE, n & 0xff]
198
- elsif (0 .. 65535).include? n
199
- return [vartag | PRIMPAR_LONG | PRIMPAR_2_BYTES, n & 0xff, (n >> 8) & 0xff]
194
+ if (0..31).cover? n
195
+ [vartag | (n & PRIMPAR_VALUE)]
196
+ elsif (0..255).cover? n
197
+ [vartag | PRIMPAR_LONG | PRIMPAR_1_BYTE, n & 0xff]
198
+ elsif (0..65535).cover? n
199
+ [vartag | PRIMPAR_LONG | PRIMPAR_2_BYTES, n & 0xff, (n >> 8) & 0xff]
200
+ else
201
+ [vartag | PRIMPAR_LONG | PRIMPAR_4_BYTES,
202
+ n & 0xff, (n >> 8) & 0xff, (n >> 16) & 0xff, (n >> 24) & 0xff]
200
203
  end
201
- [vartag | PRIMPAR_LONG | PRIMPAR_4_BYTES,
202
- n & 0xff, (n >> 8) & 0xff, (n >> 16) & 0xff, (n >> 24) & 0xff]
203
204
  end
204
205
 
205
206
  # Reference a variable.
@@ -18,7 +18,7 @@ module Lignite
18
18
  end
19
19
 
20
20
  # @return [ByteString] an already assembled body of the object
21
- attr :body
21
+ attr_reader :body
22
22
 
23
23
  def initialize(owner:, triggers:, local_bytes:, body:)
24
24
  @owner = owner
@@ -4,12 +4,24 @@ module Lignite
4
4
  include Logger
5
5
  extend Logger
6
6
 
7
+ def self.run(conn = Connection.create, &block)
8
+ sc = new(conn)
9
+ sc.instance_exec(&block)
10
+ sc.close
11
+ end
12
+
7
13
  # @param conn [Connection]
8
14
  def initialize(conn = Connection.create)
9
- @message_sender = MessageSender.new(conn)
15
+ @conn = conn
10
16
  load_yml
11
17
  end
12
18
 
19
+ def close
20
+ @conn.close
21
+ end
22
+
23
+ private
24
+
13
25
  def load_yml
14
26
  fname = File.expand_path("../../../data/sysops.yml", __FILE__)
15
27
  op_hash = YAML.load_file(fname)["sysops"]
@@ -38,7 +50,7 @@ module Lignite
38
50
  end.join("")
39
51
  logger.debug "sysop to execute: #{bytes.inspect}"
40
52
 
41
- reply = @message_sender.system_command_with_reply(bytes)
53
+ reply = system_command_with_reply(bytes)
42
54
 
43
55
  # TODO: parse it with return_handlers
44
56
  replies = return_handlers.map do |h|
@@ -99,5 +111,21 @@ module Lignite
99
111
  end
100
112
  end
101
113
 
114
+ def system_command_with_reply(instr_bytes)
115
+ cmd = Message.system_command_with_reply(instr_bytes)
116
+ @conn.send(cmd.bytes)
117
+
118
+ reply = Message.reply_from_bytes(@conn.receive)
119
+ assert_match(reply.msgid, cmd.msgid, "Reply id")
120
+ assert_match(reply.command, unpack_u8(instr_bytes[0]), "Command num")
121
+ raise VMError, format("Error: %u", reply.status) if reply.error?
122
+
123
+ reply.data
124
+ end
125
+
126
+ def assert_match(actual, expected, description)
127
+ return if actual == expected
128
+ raise "#{description} does not match, expected #{expected}, actual #{actual}"
129
+ end
102
130
  end
103
131
  end
@@ -14,7 +14,7 @@ module Lignite
14
14
  # declare
15
15
  def add(id, size, unpacker)
16
16
  raise "Duplicate variable #{id}" if @vars.key?(id)
17
- @vars[id] = {offset: @offset, size: size}
17
+ @vars[id] = { offset: @offset, size: size }
18
18
  @offset += size
19
19
  @unpacker += unpacker
20
20
  end
@@ -41,7 +41,7 @@ module Lignite
41
41
  end
42
42
  end
43
43
 
44
- # {#variables} are {Variables}
44
+ # `variables` are {Variables}
45
45
  module VariableDeclarer
46
46
  def data8(id)
47
47
  variables.add(id, 1, "C")
data/lignite.gemspec CHANGED
@@ -1,5 +1,3 @@
1
- # -*- encoding: utf-8 -*-
2
-
3
1
  require File.expand_path(File.dirname(__FILE__) + "/lib/lignite/version")
4
2
 
5
3
  Gem::Specification.new do |s|
@@ -20,6 +18,8 @@ TXT
20
18
  s.files = [
21
19
  ".coveralls.yml",
22
20
  ".gitignore",
21
+ ".rspec",
22
+ ".rubocop.yml",
23
23
  ".travis.yml",
24
24
  ".yardopts",
25
25
  "COPYING",
@@ -34,22 +34,27 @@ TXT
34
34
  "data/sysops.yml",
35
35
  "examples/bobbee.rb",
36
36
  "examples/hello.rb",
37
+ "examples/hello.yml",
37
38
  "examples/light-sensor.rb",
39
+ "examples/light-sensor.yml",
38
40
  "examples/lights.rb",
41
+ "examples/lights.yml",
39
42
  "examples/motors.rb",
40
43
  "examples/sound.rb",
41
44
  "examples/sys_list_files.rb",
45
+ "examples/sys_list_files.yml",
42
46
  "lib/lignite.rb",
43
47
  "lib/lignite/assembler.rb",
44
48
  "lib/lignite/body_compiler.rb",
45
49
  "lib/lignite/bytes.rb",
46
50
  "lib/lignite/connection.rb",
47
51
  "lib/lignite/connection/bluetooth.rb",
52
+ "lib/lignite/connection/replay.rb",
53
+ "lib/lignite/connection/tap.rb",
48
54
  "lib/lignite/connection/usb.rb",
49
55
  "lib/lignite/direct_commands.rb",
50
56
  "lib/lignite/logger.rb",
51
57
  "lib/lignite/message.rb",
52
- "lib/lignite/message_sender.rb",
53
58
  "lib/lignite/motors.rb",
54
59
  "lib/lignite/op_compiler.rb",
55
60
  "lib/lignite/rbf_object.rb",
@@ -57,7 +62,9 @@ TXT
57
62
  "lib/lignite/variables.rb",
58
63
  "lib/lignite/version.rb",
59
64
  "lignite.gemspec",
65
+ "rubocop-suse.yml",
60
66
  "spec/assembler_spec.rb",
67
+ "spec/connection_usb_spec.rb",
61
68
  "spec/data/ColorReadout.lms",
62
69
  "spec/data/ColorReadout.rb",
63
70
  "spec/data/ColorReadout.rbf",
@@ -72,13 +79,16 @@ TXT
72
79
  "spec/data/VernierReadout.lms",
73
80
  "spec/data/VernierReadout.rb",
74
81
  "spec/data/VernierReadout.rbf",
75
- "spec/spec_helper.rb"
82
+ "spec/direct_commands_spec.rb",
83
+ "spec/spec_helper.rb",
84
+ "spec/system_commands_spec.rb"
76
85
  ]
77
86
 
78
87
  s.executables = s.files.grep(/^bin\//) { |f| File.basename(f) }
79
88
 
80
89
  s.required_ruby_version = ">= 2.1" # mandatory keyword arguments
81
90
  s.add_dependency "libusb", "~> 0.6"
91
+ s.add_dependency "thor", "~> 0.19"
82
92
 
83
93
  s.add_development_dependency "coveralls", "~> 0"
84
94
  s.add_development_dependency "simplecov", "~> 0"
data/rubocop-suse.yml ADDED
@@ -0,0 +1,74 @@
1
+ # This is the shared Rubocop configuration for SUSE projects. It is maintained
2
+ # at https://github.com/SUSE/style-guides/blob/master/rubocop-suse.yml
3
+ #
4
+ # The configuration is tested and used with the Rubocop version used by Hound
5
+ # (https://houndci.com).
6
+ #
7
+ # We use the default Hound config as a baseline:
8
+ #
9
+ # https://raw.githubusercontent.com/thoughtbot/hound/master/config/style_guides/ruby.yml
10
+ #
11
+ # This file contains the rules with derive from this.
12
+
13
+ Lint/EndAlignment:
14
+ StyleGuide: https://github.com/SUSE/style-guides/blob/master/Ruby.md#lintendalignment
15
+ EnforcedStyleAlignWith: variable
16
+
17
+ Metrics/AbcSize:
18
+ StyleGuide: https://github.com/SUSE/style-guides/blob/master/Ruby.md#metricsabcsize
19
+ Max: 30
20
+
21
+ Metrics/LineLength:
22
+ StyleGuide: https://github.com/SUSE/style-guides/blob/master/Ruby.md#metricslinelength
23
+ Max: 100
24
+ # To make it possible to copy or click on URIs in the code, we allow lines
25
+ # contaning a URI to be longer than Max.
26
+ AllowURI: true
27
+ URISchemes:
28
+ - http
29
+ - https
30
+
31
+ Style/AlignHash:
32
+ StyleGuide: https://github.com/SUSE/style-guides/blob/master/Ruby.md#stylealignhash
33
+ EnforcedHashRocketStyle: table
34
+ EnforcedColonStyle: table
35
+
36
+ Style/AlignParameters:
37
+ StyleGuide: https://github.com/SUSE/style-guides/blob/master/Ruby.md#stylealignparameters
38
+ Enabled: false
39
+
40
+ Style/CollectionMethods:
41
+ StyleGuide: https://github.com/SUSE/style-guides/blob/master/Ruby.md#stylecollectionmethods
42
+ Enabled: false
43
+
44
+ Style/EmptyLinesAroundBlockBody:
45
+ StyleGuide: https://github.com/SUSE/style-guides/blob/master/Ruby.md#styleemptylinesaroundblockbody
46
+ Enabled: false
47
+
48
+ Style/MultilineOperationIndentation:
49
+ StyleGuide: https://github.com/SUSE/style-guides/blob/master/Ruby.md#stylemultilineoperationindentation
50
+ EnforcedStyle: indented
51
+
52
+ Style/StringLiterals:
53
+ StyleGuide: https://github.com/SUSE/style-guides/blob/master/Ruby.md#stylestringliterals
54
+ EnforcedStyle: double_quotes
55
+
56
+ Style/StringLiteralsInInterpolation:
57
+ StyleGuide: https://github.com/SUSE/style-guides/blob/master/Ruby.md#stylestringliteralsininterpolation
58
+ EnforcedStyle: double_quotes
59
+
60
+ Style/WordArray:
61
+ StyleGuide: https://github.com/SUSE/style-guides/blob/master/Ruby.md#deviations-from-the-upstream-style-guide
62
+ Enabled: false
63
+
64
+ Style/RegexpLiteral:
65
+ StyleGuide: https://github.com/SUSE/style-guides/blob/master/Ruby.md#deviations-from-the-upstream-style-guide
66
+ Enabled: false
67
+
68
+ Style/SignalException:
69
+ StyleGuide: https://github.com/bbatsov/ruby-style-guide#fail-method
70
+ EnforcedStyle: only_raise
71
+
72
+ Style/NumericLiterals:
73
+ StyleGuide: https://github.com/SUSE/style-guides/blob/master/Ruby.md#stylenumericliterals
74
+ Enabled: false
@@ -0,0 +1,42 @@
1
+ require_relative "spec_helper"
2
+ require "lignite"
3
+
4
+ describe Lignite::Connection::Usb do
5
+ let(:device) do
6
+ instance_double("FakeDevice", interfaces: [interface])
7
+ end
8
+ let(:interface) { double("FakeInterface", endpoints: [in_ep, out_ep]) }
9
+ let(:in_ep) { double("InEndpoint", direction: :in) }
10
+ let(:out_ep) { double("OutEndpoint", direction: :out) }
11
+ let(:dev_handle) { double("FakeDevHandle") }
12
+
13
+ before(:each) do
14
+ usb = instance_double("FakeContext", devices: [device])
15
+ allow(LIBUSB::Context).to receive(:new).and_return(usb)
16
+ allow(dev_handle).to receive(:"auto_detach_kernel_driver=")
17
+ allow(dev_handle).to receive(:claim_interface).and_yield
18
+ end
19
+
20
+ describe "#write" do
21
+ it "does not crash" do
22
+ data = "hello"
23
+ allow(device).to receive(:open).and_yield(dev_handle)
24
+ allow(dev_handle).to receive(:interrupt_transfer).and_return(data.bytesize)
25
+ expect { subject.write(data) }.to_not raise_error
26
+ end
27
+ end
28
+
29
+ describe "#read" do
30
+ it "does not crash" do
31
+ allow(device).to receive(:open).and_yield(dev_handle)
32
+ allow(dev_handle).to receive(:interrupt_transfer).and_return("hello")
33
+ expect(subject.read(1000)).to eq("hello")
34
+ end
35
+ end
36
+
37
+ describe "#write" do
38
+ it "does not crash" do
39
+ expect { subject.close }.to_not raise_error
40
+ end
41
+ end
42
+ end
@@ -15,38 +15,37 @@ vmthread :MAIN do
15
15
  data8 :Mode
16
16
  data8 :State
17
17
 
18
-
19
18
  move8_8(3, :Mode)
20
19
 
21
- self.loop do
20
+ loop do
22
21
  ui_draw(FILLWINDOW, 0x00, 0, 0)
23
22
  ui_draw(SELECT_FONT, SMALL_FONT)
24
- ui_draw(TEXT, FG_COLOR, 0, 10, ' Color Readout V0.00 ')
25
- ui_draw(TEXT, FG_COLOR, 0, 30, 'Mode ')
23
+ ui_draw(TEXT, FG_COLOR, 0, 10, " Color Readout V0.00 ")
24
+ ui_draw(TEXT, FG_COLOR, 0, 30, "Mode ")
26
25
 
27
- ui_draw(TEXT, FG_COLOR, 0, 50, 'Raw 1')
28
- ui_draw(TEXT, FG_COLOR, 0, 65, 'Raw 2')
29
- ui_draw(TEXT, FG_COLOR, 0, 80, 'Raw 3')
30
- ui_draw(TEXT, FG_COLOR, 0, 118, 'Left = 3 Right = 4')
26
+ ui_draw(TEXT, FG_COLOR, 0, 50, "Raw 1")
27
+ ui_draw(TEXT, FG_COLOR, 0, 65, "Raw 2")
28
+ ui_draw(TEXT, FG_COLOR, 0, 80, "Raw 3")
29
+ ui_draw(TEXT, FG_COLOR, 0, 118, "Left = 3 Right = 4")
31
30
  ui_draw(SELECT_FONT, NORMAL_FONT)
32
31
 
33
32
  move8_32(:Mode, :Data1)
34
33
  and32(:Data1, 0xFF, :Data1)
35
- strings(NUMBER_FORMATTED, :Data1, '%1d', 8, :String)
34
+ strings(NUMBER_FORMATTED, :Data1, "%1d", 8, :String)
36
35
  ui_draw(TEXT, FG_COLOR, 64, 30, :String)
37
36
 
38
37
  input_device(READY_RAW, 0, PORT, 0, :Mode, 3, :Data1, :Data2, :Data3)
39
38
 
40
39
  and32(:Data1, 0xFFFF, :Data1)
41
- strings(NUMBER_FORMATTED, :Data1, '%-5d', 8, :String)
40
+ strings(NUMBER_FORMATTED, :Data1, "%-5d", 8, :String)
42
41
  ui_draw(TEXT, FG_COLOR, 64, 50, :String)
43
42
 
44
43
  and32(:Data2, 0xFFFF, :Data2)
45
- strings(NUMBER_FORMATTED, :Data2, '%-5d', 8, :String)
44
+ strings(NUMBER_FORMATTED, :Data2, "%-5d", 8, :String)
46
45
  ui_draw(TEXT, FG_COLOR, 64, 65, :String)
47
46
 
48
47
  and32(:Data3, 0xFFFF, :Data3)
49
- strings(NUMBER_FORMATTED, :Data3, '%-5d', 8, :String)
48
+ strings(NUMBER_FORMATTED, :Data3, "%-5d", 8, :String)
50
49
  ui_draw(TEXT, FG_COLOR, 64, 80, :String)
51
50
 
52
51
  ui_draw(UPDATE)
@@ -1,6 +1,6 @@
1
1
  vmthread :MAIN do
2
2
  ui_draw(FILLWINDOW, 0x00, 0, 0)
3
- ui_draw(TEXT, FG_COLOR, 10, 50, 'Hello, world!')
3
+ ui_draw(TEXT, FG_COLOR, 10, 50, "Hello, world!")
4
4
  ui_draw(UPDATE)
5
5
  ui_button(WAIT_FOR_PRESS)
6
6
  end
@@ -1,6 +1,6 @@
1
1
  vmthread :MAIN do
2
2
  ui_draw_fillwindow(0x00, 0, 0)
3
- ui_draw_text(1, 10, 50, 'Hello, world!')
3
+ ui_draw_text(1, 10, 50, "Hello, world!")
4
4
  ui_draw_update
5
5
  ui_button_wait_for_press
6
6
  end
data/spec/data/NoDebug.rb CHANGED
@@ -1,4 +1,4 @@
1
- appv = 'NoDebug V1.02'
1
+ appv = "NoDebug V1.02"
2
2
 
3
3
  vmthread :MAIN do
4
4
  data8 :ShowVersion
@@ -5,18 +5,18 @@ vmthread :MAIN do
5
5
  data32 :Data1
6
6
  datas :String, 8
7
7
 
8
- self.loop do
8
+ loop do
9
9
  ui_draw(FILLWINDOW, 0x00, 0, 0)
10
10
  ui_draw(SELECT_FONT, SMALL_FONT)
11
- ui_draw(TEXT, FG_COLOR, 0, 10, 'Vernier Readout V0.00')
11
+ ui_draw(TEXT, FG_COLOR, 0, 10, "Vernier Readout V0.00")
12
12
 
13
- ui_draw(TEXT, FG_COLOR, 0, 50, 'Raw 1')
13
+ ui_draw(TEXT, FG_COLOR, 0, 50, "Raw 1")
14
14
  ui_draw(SELECT_FONT, NORMAL_FONT)
15
15
 
16
16
  input_device(READY_RAW, 0, PORT, 1, 0, 1, :Data1)
17
17
 
18
18
  and32(:Data1, 0xFFFF, :Data1)
19
- strings(NUMBER_FORMATTED, :Data1, '%-5d', 8, :String)
19
+ strings(NUMBER_FORMATTED, :Data1, "%-5d", 8, :String)
20
20
  ui_draw(TEXT, FG_COLOR, 64, 50, :String)
21
21
 
22
22
  ui_draw(UPDATE)