ruby-adept 0.0.1 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
data/Gemfile CHANGED
@@ -1,10 +1,10 @@
1
1
  source 'https://rubygems.org'
2
2
 
3
- gem "ffi"
4
- gem "bindata"
5
- gem "trollop"
6
- gem "smart_colored"
7
- gem "progressbar"
3
+ gemspec
4
+
5
+ group :development do
6
+ gem 'pry'
7
+ end
8
8
 
9
9
  # Specify your gem's dependencies in adept.gemspec
10
10
  gemspec
data/Rakefile CHANGED
@@ -1,16 +1,25 @@
1
1
  require "bundler/gem_tasks"
2
2
 
3
- task :default => [:test_offline]
3
+ task :default => :test_all
4
4
 
5
- #Offline tests only: don't perform tests that require live hardware.
6
- task :test_offline do
7
- sh "rspec -Ilib --tag=~online"
5
+ task :test_all do
6
+ sh "rspec -Ilib"
8
7
  end
9
8
 
10
- task :test do
11
- sh "rspec -Ilib"
9
+ desc 'Builds the ruby-adept gem.'
10
+ task :build do
11
+ sh "gem build ruby-adept.gemspec"
12
12
  end
13
13
 
14
- task :install_adept do
14
+ desc 'Builds and installs the ruby-adept gem.'
15
+ task :install => :build do
16
+ sh "gem install pkg/ruby-adept-#{Adept::VERSION}.gem"
17
+ end
15
18
 
19
+ desc 'Tags the current version, pushes it GitHub, and pushes the gem.'
20
+ task :release => :build do
21
+ sh "git tag v#{Adept::VERSION}"
22
+ sh "git push origin master"
23
+ sh "git push origin v#{Adept::VERSION}"
24
+ sh "git push pkg.ruby-adept-#{Adept::VERSION}.gem"
16
25
  end
data/bin/bprog CHANGED
@@ -37,10 +37,14 @@ end
37
37
  #
38
38
  # Get the currently connected device.
39
39
  #
40
- def get_target_connection(opts={})
40
+ def get_target_connection(fail_silently = false)
41
41
 
42
42
  #Ensure that we have a plugged-in board.
43
- fatal_error "It doesn't look like there's a Digilent board plugged in, on or off." if Device::connected_devices.empty?
43
+ if Device::connected_devices.empty?
44
+ fatal_error "It doesn't look like there's a Digilent board plugged in, on or off." unless fail_silently
45
+ exit
46
+ end
47
+
44
48
 
45
49
  #By default, use the first connected device.
46
50
  device = Device::open_first_connected_device
@@ -50,7 +54,12 @@ def get_target_connection(opts={})
50
54
  fatal_error "This device isn't supported." unless device.supported_connections.include?(JTAG::Connection)
51
55
 
52
56
  jtag = JTAG::Connection.new(device)
53
- fatal_error "The power switch is off on your connected board! Turn it on, and try again." if jtag.connected_devices.empty?
57
+
58
+ #Ensure that we found a supporte FPGA.
59
+ if jtag.connected_devices.empty?
60
+ fatal_error "The power switch is off on your connected board! Turn it on, and try again." unless fail_silently
61
+ exit
62
+ end
54
63
 
55
64
  jtag
56
65
 
@@ -59,16 +68,21 @@ end
59
68
  #
60
69
  # Get the target file.
61
70
  #
62
- def get_target_file(opts={})
71
+ def get_target_file(do_not_guess=false, allow_none = false)
63
72
 
64
73
  #If a file was provided on the command line, use it.
65
74
  file = ARGV.shift if ARGV
66
75
 
67
76
  #Attempt to determine the target file automagically.
68
- unless file
77
+ unless file or do_not_guess
69
78
 
70
79
  #Attempt to determine the file.
71
- file = ISE::ProjectNavigator::most_recent_project.bit_file
80
+ begin
81
+ file = ISE::ProjectNavigator::most_recent_project.bit_file
82
+ rescue
83
+ file = nil
84
+ end
85
+
72
86
  fatal_error "You didn't specify a file to program, and I couldn't figure out a likely candidate.\n Perhaps you still need to generate a programming file?" unless file
73
87
 
74
88
  #And warn the user of the file we chose.
@@ -77,27 +91,176 @@ def get_target_file(opts={})
77
91
 
78
92
  end
79
93
 
80
- fatal_error "The file you asked me to program doesn't seem to exist." unless File::exists?(file)
94
+ #If the provided file does not exist...
95
+ unless file && File::exists?(file)
96
+
97
+ #... and this is allowed, return nil.
98
+ if allow_none
99
+ return nil
100
+
101
+ #Otherwise, throw a fatal error.
102
+ end
103
+ fatal_error "The file you asked me to program doesn't seem to exist."
104
+ else
105
+
106
+ end
107
+
81
108
 
82
109
  #Return the ascertained file.
83
110
  file
84
111
 
85
112
  end
86
113
 
87
- def configure_fpga(jtag, bitfile_path)
114
+ #
115
+ # Returns the part name of the first connected FPGA,
116
+ # or nil if no FPGAs are connected.
117
+ #
118
+ def connected_fpga_part_name(jtag)
119
+
120
+ #Find the first connected FPGA.
121
+ fpga = jtag.connected_devices.find { |device| device.is_a? JTAG::Devices::FPGA }
122
+
123
+ #If we found an FPGA, return its part name. Otherwise, return nil.
124
+ return fpga ? fpga.part_name : nil
125
+
126
+ end
127
+
128
+ #
129
+ # Configures the first connected FPGA with the provided bitstream.
130
+ #
131
+ def configure_fpga(jtag, bitstream)
88
132
 
89
133
  #Find the first connected FPGA.
90
134
  fpga = jtag.connected_devices.find { |device| device.is_a? JTAG::Devices::FPGA }
91
135
  fatal_error "This board doesn't feature a supported FPGA!" unless fpga
92
136
 
93
- #Get the bit-file in question.
94
- bitstream = Adept::DataFormats::Bitstream.from_file(bitfile_path)
137
+ #If we've been provided with a string, assume it is a filename,
138
+ #and open the relevant bitfile.
139
+ if bitstream.is_a?(String)
140
+ bitstream = Adept::DataFormats::Bitstream.from_file(bitfile_path)
141
+ end
142
+
143
+ #Use the bitfile to program the device.
95
144
  fpga.configure(bitstream)
96
145
 
97
146
  end
98
147
 
99
- connection = get_target_connection
100
- file = get_target_file
148
+ #
149
+ # Displays a list of available cores.
150
+ #
151
+ def list_available_cores(compatible_with=nil, display_help=true)
152
+
153
+ #Print a short header...
154
+ puts((compatible_with ? ' Connected board supports the following' : ' Available ').bold + " cores:\n\n".bold)
155
+
156
+ #... and a list of available cores.
157
+ cores = Core.available_cores(compatible_with)
158
+ cores.each { |core| puts " #{core.shortname}:\t#{core.name}\t(#{core.targets.keys.join(", ")})" }
159
+
160
+ puts " No cores supported." if cores.empty?
161
+
162
+ #If the display_help option was set, display a short help blurb.
163
+ if display_help
164
+ puts "\n Short-names (to the left) can be used as parameters to the"
165
+ puts " --core command line flag."
166
+ end
167
+
168
+ end
169
+
170
+ #
171
+ # Merge the provided file into the specified core, and return the resultant
172
+ # bitstream.
173
+ #
174
+ def merge_file_and_core(core_name, file, target=nil)
175
+
176
+ #... try to find a core with the given name.
177
+ core = Core.from_shortname(core_name)
178
+
179
+ #If we couldn't find a core with the given name, print an error message.
180
+ unless core
181
+ fatal_error "Couldn't find a core with the name #{core_name.underline}.\n" +
182
+ "You can list all available cores with the --list-cores command line option. "
183
+ end
184
+
185
+ if file
186
+ puts "Merging".bold + " #{File.basename(file)} into the #{core.shortname} core..."
187
+ end
188
+
189
+ #Create a bitstream from the given core.
190
+ file = core.to_bitstream(target, file)
191
+
192
+ #Notify the user that programming is about to begin.
193
+ puts "Programming".bold + " the attached board with the #{core.shortname} core..."
194
+
195
+ file
196
+
197
+ end
198
+
199
+ def read_bitstream(file)
200
+ begin
201
+ Adept::DataFormats::Bitstream.from_file(file)
202
+ rescue IOError
203
+ fatal_error "You specified a file to program that wasn't a bitfile!\n" +
204
+ "(If you wanted to program this file to a processor core, use the --core <processor> option.)"
205
+ end
206
+ end
207
+
208
+ #Parse the command-line flags.
209
+ options = Trollop::options do
210
+ version "bprog #{Adept::VERSION} (c) 2013 Binghamton University"
211
+
212
+ banner <<-BANNER
213
+ bprog #{Adept::VERSION} (c) 2013 Binghamton University
214
+ Author: Kyle Temkin, ktemkin@binghamton.edu
215
+
216
+ bprog ("board programmer") is a command-line programmer for Digilent devices
217
+ intended to simplify the process of programming Digilent devices.
218
+
219
+ usage: [options] <filename>
220
+
221
+ BANNER
222
+
223
+ opt :core, "Specifies a soft-core to use. If a compiled program is provided, it will be merged into the specified core.", :type => String
224
+ opt :'list-cores', "Display a list of all available processor cores."
225
+
226
+ end
227
+
228
+ # If the list-cores option is set, list the available cores, and quit.
229
+ list_available_cores if options[:'list-cores']
230
+
231
+ # If we're using the core option, make the file argument optional,
232
+ # and do not attempt to guess it. (Options[:core] will be nil unless
233
+ # a core name is provided, and true-like otherwise.)
234
+ allow_none = do_not_guess = options[:core]
235
+
236
+ # Create a JTAG connection to the Adept board.
237
+ connection = get_target_connection(options[:'list-cores'])
238
+
239
+ # Get the name of the connected FPGA, if applicable.
240
+ part_name = connected_fpga_part_name(connection)
241
+
242
+ #If the list_available_cores flag is set, list the compatible cores,
243
+ #
244
+ #and quit.
245
+ if options[:'list-cores']
246
+ puts
247
+ puts
248
+ list_available_cores(part_name, false)
249
+ exit
250
+ end
251
+
252
+ # Get the target file, if applicable.
253
+ file = get_target_file(do_not_guess, allow_none)
254
+
255
+ # If the core option was specified, attempt to merge it with the provided
256
+ # filename. (If no filename was provided, the core's bitstream will be returned.)
257
+ if options[:core]
258
+ file = merge_file_and_core(options[:core], file, part_name)
259
+
260
+ # Otherwise, read the file as a bitstream directly.
261
+ else
262
+ file = read_bitstream(file)
263
+ end
101
264
 
102
265
  begin
103
266
  configure_fpga(connection, file)
Binary file
@@ -0,0 +1,56 @@
1
+ // BMM LOC annotation file.
2
+ //
3
+ // Release 13.4 - P.15xf, build 2.8 Mar 16, 2012
4
+ // Copyright (c) 1995-2013 Xilinx, Inc. All rights reserved.
5
+
6
+
7
+ ///////////////////////////////////////////////////////////////////////////////
8
+ //
9
+ // Processor 'avrmap', ID 0, memory map.
10
+ //
11
+ ///////////////////////////////////////////////////////////////////////////////
12
+
13
+ ADDRESS_MAP avrmap PPC405 0
14
+
15
+ ///////////////////////////////////////////////////////////////////////////////
16
+ //
17
+ // Processor 'avrmap' address space 'rom_code' 0x00000000:0x00003FFF (16 KBytes).
18
+ //
19
+ ///////////////////////////////////////////////////////////////////////////////
20
+
21
+ ADDRESS_SPACE rom_code RAMB16 [0x00000000:0x00003FFF]
22
+ BUS_BLOCK
23
+ PM_Inst/RAM_Word0 RAMB16 [15:0] [0:1023] PLACED = X1Y2;
24
+ END_BUS_BLOCK;
25
+
26
+ BUS_BLOCK
27
+ PM_Inst/RAM_Word1 RAMB16 [15:0] [1024:2047] PLACED = X0Y1;
28
+ END_BUS_BLOCK;
29
+
30
+ BUS_BLOCK
31
+ PM_Inst/RAM_Word2 RAMB16 [15:0] [2048:3071] PLACED = X0Y2;
32
+ END_BUS_BLOCK;
33
+
34
+ BUS_BLOCK
35
+ PM_Inst/RAM_Word3 RAMB16 [15:0] [3072:4095] PLACED = X1Y0;
36
+ END_BUS_BLOCK;
37
+
38
+ BUS_BLOCK
39
+ PM_Inst/RAM_Word4 RAMB16 [15:0] [4096:5119] PLACED = X1Y5;
40
+ END_BUS_BLOCK;
41
+
42
+ BUS_BLOCK
43
+ PM_Inst/RAM_Word5 RAMB16 [15:0] [5120:6143] PLACED = X1Y3;
44
+ END_BUS_BLOCK;
45
+
46
+ BUS_BLOCK
47
+ PM_Inst/RAM_Word6 RAMB16 [15:0] [6144:7167] PLACED = X1Y4;
48
+ END_BUS_BLOCK;
49
+
50
+ BUS_BLOCK
51
+ PM_Inst/RAM_Word7 RAMB16 [15:0] [7168:8191] PLACED = X1Y1;
52
+ END_BUS_BLOCK;
53
+ END_ADDRESS_SPACE;
54
+
55
+ END_ADDRESS_MAP;
56
+
@@ -0,0 +1,11 @@
1
+ name: ATMega103-compatible AVR
2
+ shortname: atmega103
3
+ version: 1.0
4
+ targets:
5
+
6
+ #Spartan 3E 250K-gate
7
+ 3s250ecp132:
8
+ bit_file: avr_250k.bit
9
+ memory_map: avr_250k.bmm
10
+
11
+
@@ -26,7 +26,7 @@
26
26
  <association xil_pn:name="PostTranslateSimulation" xil_pn:seqID="5"/>
27
27
  </file>
28
28
  <file xil_pn:name="epp_controller.vhd" xil_pn:type="FILE_VHDL">
29
- <association xil_pn:name="BehavioralSimulation" xil_pn:seqID="12"/>
29
+ <association xil_pn:name="BehavioralSimulation" xil_pn:seqID="0"/>
30
30
  <association xil_pn:name="Implementation" xil_pn:seqID="1"/>
31
31
  </file>
32
32
  <file xil_pn:name="Basys2_100_250General.ucf" xil_pn:type="FILE_UCF">
@@ -181,7 +181,7 @@
181
181
  <property xil_pn:name="Optimization Strategy (Cover Mode)" xil_pn:value="Area" xil_pn:valueState="default"/>
182
182
  <property xil_pn:name="Optimize Instantiated Primitives" xil_pn:value="false" xil_pn:valueState="default"/>
183
183
  <property xil_pn:name="Other Bitgen Command Line Options" xil_pn:value="" xil_pn:valueState="default"/>
184
- <property xil_pn:name="Other Compiler Options" xil_pn:value="" xil_pn:valueState="default"/>
184
+ <property xil_pn:name="Other Compiler Options" xil_pn:value="-mt off -v 1" xil_pn:valueState="non-default"/>
185
185
  <property xil_pn:name="Other Compiler Options Map" xil_pn:value="" xil_pn:valueState="default"/>
186
186
  <property xil_pn:name="Other Compiler Options Par" xil_pn:value="" xil_pn:valueState="default"/>
187
187
  <property xil_pn:name="Other Compiler Options Translate" xil_pn:value="" xil_pn:valueState="default"/>
@@ -256,8 +256,8 @@
256
256
  <property xil_pn:name="Run for Specified Time Translate" xil_pn:value="true" xil_pn:valueState="default"/>
257
257
  <property xil_pn:name="Safe Implementation" xil_pn:value="No" xil_pn:valueState="default"/>
258
258
  <property xil_pn:name="Security" xil_pn:value="Enable Readback and Reconfiguration" xil_pn:valueState="default"/>
259
- <property xil_pn:name="Selected Module Instance Name" xil_pn:value="/TopLevel" xil_pn:valueState="non-default"/>
260
- <property xil_pn:name="Selected Simulation Root Source Node Behavioral" xil_pn:value="work.TopLevel" xil_pn:valueState="non-default"/>
259
+ <property xil_pn:name="Selected Module Instance Name" xil_pn:value="/fifo_testbench" xil_pn:valueState="non-default"/>
260
+ <property xil_pn:name="Selected Simulation Root Source Node Behavioral" xil_pn:value="work.fifo_testbench" xil_pn:valueState="non-default"/>
261
261
  <property xil_pn:name="Selected Simulation Root Source Node Post-Map" xil_pn:value="" xil_pn:valueState="default"/>
262
262
  <property xil_pn:name="Selected Simulation Root Source Node Post-Route" xil_pn:value="" xil_pn:valueState="default"/>
263
263
  <property xil_pn:name="Selected Simulation Root Source Node Post-Translate" xil_pn:value="" xil_pn:valueState="default"/>
@@ -273,7 +273,7 @@
273
273
  <property xil_pn:name="Slice Packing" xil_pn:value="true" xil_pn:valueState="default"/>
274
274
  <property xil_pn:name="Slice Utilization Ratio" xil_pn:value="100" xil_pn:valueState="default"/>
275
275
  <property xil_pn:name="Specify 'define Macro Name and Value" xil_pn:value="" xil_pn:valueState="default"/>
276
- <property xil_pn:name="Specify Top Level Instance Names Behavioral" xil_pn:value="work.TopLevel" xil_pn:valueState="default"/>
276
+ <property xil_pn:name="Specify Top Level Instance Names Behavioral" xil_pn:value="work.fifo_testbench" xil_pn:valueState="default"/>
277
277
  <property xil_pn:name="Specify Top Level Instance Names Post-Map" xil_pn:value="Default" xil_pn:valueState="default"/>
278
278
  <property xil_pn:name="Specify Top Level Instance Names Post-Route" xil_pn:value="Default" xil_pn:valueState="default"/>
279
279
  <property xil_pn:name="Specify Top Level Instance Names Post-Translate" xil_pn:value="Default" xil_pn:valueState="default"/>
data/lib/adept.rb CHANGED
@@ -9,3 +9,4 @@ require 'adept/connection_provider'
9
9
  require 'adept/jtag'
10
10
 
11
11
  require 'adept/boards'
12
+ require 'adept/core'
data/lib/adept/core.rb ADDED
@@ -0,0 +1,148 @@
1
+ require 'adept'
2
+ require 'yaml'
3
+ require 'tempfile'
4
+
5
+ module Adept
6
+
7
+
8
+ #
9
+ # Class which represents a data-2-mem configurable IP core.
10
+ #
11
+ class Core
12
+
13
+ attr_reader :name
14
+ attr_reader :targets
15
+ attr_reader :shortname
16
+
17
+ #
18
+ # Returns a list of all available cores, optionally filtered by a device ID string.
19
+ #
20
+ def self.available_cores(device=nil)
21
+
22
+ #Determine the path at which the ruby-adept gem is stored.
23
+ gem_path = File.expand_path('../..', File.dirname(__FILE__))
24
+
25
+ #Get a list of all available core definition files.
26
+ core_definitions = Dir["#{gem_path}/cores/**/core.yaml"]
27
+
28
+ #Convert each definition to a YAML core.
29
+ definitions = core_definitions.map { |file| from_definition_file(file) }
30
+
31
+ #If we were passed a device shortname to filter by, ensure we
32
+ #only return cores that support that target.
33
+ unless device.nil?
34
+ definitions = definitions.select { |core| core.targets.include?(device) }
35
+ end
36
+
37
+ definitions
38
+
39
+ end
40
+
41
+ #
42
+ # Returns the core with the given shortname, or nil if no
43
+ # such core exists.
44
+ #
45
+ def self.from_shortname(shortname)
46
+ available_cores.find { |core| core.shortname == shortname }
47
+ end
48
+
49
+ #
50
+ # Creates a new Core object from a YAML definition file.
51
+ #
52
+ # file: The full path to a YAML core definition file.
53
+ #
54
+ def self.from_definition_file(file)
55
+
56
+ #Get the path of the directory that holds the core's files.
57
+ base_path = File.dirname(file)
58
+
59
+ #Parse the YAML definition file.
60
+ raw_definition = YAML.load_file(file)
61
+
62
+ #Return a new core object.
63
+ new(raw_definition["name"], raw_definition["shortname"], base_path, raw_definition["targets"])
64
+
65
+ end
66
+
67
+ #
68
+ # Initializes a new instance of a Core object.
69
+ #
70
+ def initialize(name, shortname, base_path, targets)
71
+ @name = name
72
+ @shortname = shortname
73
+ @base_path = base_path
74
+ @targets = targets
75
+ end
76
+
77
+ #
78
+ # Returns a bitstream which can be use to load the given core onto the target
79
+ # device. If a program is provided, it will be loaded into the resultant bitstream.
80
+ #
81
+ # target: The Device ID string of the board to be programmed.
82
+ #
83
+ def to_bitstream(target=@targets.keys.first, program=nil)
84
+
85
+ #Ensure the target is a string.
86
+ target = target.to_s
87
+
88
+ #Get the path to the bitfile and memory map which will be used to generate the new bitfile.
89
+ memory_map = "#@base_path/#{@targets[target]['memory_map']}"
90
+ bit_file = "#@base_path/#{@targets[target]['bit_file']}"
91
+
92
+ #If no program was provided, return the bitfile unmodified.
93
+ return Adept::DataFormats::Bitstream.from_file(bit_file) unless program
94
+
95
+ #Generate the new raw bitfile...
96
+ hex = with_temporary_files { |dest, _| system("avr-objcopy -O ihex -R .eeprom -R .fuse -R .lock #{program} #{dest}") }
97
+ mem = with_temporary_files(hex, '.mem', '.hex') { |dest, source| system("srec_cat #{source} -Intel -Byte_Swap 2 -Data_Only -Line_Length 100000000 -o #{dest} -vmem 8") }
98
+ bit = with_temporary_files(mem, '.bit', '.mem') { |dest, source| system("data2mem -bm #{memory_map} -bt #{bit_file} -bd #{source} -o b #{dest}") }
99
+
100
+ #... wrap it in a Bitstream object, and return it.
101
+ Adept::DataFormats::Bitstream.from_string(bit)
102
+
103
+ end
104
+
105
+ #
106
+ # Print a debugging represntation of the core.
107
+ #
108
+ def inspect
109
+ "<IP Core 0x#{object_id.to_s(16)}: #@name>"
110
+ end
111
+
112
+ private
113
+
114
+ #
115
+ # Executes a given block with an "anonymous" temporary file.
116
+ # The temporary file is deleted at the end of the block, and its contents
117
+ # are returned.
118
+ #
119
+ def with_temporary_files(file_contents='', dest_extension = '', source_extension = '', message=nil)
120
+
121
+ #File mode for all of the created temporary files.
122
+ #Create the files, and allow read/write, but do not lock for exclusive access.
123
+ file_mode = File::CREAT | File::RDWR
124
+
125
+ #Create a new file which contains the provided file content.
126
+ #Used to pass arbitrary data into an external tool.
127
+ Tempfile.open(['core_prev', source_extension], :mode => file_mode) do |source_file|
128
+
129
+ #Fill the source file with the provided file contents...
130
+ source_file.write(file_contents)
131
+ source_file.flush
132
+
133
+ #Create a new file which will store the resultant file content.
134
+ Tempfile.open(['core_next', dest_extension], :mode => file_mode) do |destination_file|
135
+
136
+ #Yield the file's paths the provided block.
137
+ raise CommandFailedError, message unless yield [destination_file.path, source_file.path]
138
+
139
+ #And return the content of the destination file.
140
+ return File::read(destination_file)
141
+
142
+ end
143
+
144
+ end
145
+ end
146
+
147
+ end
148
+ end
data/lib/adept/error.rb CHANGED
@@ -1,4 +1,6 @@
1
1
  module Adept
2
2
  class Error < StandardError; end
3
3
  class CommunicationError < Error; end
4
+ class CommandFailedError < Error; end
5
+ class UnsupportedDeviceError < Error; end
4
6
  end
@@ -161,6 +161,8 @@ module Adept
161
161
  #
162
162
  def self.idcode_matches_mask(mask, idcode)
163
163
 
164
+ return false if idcode.nil?
165
+
164
166
  #Convert the IDcode into a string, for comparison.
165
167
  idcode = idcode.unpack("H*").first.downcase
166
168
 
data/lib/adept/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Adept
2
- VERSION = "0.0.1"
2
+ VERSION = "1.0.0"
3
3
  end
@@ -15,16 +15,16 @@ Gem::Specification.new do |gem|
15
15
  gem.summary = "Framework for working with Digilent Adept devices."
16
16
  gem.homepage = "http://www.github.com/ktemkin/ruby-adept"
17
17
 
18
- gem.add_runtime_dependency 'bindata'
18
+ gem.add_runtime_dependency 'bindata', '~>1.4.5'
19
+ gem.add_runtime_dependency 'ffi', '~>1.3.1'
20
+ gem.add_runtime_dependency 'require_all', '~>1.2.1'
21
+ gem.add_runtime_dependency 'smart_colored', '~>1.1.1'
22
+ gem.add_runtime_dependency 'trollop', '~>2.0'
23
+ gem.add_runtime_dependency 'ruby-elf', '~>1.0.8'
19
24
  gem.add_runtime_dependency 'ruby-ise'
20
- gem.add_runtime_dependency 'trollop'
21
- gem.add_runtime_dependency 'smart_colored'
22
- gem.add_runtime_dependency 'ffi'
23
- gem.add_runtime_dependency 'require_all'
24
-
25
- gem.add_development_dependency 'rspec'
26
- gem.add_development_dependency 'fakefs'
27
25
 
26
+ gem.add_development_dependency 'rspec', '~>2.12.0'
27
+ gem.add_development_dependency 'fakefs', '~>0.4.2'
28
28
 
29
29
  gem.files = `git ls-files`.split($/)
30
30
  gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
@@ -0,0 +1,58 @@
1
+
2
+ require 'adept'
3
+
4
+ #
5
+ # Specification for the Adept Device interface.
6
+ # These tests assume _only_ one connected Basys2 board!
7
+ #
8
+ describe Adept::Core do
9
+
10
+ let(:avr8) { 'ATMega103-compatible AVR' }
11
+
12
+ #
13
+ # Matcher which returns true if the given list contains the AVR-8.
14
+ #
15
+ RSpec::Matchers.define :include_a_core_named do |expected|
16
+ match do |given|
17
+ given.find { |core| core.name == expected }
18
+ end
19
+
20
+ failure_message_for_should { |given| "expected #{actual.inspect} to contain a core named '#{expected}'" }
21
+ failure_message_for_should_not { |given| "expected #{actual.inspect} to not contain a core named '#{expected}'" }
22
+ end
23
+
24
+
25
+ describe "class methods" do
26
+
27
+ describe "#available_cores" do
28
+ subject { Adept::Core }
29
+
30
+ it "should return an array of known cores" do
31
+
32
+ #Get a list of all available cores...
33
+ cores = subject.available_cores
34
+
35
+ #... and validate their types.
36
+ cores.should be_an Array
37
+ cores.all? { |x| x.should be_a Adept::Core}
38
+
39
+ end
40
+
41
+ context "when provided with a device name" do
42
+ it "should return only the cores that correspond to that device name" do
43
+ subject.available_cores('invalidDevice').should_not include_a_core_named avr8
44
+ end
45
+ end
46
+
47
+ context "when a device name is not provided" do
48
+ it "should return all known cores as core objects" do
49
+ subject.available_cores('3s250ecp132').should include_a_core_named avr8
50
+ end
51
+ end
52
+
53
+ end
54
+
55
+ end
56
+
57
+ end
58
+
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ruby-adept
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 1.0.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,90 +9,106 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-01-29 00:00:00.000000000 Z
12
+ date: 2013-03-18 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: bindata
16
16
  requirement: !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
- - - ! '>='
19
+ - - ~>
20
20
  - !ruby/object:Gem::Version
21
- version: '0'
21
+ version: 1.4.5
22
22
  type: :runtime
23
23
  prerelease: false
24
24
  version_requirements: !ruby/object:Gem::Requirement
25
25
  none: false
26
26
  requirements:
27
- - - ! '>='
27
+ - - ~>
28
28
  - !ruby/object:Gem::Version
29
- version: '0'
29
+ version: 1.4.5
30
30
  - !ruby/object:Gem::Dependency
31
- name: ruby-ise
31
+ name: ffi
32
32
  requirement: !ruby/object:Gem::Requirement
33
33
  none: false
34
34
  requirements:
35
- - - ! '>='
35
+ - - ~>
36
36
  - !ruby/object:Gem::Version
37
- version: '0'
37
+ version: 1.3.1
38
38
  type: :runtime
39
39
  prerelease: false
40
40
  version_requirements: !ruby/object:Gem::Requirement
41
41
  none: false
42
42
  requirements:
43
- - - ! '>='
43
+ - - ~>
44
44
  - !ruby/object:Gem::Version
45
- version: '0'
45
+ version: 1.3.1
46
46
  - !ruby/object:Gem::Dependency
47
- name: trollop
47
+ name: require_all
48
48
  requirement: !ruby/object:Gem::Requirement
49
49
  none: false
50
50
  requirements:
51
- - - ! '>='
51
+ - - ~>
52
52
  - !ruby/object:Gem::Version
53
- version: '0'
53
+ version: 1.2.1
54
54
  type: :runtime
55
55
  prerelease: false
56
56
  version_requirements: !ruby/object:Gem::Requirement
57
57
  none: false
58
58
  requirements:
59
- - - ! '>='
59
+ - - ~>
60
60
  - !ruby/object:Gem::Version
61
- version: '0'
61
+ version: 1.2.1
62
62
  - !ruby/object:Gem::Dependency
63
63
  name: smart_colored
64
64
  requirement: !ruby/object:Gem::Requirement
65
65
  none: false
66
66
  requirements:
67
- - - ! '>='
67
+ - - ~>
68
68
  - !ruby/object:Gem::Version
69
- version: '0'
69
+ version: 1.1.1
70
70
  type: :runtime
71
71
  prerelease: false
72
72
  version_requirements: !ruby/object:Gem::Requirement
73
73
  none: false
74
74
  requirements:
75
- - - ! '>='
75
+ - - ~>
76
76
  - !ruby/object:Gem::Version
77
- version: '0'
77
+ version: 1.1.1
78
78
  - !ruby/object:Gem::Dependency
79
- name: ffi
79
+ name: trollop
80
80
  requirement: !ruby/object:Gem::Requirement
81
81
  none: false
82
82
  requirements:
83
- - - ! '>='
83
+ - - ~>
84
84
  - !ruby/object:Gem::Version
85
- version: '0'
85
+ version: '2.0'
86
86
  type: :runtime
87
87
  prerelease: false
88
88
  version_requirements: !ruby/object:Gem::Requirement
89
89
  none: false
90
90
  requirements:
91
- - - ! '>='
91
+ - - ~>
92
92
  - !ruby/object:Gem::Version
93
- version: '0'
93
+ version: '2.0'
94
94
  - !ruby/object:Gem::Dependency
95
- name: require_all
95
+ name: ruby-elf
96
+ requirement: !ruby/object:Gem::Requirement
97
+ none: false
98
+ requirements:
99
+ - - ~>
100
+ - !ruby/object:Gem::Version
101
+ version: 1.0.8
102
+ type: :runtime
103
+ prerelease: false
104
+ version_requirements: !ruby/object:Gem::Requirement
105
+ none: false
106
+ requirements:
107
+ - - ~>
108
+ - !ruby/object:Gem::Version
109
+ version: 1.0.8
110
+ - !ruby/object:Gem::Dependency
111
+ name: ruby-ise
96
112
  requirement: !ruby/object:Gem::Requirement
97
113
  none: false
98
114
  requirements:
@@ -112,33 +128,33 @@ dependencies:
112
128
  requirement: !ruby/object:Gem::Requirement
113
129
  none: false
114
130
  requirements:
115
- - - ! '>='
131
+ - - ~>
116
132
  - !ruby/object:Gem::Version
117
- version: '0'
133
+ version: 2.12.0
118
134
  type: :development
119
135
  prerelease: false
120
136
  version_requirements: !ruby/object:Gem::Requirement
121
137
  none: false
122
138
  requirements:
123
- - - ! '>='
139
+ - - ~>
124
140
  - !ruby/object:Gem::Version
125
- version: '0'
141
+ version: 2.12.0
126
142
  - !ruby/object:Gem::Dependency
127
143
  name: fakefs
128
144
  requirement: !ruby/object:Gem::Requirement
129
145
  none: false
130
146
  requirements:
131
- - - ! '>='
147
+ - - ~>
132
148
  - !ruby/object:Gem::Version
133
- version: '0'
149
+ version: 0.4.2
134
150
  type: :development
135
151
  prerelease: false
136
152
  version_requirements: !ruby/object:Gem::Requirement
137
153
  none: false
138
154
  requirements:
139
- - - ! '>='
155
+ - - ~>
140
156
  - !ruby/object:Gem::Version
141
- version: '0'
157
+ version: 0.4.2
142
158
  description: ! "Ruby library for working with Digilent devices via the Adept SDK.\n
143
159
  \ Provides both low-level wrappers for the Adept SDK elements and high-level\n
144
160
  \ interfaces, including simple programming and configuration routines."
@@ -155,9 +171,11 @@ files:
155
171
  - LICENSE.txt
156
172
  - README.md
157
173
  - Rakefile
158
- - adept.gemspec
159
174
  - autotest/discover.rb
160
175
  - bin/bprog
176
+ - cores/avr8/avr_250k.bit
177
+ - cores/avr8/avr_250k.bmm
178
+ - cores/avr8/core.yaml
161
179
  - firmware/.gitignore
162
180
  - firmware/epp_stream/Basys2_100_250General.ucf
163
181
  - firmware/epp_stream/epp_controller.vhd
@@ -168,6 +186,7 @@ files:
168
186
  - lib/adept/boards.rb
169
187
  - lib/adept/boards/basys2.rb
170
188
  - lib/adept/connection_provider.rb
189
+ - lib/adept/core.rb
171
190
  - lib/adept/data_formats.rb
172
191
  - lib/adept/data_formats/bitstream.rb
173
192
  - lib/adept/data_formats/data_factories.rb
@@ -193,7 +212,9 @@ files:
193
212
  - lib/adept/low_level/jtag.rb
194
213
  - lib/adept/low_level/library.rb
195
214
  - lib/adept/version.rb
215
+ - ruby-adept.gemspec
196
216
  - spec/firmware/epp_loopback.bit
217
+ - spec/lib/adept/core_spec.rb
197
218
  - spec/lib/adept/data_formats/bitstream_spec.rb
198
219
  - spec/lib/adept/data_formats/data_factories_spec.rb
199
220
  - spec/lib/adept/device_spec.rb
@@ -229,6 +250,7 @@ specification_version: 3
229
250
  summary: Framework for working with Digilent Adept devices.
230
251
  test_files:
231
252
  - spec/firmware/epp_loopback.bit
253
+ - spec/lib/adept/core_spec.rb
232
254
  - spec/lib/adept/data_formats/bitstream_spec.rb
233
255
  - spec/lib/adept/data_formats/data_factories_spec.rb
234
256
  - spec/lib/adept/device_spec.rb