libftdi-ruby 0.0.1

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.
@@ -0,0 +1,7 @@
1
+ *.gem
2
+ .bundle
3
+ Gemfile.lock
4
+ pkg/
5
+ .yardoc/
6
+ doc/
7
+
@@ -0,0 +1,10 @@
1
+ --markup markdown
2
+ --markup-provider redcarpet
3
+ --charset utf-8
4
+ --no-private
5
+ --readme README.md
6
+ --title "libftdi-ruby Documentation"
7
+ -
8
+ README.md
9
+ LICENSE
10
+
data/Gemfile ADDED
@@ -0,0 +1,7 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in libftdi-ruby.gemspec
4
+ gemspec
5
+
6
+ gem "ripper", :group => :development, :platforms => :ruby_18
7
+
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ Copyright (c) 2010-2011 Akzhan Abdulin and contributors
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21
+
@@ -0,0 +1,2 @@
1
+ Ruby bindings for [libftdi](http://www.intra2net.com/en/developer/libftdi/index.php) - an open source library to talk to [FTDI](http://www.ftdichip.com/) chips.
2
+
@@ -0,0 +1,6 @@
1
+ require "bundler/gem_tasks"
2
+
3
+ require "yard"
4
+
5
+ YARD::Rake::YardocTask.new
6
+
@@ -0,0 +1,203 @@
1
+ require 'ffi'
2
+ require "ftdi/version"
3
+
4
+ module Ftdi
5
+ extend FFI::Library
6
+
7
+ ffi_lib "libftdi"
8
+
9
+ # FTDI chip type.
10
+ ChipType = enum(:type_am, :type_bm, :type_2232c, :type_r, :type_2232h, :type_4232h, :type_232h)
11
+
12
+ # Automatic loading / unloading of kernel modules
13
+ ModuleDetachMode = enum(:auto_detach_sio_module, :dont_detach_sio_module)
14
+
15
+ # Number of bits for {Ftdi::Context.set_line_property}
16
+ BitsType = enum(
17
+ :bits_7, 7,
18
+ :bits_8, 8
19
+ )
20
+
21
+ # Number of stop bits for {Ftdi::Context.set_line_property}
22
+ StopbitsType = enum(
23
+ :stop_bit_1, 0,
24
+ :stop_bit_15, 1,
25
+ :stop_bit_2, 2
26
+ )
27
+
28
+ # Parity mode for {Ftdi::Context.set_line_property}
29
+ ParityType = enum(:none, :odd, :even, :mark, :space)
30
+
31
+ # Break type for {Ftdi::Context.set_line_property2}
32
+ BreakType = enum(:break_off, :break_on)
33
+
34
+ SIO_DISABLE_FLOW_CTRL = 0x0
35
+
36
+ # Base error of libftdi.
37
+ class Error < RuntimeError; end
38
+
39
+ # Initialization error of libftdi.
40
+ class CannotInitializeContextError < Error; end
41
+
42
+ # Error of libftdi with its status code.
43
+ class StatusCodeError < Error
44
+ attr_accessor :status_code
45
+
46
+ def initialize(status_code, message)
47
+ super(message)
48
+ self.status_code = status_code
49
+ end
50
+
51
+ def to_s
52
+ "#{status_code}: #{super}"
53
+ end
54
+ end
55
+
56
+ # libftdi context
57
+ class Context < FFI::Struct
58
+ layout(
59
+ # USB specific
60
+ # libusb's context
61
+ :usb_ctx, :pointer,
62
+ # libusb's usb_dev_handle
63
+ :usb_dev, :pointer,
64
+ # usb read timeout
65
+ :usb_read_timeout, :int,
66
+ # usb write timeout
67
+ :usb_write_timeout, :int,
68
+
69
+ # FTDI specific
70
+ # FTDI chip type
71
+ :type, Ftdi::ChipType,
72
+ # baudrate
73
+ :baudrate, :int,
74
+ # bitbang mode state
75
+ :bitbang_enabled, :uint8,
76
+ # pointer to read buffer for ftdi_read_data
77
+ :readbuffer, :pointer,
78
+ # read buffer offset
79
+ :readbuffer_offset, :uint,
80
+ # number of remaining data in internal read buffer
81
+ :readbuffer_remaining, :uint,
82
+ # read buffer chunk size
83
+ :readbuffer_chunksize, :uint,
84
+ # write buffer chunk size
85
+ :writebuffer_chunksize, :uint,
86
+ # maximum packet size. Needed for filtering modem status bytes every n packets.
87
+ :max_packet_size, :uint,
88
+
89
+ # FTDI FT2232C requirements
90
+ # FT2232C interface number: 0 or 1
91
+ :interface, :int, # 0 or 1
92
+ # FT2232C index number: 1 or 2
93
+ :index, :int, # 1 or 2
94
+ # Endpoints
95
+ # FT2232C end points: 1 or 2
96
+ :in_ep, :int,
97
+ :out_ep, :int, # 1 or 2
98
+
99
+ # Bitbang mode. 1: (default) Normal bitbang mode, 2: FT2232C SPI bitbang mode
100
+ :bitbang_mode, :uint8,
101
+
102
+ # Decoded eeprom structure
103
+ :eeprom, :pointer,
104
+
105
+ # String representation of last error
106
+ :error_str, :string,
107
+
108
+ # Defines behavior in case a kernel module is already attached to the device
109
+ :module_detach_mode, Ftdi::ModuleDetachMode
110
+ )
111
+
112
+ def initialize
113
+ ptr = Ftdi.ftdi_new
114
+ raise CannotInitializeContextError.new if ptr.nil?
115
+ super(ptr)
116
+ end
117
+
118
+ # Deinitialize and free an ftdi context.
119
+ def dispose
120
+ Ftdi.ftdi_free(ctx)
121
+ nil
122
+ end
123
+
124
+ alias :close :dispose
125
+
126
+ def error_string
127
+ self[:error_str]
128
+ end
129
+
130
+ # Opens the first device with a given vendor and product ids.
131
+ def usb_open(vendor, product)
132
+ raise ArgumentError.new('vendor should be Fixnum') unless vendor.kind_of?(Fixnum)
133
+ raise ArgumentError.new('product should be Fixnum') unless product.kind_of?(Fixnum)
134
+ check_result(Ftdi.ftdi_usb_open(ctx, vendor, product))
135
+ end
136
+
137
+ # Closes the ftdi device.
138
+ def usb_close
139
+ Ftdi.ftdi_usb_close(ctx)
140
+ nil
141
+ end
142
+
143
+ # Gets the chip baud rate.
144
+ def baudrate
145
+ self[:baudrate]
146
+ end
147
+
148
+ # Sets the chip baud rate.
149
+ def baudrate=(new_baudrate)
150
+ raise ArgumentError.new('baudrate should be Fixnum') unless new_baudrate.kind_of?(Fixnum)
151
+ check_result(Ftdi.ftdi_set_baudrate(ctx, new_baudrate))
152
+ end
153
+
154
+ # Set (RS232) line characteristics.
155
+ # The break type can only be set via {#set_line_property2} and defaults to "off".
156
+ def set_line_property(bits, stopbits, parity)
157
+ check_result(Ftdi.ftdi_set_line_property(ctx, bits, stopbits, parity))
158
+ end
159
+
160
+ # Set (RS232) line characteristics.
161
+ def set_line_property2(bits, stopbits, parity, _break)
162
+ check_result(Ftdi.ftdi_set_line_property2(ctx, bits, stopbits, parity, _break))
163
+ end
164
+
165
+ # Set flowcontrol for ftdi chip.
166
+ def flowctrl=(new_flowctrl)
167
+ check_result(Ftdi.ftdi_setflowctrl(ctx, new_flowctrl))
168
+ end
169
+
170
+ def write_data(bytes)
171
+ bytes = bytes.pack('c*') if bytes.respond_to?(:pack)
172
+ size = bytes.respond_to?(:bytesize) ? bytes.bytesize : bytes.size
173
+ mem_buf = FFI::MemoryPointer.new(:char, size)
174
+ mem_buf.put_bytes(0, bytes)
175
+ r = Ftdi.ftdi_write_data(ctx, mem_buf, size)
176
+ check_result(r)
177
+ r
178
+ end
179
+
180
+ private
181
+ def ctx
182
+ self.to_ptr
183
+ end
184
+
185
+ def check_result(status_code)
186
+ if status_code < 0
187
+ raise StatusCodeError.new(status_code, error_string)
188
+ end
189
+ nil
190
+ end
191
+ end
192
+
193
+ attach_function :ftdi_new, [ ], :pointer
194
+ attach_function :ftdi_free, [ :pointer ], :void
195
+ attach_function :ftdi_usb_open, [ :pointer, :int, :int ], :int
196
+ attach_function :ftdi_usb_close, [ :pointer ], :void
197
+ attach_function :ftdi_set_baudrate, [ :pointer, :int ], :int
198
+ attach_function :ftdi_set_line_property, [ :pointer, BitsType, StopbitsType, ParityType ], :int
199
+ attach_function :ftdi_set_line_property2, [ :pointer, BitsType, StopbitsType, ParityType, BreakType ], :int
200
+ attach_function :ftdi_setflowctrl, [ :pointer, :int ], :int
201
+ attach_function :ftdi_write_data, [ :pointer, :pointer, :int ], :int
202
+ end
203
+
@@ -0,0 +1,6 @@
1
+ # libftdi ruby bindings.
2
+ module Ftdi
3
+ # Gem version.
4
+ VERSION = "0.0.1".freeze
5
+ end
6
+
@@ -0,0 +1,24 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "ftdi/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "libftdi-ruby"
7
+ s.version = Ftdi::VERSION.dup
8
+ s.authors = ["Akzhan Abdulin"]
9
+ s.email = ["akzhan.abdulin@gmail.com"]
10
+ s.homepage = "http://github.com/akzhan/libftdi-ruby"
11
+ s.summary = %q{libftdi library binding}
12
+ s.description = %q{libftdi library binding to talk to FTDI chips}
13
+
14
+ s.rubyforge_project = "libftdi-ruby"
15
+
16
+ s.files = `git ls-files`.split("\n")
17
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
18
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
19
+ s.require_paths = ["lib"]
20
+
21
+ s.add_runtime_dependency "ffi", "~> 1.0"
22
+ s.add_development_dependency "yard", "~> 0.7.5"
23
+ end
24
+
data/test.rb ADDED
@@ -0,0 +1,54 @@
1
+ require 'rubygems'
2
+ require 'bundler/setup'
3
+
4
+ $LOAD_PATH.unshift(File.expand_path('lib', File.dirname(__FILE__)))
5
+
6
+ require 'ftdi'
7
+
8
+ DMX_BREAK = 110. / 1000 # Break 88 uS or more
9
+ DMX_MAB = 160. / 1000 # Mark After Break 8 uS or more
10
+ BAUD_RATE = 250000
11
+
12
+ ctx = Ftdi::Context.new
13
+
14
+ def dmx_break(ctx)
15
+ ctx.set_line_property2(:bits_8, :stop_bit_2, :none, :break_on)
16
+ sleep DMX_BREAK
17
+ ctx.set_line_property2(:bits_8, :stop_bit_2, :none, :break_off)
18
+ sleep DMX_MAB
19
+ end
20
+
21
+ def dmx_write(ctx, bytes)
22
+ dmx_break(ctx)
23
+ ctx.write_data(bytes)
24
+ end
25
+
26
+ begin
27
+ ctx.usb_open(0x0403, 0x6001)
28
+ begin
29
+ ctx.baudrate = BAUD_RATE
30
+ ctx.set_line_property(:bits_8, :stop_bit_2, :none)
31
+ ctx.flowctrl = Ftdi::SIO_DISABLE_FLOW_CTRL
32
+
33
+ arr = [ 0 ]
34
+ 512.times { arr << 1 }
35
+ dmx_write(ctx, arr)
36
+
37
+ sleep 1
38
+
39
+ arr = [ 0 ]
40
+ 512.times { arr << 0 }
41
+ dmx_write(ctx, arr)
42
+
43
+ puts "Context is:"
44
+ ctx.members.each { |k| puts "#{k} = #{ctx[k]}" }
45
+
46
+ ensure
47
+ ctx.usb_close
48
+ end
49
+ rescue Ftdi::Error => e
50
+ $stderr.puts e.to_s
51
+ end
52
+
53
+ ctx.dispose
54
+
metadata ADDED
@@ -0,0 +1,78 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: libftdi-ruby
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Akzhan Abdulin
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-04-11 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: ffi
16
+ requirement: &2153142340 !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ~>
20
+ - !ruby/object:Gem::Version
21
+ version: '1.0'
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: *2153142340
25
+ - !ruby/object:Gem::Dependency
26
+ name: yard
27
+ requirement: &2153157740 !ruby/object:Gem::Requirement
28
+ none: false
29
+ requirements:
30
+ - - ~>
31
+ - !ruby/object:Gem::Version
32
+ version: 0.7.5
33
+ type: :development
34
+ prerelease: false
35
+ version_requirements: *2153157740
36
+ description: libftdi library binding to talk to FTDI chips
37
+ email:
38
+ - akzhan.abdulin@gmail.com
39
+ executables: []
40
+ extensions: []
41
+ extra_rdoc_files: []
42
+ files:
43
+ - .gitignore
44
+ - .yardopts
45
+ - Gemfile
46
+ - LICENSE
47
+ - README.md
48
+ - Rakefile
49
+ - lib/ftdi.rb
50
+ - lib/ftdi/version.rb
51
+ - libftdi-ruby.gemspec
52
+ - test.rb
53
+ homepage: http://github.com/akzhan/libftdi-ruby
54
+ licenses: []
55
+ post_install_message:
56
+ rdoc_options: []
57
+ require_paths:
58
+ - lib
59
+ required_ruby_version: !ruby/object:Gem::Requirement
60
+ none: false
61
+ requirements:
62
+ - - ! '>='
63
+ - !ruby/object:Gem::Version
64
+ version: '0'
65
+ required_rubygems_version: !ruby/object:Gem::Requirement
66
+ none: false
67
+ requirements:
68
+ - - ! '>='
69
+ - !ruby/object:Gem::Version
70
+ version: '0'
71
+ requirements: []
72
+ rubyforge_project: libftdi-ruby
73
+ rubygems_version: 1.8.15
74
+ signing_key:
75
+ specification_version: 3
76
+ summary: libftdi library binding
77
+ test_files: []
78
+ has_rdoc: