cp2112 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 236ce95509446f965c43a5d5ff5931ce468ebf2e6e13f1a4f42dae9ba046a0d0
4
+ data.tar.gz: 178532fb537e292c8921736bf65bc4cb09a7e81dd918ecc71f18e3f040eda758
5
+ SHA512:
6
+ metadata.gz: 51913845b2fbade52bc6e22f74c20e7426c86c1a86d879ac479fad661c1199e9552e05b4ef6654663c9842f2ce0a92538978708122d78b30643d0403a635973f
7
+ data.tar.gz: 4a75e61ed5718c9fe63eec76ce52a6a637d3b1e0c6d52a584b54caba5055b77ea85a6eda03f8b81ef51eaedb0d6a4b8d7af0d5017d98fcadd5130cccb8abeddc
data/.gitignore ADDED
@@ -0,0 +1,12 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /_yardoc/
4
+ /coverage/
5
+ /doc/
6
+ /pkg/
7
+ /spec/reports/
8
+ /tmp/
9
+ /lib/cp2112/silabs/
10
+
11
+ # rspec failure tracking
12
+ .rspec_status
data/.rspec ADDED
@@ -0,0 +1,3 @@
1
+ --format documentation
2
+ --color
3
+ --require spec_helper
data/.travis.yml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ sudo: false
3
+ language: ruby
4
+ cache: bundler
5
+ rvm:
6
+ - 2.4.4
7
+ before_install: gem install bundler -v 1.16.5
data/Gemfile ADDED
@@ -0,0 +1,6 @@
1
+ source "https://rubygems.org"
2
+
3
+ git_source(:github) {|repo_name| "https://github.com/#{repo_name}" }
4
+
5
+ # Specify your gem's dependencies in cp2112.gemspec
6
+ gemspec
data/LICENSE ADDED
@@ -0,0 +1,29 @@
1
+ BSD 3-Clause License
2
+
3
+ Copyright (c) 2020, fenrir
4
+ All rights reserved.
5
+
6
+ Redistribution and use in source and binary forms, with or without
7
+ modification, are permitted provided that the following conditions are met:
8
+
9
+ 1. Redistributions of source code must retain the above copyright notice, this
10
+ list of conditions and the following disclaimer.
11
+
12
+ 2. Redistributions in binary form must reproduce the above copyright notice,
13
+ this list of conditions and the following disclaimer in the documentation
14
+ and/or other materials provided with the distribution.
15
+
16
+ 3. Neither the name of the copyright holder nor the names of its
17
+ contributors may be used to endorse or promote products derived from
18
+ this software without specific prior written permission.
19
+
20
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
23
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
24
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
26
+ SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
27
+ CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
28
+ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
data/README.md ADDED
@@ -0,0 +1,71 @@
1
+ # CP2112
2
+
3
+ Ruby wrapper for Silicon Laboratories CP2112 USB(HID) i2c/SMBus bridge library
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ ```ruby
10
+ gem 'cp2112'
11
+ ```
12
+
13
+ And then execute:
14
+
15
+ $ bundle
16
+
17
+ Or install it yourself as:
18
+
19
+ $ gem install cp2112
20
+
21
+ ## Usage
22
+
23
+ ```ruby
24
+ require 'cp2112'
25
+
26
+ dev = CP2112[0, 0x10C4, 0xEA90] # [index, vendor id, product id], [0x10C4, 0xEA90] are default parameters
27
+ raise unless dev.getPartNumber[0] == 0x0C # must always be 0xC0
28
+
29
+ gpio_new = [
30
+ 0x03, # GPIO.0-1: OUT, GPIO.2-7:IN
31
+ 0x00, # open-drain
32
+ 0x00, # GPIO
33
+ 0x00, # clkDiv
34
+ ]
35
+ dev.setGpioConfig(*gpio_new)
36
+ raise unless (dev.getGpioConfig == gpio_new)
37
+ 50.times{|i| # toggle GPIO.0-1
38
+ bits = dev.readLatch[0]
39
+ dev.writeLatch(bits ^ 0x03, 0x03)
40
+ sleep(0.02)
41
+ }
42
+
43
+ # Read via I2C
44
+ i2c_read = proc{|addr, size|
45
+ dev.readRequest(addr, size)
46
+ dev.forceReadResponse(size)
47
+ res = dev.getReadResponse
48
+ res[1][0...res[2]]
49
+ }
50
+
51
+ # Write via I2C
52
+ i2c_write = proc{|addr, data| # packed data is expected; data = [byte, ...].pack('C*')
53
+ dev.writeRequest(addr, data, data.size)
54
+ dev.transferStatusRequest
55
+ dev.getTransferStatusResponse
56
+ }
57
+
58
+ # TODO: your i2c_read, i2c_write operation
59
+
60
+ dev.close
61
+ ```
62
+
63
+ ## Development
64
+
65
+ After checking out the repo, run `rake compile` to install dependencies. Then, run `rake spec` to run the tests.
66
+
67
+ To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
68
+
69
+ ## Contributing
70
+
71
+ Bug reports and pull requests are welcome on GitHub at https://github.com/fenrir-naru/ruby-cp2112.
data/Rakefile ADDED
@@ -0,0 +1,23 @@
1
+ require "bundler/gem_tasks"
2
+
3
+ require "rspec/core/rake_task"
4
+ RSpec::Core::RakeTask.new(:spec)
5
+
6
+ require 'rake/baseextensiontask'
7
+ Class::new(Rake::BaseExtensionTask){
8
+ def define_compile_tasks
9
+ import File::join(@ext_dir, "Rakefile")
10
+
11
+ ENV["RUBYLIBDIR"] ||= @lib_dir
12
+
13
+ desc "Compile #{@name}"
14
+ task "compile:#{@name}" => [:fetch_libs]
15
+
16
+ desc "Compile all the extensions"
17
+ task "compile" => ["compile:#{@name}"]
18
+ end
19
+ }::new("cp2112"){|ext|
20
+ #ext.lib_dir = File::join("lib") # default
21
+ }
22
+
23
+ task :default => :spec
data/cp2112.gemspec ADDED
@@ -0,0 +1,31 @@
1
+
2
+ lib = File.expand_path("../lib", __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require "cp2112/version"
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "cp2112"
8
+ spec.version = CP2112::VERSION
9
+ spec.authors = ["fenrir(M.Naruoka)"]
10
+ spec.email = ["fenrir.naru@gmail.com"]
11
+
12
+ spec.summary = %q{Ruby wrapper for Silicon Laboratories CP2112 USB(HID) i2c/SMBus bridge library}
13
+ spec.description = %q{cp2112 is a Ruby wrapper for shared library of CP2112, a USB(HID) i2c/SMBus bridge device, which is distributed by Silicon Laboratories.}
14
+ spec.homepage = "https://github.com/fenrir-naru/ruby-cp2112"
15
+ spec.license = "BSD-3-Clause"
16
+
17
+ spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do
18
+ `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
19
+ end
20
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
21
+ spec.require_paths = ["lib"]
22
+ spec.required_ruby_version = '>= 2.0.0' # for Fiddle dependency
23
+
24
+ spec.extensions = ["ext/cp2112/Rakefile"]
25
+
26
+ spec.add_runtime_dependency 'rubyzip'
27
+ spec.add_development_dependency "bundler", ">= 1.16"
28
+ spec.add_development_dependency "rake", "~> 10.0"
29
+ spec.add_development_dependency "rake-compiler"
30
+ spec.add_development_dependency "rspec", "~> 3.0"
31
+ end
@@ -0,0 +1,35 @@
1
+ raise unless ENV["RUBYLIBDIR"]
2
+
3
+ # @see https://github.com/rubygems/rubygems/blob/20f66aae16d8aaae26d9abf338dc4a0ec083b063/lib/rubygems/ext/rake_builder.rb#L29
4
+ SILABS_LIB_DIR = File::join(ENV["RUBYLIBDIR"], 'cp2112', 'silabs')
5
+
6
+ file SILABS_LIB_DIR do
7
+ require 'zip'
8
+ require 'open-uri'
9
+ require 'fileutils'
10
+
11
+ print "Downloading Silicon Laboratories libraries ..."
12
+ open("https://silabs.com/documents/public/software/CP2112_Windows.exe"){|f|
13
+ # @see https://ja.wikipedia.org/wiki/ZIP_(%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB%E3%83%95%E3%82%A9%E3%83%BC%E3%83%9E%E3%83%83%E3%83%88)
14
+ f.read(0x9D404) # offset appearing the first 0x504B0304
15
+ src = StringIO::new
16
+ src.write(f.read(0x33BAAC0 - 0x9D404 + 22)) # length to the last EOCD, whose signature is 0x504B0506
17
+ Zip::File::open_buffer(src){|zf|
18
+ Zip::File::open_buffer(zf.read("InstallerData/Disk1/InstData/Resource1.zip")){|zf2|
19
+ Zip::File::open_buffer(zf2.read("$IA_PROJECT_DIR$/Release_zg_ia_sf.jar")){|zf3|
20
+ zf3.glob("CP2112_SDK/Library/*", File::FNM_DOTMATCH | File::FNM_EXTGLOB){|item|
21
+ next unless item.name =~ /CP2112_SDK\/Library\//
22
+ dst = File::join(SILABS_LIB_DIR, $')
23
+ zf3.extract(item, dst)
24
+ FileUtils::chmod(0755, dst) if File::ftype(dst) == "file" # executable permission is required for Fiddle::dlload
25
+ }
26
+ }
27
+ }
28
+ }
29
+ }
30
+ puts " Done."
31
+ end
32
+
33
+ task :fetch_libs => [SILABS_LIB_DIR]
34
+
35
+ task :default => :fetch_libs
@@ -0,0 +1,3 @@
1
+ module CP2112
2
+ VERSION = "0.1.0"
3
+ end
data/lib/cp2112.rb ADDED
@@ -0,0 +1,339 @@
1
+ require "cp2112/version"
2
+
3
+ require "fiddle/import"
4
+ require "fiddle/types"
5
+
6
+ module CP2112
7
+
8
+ module WinAPI
9
+ extend Fiddle::Importer
10
+ dlload 'kernel32.dll'
11
+ include Fiddle::Win32Types
12
+ extern 'int SetDllDirectory(LPCSTR)'
13
+ # @see https://ja.stackoverflow.com/questions/60784/windows-%E3%81%AE-ruby-%E3%81%AE-fiddle-%E3%81%A7-lib-dll-%E3%81%8C%E8%AA%AD%E3%81%BF%E8%BE%BC%E3%82%81%E3%81%AA%E3%81%84%E6%99%82-%E4%BD%95%E3%82%92%E3%83%81%E3%82%A7%E3%83%83%E3%82%AF%E3%81%99%E3%82%8C%E3%81%B0%E3%82%88%E3%81%84%E3%81%A7%E3%81%97%E3%82%87%E3%81%86%E3%81%8B
14
+ end
15
+
16
+ extend Fiddle::Importer
17
+
18
+ @@dll_name ||= 'SLABHIDtoSMBus.dll'
19
+ @@dll_dirs ||= proc{
20
+ root = (RUBY_PLATFORM =~ /cygwin/) ? ['/cygdrive', 'c'] : ['C:']
21
+ [
22
+ ['.'] # current dir
23
+ ] + $:.collect{|dir| # automatically downloaded library
24
+ ['x86', 'x64'].collect{|arch|
25
+ [dir, 'cp2112', 'silabs', 'Windows'] + [arch]
26
+ }
27
+ }.flatten(1) + ['x86', 'x64'].collect{|arch|
28
+ # default install dirs
29
+ root + ['SiliconLabs', 'MCU', 'CP2112_SDK', 'Library', 'Windows'] + [arch]
30
+ }
31
+ }.call
32
+ @@dll_setup ||= proc{|dll|
33
+ path = File::expand_path(File::dirname(dll))
34
+ path = `cygpath -w #{path}`.chomp if (RUBY_PLATFORM =~ /cygwin/)
35
+ WinAPI.SetDllDirectory(path)
36
+ }
37
+
38
+ raise "Cannot load HID dll!" unless proc{
39
+ @@dll_dirs.any?{|dir|
40
+ dll = File::join(*((dir || []) + [@@dll_name]))
41
+ next false unless File::exist?(dll)
42
+ begin
43
+ @@dll_setup.call(dll)
44
+ dlload(dll)
45
+ true
46
+ rescue
47
+ false
48
+ end
49
+ }
50
+ }.call
51
+
52
+ include Fiddle::Win32Types
53
+
54
+ typealias('HID_SMBUS_STATUS', 'int')
55
+ typealias('HID_SMBUS_DEVICE', 'void*')
56
+ typealias('HID_SMBUS_S0', 'BYTE')
57
+ typealias('HID_SMBUS_S1', 'BYTE')
58
+
59
+ def CP2112.get_ptr(type)
60
+ array, type = [1, type.to_s]
61
+ size = if type =~ /\[(\d*)\]$/ then
62
+ type, array = [$`, $1.to_i]
63
+ array = 0x200 if array <= 0
64
+ CP2112::sizeof(type) * array
65
+ else
66
+ CP2112::sizeof(type)
67
+ end
68
+ content = Fiddle::malloc(size)
69
+ ptr = Fiddle::Pointer[content]
70
+ if (array > 1) && ("char" == type) then
71
+ ptr.define_singleton_method(:to_value){self.to_str(size).unpack('Z*')[0]}
72
+ else
73
+ ctype = parse_ctype(type, type_alias)
74
+ packer = Fiddle::Packer[ctype]
75
+ packer.instance_eval{
76
+ =begin
77
+ Fix bug in original library; negative value means unsigned type
78
+ An unsigned value is treated with the same manner of a signed value in the original library.
79
+ Therefore, modification of @template, which is used for unpack method, is performed.
80
+ Alternative way is
81
+ module Fiddle
82
+ PackInfo::PACK_MAP[-TYPE_CHAR] = "C"
83
+ PackInfo::PACK_MAP[-TYPE_SHORT] = "S!"
84
+ PackInfo::PACK_MAP[-TYPE_INT] = "I!"
85
+ PackInfo::PACK_MAP[-TYPE_LONG] = "L!"
86
+ end
87
+ , which affects globally.
88
+ =end
89
+ @template.sub!(/^./){$&.upcase} if ctype < 0
90
+ @template.sub!(/$/, array.to_s) if array > 1
91
+ }
92
+ ptr.define_singleton_method(:to_value){
93
+ values = packer.unpack([self.to_str(size)])
94
+ (array == 1) ? values[0] : values
95
+ }
96
+ end
97
+ return ptr
98
+ end
99
+
100
+ module Return_Code
101
+ CONST_TABLE = {
102
+ :STATUS => { # HID_SMBUS_STATUS Return Codes
103
+ :HID_SMBUS_SUCCESS => 0x00,
104
+ :HID_SMBUS_DEVICE_NOT_FOUND => 0x01,
105
+ :HID_SMBUS_INVALID_HANDLE => 0x02,
106
+ :HID_SMBUS_INVALID_DEVICE_OBJECT => 0x03,
107
+ :HID_SMBUS_INVALID_PARAMETER => 0x04,
108
+ :HID_SMBUS_INVALID_REQUEST_LENGTH => 0x05,
109
+
110
+ :HID_SMBUS_READ_ERROR => 0x10,
111
+ :HID_SMBUS_WRITE_ERROR => 0x11,
112
+ :HID_SMBUS_READ_TIMED_OUT => 0x12,
113
+ :HID_SMBUS_WRITE_TIMED_OUT => 0x13,
114
+ :HID_SMBUS_DEVICE_IO_FAILED => 0x14,
115
+ :HID_SMBUS_DEVICE_ACCESS_ERROR => 0x15,
116
+ :HID_SMBUS_DEVICE_NOT_SUPPORTED => 0x16,
117
+
118
+ :HID_SMBUS_UNKNOWN_ERROR => 0xFF,
119
+ },
120
+
121
+ :S0 => { # HID_SMBUS_TRANSFER_S0
122
+ :HID_SMBUS_S0_IDLE => 0x00,
123
+ :HID_SMBUS_S0_BUSY => 0x01,
124
+ :HID_SMBUS_S0_COMPLETE => 0x02,
125
+ :HID_SMBUS_S0_ERROR => 0x03,
126
+ },
127
+
128
+ :S1_BUSY => { # HID_SMBUS_TRANSFER_S1
129
+ :HID_SMBUS_S1_BUSY_ADDRESS_ACKED => 0x00,
130
+ :HID_SMBUS_S1_BUSY_ADDRESS_NACKED => 0x01,
131
+ :HID_SMBUS_S1_BUSY_READING => 0x02,
132
+ :HID_SMBUS_S1_BUSY_WRITING => 0x03,
133
+ },
134
+
135
+ :S1_ERROR => { # HID_SMBUS_TRANSFER_S1
136
+ :HID_SMBUS_S1_ERROR_TIMEOUT_NACK => 0x00,
137
+ :HID_SMBUS_S1_ERROR_TIMEOUT_BUS_NOT_FREE => 0x01,
138
+ :HID_SMBUS_S1_ERROR_ARB_LOST => 0x02,
139
+ :HID_SMBUS_S1_ERROR_READ_INCOMPLETE => 0x03,
140
+ :HID_SMBUS_S1_ERROR_WRITE_INCOMPLETE => 0x04,
141
+ :HID_SMBUS_S1_ERROR_SUCCESS_AFTER_RETRY => 0x05,
142
+ },
143
+ }
144
+
145
+ CONST_TABLE.collect{|k, v| v.to_a}.flatten(1).each{|k, v| const_set(k, v)}
146
+ end
147
+
148
+ class <<self
149
+ # define class methods such as CP2112::status
150
+ Return_Code::CONST_TABLE.keys.each{|k|
151
+ define_method(k.to_s.downcase.to_sym, proc{|i| Return_Code::CONST_TABLE[k].find([nil]){|k2, v| v == i}[0]})
152
+ }
153
+ end
154
+
155
+ module String_Definitions
156
+ # Product String Types
157
+ HID_SMBUS_GET_VID_STR = 0x01
158
+ HID_SMBUS_GET_PID_STR = 0x02
159
+ HID_SMBUS_GET_PATH_STR = 0x03
160
+ HID_SMBUS_GET_SERIAL_STR = 0x04
161
+ HID_SMBUS_GET_MANUFACTURER_STR = 0x05
162
+ HID_SMBUS_GET_PRODUCT_STR = 0x06
163
+
164
+ # String Lengths
165
+ HID_SMBUS_DEVICE_STRLEN = 260
166
+ end
167
+
168
+ module SMBUS_Definitions
169
+ # SMbus Configuration Limits
170
+ HID_SMBUS_MIN_BIT_RATE = 1
171
+ HID_SMBUS_MIN_TIMEOUT = 0
172
+ HID_SMBUS_MAX_TIMEOUT = 1000
173
+ HID_SMBUS_MAX_RETRIES = 1000
174
+ HID_SMBUS_MIN_ADDRESS = 0x02
175
+ HID_SMBUS_MAX_ADDRESS = 0xFE
176
+
177
+ # Read/Write Limits
178
+ HID_SMBUS_MIN_READ_REQUEST_SIZE = 1
179
+ HID_SMBUS_MAX_READ_REQUEST_SIZE = 512
180
+ HID_SMBUS_MIN_TARGET_ADDRESS_SIZE = 1
181
+ HID_SMBUS_MAX_TARGET_ADDRESS_SIZE = 16
182
+ HID_SMBUS_MAX_READ_RESPONSE_SIZE = 61
183
+ HID_SMBUS_MIN_WRITE_REQUEST_SIZE = 1
184
+ HID_SMBUS_MAX_WRITE_REQUEST_SIZE = 61
185
+ end
186
+
187
+ module GPIO_Definitions
188
+ # GPIO Pin Direction Bit Value
189
+ HID_SMBUS_DIRECTION_INPUT = 0
190
+ HID_SMBUS_DIRECTION_OUTPUT = 1
191
+
192
+ # GPIO Pin Mode Bit Value
193
+ HID_SMBUS_MODE_OPEN_DRAIN = 0
194
+ HID_SMBUS_MODE_PUSH_PULL = 1
195
+
196
+ # GPIO Function Bitmask
197
+ HID_SMBUS_MASK_FUNCTION_GPIO_7_CLK = 0x01
198
+ HID_SMBUS_MASK_FUNCTION_GPIO_0_TXT = 0x02
199
+ HID_SMBUS_MASK_FUNCTION_GPIO_1_RXT = 0x04
200
+
201
+ # GPIO Function Bit Value
202
+ HID_SMBUS_GPIO_FUNCTION = 0
203
+ HID_SMBUS_SPECIAL_FUNCTION = 1
204
+
205
+ # GPIO Pin Bitmask
206
+ HID_SMBUS_MASK_GPIO_0 = 0x01
207
+ HID_SMBUS_MASK_GPIO_1 = 0x02
208
+ HID_SMBUS_MASK_GPIO_2 = 0x04
209
+ HID_SMBUS_MASK_GPIO_3 = 0x08
210
+ HID_SMBUS_MASK_GPIO_4 = 0x10
211
+ HID_SMBUS_MASK_GPIO_5 = 0x20
212
+ HID_SMBUS_MASK_GPIO_6 = 0x40
213
+ HID_SMBUS_MASK_GPIO_7 = 0x80
214
+ end
215
+
216
+ module Part_Number_Definitions
217
+ # Part Numbers
218
+ HID_SMBUS_PART_CP2112 = 0x0C
219
+ end
220
+
221
+ module User_Customization_Definitions
222
+ # User-Customizable Field Lock Bitmasks
223
+ HID_SMBUS_LOCK_VID = 0x01
224
+ HID_SMBUS_LOCK_PID = 0x02
225
+ HID_SMBUS_LOCK_POWER = 0x04
226
+ HID_SMBUS_LOCK_POWER_MODE = 0x08
227
+ HID_SMBUS_LOCK_RELEASE_VERSION = 0x10
228
+ HID_SMBUS_LOCK_MFG_STR = 0x20
229
+ HID_SMBUS_LOCK_PRODUCT_STR = 0x40
230
+ HID_SMBUS_LOCK_SERIAL_STR = 0x80
231
+
232
+ # Field Lock Bit Values
233
+ HID_SMBUS_LOCK_UNLOCKED = 1
234
+ HID_SMBUS_LOCK_LOCKED = 0
235
+
236
+ # Power Max Value (500 mA)
237
+ HID_SMBUS_BUS_POWER_MAX = 0xFA
238
+
239
+ # Power Modes
240
+ HID_SMBUS_BUS_POWER = 0x00
241
+ HID_SMBUS_SELF_POWER_VREG_DIS = 0x01
242
+ HID_SMBUS_SELF_POWER_VREG_EN = 0x02
243
+
244
+ # USB Config Bitmasks
245
+ HID_SMBUS_SET_VID = 0x01
246
+ HID_SMBUS_SET_PID = 0x02
247
+ HID_SMBUS_SET_POWER = 0x04
248
+ HID_SMBUS_SET_POWER_MODE = 0x08
249
+ HID_SMBUS_SET_RELEASE_VERSION = 0x10
250
+
251
+ # USB Config Bit Values
252
+ HID_SMBUS_SET_IGNORE = 0
253
+ HID_SMBUS_SET_PROGRAM = 1
254
+
255
+ # String Lengths
256
+ HID_SMBUS_CP2112_MFG_STRLEN = 30
257
+ HID_SMBUS_CP2112_PRODUCT_STRLEN = 30
258
+ HID_SMBUS_CP2112_SERIAL_STRLEN = 30
259
+ end
260
+
261
+ class Device; end
262
+
263
+ {
264
+ # API Functions
265
+ 'HID_SMBUS_STATUS HidSmbus_GetNumDevices(DWORD*, WORD, WORD)' => [0],
266
+ 'HID_SMBUS_STATUS HidSmbus_GetString(DWORD, WORD, WORD, char[], DWORD)' => [3],
267
+ 'HID_SMBUS_STATUS HidSmbus_GetOpenedString(HID_SMBUS_DEVICE, char[], DWORD)' => [1],
268
+ 'HID_SMBUS_STATUS HidSmbus_GetIndexedString(DWORD, WORD, WORD, DWORD, char[])' => [4],
269
+ 'HID_SMBUS_STATUS HidSmbus_GetOpenedIndexedString(HID_SMBUS_DEVICE, DWORD, char[])' => [2],
270
+ 'HID_SMBUS_STATUS HidSmbus_GetAttributes(DWORD, WORD, WORD, WORD*, WORD*, WORD*)' => [3, 4, 5],
271
+ 'HID_SMBUS_STATUS HidSmbus_GetOpenedAttributes(HID_SMBUS_DEVICE, WORD*, WORD*, WORD*)' => [1, 2, 3],
272
+ 'HID_SMBUS_STATUS HidSmbus_Open(HID_SMBUS_DEVICE*, DWORD, WORD, WORD)' => [0],
273
+ 'HID_SMBUS_STATUS HidSmbus_Close(HID_SMBUS_DEVICE)' => [],
274
+ 'HID_SMBUS_STATUS HidSmbus_IsOpened(HID_SMBUS_DEVICE, BOOL*)' => [1],
275
+ 'HID_SMBUS_STATUS HidSmbus_ReadRequest(HID_SMBUS_DEVICE, BYTE, WORD)' => [],
276
+ 'HID_SMBUS_STATUS HidSmbus_AddressReadRequest(HID_SMBUS_DEVICE, BYTE, WORD, BYTE, BYTE*)' => [],
277
+ 'HID_SMBUS_STATUS HidSmbus_ForceReadResponse(HID_SMBUS_DEVICE, WORD)' => [],
278
+ "HID_SMBUS_STATUS HidSmbus_GetReadResponse(HID_SMBUS_DEVICE, HID_SMBUS_S0*, BYTE[#{SMBUS_Definitions::HID_SMBUS_MAX_READ_RESPONSE_SIZE}], BYTE, BYTE*)" => [1, 2, [3, SMBUS_Definitions::HID_SMBUS_MAX_READ_RESPONSE_SIZE], 4],
279
+ 'HID_SMBUS_STATUS HidSmbus_WriteRequest(HID_SMBUS_DEVICE, BYTE, BYTE*, BYTE)' => [],
280
+ 'HID_SMBUS_STATUS HidSmbus_TransferStatusRequest(HID_SMBUS_DEVICE)' => [],
281
+ 'HID_SMBUS_STATUS HidSmbus_GetTransferStatusResponse(HID_SMBUS_DEVICE, HID_SMBUS_S0*, HID_SMBUS_S1*, WORD*, WORD*)' => [1, 2, 3, 4],
282
+ 'HID_SMBUS_STATUS HidSmbus_CancelTransfer(HID_SMBUS_DEVICE)' => [],
283
+ 'HID_SMBUS_STATUS HidSmbus_CancelIo(HID_SMBUS_DEVICE)' => [],
284
+ 'HID_SMBUS_STATUS HidSmbus_SetTimeouts(HID_SMBUS_DEVICE, DWORD)' => [],
285
+ 'HID_SMBUS_STATUS HidSmbus_GetTimeouts(HID_SMBUS_DEVICE, DWORD*)' => [1],
286
+ 'HID_SMBUS_STATUS HidSmbus_SetSmbusConfig(HID_SMBUS_DEVICE, DWORD, BYTE, BOOL, WORD, WORD, BOOL, WORD)' => [],
287
+ 'HID_SMBUS_STATUS HidSmbus_GetSmbusConfig(HID_SMBUS_DEVICE, DWORD*, BYTE*, BOOL*, WORD*, WORD*, BOOL*, WORD*)' => (1..7).to_a,
288
+ 'HID_SMBUS_STATUS HidSmbus_Reset(HID_SMBUS_DEVICE)' => [],
289
+ 'HID_SMBUS_STATUS HidSmbus_SetGpioConfig(HID_SMBUS_DEVICE, BYTE, BYTE, BYTE, BYTE)' => [],
290
+ 'HID_SMBUS_STATUS HidSmbus_GetGpioConfig(HID_SMBUS_DEVICE, BYTE*, BYTE*, BYTE*, BYTE*)' => (1..4).to_a,
291
+ 'HID_SMBUS_STATUS HidSmbus_ReadLatch(HID_SMBUS_DEVICE, BYTE*)' => [1],
292
+ 'HID_SMBUS_STATUS HidSmbus_WriteLatch(HID_SMBUS_DEVICE, BYTE, BYTE)' => [],
293
+ 'HID_SMBUS_STATUS HidSmbus_GetPartNumber(HID_SMBUS_DEVICE, BYTE*, BYTE*)' => [1, 2],
294
+ 'HID_SMBUS_STATUS HidSmbus_GetLibraryVersion(BYTE*, BYTE*, BOOL*)' => (0..2).to_a,
295
+ 'HID_SMBUS_STATUS HidSmbus_GetHidLibraryVersion(BYTE*, BYTE*, BOOL*)' => (0..2).to_a,
296
+ 'HID_SMBUS_STATUS HidSmbus_GetHidGuid(void*)' => [], # TODO
297
+ # User Customization API Functions
298
+ 'HID_SMBUS_STATUS HidSmbus_SetLock(HID_SMBUS_DEVICE, BYTE)' => [],
299
+ 'HID_SMBUS_STATUS HidSmbus_GetLock(HID_SMBUS_DEVICE, BYTE*)' => [1],
300
+ 'HID_SMBUS_STATUS HidSmbus_SetUsbConfig(HID_SMBUS_DEVICE, WORD, WORD, BYTE, BYTE, WORD, BYTE)' => [],
301
+ 'HID_SMBUS_STATUS HidSmbus_GetUsbConfig(HID_SMBUS_DEVICE, WORD*, WORD*, BYTE*, BYTE*, WORD*)' => (1..5).to_a,
302
+ 'HID_SMBUS_STATUS HidSmbus_SetManufacturingString(HID_SMBUS_DEVICE, char[], BYTE)' => [],
303
+ 'HID_SMBUS_STATUS HidSmbus_GetManufacturingString(HID_SMBUS_DEVICE, char[], BYTE*)' => [1, 2],
304
+ 'HID_SMBUS_STATUS HidSmbus_SetProductString(HID_SMBUS_DEVICE, char[], BYTE)' => [],
305
+ 'HID_SMBUS_STATUS HidSmbus_GetProductString(HID_SMBUS_DEVICE, char[], BYTE*)' => [1, 2],
306
+ 'HID_SMBUS_STATUS HidSmbus_SetSerialString(HID_SMBUS_DEVICE, char[], BYTE)' => [],
307
+ 'HID_SMBUS_STATUS HidSmbus_GetSerialString(HID_SMBUS_DEVICE, char[], BYTE*)' => [1, 2],
308
+ }.each{|func, args_auto|
309
+ extern(func) # enable original function
310
+ next unless func =~ /HidSmbus_([^\(]+)\(([^)]+)\)$/
311
+ fname, args = [$1, $2.split(/, */).collect{|type| type.sub(/\*$/, '').to_sym}]
312
+ fname_orig = "HidSmbus_#{fname}".to_sym
313
+ # alternative function having return value helper
314
+ args_auto_buf = args_auto.collect{|arg|
315
+ # arg will be fixed when arg = [index, value], otherwise pointer is newly made
316
+ arg.kind_of?(Array) ? arg : [arg, get_ptr(args[arg])]
317
+ }
318
+ fname_new = fname.sub(/^./){$&.downcase}
319
+ define_singleton_method(fname_new, proc{|*inputs|
320
+ args_auto_buf.each{|arg| inputs.insert(arg[0], arg[1])}
321
+ s = status(self.send(fname_orig, *inputs))
322
+ raise [s, *inputs].inspect if :HID_SMBUS_SUCCESS != s
323
+ args_auto.collect{|arg|
324
+ arg.kind_of?(Array) ? nil : inputs[arg].to_value
325
+ }.compact
326
+ })
327
+ if (:HID_SMBUS_DEVICE == args[0]) && (!args_auto.include?(0)) then
328
+ Device.send(:define_method, fname_new, proc{|*args| CP2112::send(fname_new, @device, *args)})
329
+ end
330
+ }
331
+
332
+ Device.send(:define_method, :initialize, proc{|*args| @device = CP2112::open(*args)[0]})
333
+
334
+ class <<self
335
+ def [](index, vid = 0x0000, pid = 0x0000)
336
+ Device::new(index, vid, pid)
337
+ end
338
+ end
339
+ end
metadata ADDED
@@ -0,0 +1,126 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: cp2112
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - fenrir(M.Naruoka)
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2020-01-30 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: rubyzip
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: bundler
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '1.16'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '1.16'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rake
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '10.0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '10.0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rake-compiler
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: rspec
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: '3.0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: '3.0'
83
+ description: cp2112 is a Ruby wrapper for shared library of CP2112, a USB(HID) i2c/SMBus
84
+ bridge device, which is distributed by Silicon Laboratories.
85
+ email:
86
+ - fenrir.naru@gmail.com
87
+ executables: []
88
+ extensions:
89
+ - ext/cp2112/Rakefile
90
+ extra_rdoc_files: []
91
+ files:
92
+ - ".gitignore"
93
+ - ".rspec"
94
+ - ".travis.yml"
95
+ - Gemfile
96
+ - LICENSE
97
+ - README.md
98
+ - Rakefile
99
+ - cp2112.gemspec
100
+ - ext/cp2112/Rakefile
101
+ - lib/cp2112.rb
102
+ - lib/cp2112/version.rb
103
+ homepage: https://github.com/fenrir-naru/ruby-cp2112
104
+ licenses:
105
+ - BSD-3-Clause
106
+ metadata: {}
107
+ post_install_message:
108
+ rdoc_options: []
109
+ require_paths:
110
+ - lib
111
+ required_ruby_version: !ruby/object:Gem::Requirement
112
+ requirements:
113
+ - - ">="
114
+ - !ruby/object:Gem::Version
115
+ version: 2.0.0
116
+ required_rubygems_version: !ruby/object:Gem::Requirement
117
+ requirements:
118
+ - - ">="
119
+ - !ruby/object:Gem::Version
120
+ version: '0'
121
+ requirements: []
122
+ rubygems_version: 3.0.3
123
+ signing_key:
124
+ specification_version: 4
125
+ summary: Ruby wrapper for Silicon Laboratories CP2112 USB(HID) i2c/SMBus bridge library
126
+ test_files: []