Skip to content

cjhdev/ruby-ppk2

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

PPK2

Interface with the PPK2 in style on Linux and Mac.

This is third party software. The official software is pc-nrfconnect-ppk.

PPK2 Front

Why?

This is useful if you use Ruby to orchestrate hardware test.

Install

Add this library and a version of serialport to your Gemfile:

gem 'ppk2', git: 'https://github.com/cjhdev/ruby-ppk2'
gem 'serialport'

Use bundler to install, then require the library:

require 'ppk2'

Examples

Create an instance of driver

Connect to the first recognisable PPK2 on the system:

driver = PPK2.new

# ...

driver.close

Same, but use a block to manage the lifetime of the driver:

PPK2.new do |driver|

  # ...

end

Same, but specify which PPK2 to connect to if you are on Mac or have more than one plugged into your Linux machine:

PPK2.new("/dev/ttyACM0") do |driver|

  # ...

end

Any of the above, but with logging to stdout:

PPK2.new(logger: Logger.new(STDOUT)) do

  # ...

end

Configure SMU or AMP Mode

PPK2 is either in SMU or AMP mode. The circuit diagram on the silkscreen illustrates what this means.

The initial configuration depends on PPK2 memory.

PPK2.new do |driver|

  # enable SMU mode (disable AMP mode)
  driver.smu_on

  # puts true (SMU mode is enabled)
  puts driver.smu_is_on?

  # disable SMU mode (enable AMP mode)
  driver.smu_off

  # puts false (SMU mode is disabled)
  puts driver.smu_is_on?

end

Configure Internal Voltage Source

The PPK2 internal voltage source can be configured in the range 0.8V to 5.0V.

In SMU mode, this will be the voltage applied to the VOUT pin.

The initial configuration depends on PPK2 memory.

PPK2.new do |driver|

  # set the source voltage to 4 volts
  driver.vdd = 4

  # read back 4 volts
  puts driver.vdd

  # set again, outside of allowable range
  driver.vdd = 0

  # read back 0.8 volts (clamped to minimum)
  puts driver.vdd

  # set again, outside of allowable range
  driver.vdd = 5.5

  # read back 5 volts (clamped to maximum)
  puts driver.vdd

end

DUT Switch

PPK2 has a switch between the ammeter and the VOUT pin.

Initial configuration is open (i.e. #dut_off).

The method #close always calls #dut_off.

PPK2.new do |driver|

  # open switch
  driver.dut_off

  # puts false (switch is open)
  puts driver.dut_is_on?

  # close switch
  driver.dut_on

  # puts true  (switch is closed)
  puts driver.dut_is_on?

Start and Stop Measurement Stream

When measurement is enabled, a series of measurements will be read, scaled, spike filtered, and then pushed to the application via the block assigned to PPK2#on_output.

The PPK2 hardware sample rate is 100KHz.

The application code running in the #on_output can block the thread as required, but be aware that there is a queue inside the driver instance that will grow as the measurements back up.

The initial configuration is off (i.e. #measure_off).

The method #close always calls #measure_off.

Note that PPK2 instance rescues any exceptions that occur in PPK2#on_output.

PPK2.new do |driver|

  driver.vdd = 4.5
  driver.smu_on
  driver.dut_on

  driver.on_output do |measurement|

    # access stream of measurements here

  end

  driver.measure_on

  # wait while measurements are produced
  sleep 10

  # note. this will block until all queued measurements make their way to on_output
  driver.measure_off

  # a counter for the number of measurements received
  puts driver.count

  # a counter for the number of measurements that appear to be missing from the sequence
  # normally this will read 0
  puts driver.missing

end

Measurement Processing

Measurements are instances of PPK2::Measurement:

Measurement = Struct.new(:current, :range, :counter, :logic, keyword_init: true)
  • current is current in Amperes
  • range is the active measurement range
  • counter counts from 0 from when #measure_on is called, does not overflow
  • logic single byte where each bit represets the state of the logic port

Some basic processing features are provided. These can be plumbed in via the PPK2#on_output block.

PPK2::MovingAverage

Calculate a moving average from measurements stored in RAM.

PPK2.new do |driver|

  driver.vdd = 4.5
  driver.smu_on
  driver.dut_on

  # a 5 second moving average
  result = PPK2::MovingAverage.new(5)

  driver.on_output do |m|

    result.input(m)

  end

  driver.measure_on

  sleep 5

  driver.measure_off

  puts result.average
  puts result.min
  puts result.max

end

PPK2::FileStore

Save measurements to file in CSV format. The measurements are saved as they become available.

PPK2.new do |driver|

  driver.vdd = 4.5
  driver.smu_on
  driver.dut_on

  # Note that the first line will contain a description of the columns:
  #
  # "counter,current,range,d7,d6,d5,d4,d3,d2,d1,d0"
  #
  store = PPK2::FileStore.new("your_data.csv")

  driver.on_output do |m|

    store.input(m)

  end

  driver.measure_on

  sleep 5

  driver.measure_off

  store.close

end

Asserting DUT Behavior

Bringing everything together, it is possible to use minitest to assert that a DUT is working as expected.

require 'minitest/spec'
require 'ppk2'

describe "average current consumption after startup" do

  let(:driver){PPK2.new}

  let(:avg){PPK2::MovingAverage.new(interval)}

  let(:interval){10}

  before do

    driver.vdd = 4.5
    driver.smu_on
    driver.dut_on

    driver.on_output do |m|

      avg.input(m)

    end

    driver.measure_on

    sleep interval

    driver.measure_off

    assert_equal 0, driver.missing

  end

  it "consumes current within expected range" do

    assert (100e-6 .. 10e-3).include? avg.average

  end

  after do

    driver.close

  end

end

About

Unofficial PPK2 driver for Ruby

Topics

Resources

License

Stars

Watchers

Forks

Languages