Commit 930ca719 authored by Vincent van Beveren's avatar Vincent van Beveren

Merge branch 'master' of ohwr.org:sfp/sfp-plus-i2c

# Conflicts:
#	sw/jsfp/src/nl/nikhef/sfp/SFPDeviceBase.java
#	sw/safaripark/src/nl/nikhef/safaripark/SafariPark.java
parents 0eb2ec5f bcd2335f
......@@ -6,6 +6,7 @@ import com.ftdi.FTD2XXException;
import com.ftdi.FTDevice;
import nl.nikhef.rebus.dev.PCA9848;
import nl.nikhef.rebus.ftdi.GPIO;
import nl.nikhef.rebus.ftdi.I2C;
import nl.nikhef.rebus.ftdi.JavaFTD2xxMPSSE;
import nl.nikhef.rebus.ftdi.MPSSE;
......@@ -18,17 +19,26 @@ public class MultiSFPDevice extends SFPDeviceBase {
private static final int TX_LED = I2C.GPIO_AL2;
private static final int RX_LED = I2C.GPIO_AL3;
private static final int MODULE_PRESENT_IOS = GPIO.GPIO_AL0 | GPIO.GPIO_AL1 | GPIO.GPIO_AL2 | GPIO.GPIO_AL3;
private static final int MODULE_PRESENT_SHIFT = 4;
private static final int OUTPUT_MASK = ACTIVE_LED | TX_LED | RX_LED;
private static final int NO_OF_BAYS = 4;
private FTDevice _portA; // FTDI Port A device
private FTDevice _portB; // FTDI Port B device
private String _serial;
private I2C _i2c;
private MPSSE _mpsse;
private GPIO _gpio;
private MPSSE _mpsseA;
private MPSSE _mpsseB;
private PCA9848 _mux;
private int _selected = -1;
private MultiSFPI2CLink[] _links = new MultiSFPI2CLink[NO_OF_BAYS];
private Thread _thread;
private boolean _shutdown = false;
private volatile int _modulePresentMask = 0;
public MultiSFPDevice(String ftdiSerial) throws IOException
{
......@@ -36,16 +46,21 @@ public class MultiSFPDevice extends SFPDeviceBase {
try {
_portA = FTDevice.getDevicesBySerialNumber(ftdiSerial + "A").get(0);
_portB = FTDevice.getDevicesBySerialNumber(ftdiSerial + "B").get(0);
} catch (FTD2XXException e) {
throw new IOException("Could not initialize FTDI", e);
}
_mpsse = new JavaFTD2xxMPSSE(_portA);
_i2c = new I2C(_mpsse, 400000, false);
_mpsseA = new JavaFTD2xxMPSSE(_portA);
_mpsseB = new JavaFTD2xxMPSSE(_portB);
_i2c = new I2C(_mpsseA, 400000, false);
_i2c.setModes(OUTPUT_MASK | PCA_RESET, OUTPUT_MASK | PCA_RESET);
// Reset PCA9848
_i2c.setOutputs(0, PCA_RESET);
_i2c.setOutputs(PCA_RESET, PCA_RESET);
_gpio = new GPIO(_mpsseB);
_gpio.setModes(0, MODULE_PRESENT_IOS);
setLeds(false, false);
// _i2c.setOutputs(0xF0, 0xE0);
......@@ -57,20 +72,6 @@ public class MultiSFPDevice extends SFPDeviceBase {
{
_links[i] = new MultiSFPI2CLink(i);
}
_thread = new Thread("MultiSFP " + ftdiSerial) {
public void run() {
multiRun();;
};
};
_thread.setDaemon(true);
_thread.start();
}
private void multiRun()
{
}
......@@ -91,7 +92,7 @@ public class MultiSFPDevice extends SFPDeviceBase {
@Override
public boolean isModulePresent(int bay) {
return true;
return ((_modulePresentMask >> bay) & 0x1) != 0;
}
......@@ -113,8 +114,43 @@ public class MultiSFPDevice extends SFPDeviceBase {
}
_selected = bay;
}
private synchronized void updateIOState() throws IOException
{
int nowPresent;
try {
nowPresent = 0xF ^ (_gpio.getInputs(MODULE_PRESENT_IOS) >> MODULE_PRESENT_SHIFT);
} catch (IOException io)
{
nowPresent = 0;
}
int changes = nowPresent ^ _modulePresentMask;
_modulePresentMask = nowPresent;
if (changes != 0) {
for (int i = 0; i < NO_OF_BAYS; ++i)
{
if ((changes & 1 << i) != 0) {
sdlMgr.getProxy().sfpModuleStateChanged(this, i);
}
}
}
}
@Override
public void updateModules() {
try {
updateIOState();
} catch (IOException e) {
e.printStackTrace();
}
}
private synchronized byte[] i2cWrRd(int addr, byte[] dataWr, boolean contRd, int rdLen) throws IOException {
setLeds(true, true);
byte[] dta = _i2c.writeRead(addr, dataWr, rdLen);
......@@ -186,4 +222,35 @@ public class MultiSFPDevice extends SFPDeviceBase {
}
}
@Override
public void shutdown()
{
_shutdown = true;
int wasPresent = _modulePresentMask;
_modulePresentMask = 0;
if (wasPresent != 0) {
for (int i = 0; i < NO_OF_BAYS; ++i)
{
if ((wasPresent & 1 << i) != 0) {
sdlMgr.getProxy().sfpModuleStateChanged(this, i);
}
}
}
try {
_mpsseA.close();
} catch (IOException e) {
}
try {
_mpsseB.close();
} catch (IOException e) {
}
}
}
......@@ -21,11 +21,10 @@ public class MultiSFPProvider extends SFPProviderBase
return null;
}
@Override
public void scanForDevices() {
private void findNewDevices() {
try {
List<FTDevice> devs = FTDevice.getDevices();
List<FTDevice> devs = FTDevice.getDevices(true);
for (FTDevice devRaw : devs)
{
......@@ -53,5 +52,12 @@ public class MultiSFPProvider extends SFPProviderBase
}
updProcess();
}
@Override
public void updateDevices() {
findNewDevices();
super.updateDevices();
}
}
......@@ -57,5 +57,15 @@ public interface SFPDevice extends Comparable<SFPDevice>
public Collection<SFPDeviceListener> getDeviceListeners();
public void removeDeviceListener(SFPDeviceListener sdl);
/**
* Closes the device.
*/
public void shutdown();
/**
* Call invoked by provider each second to check the module state.
*/
public void updateModules();
}
......@@ -38,19 +38,14 @@ public abstract class SFPDeviceBase implements SFPDevice {
if (_modSerials[bay] == null) {
try {
I2CLink i2c = getLink(bay);
byte[] serialbytes;
try {
i2c.open();
serialbytes = i2c.i2cWrRd(I2C_EEPROM_ADDR, new byte[] { (byte)I2C_EEPROM_SERIAL_OFFSET }, true, I2C_EEPROM_SERIAL_LENGTH);
} finally {
i2c.close();
}
_modSerials[bay] = new String(serialbytes).trim();
} catch (IOException e) {
_modSerials[bay] = getSerial() + ":" + bay;
i2c.open();
serialbytes = i2c.i2cWrRd(I2C_EEPROM_ADDR, new byte[] { (byte)I2C_EEPROM_SERIAL_OFFSET }, true, I2C_EEPROM_SERIAL_LENGTH);
} finally {
i2c.close();
}
return new String(serialbytes).trim();
} catch (IOException e) {
// read error
}
return _modSerials[bay];
......@@ -104,4 +99,9 @@ public abstract class SFPDeviceBase implements SFPDevice {
public int compareTo(SFPDevice o) {
return getSerial().compareTo(o.getSerial());
}
public void updateModules()
{
}
}
......@@ -20,10 +20,12 @@ public class SFPManager {
private List<SFPProvider> _providers = new ArrayList<SFPProvider>();
private List<SFPProvider> _umProviders = Collections.unmodifiableList(_providers);
private Thread _sfpLoopThread;
private SFPManager()
{
_providers.add(new SimSFPProvider());
_providers.add(new MultiSFPProvider());
}
......@@ -54,11 +56,75 @@ public class SFPManager {
}
}
public void scanForDevices() {
public synchronized boolean isRunning() {
return _sfpLoopThread != null;
}
public synchronized void start()
{
if (_sfpLoopThread != null) return;
_sfpLoopThread = new Thread(new Runnable() {
@Override
public void run() {
try {
sfpLoop();
} catch (InterruptedException e) {
}
}
}, "SFP Device Loop");
_sfpLoopThread.start();
}
private void sfpLoop() throws InterruptedException
{
final int DELAY = 1000;
long next = System.currentTimeMillis() + DELAY;
while (!_sfpLoopThread.isInterrupted()) {
for (SFPProvider prov : _providers)
{
prov.updateDevices();
long sleepTime = next - System.currentTimeMillis();
if (sleepTime > 0) {
Thread.sleep(sleepTime);
}
next += DELAY;
}
}
}
public synchronized void stop()
{
if (_sfpLoopThread == null) return;
_sfpLoopThread.interrupt();
try {
_sfpLoopThread.join();
} catch (InterruptedException e) {
}
_sfpLoopThread = null;
for (SFPProvider prov : _providers){
prov.scanForDevices();
for (SFPDevice dev: prov.getDevices())
{
dev.shutdown();
}
}
}
......
......@@ -13,6 +13,6 @@ public interface SFPProvider {
public String getName();
public void scanForDevices();
public void updateDevices();
}
......@@ -45,6 +45,7 @@ public abstract class SFPProviderBase implements SFPProvider {
SFPDevice dev = it.next();
if (!_updSet.contains(dev)) {
it.remove();
dev.shutdown();
_splMgr.getProxy().sfpDeviceRemoved(this, dev);
}
}
......@@ -61,6 +62,7 @@ public abstract class SFPProviderBase implements SFPProvider {
protected void removeDevice(SFPDevice dev)
{
_devices.remove(dev);
dev.shutdown();
_splMgr.getProxy().sfpDeviceRemoved(this, dev);
}
......@@ -75,4 +77,11 @@ public abstract class SFPProviderBase implements SFPProvider {
return getName();
}
@Override
public void updateDevices() {
for (SFPDevice dev : getDevices()) {
dev.updateModules();
}
}
}
......@@ -57,6 +57,10 @@ public class SimSFPDevice extends SFPDeviceBase {
sdlMgr.getProxy().sfpModuleStateChanged(this, bay);
}
@Override
public void shutdown() {
}
}
......@@ -8,7 +8,7 @@ public class SimSFPProvider extends SFPProviderBase {
private SimSFPDevice _device = new SimSFPDevice("SIM1", 4);
@Override
public void scanForDevices() {
public void updateDevices() {
if (!_firstRun) return;
addDevice(_device);
......
......@@ -44,5 +44,10 @@ public class SimpleFTDIDevice extends SFPDeviceBase {
return bay == 0;
}
@Override
public void shutdown() {
}
}
......@@ -23,7 +23,7 @@ public class SimpleFTDIProvider extends SFPProviderBase {
@Override
public void scanForDevices()
public void updateDevices()
{
try {
List<FTDevice> devs = FTDevice.getDevices();
......
......@@ -47,24 +47,35 @@ public class DDMIMeta<T extends Object> {
public static final class Conversion {
private double _scale;
private double _offset;
private float _scale = 1;
private float _offset = 0;
public Conversion() {
System.out.println("Conversion created, no args");
}
public void setScaling(double scale, double offset)
public void setScaling(float scale, float offset)
{
_scale = scale;
_offset = offset;
}
public Conversion(double scale, double offset)
public Conversion(float scale, float offset)
{
this._scale = scale;
this._offset = offset;
}
public float apply(float value)
{
return (value - _offset) * _scale;
}
public float revert(float value)
{
return (value / _scale) + _offset;
}
}
public static class BitFieldValue
......
package nl.nikhef.sfp.test;
import nl.nikhef.sfp.SFPDevice;
import nl.nikhef.sfp.SFPDeviceListener;
import nl.nikhef.sfp.SFPManager;
import nl.nikhef.sfp.SFPProvider;
import nl.nikhef.sfp.SFPProviderListener;
public class MultiSFPTest {
public static void main(String[] args)
public static void main(String[] args) throws InterruptedException
{
SFPManager sfpMgr = SFPManager.SINGLETON;
......@@ -23,19 +24,28 @@ public class MultiSFPTest {
public void sfpDeviceAdded(SFPProvider provider, SFPDevice dev) {
System.out.printf("Device: %s/%s, Bays = %d\n", dev.getClass().getSimpleName(), dev.getSerial(), dev.getBayCount());
for (int i = 0; i < dev.getBayCount(); i++)
{
System.out.printf(" %d: ", i);
if (dev.isModulePresent(i)) {
System.out.printf("%s\n", dev.getModuleSerial(i));
} else {
System.out.println("Not connected");
dev.addDeviceListener(new SFPDeviceListener() {
@Override
public void sfpModuleStateChanged(SFPDevice dev, int bay) {
if (dev.isModulePresent(bay)) {
System.out.printf("Module added to bay %d: %s\n", bay, dev.getModuleSerial(bay));
} else {
System.out.printf("Module removed from bay %d\n", bay);
}
}
}
});
}
});
sfpMgr.scanForDevices();
sfpMgr.start();
Thread.sleep(2000);
sfpMgr.stop();
}
}
......@@ -146,6 +146,7 @@ public class XOL
{
parent = stack.pop();
parent.addChild(current);
current.complete();
current = parent;
parent = stack.peek();
}
......
......@@ -50,7 +50,7 @@ public abstract class BusBase {
protected int outMask;
protected abstract void setGPIOChild(int port) throws IOException;
protected abstract void setGPIOChild(int portMask) throws IOException;
protected void setBusIO(int value, int direction) throws IOException
{
......
package nl.nikhef.rebus.ftdi;
import java.io.IOException;
public class GPIO extends BusBase {
public GPIO(MPSSE mpsse) throws IOException {
super(mpsse);
mpsse.switchMode(0);
}
@Override
protected void setGPIOChild(int port) throws IOException
{
mpsse.setDataLowByte(outMask & LO_A_MASK, modeMask & LO_A_MASK);
}
}
......@@ -30,7 +30,7 @@ public class I2C extends BusBase {
}
@Override
protected void setGPIOChild(int port) throws IOException
protected void setGPIOChild(int portMask) throws IOException
{
_regenSeqs = true;
setBusIO(0xF, 0xB);
......
......@@ -6,6 +6,9 @@ import java.awt.Font;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;
import java.awt.event.WindowStateListener;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.Map.Entry;
......@@ -34,7 +37,7 @@ import nl.nikhef.safaripark.monitor.Monitor;
import nl.nikhef.sfp.SFPDevice;
import nl.nikhef.sfp.SFPManager;
public class SafariPark extends JFrame implements BaySelectionListener {
public class SafariPark extends JFrame implements BaySelectionListener, WindowListener {
private final JComboBox<nl.nikhef.sfp.SFPDevice> _cbBoards = new JComboBox<SFPDevice>();
......@@ -74,8 +77,12 @@ public class SafariPark extends JFrame implements BaySelectionListener {
split.setResizeWeight(0.1);
add(split, BorderLayout.CENTER);
setExtendedState(JFrame.MAXIMIZED_BOTH);
addWindowListener(this);
}
private void makeToolbar()
{
JToolBar tb = new JToolBar();
......@@ -159,6 +166,15 @@ public class SafariPark extends JFrame implements BaySelectionListener {
});
}
public void deinit() {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
SFPManager.get().stop();
}
});
}
@Override
......@@ -209,5 +225,46 @@ public class SafariPark extends JFrame implements BaySelectionListener {
public static JFrame getSingleton() {
return SINGLETON;
}
@Override
public void windowOpened(WindowEvent e) {
}
@Override
public void windowClosing(WindowEvent e) {
deinit();
}
@Override
public void windowClosed(WindowEvent e) {
}
@Override
public void windowIconified(WindowEvent e) {
}
@Override
public void windowDeiconified(WindowEvent e) {
}
@Override
public void windowActivated(WindowEvent e) {
}
@Override
public void windowDeactivated(WindowEvent e) {
}
}
......@@ -144,6 +144,7 @@ public class DeviceManager extends JPanel implements TreeSelectionListener, SFPD
{
dsl.baySelected(dev, bay);
}
repaint();
}
......@@ -151,9 +152,9 @@ public class DeviceManager extends JPanel implements TreeSelectionListener, SFPD
@Override
public void treeNodesChanged(TreeModelEvent arg0) {
expandAll();
public void treeNodesChanged(TreeModelEvent arg0)
{
//expandAll();
}
......@@ -162,7 +163,7 @@ public class DeviceManager extends JPanel implements TreeSelectionListener, SFPD
@Override
public void treeNodesInserted(TreeModelEvent arg0) {
expandAll();
//expandAll();
}
......@@ -171,7 +172,7 @@ public class DeviceManager extends JPanel implements TreeSelectionListener, SFPD
@Override
public void treeNodesRemoved(TreeModelEvent arg0) {
expandAll();
//expandAll();
}
......@@ -180,7 +181,7 @@ public class DeviceManager extends JPanel implements TreeSelectionListener, SFPD
@Override
public void treeStructureChanged(TreeModelEvent arg0) {
expandAll();
//expandAll();
}
......
......@@ -173,7 +173,13 @@ public class DeviceManagerModel implements SFPProviderListener, SFPDeviceListene
public String toString() {
SFPDevice dev = _parent.getDevice();
if (dev.isModulePresent(pos)) {
return String.format("%d: %s", pos, dev.getModuleSerial(pos));
String serial = dev.getModuleSerial(pos);
// small window between isPresent and reading serial may allow for null value to be returned
if (serial == null) serial = "<none>";
return String.format("%d: %s", pos, serial);
} else {
return String.format("%d: <none>", pos);
}
......@@ -234,6 +240,13 @@ public class DeviceManagerModel implements SFPProviderListener, SFPDeviceListene
_devices.add(new DeviceNode(dev));
}
private void removeDevice(SFPDevice dev)
{
dev.removeDeviceListener(this);
_devices.remove(nodeForSfp(dev));
}
public void populateDevices()
{
for (SFPProvider prov : _mgr.getProviders()) {
......@@ -250,14 +263,16 @@ public class DeviceManagerModel implements SFPProviderListener, SFPDeviceListene
}
private boolean containsDevice(SFPDevice dev)
private DeviceNode nodeForSfp(SFPDevice dev)
{
for (DeviceNode devNode : _devices)
{
if (devNode.getDevice().equals(dev)) return true;
if (devNode.getDevice().equals(dev)) return devNode;
}
return false;
return null;
}
@Override
public void sfpDeviceAdded(SFPProvider provider, SFPDevice dev) {
......@@ -273,6 +288,8 @@ public class DeviceManagerModel implements SFPProviderListener, SFPDeviceListene
@Override
public void sfpDeviceRemoved(SFPProvider provider, SFPDevice dev)
{
removeDevice(dev);
_dtm.nodeStructureChanged(_root);
}
@Override
......
......@@ -97,7 +97,7 @@ public class BitfieldEditor extends ValueEditor implements ActionListener, Docum
protected void updateValue()
{
_tf.setEnabled(isValid());
_tf.setEnabled(isValueValid());
_tf.setEditable(value.isWritable());
updateComponent();
}
......@@ -110,7 +110,7 @@ public class BitfieldEditor extends ValueEditor implements ActionListener, Docum
JComponent comp = e.getValue();
BitFieldValue bfv = e.getKey();
comp.setEnabled(isValid() && value.isWritable());
comp.setEnabled(isValueValid() && value.isWritable());
if (bfv.length == 1) {
boolean bitV;
if (rawValue != null) {
......@@ -129,7 +129,7 @@ public class BitfieldEditor extends ValueEditor implements ActionListener, Docum
_ignoreEvents = true;
if (isValid()) {
if (isValueValid() && rawValue != null) {
StringBuilder sb = new StringBuilder(toHex(rawValue[0]));
for (int i = 1; i < rawValue.length; i++)
{
......
......@@ -30,7 +30,7 @@ public class DecimalEditor extends ValueEditor implements DocumentListener {
@Override
protected void updateValue()
{
_tf.setEnabled(isValid());
_tf.setEnabled(isValueValid());
_tf.setEditable(value.isWritable());
_ignoreEvents = true;
String text = String.format("%f", getAsDecimal());
......
......@@ -151,7 +151,7 @@ public class EnumEditor extends ValueEditor implements ActionListener {
protected void updateValue()
{
_ignoreEvents = true;
_cb.setEnabled(isValid());
_cb.setEnabled(isValueValid());
Integer val = Integer.valueOf(getAsInt());
_cb.setSelectedItem(val);
_cb.getEditor().setItem(val);
......
......@@ -39,7 +39,7 @@ public class IntegerEditor extends ValueEditor implements DocumentListener {
@Override
protected void updateValue()
{
_tf.setEnabled(isValid());
_tf.setEnabled(isValueValid());
_tf.setEditable(value.isWritable());
_ignoreEvents = true;
_tf.setValue(getAsInt());
......
......@@ -9,6 +9,7 @@ import javax.swing.JPanel;
import nl.nikhef.safaripark.DeferredReader;
import nl.nikhef.safaripark.DeferredReaderResult;
import nl.nikhef.sfp.ddmi.AccessException;
import nl.nikhef.sfp.ddmi.DDMIMeta;
import nl.nikhef.sfp.ddmi.DDMIValue;
public abstract class ValueEditor extends JPanel {
......@@ -40,7 +41,7 @@ public abstract class ValueEditor extends JPanel {
protected abstract void clearValue();
public boolean isValid() {
public boolean isValueValid() {
if (_ctx == null) return false;
if (_ctx.getContext() == null) return false;
return value.isValid(_ctx.getContext());
......@@ -51,7 +52,7 @@ public abstract class ValueEditor extends JPanel {
dirty = false;
updateLabel();
if (_ctx.getContext() == null || !isValid())
if (_ctx.getContext() == null || !isValueValid())
{
rawValue = null;
setEnabled(false);
......@@ -166,15 +167,20 @@ public abstract class ValueEditor extends JPanel {
baseValue = Float.intBitsToFloat(getAsInt());
break;
case DECIMAL_TYPE_UNSIGNED:
baseValue = getAsInt();
baseValue = 0xFFFFFFFFL & getAsInt();
break;
case DECIMAL_TYPE_SIGNED:
baseValue = getAsInt();
break;
default:
break;
}
if (DDMIMeta.CONV.partOf(value)) {
baseValue = DDMIMeta.CONV.of(value).apply(baseValue);
}
return baseValue;
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment