bryan-ash-pcanusb 1.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.
Files changed (5) hide show
  1. data/README.rdoc +48 -0
  2. data/lib/Pcan_usb.dll +0 -0
  3. data/lib/pcanusb.rb +175 -0
  4. data/rakefile +58 -0
  5. metadata +59 -0
data/README.rdoc ADDED
@@ -0,0 +1,48 @@
1
+ = PCANUSB - PCAN DLL Wrapper
2
+
3
+ PCAN is a Controller Area Network (CAN) device that connects to a PC via USB. It ships with a DLL and documented API. This is a Ruby wrapper for that API allowing CAN messages to be sent and received from Ruby.
4
+
5
+
6
+ == Example Usage
7
+
8
+ err = PCANUSB.init(PCANUSB::BAUD_250K)
9
+ raise INITIALIZATION_ERROR if err != PCANUSB::CAN_OK
10
+
11
+ err, number = PCANUSB.get_usb_device_number
12
+ puts "\n\nUsing PCAN USB device number = " + number.to_s(base=16)
13
+
14
+ err = PCANUSB.set_receive_filter(0x0E000000, 0x0EFFFFFF)
15
+ raise RECEIVE_FILTER_ERROR if err != PCANUSB::CAN_OK
16
+
17
+ err = PCANUSB.write(TRANSMIT_ID,[1, 2, 3, 4] )
18
+ raise WRITE_ERROR if err != PCANUSB::CAN_OK
19
+
20
+ assert_equal [5, 6, 7, 8], PCANUSB.read_id(RECEIVE_ID)
21
+
22
+ PCANUSB.close
23
+
24
+
25
+ == License
26
+
27
+ Copyright (c) 2009 Bryan Ash
28
+
29
+ Permission is hereby granted, free of charge, to any person
30
+ obtaining a copy of this software and associated documentation
31
+ files (the "Software"), to deal in the Software without
32
+ restriction, including without limitation the rights to use,
33
+ copy, modify, merge, publish, distribute, sublicense, and/or sell
34
+ copies of the Software, and to permit persons to whom the
35
+ Software is furnished to do so, subject to the following
36
+ conditions:
37
+
38
+ The above copyright notice and this permission notice shall be
39
+ included in all copies or substantial portions of the Software.
40
+
41
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
42
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
43
+ OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
44
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
45
+ HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
46
+ WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
47
+ FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
48
+ OTHER DEALINGS IN THE SOFTWARE.
data/lib/Pcan_usb.dll ADDED
Binary file
data/lib/pcanusb.rb ADDED
@@ -0,0 +1,175 @@
1
+ =begin
2
+ This class is a wrapper for the PCAN USB DLL
3
+ =end
4
+
5
+ require "dl"
6
+ require "dl/import"
7
+ require "dl/struct"
8
+
9
+ class PCANUSB
10
+
11
+ # BAUD rates used by "init"
12
+ BAUD_1M = 0x0014
13
+ BAUD_500K = 0x001C
14
+ BAUD_250K = 0x011C
15
+ BAUD_125K = 0x031C
16
+ BAUD_100K = 0x432F
17
+ BAUD_50K = 0x472F
18
+ BAUD_20K = 0x532F
19
+ BAUD_10K = 0x672F
20
+ BAUD_5K = 0x7F7F
21
+
22
+ # used by "init" and "set_receive_filter"
23
+ CAN_INIT_TYPE_ST = 0 # 11 Bit-ID handling - Standard frame
24
+ CAN_INIT_TYPE_EX = 1 # 29 Bit ID handling - Extended frame
25
+
26
+ # used by "write" and "read"
27
+ MSGTYPE_STANDARD = 0x00
28
+ MSGTYPE_RTR = 0x01
29
+ MSGTYPE_EXTENDED = 0x02
30
+ MSGTYPE_STATUS = 0x80
31
+
32
+ # return values
33
+ CAN_OK = 0x0000 # No error.
34
+ CAN_XMTFULL = 0x0001 # Transmission buffer of the controller is full.
35
+ CAN_OVERRUN = 0x0002 # CAN controller has been read out too late.
36
+ CAN_BUSLIGHT = 0x0004 # Bus error: An error counter has reached the 'Light' limit.
37
+ CAN_BUSHEAVY = 0x0008 # Bus error: An error counter has reached the 'Heavy' limit.
38
+ CAN_BUSOFF = 0x0010 # Bus error:Actual state from the CAN controller is 'Bus Off'.
39
+ CAN_QRCVEMPTY = 0x0020 # Receive queue is empty.
40
+ CAN_QOVERRUN = 0x0040 # Receive queue has been read out too late.
41
+ CAN_QXMTFULL = 0x0080 # Transmission queue is full.
42
+ CAN_REGTEST = 0x0100 # Register test of the 82C200/SJA1000 has failed.
43
+ CAN_NOVXD = 0x0200 # Driver is not loaded.
44
+ CAN_ILLHW = 0x1400 # Hardware handle is invalid.
45
+ CAN_ILLNET = 0x1800 # Net handle is invalid.
46
+ CAN_MASK_ILLHANDLE = 0x1C00 # Mask for all handle errors.
47
+ CAN_ILLCLIENT = 0x1C00 # Client handle is invalid.
48
+ CAN_RESOURCE = 0x2000 # Resource (FIFO, client, timeout) cannot be created.
49
+ CAN_ILLPARAMTYPE = 0x4000 # Parameter is not permitted/applicable here.
50
+ CAN_ILLPARAMVAL = 0x8000 # Parameter value is invalid.
51
+
52
+ # Initialize the PCAN device with a BAUD rate and message type.
53
+ # Valid message types are
54
+ # * CAN_INIT_TYPE_ST:: Standard format IDs
55
+ # * CAN_INIT_TYPE_EX:: Extended IDs
56
+ def self.init(baud_value, message_type = CAN_INIT_TYPE_EX)
57
+ err = Core::cAN_Init(baud_value, message_type)
58
+
59
+ # allow the hardware to initialize
60
+ sleep 0.125
61
+
62
+ return err
63
+ end
64
+
65
+ # Close the PCAN device connection.
66
+ def self.close
67
+ return Core::cAN_Close
68
+ end
69
+
70
+ # Retrieve the current PCAN status.
71
+ def self.status
72
+ return Core::cAN_Status
73
+ end
74
+
75
+ # Initiates a transmission of a CAN message with a given ID.
76
+ # the data parameter is expected to be less than 8 bytes.
77
+ def self.write(id, data, message_type = MSGTYPE_EXTENDED)
78
+ message = Core::TPCANMsg.malloc
79
+ message.id = id
80
+ message.message_type = message_type
81
+ message.length = data.length
82
+ message.data = data.dup
83
+
84
+ return Core::cAN_Write(message)
85
+ end
86
+
87
+ # Set the range of message ID that will be accepted.
88
+ # CAN_ResetFilter is used first to close the filter range,
89
+ # then CAN_MsgFilter is used to open it up.
90
+ def self.set_receive_filter(fromID, toID, message_type = MSGTYPE_EXTENDED)
91
+ Core::cAN_ResetFilter
92
+ return Core::cAN_MsgFilter(fromID, toID, message_type)
93
+ end
94
+
95
+ # Read one CAN message from the PCAN FIFO.
96
+ # Returns the error code, message type, ID and data array.
97
+ def self.read
98
+ message = Core::TPCANMsg.malloc
99
+
100
+ err = Core::cAN_Read(message)
101
+
102
+ return err, message.message_type, message.id, message.data[0..message.length - 1]
103
+ end
104
+
105
+ # Read a message with a given ID.
106
+ # Returns the received data array if the required ID is received within the timeout or false if not.
107
+ def self.read_id(id, timeout=1)
108
+ read_timeout = Time.now + timeout
109
+
110
+ begin
111
+ err, rx_type, rx_id, rx_data = self.read
112
+
113
+ if err == CAN_OK && rx_id == id then
114
+ return rx_data
115
+ end
116
+ end while Time.now < read_timeout
117
+
118
+ return false
119
+ end
120
+
121
+ # Reset the PCAN device.
122
+ def self.reset_client
123
+ return Core::cAN_ResetClient
124
+ end
125
+
126
+ # Provide information about the PCAN.
127
+ def self.version_info
128
+ info = Core::Version_Info.malloc
129
+
130
+ err = Core::cAN_VersionInfo(info)
131
+
132
+ # info.value is an array of characters, convert it to string
133
+ return info.value.pack("c128")
134
+ end
135
+
136
+ # Return the device number associated with the connected PCAN.
137
+ def self.get_usb_device_number
138
+ number = Core::Device_Number.malloc
139
+
140
+ err = Core::getUSBDeviceNr(number)
141
+
142
+ return err, number.value
143
+ end
144
+
145
+ #-----
146
+
147
+ module Core #:nodoc:all
148
+ extend DL::Importable
149
+
150
+ dlload File.dirname(__FILE__) + "/Pcan_usb.dll"
151
+
152
+ TPCANMsg = struct [
153
+ "long id",
154
+ "char message_type",
155
+ "char length",
156
+ "UCHAR data[8]",
157
+ ]
158
+
159
+ Device_Number = struct ["long value"]
160
+ Version_Info = struct ["char value[128]"]
161
+
162
+ extern "long CAN_Init(long, int)"
163
+ extern "long CAN_Close()"
164
+ extern "long CAN_Status()"
165
+ extern "long CAN_Write(TPCANMsg *)"
166
+ extern "long CAN_Read(TPCANMsg *)"
167
+ extern "long CAN_VersionInfo(Version_Info *)"
168
+ extern "long CAN_ResetClient()"
169
+ extern "long CAN_MsgFilter(DWORD, DWORD, int)"
170
+ extern "long CAN_ResetFilter()"
171
+ extern "long SetUSBDeviceNr(long)"
172
+ extern "long GetUSBDeviceNr(long *)"
173
+ end # module Core
174
+
175
+ end # class PCAN_USB
data/rakefile ADDED
@@ -0,0 +1,58 @@
1
+ #-*- ruby -*-
2
+
3
+ require 'rubygems'
4
+ require 'rake'
5
+ require 'rake/packagetask'
6
+ require 'rake/gempackagetask'
7
+ require 'rake/rdoctask'
8
+ require 'rake/contrib/rubyforgepublisher'
9
+
10
+ PKG_NAME = 'pcanusb'
11
+ PKG_VERSION = '1.0.0'
12
+
13
+ # Create compressed packages
14
+ dist_dirs = [ 'lib' ]
15
+
16
+ spec = Gem::Specification.new do |s|
17
+ s.platform = Gem::Platform::RUBY
18
+ s.name = PKG_NAME
19
+ s.version = PKG_VERSION
20
+ s.summary = 'PCAN DLL wrapper'
21
+ s.description = <<EOF
22
+ PCAN is a Controller Area Network (CAN) device that connects to a PC via USB.
23
+ It ships with a DLL and documented API.
24
+ This is a Ruby wrapper for that API allowing CAN messages to be sent and received from Ruby.
25
+ EOF
26
+
27
+ s.has_rdoc = true
28
+ s.requirements << 'none'
29
+
30
+ s.require_path = 'lib'
31
+ s.autorequire = 'rake'
32
+
33
+ s.files = [ "rakefile" ]
34
+ dist_dirs.each do |dir|
35
+ s.files = s.files + Dir.glob( "#{dir}/**/*" ).delete_if { |item| item.include?( "\.svn" ) }
36
+ end
37
+ end
38
+
39
+ Rake::GemPackageTask.new(spec) do |pkg|
40
+ pkg.gem_spec = spec
41
+ pkg.need_zip = true
42
+ end
43
+
44
+ desc "Publish the release files to RubyForge."
45
+ task :release => [ :package ] do
46
+ require 'rubyforge'
47
+
48
+ packages = %w( gem zip ).collect{ |ext| "pkg/#{PKG_NAME}-#{PKG_VERSION}.#{ext}" }
49
+
50
+ rubyforge = RubyForge.new
51
+ rubyforge.login
52
+ rubyforge.add_release(PKG_NAME, PKG_NAME, "REL #{PKG_VERSION}", *packages)
53
+ end
54
+
55
+ Rake::RDocTask.new do |rd|
56
+ rd.main = "lib/pcanusb.rb"
57
+ rd.rdoc_files.include("lib/**/*.rb")
58
+ end
metadata ADDED
@@ -0,0 +1,59 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: bryan-ash-pcanusb
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Bryan Ash
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2009-04-19 00:00:00 -07:00
13
+ default_executable:
14
+ dependencies: []
15
+
16
+ description: PCAN is a Controller Area Network (CAN) device that connects to a PC via USB. It ships with a DLL and documented API. This is a Ruby wrapper for that API allowing CAN messages to be sent and received from Ruby.
17
+ email: bryan.a.ash@gmail.com
18
+ executables: []
19
+
20
+ extensions: []
21
+
22
+ extra_rdoc_files: []
23
+
24
+ files:
25
+ - rakefile
26
+ - README.rdoc
27
+ - lib/Pcan_usb.dll
28
+ - lib/pcanusb.rb
29
+ has_rdoc: true
30
+ homepage: http://bryan-ash.github.com/pcanusb
31
+ post_install_message:
32
+ rdoc_options:
33
+ - --main
34
+ - README.rdoc
35
+ - --inline-source
36
+ - --charset=UTF-8
37
+ require_paths:
38
+ - lib
39
+ required_ruby_version: !ruby/object:Gem::Requirement
40
+ requirements:
41
+ - - ">="
42
+ - !ruby/object:Gem::Version
43
+ version: "0"
44
+ version:
45
+ required_rubygems_version: !ruby/object:Gem::Requirement
46
+ requirements:
47
+ - - ">="
48
+ - !ruby/object:Gem::Version
49
+ version: "0"
50
+ version:
51
+ requirements: []
52
+
53
+ rubyforge_project: pcanusb
54
+ rubygems_version: 1.2.0
55
+ signing_key:
56
+ specification_version: 2
57
+ summary: PCAN is a Controller Area Network (CAN) device that connects to a PC via USB. It ships with a DLL and documented API. This is a Ruby wrapper for that API allowing CAN messages to be sent and received from Ruby.
58
+ test_files: []
59
+