ladder_drive 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (70) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +11 -0
  3. data/Gemfile +8 -0
  4. data/Gemfile.lock +41 -0
  5. data/LICENSE +21 -0
  6. data/README.md +191 -0
  7. data/README_jp.md +193 -0
  8. data/Rakefile +9 -0
  9. data/bin/console +14 -0
  10. data/bin/setup +8 -0
  11. data/exe/ladder_drive +28 -0
  12. data/ladder_drive.gemspec +33 -0
  13. data/lib/ladder_drive/asm.rb +211 -0
  14. data/lib/ladder_drive/cli.rb +55 -0
  15. data/lib/ladder_drive/config.rb +107 -0
  16. data/lib/ladder_drive/config_target.rb +93 -0
  17. data/lib/ladder_drive/console.rb +113 -0
  18. data/lib/ladder_drive/intel_hex.rb +79 -0
  19. data/lib/ladder_drive/ladder_drive.rb +36 -0
  20. data/lib/ladder_drive/plc_define.rb +35 -0
  21. data/lib/ladder_drive/plc_device.rb +171 -0
  22. data/lib/ladder_drive/protocol/emulator/emu_protocol.rb +54 -0
  23. data/lib/ladder_drive/protocol/emulator/emulator.rb +29 -0
  24. data/lib/ladder_drive/protocol/keyence/keyence.rb +31 -0
  25. data/lib/ladder_drive/protocol/keyence/kv_device.rb +51 -0
  26. data/lib/ladder_drive/protocol/keyence/kv_protocol.rb +187 -0
  27. data/lib/ladder_drive/protocol/mitsubishi/mc_protocol.rb +268 -0
  28. data/lib/ladder_drive/protocol/mitsubishi/mitsubishi.rb +30 -0
  29. data/lib/ladder_drive/protocol/mitsubishi/qdevice.rb +114 -0
  30. data/lib/ladder_drive/protocol/protocol.rb +107 -0
  31. data/lib/ladder_drive/tasks/build.rb +101 -0
  32. data/lib/ladder_drive/uploader.rb +101 -0
  33. data/lib/ladder_drive/version.rb +26 -0
  34. data/lib/ladder_drive.rb +32 -0
  35. data/lib/plc/LICENSE +21 -0
  36. data/lib/plc/emulator/emu_device.rb +121 -0
  37. data/lib/plc/emulator/emu_plc.rb +482 -0
  38. data/lib/plc/emulator/emu_plc_server.rb +71 -0
  39. data/lib/plc/emulator/emulator.rb +28 -0
  40. data/lib/plc/keyence/kv/kv-5000/DocumentWindowInfo.xml +91 -0
  41. data/lib/plc/keyence/kv/kv-5000/KvsMon.ini +0 -0
  42. data/lib/plc/keyence/kv/kv-5000/LadderDrive.mod +0 -0
  43. data/lib/plc/keyence/kv/kv-5000/LbkMdm.ini +0 -0
  44. data/lib/plc/keyence/kv/kv-5000/Main.mod +0 -0
  45. data/lib/plc/keyence/kv/kv-5000/MonEnv.kmu +1 -0
  46. data/lib/plc/keyence/kv/kv-5000/PlcSended.dky +0 -0
  47. data/lib/plc/keyence/kv/kv-5000/SensorMonitorInfo.xml +4 -0
  48. data/lib/plc/keyence/kv/kv-5000/TransInfo.tif +0 -0
  49. data/lib/plc/keyence/kv/kv-5000/UnitSet.ue2 +0 -0
  50. data/lib/plc/keyence/kv/kv-5000/UnitSet.ue2.old +0 -0
  51. data/lib/plc/keyence/kv/kv-5000/WsTreeEnv.xml +28 -0
  52. data/lib/plc/keyence/kv/kv-5000/kv-5000.cm1 +0 -0
  53. data/lib/plc/keyence/kv/kv-5000/kv-5000.cm2 +0 -0
  54. data/lib/plc/keyence/kv/kv-5000/kv-5000.ftc +0 -0
  55. data/lib/plc/keyence/kv/kv-5000/kv-5000.kpr +0 -0
  56. data/lib/plc/keyence/kv/kv-5000/kv-5000.lbl +0 -0
  57. data/lib/plc/keyence/kv/kv-5000/kv-5000.mil +0 -0
  58. data/lib/plc/keyence/kv/kv-5000/kv-5000.spl +0 -0
  59. data/lib/plc/keyence/kv/kv-5000/operand-history.txt +16 -0
  60. data/lib/plc/keyence/kv/kv-5000/sample.al2 +2 -0
  61. data/lib/plc/mitsubishi/iq-r/r08/r08.gx3 +0 -0
  62. data/lib/plc/plc.rb +27 -0
  63. data/sample/ladder_drive/sample1.esc +4 -0
  64. data/sample/ladder_drive/sample2.esc +28 -0
  65. data/sample/ladder_drive/sample2.png +0 -0
  66. data/template/escalator/config/plc.yml +27 -0
  67. data/template/ladder_drive/Rakefile +1 -0
  68. data/template/ladder_drive/asm/main.esc +70 -0
  69. data/template/ladder_drive/config/plc.yml +27 -0
  70. metadata +174 -0
@@ -0,0 +1,268 @@
1
+ # The MIT License (MIT)
2
+ #
3
+ # Copyright (c) 2016 ITO SOFT DESIGN Inc.
4
+ #
5
+ # Permission is hereby granted, free of charge, to any person obtaining
6
+ # a copy of this software and associated documentation files (the
7
+ # "Software"), to deal in the Software without restriction, including
8
+ # without limitation the rights to use, copy, modify, merge, publish,
9
+ # distribute, sublicense, and/or sell copies of the Software, and to
10
+ # permit persons to whom the Software is furnished to do so, subject to
11
+ # the following conditions:
12
+ #
13
+ # The above copyright notice and this permission notice shall be
14
+ # included in all copies or substantial portions of the Software.
15
+ #
16
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23
+
24
+ module LadderDrive
25
+ module Protocol
26
+ module Mitsubishi
27
+
28
+ class McProtocol < Protocol
29
+
30
+ def initialize options={}
31
+ super
32
+ @host = options[:host] || "192.168.0.10"
33
+ @port = options[:port] || 5010
34
+ prepare_device_map
35
+ end
36
+
37
+ def open
38
+ open!
39
+ rescue
40
+ nil
41
+ end
42
+
43
+ def open!
44
+ @socket ||= TCPSocket.open(@host, @port)
45
+ end
46
+
47
+ def close
48
+ @socket.close if @socket
49
+ @socket = nil
50
+ end
51
+
52
+ def get_bit_from_device device
53
+ device = device_by_name device
54
+ get_bits_from_device(1, device).first
55
+ end
56
+
57
+ def get_bits_from_device count, device
58
+ device = device_by_name device
59
+ packet = make_packet(body_for_get_bits_from_deivce(count, device))
60
+ @logger.debug("> #{dump_packet packet}")
61
+ open
62
+ @socket.write(packet.pack("c*"))
63
+ @socket.flush
64
+ res = receive
65
+ bits = []
66
+ count.times do |i|
67
+ v = res[11 + i / 2]
68
+ if i % 2 == 0
69
+ bits << ((v >> 4) != 0)
70
+ else
71
+ bits << ((v & 0xf) != 0)
72
+ end
73
+ end
74
+ @logger.debug("get #{device.name} => #{bits}")
75
+ bits
76
+ end
77
+
78
+ def set_bits_to_device bits, device
79
+ device = device_by_name device
80
+ packet = make_packet(body_for_set_bits_to_device(bits, device))
81
+ @logger.debug("> #{dump_packet packet}")
82
+ open
83
+ @socket.write(packet.pack("c*"))
84
+ @socket.flush
85
+ res = receive
86
+ @logger.debug("set #{bits} to:#{device.name}")
87
+ end
88
+
89
+
90
+ def get_word_from_device device
91
+ device = device_by_name device
92
+ get_words_from_device(1, device).first
93
+ end
94
+
95
+ def get_words_from_device(count, device)
96
+ device = device_by_name device
97
+ packet = make_packet(body_for_get_words_from_deivce(count, device))
98
+ @logger.debug("> #{dump_packet packet}")
99
+ open
100
+ @socket.write(packet.pack("c*"))
101
+ @socket.flush
102
+ res = receive
103
+ words = []
104
+ res[11, 2 * count].each_slice(2) do |pair|
105
+ words << pair.pack("c*").unpack("v").first
106
+ end
107
+ @logger.debug("get from: #{device.name} => #{words}")
108
+ words
109
+ end
110
+
111
+ def set_words_to_device words, device
112
+ device = device_by_name device
113
+ packet = make_packet(body_for_set_words_to_device(words, device))
114
+ @logger.debug("> #{dump_packet packet}")
115
+ open
116
+ @socket.write(packet.pack("c*"))
117
+ @socket.flush
118
+ res = receive
119
+ @logger.debug("set #{words} to: #{device.name}")
120
+ end
121
+
122
+
123
+ def device_by_name name
124
+ case name
125
+ when String
126
+ QDevice.new name
127
+ when EscDevice
128
+ local_device_of name
129
+ else
130
+ # it may be already QDevice
131
+ name
132
+ end
133
+ end
134
+
135
+
136
+ def receive
137
+ res = []
138
+ len = 0
139
+ begin
140
+ Timeout.timeout(1.0) do
141
+ loop do
142
+ c = @socket.read(1)
143
+ next if c.nil? || c == ""
144
+
145
+ res << c.bytes.first
146
+ len = res[7,2].pack("c*").unpack("v*").first if res.length >= 9
147
+ break if (len + 9 == res.length)
148
+ end
149
+ end
150
+ rescue Timeout::Error
151
+ puts "*** ERROR: TIME OUT ***"
152
+ end
153
+ @logger.debug("< #{dump_packet res}")
154
+ res
155
+ end
156
+
157
+ private
158
+
159
+ def make_packet body
160
+ header = [0x50, 0x00, 0x00, 0xff, 0xff, 0x03, 0x00, 0x00, 0x00, 0x10, 0x00]
161
+ header[7..8] = data_for_short(body.length + 2)
162
+ header + body
163
+ end
164
+
165
+ def body_for_get_bit_from_deivce device
166
+ body_for_get_bits_from_deivce 1, device
167
+ end
168
+
169
+ def body_for_get_bits_from_deivce count, device
170
+ body_for_get_words_from_deivce count, device, false
171
+ end
172
+
173
+ def body_for_get_words_from_deivce count, device, word = true
174
+ body = [0x01, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x90, 0x01, 0x00]
175
+ body[2] = 1 unless word
176
+ body[4..7] = data_for_device(device)
177
+ body[8..9] = data_for_short count
178
+ body
179
+ end
180
+
181
+
182
+ def body_for_set_bits_to_device bits, device
183
+ body = [0x01, 0x14, 0x01, 0x00, 0x00, 0x00, 0x00, 0x90, 0x01, 0x00]
184
+ d = device
185
+ bits = [bits] unless bits.is_a? Array
186
+ bits.each_slice(2) do |pair|
187
+ body << (pair.first ? 0x10 : 0x00)
188
+ body[-1] |= (pair.last ? 0x1 : 0x00) if pair.size == 2
189
+ d = d.next_device
190
+ end
191
+ body[4..7] = data_for_device(device)
192
+ body[8..9] = data_for_short bits.size
193
+ body
194
+ end
195
+ alias :body_for_set_bit_to_device :body_for_set_bits_to_device
196
+
197
+ def body_for_set_words_to_device words, device
198
+ body = [0x01, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x90, 0x01, 0x00]
199
+ d = device
200
+ words = [words] unless words.is_a? Array
201
+ words.each do |v|
202
+ body += data_for_short v
203
+ d = d.next_device
204
+ end
205
+ body[4..7] = data_for_device(device)
206
+ body[8..9] = data_for_short words.size
207
+ body
208
+ end
209
+
210
+ def data_for_device device
211
+ a = data_for_int device.number
212
+ a[3] = device.suffix_code
213
+ a
214
+ end
215
+
216
+ def data_for_short value
217
+ [value].pack("v").unpack("c*")
218
+ end
219
+
220
+ def data_for_int value
221
+ [value].pack("V").unpack("c*")
222
+ end
223
+
224
+ def dump_packet packet
225
+ a = []
226
+ len = packet.length
227
+ bytes = packet.dup
228
+ len.times do |i|
229
+ a << ("0" + bytes[i].to_s(16))[-2, 2]
230
+ end
231
+ "[" + a.join(", ") + "]"
232
+ end
233
+
234
+ def prepare_device_map
235
+ @conv_dev_dict ||= begin
236
+ h = {}
237
+ [
238
+ ["X", "X0", 1024],
239
+ ["Y", "Y0", 1024],
240
+ ["M", "M0", 1024],
241
+ ["C", "C0", 256],
242
+ ["T", "T0", 256],
243
+ ["L", "L0", 1024],
244
+ ["SC", "M1024", 1024],
245
+ ["D", "D0", 1024],
246
+ ["H", "D1024", 1024],
247
+ ["SD", "D2048", 1024],
248
+ ["PRG", "D3072", 1024] # ..D4095
249
+ ].each do |s,d,c|
250
+ h[s] = [QDevice.new(d), c]
251
+ end
252
+ h
253
+ end
254
+ end
255
+
256
+ def local_device_of device
257
+ return device if device.is_a? QDevice
258
+ d, c = @conv_dev_dict[device.suffix]
259
+ return nil unless device.number < c
260
+ ld = QDevice.new(d.suffix, d.number + device.number)
261
+ device_by_name ld.name
262
+ end
263
+
264
+ end
265
+
266
+ end
267
+ end
268
+ end
@@ -0,0 +1,30 @@
1
+ # The MIT License (MIT)
2
+ #
3
+ # Copyright (c) 2016 ITO SOFT DESIGN Inc.
4
+ #
5
+ # Permission is hereby granted, free of charge, to any person obtaining
6
+ # a copy of this software and associated documentation files (the
7
+ # "Software"), to deal in the Software without restriction, including
8
+ # without limitation the rights to use, copy, modify, merge, publish,
9
+ # distribute, sublicense, and/or sell copies of the Software, and to
10
+ # permit persons to whom the Software is furnished to do so, subject to
11
+ # the following conditions:
12
+ #
13
+ # The above copyright notice and this permission notice shall be
14
+ # included in all copies or substantial portions of the Software.
15
+ #
16
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23
+
24
+ $:.unshift File.dirname(__FILE__)
25
+
26
+ require 'socket'
27
+ require 'logger'
28
+ require 'timeout'
29
+ require 'qdevice'
30
+ require 'mc_protocol'
@@ -0,0 +1,114 @@
1
+ # The MIT License (MIT)
2
+ #
3
+ # Copyright (c) 2016 ITO SOFT DESIGN Inc.
4
+ #
5
+ # Permission is hereby granted, free of charge, to any person obtaining
6
+ # a copy of this software and associated documentation files (the
7
+ # "Software"), to deal in the Software without restriction, including
8
+ # without limitation the rights to use, copy, modify, merge, publish,
9
+ # distribute, sublicense, and/or sell copies of the Software, and to
10
+ # permit persons to whom the Software is furnished to do so, subject to
11
+ # the following conditions:
12
+ #
13
+ # The above copyright notice and this permission notice shall be
14
+ # included in all copies or substantial portions of the Software.
15
+ #
16
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23
+
24
+ module LadderDrive
25
+ module Protocol
26
+ module Mitsubishi
27
+
28
+ class QDevice
29
+
30
+ attr_reader :suffix, :number
31
+
32
+ SUFFIXES = %w(SM SD X Y M L F V B D W TS TC TN SS SC SN CS CC CN SB SW S DX DY Z R ZR)
33
+ SUFFIX_CODES = [0x91, 0xa9, 0x9c, 0x9d, 0x90, 0x92, 0x93, 0x94, 0xa0, 0xa8, 0xb4, 0xc1, 0xc0, 0xc2, 0xc7, 0xc6, 0xc8, 0xc4, 0xc3, 0xc5, 0xa1, 0xb5, 0x98, 0xa2, 0xa3, 0xcc ,0xaf, 0xb0]
34
+
35
+ def initialize a, b = nil
36
+ case a
37
+ when Array
38
+ case a.size
39
+ when 4
40
+ @suffix = suffix_for_code(a[3])
41
+ @number = ((a[2] << 8 | a[1]) << 8) | a[0]
42
+ end
43
+ when String
44
+ if b
45
+ @suffix = a.upcase
46
+ @number = b
47
+ else
48
+ if a.length == 12
49
+ @suffix = [a[0,2].to_i(16), a[2,2].to_i(16)].pack "c*"
50
+ @suffix.strip!
51
+ @number = a[4,8].to_i(16)
52
+ elsif /(X|Y)(.+)/i =~ a
53
+ @suffix = $1.upcase
54
+ @number = $2.to_i(p_adic_number)
55
+ else
56
+ /(M|L|S|B|F|T|C|D|W|R)(.+)/i =~ a
57
+ @suffix = $1.upcase
58
+ @number = $2.to_i(p_adic_number)
59
+ end
60
+ end
61
+ end
62
+ end
63
+
64
+ def p_adic_number
65
+ case @suffix
66
+ when "X", "Y", "B", "W", "SB", "SW", "DX", "DY", "ZR"
67
+ 16
68
+ else
69
+ 10
70
+ end
71
+ end
72
+
73
+ def name
74
+ @suffix + @number.to_s(p_adic_number).upcase
75
+ end
76
+
77
+ def next_device
78
+ d = self.class.new @suffix, @number + 1
79
+ d
80
+ end
81
+
82
+ def bit_device?
83
+ case @suffix
84
+ when "SM", "X", "Y", "M", "L", "F", "V", "B",
85
+ "TS", "TC", "SS", "SC","CS", "CC", "SB", "S", "DX", "DY"
86
+ true
87
+ else
88
+ false
89
+ end
90
+ end
91
+
92
+ def suffix_for_code code
93
+ index = SUFFIX_CODES.index code
94
+ index ? SUFFIXES[index] : nil
95
+ end
96
+
97
+ def suffix_code
98
+ index = SUFFIXES.index suffix
99
+ index ? SUFFIX_CODES[index] : 0
100
+ end
101
+
102
+ def + value
103
+ self.class.new self.suffix, self.number + value
104
+ end
105
+
106
+ def - value
107
+ self.class.new self.suffix, [self.number - value, 0].max
108
+ end
109
+
110
+ end
111
+
112
+ end
113
+ end
114
+ end
@@ -0,0 +1,107 @@
1
+ # The MIT License (MIT)
2
+ #
3
+ # Copyright (c) 2016 ITO SOFT DESIGN Inc.
4
+ #
5
+ # Permission is hereby granted, free of charge, to any person obtaining
6
+ # a copy of this software and associated documentation files (the
7
+ # "Software"), to deal in the Software without restriction, including
8
+ # without limitation the rights to use, copy, modify, merge, publish,
9
+ # distribute, sublicense, and/or sell copies of the Software, and to
10
+ # permit persons to whom the Software is furnished to do so, subject to
11
+ # the following conditions:
12
+ #
13
+ # The above copyright notice and this permission notice shall be
14
+ # included in all copies or substantial portions of the Software.
15
+ #
16
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23
+
24
+ dir = File.expand_path(File.dirname(__FILE__))
25
+ $:.unshift dir unless $:.include? dir
26
+
27
+ module LadderDrive
28
+ module Protocol
29
+ end
30
+ end
31
+
32
+ module LadderDrive
33
+ module Protocol
34
+
35
+ class Protocol
36
+
37
+ attr_accessor :host, :port, :log_level
38
+
39
+ def initialize options={}
40
+ @logger = Logger.new(STDOUT)
41
+ self.log_level = options[:log_level] || :info
42
+ end
43
+
44
+ def log_level= level
45
+ @log_level = level.is_a?(String) ? level.to_sym : level
46
+ case @log_level
47
+ when :debug
48
+ @logger.level = Logger::DEBUG
49
+ when :error
50
+ @logger.level = Logger::ERROR
51
+ when :fatal
52
+ @logger.level = Logger::FATAL
53
+ when :info
54
+ @logger.level = Logger::INFO
55
+ when :unknown
56
+ @logger.level = Logger::UNKNOWN
57
+ when :warn
58
+ @logger.level = Logger::WARN
59
+ end
60
+ end
61
+
62
+ # abstract methods
63
+
64
+ def open; end
65
+ def close; end
66
+
67
+ def get_bit_from_device device; end
68
+ def get_bits_from_device count, device; end
69
+ def set_bits_to_device bits, device; end
70
+ def set_bit_to_device bit, device; set_bits_to_device bit, device; end
71
+
72
+ def get_word_from_device device; end
73
+ def get_words_from_device(count, device); end
74
+ def set_words_to_device words, device; end
75
+ def set_word_to_device word, device; set_words_to_device word, device; end
76
+
77
+ def device_by_name name; nil; end
78
+
79
+ def get_from_devices device, count = 1
80
+ d = device_by_name device
81
+ if d.bit_device?
82
+ get_bits_from_device count, d
83
+ else
84
+ get_words_from_device count, d
85
+ end
86
+ end
87
+
88
+ def set_to_devices device, values
89
+ values = [values] unless values.is_a? Array
90
+ d = device_by_name device
91
+ if d.bit_device?
92
+ values = values.map{|v| case v; when 1; true; when 0; false; else; v; end}
93
+ set_bits_to_device values, d
94
+ else
95
+ set_words_to_device values, d
96
+ end
97
+ end
98
+
99
+ end
100
+
101
+ end
102
+ end
103
+
104
+ require 'keyence/keyence'
105
+ # Use load instead require, because there are two emulator files.
106
+ load File.join(dir, 'emulator/emulator.rb')
107
+ require 'mitsubishi/mitsubishi'
@@ -0,0 +1,101 @@
1
+ # The MIT License (MIT)
2
+ #
3
+ # Copyright (c) 2016 ITO SOFT DESIGN Inc.
4
+ #
5
+ # Permission is hereby granted, free of charge, to any person obtaining
6
+ # a copy of this software and associated documentation files (the
7
+ # "Software"), to deal in the Software without restriction, including
8
+ # without limitation the rights to use, copy, modify, merge, publish,
9
+ # distribute, sublicense, and/or sell copies of the Software, and to
10
+ # permit persons to whom the Software is furnished to do so, subject to
11
+ # the following conditions:
12
+ #
13
+ # The above copyright notice and this permission notice shall be
14
+ # included in all copies or substantial portions of the Software.
15
+ #
16
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23
+
24
+ dir = File.expand_path(File.join(File.dirname(__FILE__), "../../../lib"))
25
+ $:.unshift dir unless $:.include? dir
26
+
27
+ require 'rake/loaders/makefile'
28
+ require 'fileutils'
29
+ require "ladder_drive"
30
+
31
+ directory "build"
32
+
33
+ desc "Assemble codes"
34
+ rule %r{^build/.+\.lst} => ['%{^build,asm}X.esc'] do |t|
35
+ Rake::Task["build"].invoke
36
+ begin
37
+ $stderr = File.open('hb.log', 'w')
38
+ $stdout = $stderr
39
+ ensure
40
+ $stdout = STDOUT
41
+ $stderr = STDERR
42
+ end
43
+ #dir = "./asm"
44
+ stream = StringIO.new
45
+ #filename = "asm/#{t.source}"
46
+ puts "asm #{t.source}"
47
+ asm = LadderDrive::Asm.new File.read(t.source)
48
+ #dst = File.join("build", t.name)
49
+ File.write(t.name, asm.dump_line)
50
+ end
51
+
52
+ desc "Make hex codes"
53
+ rule %r{^build/.+\.hex} => ['%{^build,asm}X.esc'] do |t|
54
+ Rake::Task["build"].invoke
55
+ begin
56
+ $stderr = File.open('hb.log', 'w')
57
+ $stdout = $stderr
58
+ ensure
59
+ $stdout = STDOUT
60
+ $stderr = STDERR
61
+ end
62
+ stream = StringIO.new
63
+ puts "hex #{t.source}"
64
+ asm = LadderDrive::Asm.new File.read(t.source)
65
+ hex = LadderDrive::IntelHex.new asm.codes
66
+ File.write(t.name, hex.dump)
67
+ end
68
+
69
+ desc "Clean all generated files."
70
+ task :clean do
71
+ FileUtils.rm_r "build"
72
+ end
73
+
74
+ @config = LadderDrive::LadderDriveConfig.default
75
+
76
+ desc "Install program to PLCs."
77
+ task :upload => @config.output do
78
+ t = @config.target ENV['target']
79
+ t.run
80
+ u = t.uploader
81
+ u.source = @config.output
82
+ puts "uploading #{u.source} ..."
83
+ u.upload
84
+ puts "done uploading"
85
+ end
86
+
87
+ desc "Launch emulator."
88
+ task :emulator do
89
+ t = @config.target :emulator
90
+ t.run
91
+ puts "launch emulator"
92
+ LadderDrive::Console.instance.run
93
+ end
94
+
95
+ task :console => :upload do
96
+ c = LadderDrive::Console.instance
97
+ c.target = @config.target ENV['target']
98
+ c.run
99
+ end
100
+
101
+ task :default => :console