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 +7 -0
- data/.gitignore +12 -0
- data/.rspec +3 -0
- data/.travis.yml +7 -0
- data/Gemfile +6 -0
- data/LICENSE +29 -0
- data/README.md +71 -0
- data/Rakefile +23 -0
- data/cp2112.gemspec +31 -0
- data/ext/cp2112/Rakefile +35 -0
- data/lib/cp2112/version.rb +3 -0
- data/lib/cp2112.rb +339 -0
- metadata +126 -0
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
data/.rspec
ADDED
data/.travis.yml
ADDED
data/Gemfile
ADDED
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
|
data/ext/cp2112/Rakefile
ADDED
@@ -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
|
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: []
|