Ruby Migration Guide
FrontPanel 6.0 introduces several breaking changes to the Ruby API. The most significant are:
- Device opening —
OpenBySerial()and device-listing methods are removed; useFrontPanelDevicesinstead - Data port separation — Wire, Trigger, Pipe, Register, and
ResetFPGAoperations move fromOkCFrontPanelto a dedicatedOkCFPGADataPortClassicobject - Standalone error codes —
OkCFrontPanel::NoError, etc. become standaloneErrorCode_NoErrorconstants - Removed convenience methods — Several methods eliminated in favor of
GetDeviceInfo()
Update Device Opening
OpenBySerial(), GetDeviceCount(), and GetDeviceListSerial() are removed. Use FrontPanelDevices instead.
# FP5:
dev = OpalKelly::OkCFrontPanel.new
dev.OpenBySerial("")
# FP6:
devices = OpalKelly::FrontPanelDevices.new
dev = devices.Open()Code language: Ruby (ruby)Open() returns the device object directly. Pass a serial number to open a specific device, or pass an empty string to open the first available device.
Device enumeration:
# FP5:
dev = OpalKelly::OkCFrontPanel.new
count = dev.GetDeviceCount()
(0...count).each do |i|
serial = dev.GetDeviceListSerial(i)
end
# FP6:
devices = OpalKelly::FrontPanelDevices.new
count = devices.GetCount()
(0...count).each do |i|
serial = devices.GetSerial(i)
endCode language: Ruby (ruby)Obtain the Classic Data Port
After configuring the FPGA, call GetFPGADataPortClassic() on the device instance:
# FP5:
dev.ConfigureFPGA("my_design.bit")
if dev.IsFrontPanelEnabled()
puts "FrontPanel support is enabled."
end
dev.SetWireInValue(0x00, 0x01)
dev.UpdateWireIns()
# FP6:
dev.ConfigureFPGA("my_design.bit")
if dev.IsFrontPanelEnabled()
puts "FrontPanel support is enabled."
end
classic_data_port = dev.GetFPGADataPortClassic()
classic_data_port.SetWireInValue(0x00, 0x01)
classic_data_port.UpdateWireIns()Code language: Ruby (ruby)The object returned by GetFPGADataPortClassic() is owned by the device instance. It remains valid for the lifetime of that object.
Replace All Wire, Trigger, Pipe, and Register Calls
Change every call that previously went through the device object to go through the classic data port instead. The method names and parameters are identical — only the target object changes.
Wires:
# FP5:
dev.SetWireInValue(0x00, value, mask)
dev.UpdateWireIns()
dev.UpdateWireOuts()
wire_out = dev.GetWireOutValue(0x20)
# FP6:
classic_data_port.SetWireInValue(0x00, value, mask)
classic_data_port.UpdateWireIns()
classic_data_port.UpdateWireOuts()
wire_out = classic_data_port.GetWireOutValue(0x20)Code language: Ruby (ruby)Triggers:
# FP5:
dev.ActivateTriggerIn(0x40, 0)
dev.UpdateTriggerOuts()
if dev.IsTriggered(0x60, 1)
...
end
# FP6:
classic_data_port.ActivateTriggerIn(0x40, 0)
classic_data_port.UpdateTriggerOuts()
if classic_data_port.IsTriggered(0x60, 1)
...
endCode language: Ruby (ruby)Pipes:
# FP5:
dev.WriteToPipeIn(0x80, data)
dev.ReadFromPipeOut(0xA0, data)
dev.WriteToBlockPipeIn(0x80, blockSize, data)
dev.ReadFromBlockPipeOut(0xA0, blockSize, data)
# FP6:
classic_data_port.WriteToPipeIn(0x80, data)
classic_data_port.ReadFromPipeOut(0xA0, data)
classic_data_port.WriteToBlockPipeIn(0x80, blockSize, data)
classic_data_port.ReadFromBlockPipeOut(0xA0, blockSize, data)Code language: Ruby (ruby)Registers:
# FP5:
value = dev.ReadRegister(addr)
dev.WriteRegister(addr, data)
# FP6:
value = classic_data_port.ReadRegister(addr)
classic_data_port.WriteRegister(addr, data)Code language: Ruby (ruby)ResetFPGA:
# FP5:
dev.ResetFPGA()
# FP6:
classic_data_port.ResetFPGA()Code language: Ruby (ruby)Update Error Code References
Error code values are no longer nested in OkCFrontPanel. They are now standalone constants in the OpalKelly module:
# FP5:
if dev.ConfigureFPGA(file) != OpalKelly::OkCFrontPanel::NoError
...
end
# FP6:
if dev.ConfigureFPGA(file) != OpalKelly::ErrorCode_NoError
...
endCode language: Ruby (ruby)Common replacements:
OpalKelly::OkCFrontPanel::NoError→OpalKelly::ErrorCode_NoErrorOpalKelly::OkCFrontPanel::Failed→OpalKelly::ErrorCode_FailedOpalKelly::OkCFrontPanel::Timeout→OpalKelly::ErrorCode_TimeoutOpalKelly::OkCFrontPanel::DeviceNotOpen→OpalKelly::ErrorCode_DeviceNotOpenOpalKelly::OkCFrontPanel::FileError→OpalKelly::ErrorCode_FileError
Replace Removed Convenience Methods
Several convenience methods are removed in favor of GetDeviceInfo():
# FP5:
serial = dev.GetSerialNumber()
model = dev.GetBoardModel()
major = dev.GetDeviceMajorVersion()
minor = dev.GetDeviceMinorVersion()
id = dev.GetDeviceID()
fast = dev.IsHighSpeed()
# FP6:
info = OpalKelly::OkTDeviceInfo.new
dev.GetDeviceInfo(info)
# info.serialNumber, info.deviceID, info.productName,
# info.productID, info.deviceMajorVersion, info.deviceMinorVersion,
# info.usbSpeed, info.wireWidthCode language: Ruby (ruby)Other removals:
GetErrorString()— useGetErrorMessage()insteadEnableAsynchronousTransfers()— removed, no replacementIsFrontPanel3Supported()— removed, no replacementGetHostInterfaceWidth()— useinfo.wireWidthfromGetDeviceInfo()GetDeviceListModel()— useFrontPanelDevices(see Step 1)
Migration Checklist
- Replace
OkCFrontPanel.new+OpenBySerial("")withFrontPanelDevices.new+Open(). - After
ConfigureFPGA(), addclassic_data_port = dev.GetFPGADataPortClassic(). - Find-and-replace all wire/trigger/pipe/register calls from
dev.toclassic_data_port.. - Replace
OkCFrontPanel::NoErrorwithOpalKelly::ErrorCode_NoError(and similar for other error codes). - Replace removed convenience methods with
GetDeviceInfo().