cp2112 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- 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: []
|