Class: OrigenSpi::Driver
- Inherits:
-
Object
- Object
- OrigenSpi::Driver
- Includes:
- Origen::Model
- Defined in:
- lib/origen_spi/driver.rb
Instance Attribute Summary collapse
-
#clk_format ⇒ Object
clock format.
-
#clk_multiple ⇒ Object
number of tester cycles per spi clock.
-
#clk_wait_time ⇒ Object
time between ss_active and the first spi clock.
-
#data_order ⇒ Object
data order.
-
#miso_compare_cycle ⇒ Object
cycle on which miso compares are placed (0 is the first cycle).
-
#miso_pin ⇒ Object
Dut pin that serves as the master in slave out.
-
#mosi_pin ⇒ Object
Dut pin that serves as the master out slave in pin.
-
#sclk_pin ⇒ Object
Dut pin that serves as the spi clock.
-
#settings_validated ⇒ Object
readonly
internal attribute.
-
#ss_active ⇒ Object
pin state corresponding to slave select active.
-
#ss_pin ⇒ Object
Dut pin that serves as the slave select.
Instance Method Summary collapse
-
#build_input_packet(options) ⇒ Object
Build the input packet.
-
#build_output_packet(options) ⇒ Object
Build the shift out packet.
-
#cycle(overlay_options = {}) ⇒ Object
Internal method.
-
#handle_miso(c, bit) ⇒ Object
Internal method.
-
#initialize(options = {}) ⇒ Driver
constructor
options hash can configure.
-
#sclk_cycle ⇒ Object
Run a spi clock cycle.
-
#shift(options = {}) ⇒ Object
Shift a spi packet.
-
#validate_options(options) ⇒ Object
Internal method that logs errors in options passed to the shift method.
-
#validate_settings ⇒ Object
Check settings.
Constructor Details
#initialize(options = {}) ⇒ Driver
options hash can configure
87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 |
# File 'lib/origen_spi/driver.rb', line 87 def initialize( = {}) = { sclk_pin: nil, mosi_pin: nil, miso_pin: nil, ss_pin: nil, clk_format: :nr, ss_active: 0, clk_wait_time: { time_in_us: 0 }, clk_multiple: 2, data_order: :msb0 }.merge() @sclk_pin = [:sclk_pin] @mosi_pin = [:mosi_pin] @miso_pin = [:miso_pin] @ss_pin = [:ss_pin] @clk_format = [:clk_format] @ss_active = [:ss_active] @clk_wait_time = [:clk_wait_time] @clk_multiple = [:clk_multiple] @miso_compare_cycle = [:miso_compare_cycle] ? [:miso_compare_cycle] : @clk_multiple - 1 @data_order = [:data_order] @settings_validated = false end |
Instance Attribute Details
#clk_format ⇒ Object
clock format
available options are:
:rl # return low - data changes while sclk is low, latches on rising edge
:rh # return high
35 36 37 |
# File 'lib/origen_spi/driver.rb', line 35 def clk_format @clk_format end |
#clk_multiple ⇒ Object
number of tester cycles per spi clock
53 54 55 |
# File 'lib/origen_spi/driver.rb', line 53 def clk_multiple @clk_multiple end |
#clk_wait_time ⇒ Object
time between ss_active and the first spi clock
hash containing the wait time
50 51 52 |
# File 'lib/origen_spi/driver.rb', line 50 def clk_wait_time @clk_wait_time end |
#data_order ⇒ Object
data order
available options are:
:msb0 - MSB is shifted first
:lsb0
66 67 68 |
# File 'lib/origen_spi/driver.rb', line 66 def data_order @data_order end |
#miso_compare_cycle ⇒ Object
cycle on which miso compares are placed (0 is the first cycle)
56 57 58 |
# File 'lib/origen_spi/driver.rb', line 56 def miso_compare_cycle @miso_compare_cycle end |
#miso_pin ⇒ Object
Dut pin that serves as the master in slave out
18 19 20 |
# File 'lib/origen_spi/driver.rb', line 18 def miso_pin @miso_pin end |
#mosi_pin ⇒ Object
Dut pin that serves as the master out slave in pin
13 14 15 |
# File 'lib/origen_spi/driver.rb', line 13 def mosi_pin @mosi_pin end |
#sclk_pin ⇒ Object
Dut pin that serves as the spi clock
8 9 10 |
# File 'lib/origen_spi/driver.rb', line 8 def sclk_pin @sclk_pin end |
#settings_validated ⇒ Object (readonly)
internal attribute
69 70 71 |
# File 'lib/origen_spi/driver.rb', line 69 def settings_validated @settings_validated end |
#ss_active ⇒ Object
pin state corresponding to slave select active
40 41 42 |
# File 'lib/origen_spi/driver.rb', line 40 def ss_active @ss_active end |
#ss_pin ⇒ Object
Dut pin that serves as the slave select
25 26 27 |
# File 'lib/origen_spi/driver.rb', line 25 def ss_pin @ss_pin end |
Instance Method Details
#build_input_packet(options) ⇒ Object
Build the input packet
This is an internal method used by the shift method
333 334 335 336 337 338 339 340 341 342 343 344 |
# File 'lib/origen_spi/driver.rb', line 333 def build_input_packet() in_reg = Origen::Registers::Reg.dummy([:size]) if [:master_in].respond_to?(:data) in_reg.copy_all([:master_in]) else unless [:master_in].nil? in_reg.write [:master_in] in_reg.read end end in_reg end |
#build_output_packet(options) ⇒ Object
Build the shift out packet
This is an internal method used by the shift method
320 321 322 323 324 325 326 327 328 |
# File 'lib/origen_spi/driver.rb', line 320 def build_output_packet() out_reg = Origen::Registers::Reg.dummy([:size]) if [:master_out].respond_to?(:data) out_reg.copy_all([:master_out]) else out_reg.write [:master_out] end out_reg end |
#cycle(overlay_options = {}) ⇒ Object
Internal method
Issue a tester cycle, conditionally with overlay options supplied
313 314 315 |
# File 'lib/origen_spi/driver.rb', line 313 def cycle( = {}) == {} ? tester.cycle : (tester.cycle overlay: ) end |
#handle_miso(c, bit) ⇒ Object
Internal method
Set the state of miso
299 300 301 302 303 304 305 306 307 308 |
# File 'lib/origen_spi/driver.rb', line 299 def handle_miso(c, bit) unless @miso_pin.nil? if c == @miso_compare_cycle @miso_pin.assert bit.data if bit.is_to_be_read? tester.store_next_cycle @miso_pin if bit.is_to_be_stored? else @miso_pin.dont_care end end end |
#sclk_cycle ⇒ Object
Run a spi clock cycle
This method can be used to clock the spi port without specifying shift data
213 214 215 216 217 218 219 220 221 222 |
# File 'lib/origen_spi/driver.rb', line 213 def sclk_cycle validate_settings cc 'OrigenSpi::Driver - Issue a clock cycle' @sclk_pin.restore_state do @sclk_pin.drive @clk_format == :rl ? 0 : 1 @half_cycle.times { tester.cycle } @sclk_pin.drive @clk_format == :rl ? 1 : 0 @half_cycle.upto(@clk_multiple - 1) { tester.cycle } end end |
#shift(options = {}) ⇒ Object
Shift a spi packet
Overlay and capture is specified through reg.overlay and reg.store
234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 |
# File 'lib/origen_spi/driver.rb', line 234 def shift( = {}) = { master_out: 0 }.merge() validate_settings = () out_reg = build_output_packet().bits in_reg = build_input_packet().bits # reverse bit order if :msb0 if @data_order == :msb0 out_reg = out_reg.reverse in_reg = in_reg.reverse end # set ss active @ss_pin.drive @ss_active unless @ss_pin.nil? # apply wait time if requested tester.wait @clk_wait_time unless @clk_wait_time == { time_in_us: 0 } # now do the shifting 0.upto(out_reg.size - 1) do |bit| # park the clock @sclk_pin.drive @clk_format == :rl ? 0 : 1 @miso_pin.dont_care unless @miso_pin.nil? # setup the bit to be driven, prep for overlay if requested = {} unless @mosi_pin.nil? @mosi_pin.drive out_reg[bit].data if out_reg[bit]. [:pins] = @mosi_pin [:overlay_str] = out_reg[bit]. end end # advance to clock active edge @half_cycle.times do |c| handle_miso c, in_reg[bit] cycle [:change_data] = false unless == {} end # drive the clock to active @sclk_pin.drive @clk_format == :rl ? 1 : 0 # advance to the end of the sclk cycle checking for appropriate miso compare placement @half_cycle.upto(@clk_multiple - 1) do |c| handle_miso c, in_reg[bit] cycle end end # park the clock, mask miso, clear ss @sclk_pin.drive @clk_format == :rl ? 0 : 1 @miso_pin.dont_care unless @miso_pin.nil? @mosi_pin.drive 0 unless @mosi_pin.nil? @ss_pin.drive @ss_active == 1 ? 0 : 1 unless @ss_pin.nil? end |
#validate_options(options) ⇒ Object
Internal method that logs errors in options passed to the shift method
347 348 349 350 351 352 353 354 355 356 357 358 359 360 |
# File 'lib/origen_spi/driver.rb', line 347 def () # check that size of the packet can be determined unless [:size] [:size] = [:master_in].size if [:master_in].respond_to?(:data) end unless [:size] [:size] = [:master_out].size if [:master_out].respond_to?(:data) end unless [:size] Origen.log.error "OrigenSpi::Driver can't determine the packet size" exit end end |
#validate_settings ⇒ Object
Check settings
176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 |
# File 'lib/origen_spi/driver.rb', line 176 def validate_settings unless @settings_validated settings_valid = true # check that clock and miso are provided unless @sclk_pin.is_a?(Origen::Pins::Pin) settings_valid = false Origen.log.error 'OrigenSpi::Driver.sclk_pin must be an Origen pin object' end unless @clk_format == :rl || @clk_format == :rh settings_valid = false Origen.log.error 'OrigenSpi::Driver.clk_format must be one of :rl, :rh' end unless @ss_active == 0 || @ss_active == 1 settings_valid = false Origen.log.error 'OrigenSpi::Driver.ss_active must be either 0 or 1' end @clk_multiple = 1 if @clk_multiple < 1 @half_cycle = @clk_multiple / 2 @miso_compare_cycle = @clk_multiple - 1 if @miso_compare_cycle > @clk_multiple - 1 unless @data_order == :msb0 || @data_order == :lsb0 settings_valid = false Origen.log.error 'OrigenSpi::Driver.data_order must be either :msb0 or :lsb0' end @settings_validated = settings_valid end end |