ruby-adept 0.0.1 → 1.0.0

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.
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