cp2112 0.1.0

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.
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: []