libftdi-ruby 0.0.1

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