diff options
author | Jonathan McCrohan <jmccrohan@gmail.com> | 2013-03-03 20:04:36 +0000 |
---|---|---|
committer | Jonathan McCrohan <jmccrohan@gmail.com> | 2013-03-03 20:04:36 +0000 |
commit | 571d570e1be6f783a2e8ef0dafa838e9d82f923e (patch) | |
tree | 9b18682751acba56d650129922ecc4c5f12a3469 | |
parent | 62172377c57ff85bce35a43e0ca3e76f67a473ad (diff) | |
parent | 4e6290d8e2dc4dcd784102bdab18d7e1854e11c0 (diff) | |
download | libphidget21-squeeze-backports.tar.gz |
Merge branch 'master' into squeeze-backportssqueeze-backports
Conflicts:
debian/changelog
48 files changed, 2380 insertions, 2394 deletions
diff --git a/Java/com/phidgets/AccelerometerPhidget.java b/Java/com/phidgets/AccelerometerPhidget.java index 062ea6f..c0c82ae 100644 --- a/Java/com/phidgets/AccelerometerPhidget.java +++ b/Java/com/phidgets/AccelerometerPhidget.java @@ -1,6 +1,6 @@ /* - * Copyright 2012 Phidgets Inc. All rights reserved. + * Copyright 2006 Phidgets Inc. All rights reserved. */ package com.phidgets; @@ -11,10 +11,9 @@ import com.phidgets.event.*; * This class represents a Phidget Accelerometer. All methods to read * acceleration data from an Accelerometer are implemented in this class. <p> - * The Phidget Accelerometer provides 2 or 3 axes of acceleration data, at anywhere from 2g to 10g - * sensitivity, depending on the specific revision. See your device's User Guide for more specific API details, - * technical information, and revision details. The User Guide, along with other resources, can be found on - * the product page for your device. + The Phidget Accelerometer provides 2 or 3 axes of acceleration data, at anywhere from 2g to 10g + sensitivity, depending on the specific revision. See your hardware documetation for more information. + They can measure both static (gravity) and dynamic acceleration. * @author Phidgets Inc. */ diff --git a/Java/com/phidgets/AdvancedServoPhidget.java b/Java/com/phidgets/AdvancedServoPhidget.java index f66b924..db33e2a 100644 --- a/Java/com/phidgets/AdvancedServoPhidget.java +++ b/Java/com/phidgets/AdvancedServoPhidget.java @@ -1,6 +1,6 @@ /* - * Copyright 2012 Phidgets Inc. All rights reserved. + * Copyright 2006 Phidgets Inc. All rights reserved. */ package com.phidgets; @@ -11,11 +11,9 @@ import com.phidgets.event.*; * This class represents a Phidget Advanced Servo Controller. All methods * to to control a motor controller and read back motor data are implemented in this class. * <p> - * The Phidget Advanced Servo Controller is able to control 1 or more servo motors. Motor acceleration + * The Phidget Advanced Servo Controller is able to control 1 or more servo motors. Motos acceleration * and Velocity are controllable. The number of servos that can be controlled depends on the - * version of the controller. See your device's User Guide for more specific API details, - * technical information, and revision details. The User Guide, along with other resources, can be found on - * the product page for your device. + * version of the controller. * * @author Phidgets Inc. */ diff --git a/Java/com/phidgets/EncoderPhidget.java b/Java/com/phidgets/EncoderPhidget.java index 7430aec..1543bd3 100644 --- a/Java/com/phidgets/EncoderPhidget.java +++ b/Java/com/phidgets/EncoderPhidget.java @@ -1,6 +1,6 @@ /* - * Copyright 2012 Phidgets Inc. All rights reserved. + * Copyright 2006 Phidgets Inc. All rights reserved. */ package com.phidgets; @@ -12,10 +12,7 @@ import com.phidgets.event.*; * to read encoder data from an encoder are implemented in this class. <p> Phidget Encoder boards generally support 1 or more encoders with 0 or more digital inputs. - Both high speed optical and low speed mechanical encoders are supported with this API. - * See your device's User Guide for more specific API details, - * technical information, and revision details. The User Guide, along with other resources, can be found on - * the product page for your device. + Both high speed optical and low speed mechanical encoders are supported with this API. * * @author Phidgets Inc. */ diff --git a/Java/com/phidgets/IRPhidget.java b/Java/com/phidgets/IRPhidget.java index 6647eeb..3a11f70 100644 --- a/Java/com/phidgets/IRPhidget.java +++ b/Java/com/phidgets/IRPhidget.java @@ -1,242 +1,239 @@ - -/* - * Copyright 2012 Phidgets Inc. All rights reserved. - */ - -package com.phidgets; -import java.util.Iterator; -import java.util.LinkedList; +
+/*
+ * Copyright 2010 Phidgets Inc. All rights reserved.
+ */
+
+package com.phidgets;
+import java.util.Iterator;
+import java.util.LinkedList;
import com.phidgets.event.*;
-/** - * This class represents a Phidget IR. All methods - * to send and receive IR data are implemented in this class. - * <p> - * The Phidget IR Receiver-Transmitter can send and receive Consumer-IR signals. Ability to learn and re-transmit codes, - * as well as low-level access to raw data, is provided. - * See your device's User Guide for more specific API details,
- * technical information, and revision details. The User Guide, along with other resources, can be found on
- * the product page for your device. - * - * @author Phidgets Inc. +/**
+ * This class represents a Phidget IR. All methods
+ * to send and receive IR data are implemented in this class.
+ * <p>
+ * The Phidget IR Receiver-Transmitter can send and receive Consumer-IR signals. Ability to learn and re-transmit codes,
+ * as well as low-level access to raw data, is provided.
+ *
+ * @author Phidgets Inc.
*/
-public final class IRPhidget extends Phidget -{ - public IRPhidget () throws PhidgetException - { - super (create ()); - } - private static native long create () throws PhidgetException; - - /** - * Represents a long space (greater then 327,670 microseconds) in raw data. - * This can be considered a period of no IR activity. This is used with {@link #readRaw readRaw} - */ - public static final int RAWDATA_LONGSPACE = 0x7fffffff; - - /** - * Transmits a code. - * @param code the code to transmit - * @param codeInfo the code specification - * @throws PhidgetException If this Phidget is not opened and attached. - * See {@link com.phidgets.Phidget#open(int) open} for information on determining if a device is attached. - */ - public native void transmit (IRCode code, IRCodeInfo codeInfo) throws PhidgetException; - /** - * Transmits a repeat. This needs to be called within the gap time of a transmit to be meaningful. - * @throws PhidgetException If this Phidget is not opened and attached. - * See {@link com.phidgets.Phidget#open(int) open} for information on determining if a device is attached. - */ - public native void transmitRepeat () throws PhidgetException; - /** - * Transmits raw data. - * @param data data in microseconds, must start and end with a pulse - * @param offset offset in the data array to start transmitting - * @param count number of elements of data to transmit - * @param gap gap size in microseconds - * @param carrierFrequency carrier frequency in kHz - * @param dutyCycle duty cycle in percent - * @throws PhidgetException If this Phidget is not opened and attached. - * See {@link com.phidgets.Phidget#open(int) open} for information on determining if a device is attached. - */ - public native void transmitRaw (int[]data, int offset, int count, int gap, int carrierFrequency, int dutyCycle) throws PhidgetException; - /** - * Transmits raw data. - * @param data data in microseconds, must start and end with a pulse - * @throws PhidgetException If this Phidget is not opened and attached. - * See {@link com.phidgets.Phidget#open(int) open} for information on determining if a device is attached. - */ - public final void transmitRaw (int[]data) throws PhidgetException - { - transmitRaw (data, 0, data.length, 0, 0, 0); - } - /** - * Transmits raw data. - * @param data data in microseconds, must start and end with a pulse - * @param gap gap size in microseconds - * @throws PhidgetException If this Phidget is not opened and attached. - * See {@link com.phidgets.Phidget#open(int) open} for information on determining if a device is attached. - */ - public final void transmitRaw (int[]data, int gap) throws PhidgetException - { - transmitRaw (data, 0, data.length, gap, 0, 0); - } - /** - * Transmits raw data. - * @param data data in microseconds, must start and end with a pulse - * @param offset offset in the data array to start transmitting - * @param count number of elements of data to transmit - * @throws PhidgetException If this Phidget is not opened and attached. - * See {@link com.phidgets.Phidget#open(int) open} for information on determining if a device is attached. - */ - public final void transmitRaw (int[]data, int offset, int count) throws PhidgetException - { - transmitRaw (data, offset, count, 0, 0, 0); - } - /** - * Transmits raw data. - * @param data data in microseconds, must start and end with a pulse - * @param offset offset in the data array to start transmitting - * @param count number of elements of data to transmit - * @param gap gap size in microseconds - * @throws PhidgetException If this Phidget is not opened and attached. - * See {@link com.phidgets.Phidget#open(int) open} for information on determining if a device is attached. - */ - public final void transmitRaw (int[]data, int offset, int count, int gap) throws PhidgetException - { - transmitRaw (data, offset, count, gap, 0, 0); - } - /** - * Reads raw data. Use {@link #RAWDATA_LONGSPACE RAWDATA_LONGSPACE} to detect gaps in IR data. - * @param buffer array into which data will be read. - * @param offset offset in data to start writing - * @param count maximum ammount of data to read - * @return ammount of data read - * @throws PhidgetException If this Phidget is not opened and attached. - * See {@link com.phidgets.Phidget#open(int) open} for information on determining if a device is attached. - */ - public native int readRaw (int[]buffer, int offset, int count) throws PhidgetException; - /** - * Reads raw data. Use {@link #RAWDATA_LONGSPACE RAWDATA_LONGSPACE} to detect gaps in IR data. - * @param buffer array into which data will be read. - * @return ammount of data read - * @throws PhidgetException If this Phidget is not opened and attached. - * See {@link com.phidgets.Phidget#open(int) open} for information on determining if a device is attached. - */ - public final int readRaw (int[]buffer) throws PhidgetException - { - return readRaw (buffer, 0, buffer.length); - } - /** - * Returns the last received code. This is updated right after the code event returns. - * @return last code - * @throws PhidgetException If this Phidget is not opened and attached. - * See {@link com.phidgets.Phidget#open(int) open} for information on determining if a device is attached. - */ - public native IRCode getLastCode () throws PhidgetException; - /** - * Returns the last learned code. This is updated right after the learn event returns. - * @return last learned code - * @throws PhidgetException If this Phidget is not opened and attached. - * See {@link com.phidgets.Phidget#open(int) open} for information on determining if a device is attached. - */ - public native IRLearnedCode getLastLearnedCode () throws PhidgetException; - - private final void enableDeviceSpecificEvents (boolean b) - { - enableCodeEvents (b && codeListeners.size () > 0); - enableLearnEvents (b && learnListeners.size () > 0); - enableRawDataEvents (b && rawDataListeners.size () > 0); - } - /** - * Adds a code listener. The code handler is a method that will be called when a new code is - seen by the reader. The event is fired on each code, including repetitions. - * <p> - * There is no limit on the number of code handlers that can be registered for a particular Phidget. - * - * @param l An implemetation of the {@link com.phidgets.event.CodeListener CodeListener} interface - */ - public final void addCodeListener (CodeListener l) - { - synchronized (codeListeners) - { - codeListeners.add (l); - enableCodeEvents (true); - }} private LinkedList codeListeners = new LinkedList (); - private long nativeCodeHandler = 0; - public final void removeCodeListener (CodeListener l) - { - synchronized (codeListeners) - { - codeListeners.remove (l); - enableCodeEvents (codeListeners.size () > 0); - }} private void fireCode (CodeEvent e) - { - synchronized (codeListeners) - { - for (Iterator it = codeListeners.iterator (); it.hasNext ();) - ((CodeListener) it.next ()).code (e); - } - } - private native void enableCodeEvents (boolean b); - /** - * Adds a code learn listener. The learn handler is a method that will be called when a new code is - learned by the reader. This requires that the code be repeated several times. - * <p> - * There is no limit on the number of learn handlers that can be registered for a particular Phidget. - * - * @param l An implemetation of the {@link com.phidgets.event.LearnListener LearnListener} interface - */ - public final void addLearnListener (LearnListener l) - { - synchronized (learnListeners) - { - learnListeners.add (l); - enableLearnEvents (true); - }} private LinkedList learnListeners = new LinkedList (); - private long nativeLearnHandler = 0; - public final void removeLearnListener (LearnListener l) - { - synchronized (learnListeners) - { - learnListeners.remove (l); - enableLearnEvents (learnListeners.size () > 0); - }} private void fireLearn (LearnEvent e) - { - synchronized (learnListeners) - { - for (Iterator it = learnListeners.iterator (); it.hasNext ();) - ((LearnListener) it.next ()).learn (e); - } - } - private native void enableLearnEvents (boolean b); - /** - * Adds a rawData listener. The rawData handler is a method that will be called when a raw IR data is received. - * <p> - * There is no limit on the number of rawData handlers that can be registered for a particular Phidget. - * - * @param l An implemetation of the {@link com.phidgets.event.RawDataListener RawDataListener} interface - */ - public final void addRawDataListener (RawDataListener l) - { - synchronized (rawDataListeners) - { - rawDataListeners.add (l); - enableRawDataEvents (true); - }} private LinkedList rawDataListeners = new LinkedList (); - private long nativeRawDataHandler = 0; - public final void removeRawDataListener (RawDataListener l) - { - synchronized (rawDataListeners) - { - rawDataListeners.remove (l); - enableRawDataEvents (rawDataListeners.size () > 0); - }} private void fireRawData (RawDataEvent e) - { - synchronized (rawDataListeners) - { - for (Iterator it = rawDataListeners.iterator (); it.hasNext ();) - ((RawDataListener) it.next ()).rawData (e); - } - } - private native void enableRawDataEvents (boolean b); -} +public final class IRPhidget extends Phidget
+{
+ public IRPhidget () throws PhidgetException
+ {
+ super (create ());
+ }
+ private static native long create () throws PhidgetException;
+
+ /**
+ * Represents a long space (greater then 327,670 microseconds) in raw data.
+ * This can be considered a period of no IR activity. This is used with {@link #readRaw readRaw}
+ */
+ public static final int RAWDATA_LONGSPACE = 0x7fffffff;
+
+ /**
+ * Transmits a code.
+ * @param code the code to transmit
+ * @param codeInfo the code specification
+ * @throws PhidgetException If this Phidget is not opened and attached.
+ * See {@link com.phidgets.Phidget#open(int) open} for information on determining if a device is attached.
+ */
+ public native void transmit (IRCode code, IRCodeInfo codeInfo) throws PhidgetException;
+ /**
+ * Transmits a repeat. This needs to be called within the gap time of a transmit to be meaningful.
+ * @throws PhidgetException If this Phidget is not opened and attached.
+ * See {@link com.phidgets.Phidget#open(int) open} for information on determining if a device is attached.
+ */
+ public native void transmitRepeat () throws PhidgetException;
+ /**
+ * Transmits raw data.
+ * @param data data in microseconds, must start and end with a pulse
+ * @param offset offset in the data array to start transmitting
+ * @param count number of elements of data to transmit
+ * @param gap gap size in microseconds
+ * @param carrierFrequency carrier frequency in kHz
+ * @param dutyCycle duty cycle in percent
+ * @throws PhidgetException If this Phidget is not opened and attached.
+ * See {@link com.phidgets.Phidget#open(int) open} for information on determining if a device is attached.
+ */
+ public native void transmitRaw (int[]data, int offset, int count, int gap, int carrierFrequency, int dutyCycle) throws PhidgetException;
+ /**
+ * Transmits raw data.
+ * @param data data in microseconds, must start and end with a pulse
+ * @throws PhidgetException If this Phidget is not opened and attached.
+ * See {@link com.phidgets.Phidget#open(int) open} for information on determining if a device is attached.
+ */
+ public final void transmitRaw (int[]data) throws PhidgetException
+ {
+ transmitRaw (data, 0, data.length, 0, 0, 0);
+ }
+ /**
+ * Transmits raw data.
+ * @param data data in microseconds, must start and end with a pulse
+ * @param gap gap size in microseconds
+ * @throws PhidgetException If this Phidget is not opened and attached.
+ * See {@link com.phidgets.Phidget#open(int) open} for information on determining if a device is attached.
+ */
+ public final void transmitRaw (int[]data, int gap) throws PhidgetException
+ {
+ transmitRaw (data, 0, data.length, gap, 0, 0);
+ }
+ /**
+ * Transmits raw data.
+ * @param data data in microseconds, must start and end with a pulse
+ * @param offset offset in the data array to start transmitting
+ * @param count number of elements of data to transmit
+ * @throws PhidgetException If this Phidget is not opened and attached.
+ * See {@link com.phidgets.Phidget#open(int) open} for information on determining if a device is attached.
+ */
+ public final void transmitRaw (int[]data, int offset, int count) throws PhidgetException
+ {
+ transmitRaw (data, offset, count, 0, 0, 0);
+ }
+ /**
+ * Transmits raw data.
+ * @param data data in microseconds, must start and end with a pulse
+ * @param offset offset in the data array to start transmitting
+ * @param count number of elements of data to transmit
+ * @param gap gap size in microseconds
+ * @throws PhidgetException If this Phidget is not opened and attached.
+ * See {@link com.phidgets.Phidget#open(int) open} for information on determining if a device is attached.
+ */
+ public final void transmitRaw (int[]data, int offset, int count, int gap) throws PhidgetException
+ {
+ transmitRaw (data, offset, count, gap, 0, 0);
+ }
+ /**
+ * Reads raw data. Use {@link #RAWDATA_LONGSPACE RAWDATA_LONGSPACE} to detect gaps in IR data.
+ * @param buffer array into which data will be read.
+ * @param offset offset in data to start writing
+ * @param count maximum ammount of data to read
+ * @return ammount of data read
+ * @throws PhidgetException If this Phidget is not opened and attached.
+ * See {@link com.phidgets.Phidget#open(int) open} for information on determining if a device is attached.
+ */
+ public native int readRaw (int[]buffer, int offset, int count) throws PhidgetException;
+ /**
+ * Reads raw data. Use {@link #RAWDATA_LONGSPACE RAWDATA_LONGSPACE} to detect gaps in IR data.
+ * @param buffer array into which data will be read.
+ * @return ammount of data read
+ * @throws PhidgetException If this Phidget is not opened and attached.
+ * See {@link com.phidgets.Phidget#open(int) open} for information on determining if a device is attached.
+ */
+ public final int readRaw (int[]buffer) throws PhidgetException
+ {
+ return readRaw (buffer, 0, buffer.length);
+ }
+ /**
+ * Returns the last received code. This is updated right after the code event returns.
+ * @return last code
+ * @throws PhidgetException If this Phidget is not opened and attached.
+ * See {@link com.phidgets.Phidget#open(int) open} for information on determining if a device is attached.
+ */
+ public native IRCode getLastCode () throws PhidgetException;
+ /**
+ * Returns the last learned code. This is updated right after the learn event returns.
+ * @return last learned code
+ * @throws PhidgetException If this Phidget is not opened and attached.
+ * See {@link com.phidgets.Phidget#open(int) open} for information on determining if a device is attached.
+ */
+ public native IRLearnedCode getLastLearnedCode () throws PhidgetException;
+
+ private final void enableDeviceSpecificEvents (boolean b)
+ {
+ enableCodeEvents (b && codeListeners.size () > 0);
+ enableLearnEvents (b && learnListeners.size () > 0);
+ enableRawDataEvents (b && rawDataListeners.size () > 0);
+ }
+ /**
+ * Adds a code listener. The code handler is a method that will be called when a new code is
+ seen by the reader. The event is fired on each code, including repetitions.
+ * <p>
+ * There is no limit on the number of code handlers that can be registered for a particular Phidget.
+ *
+ * @param l An implemetation of the {@link com.phidgets.event.CodeListener CodeListener} interface
+ */
+ public final void addCodeListener (CodeListener l)
+ {
+ synchronized (codeListeners)
+ {
+ codeListeners.add (l);
+ enableCodeEvents (true);
+ }} private LinkedList codeListeners = new LinkedList ();
+ private long nativeCodeHandler = 0;
+ public final void removeCodeListener (CodeListener l)
+ {
+ synchronized (codeListeners)
+ {
+ codeListeners.remove (l);
+ enableCodeEvents (codeListeners.size () > 0);
+ }} private void fireCode (CodeEvent e)
+ {
+ synchronized (codeListeners)
+ {
+ for (Iterator it = codeListeners.iterator (); it.hasNext ();)
+ ((CodeListener) it.next ()).code (e);
+ }
+ }
+ private native void enableCodeEvents (boolean b);
+ /**
+ * Adds a code learn listener. The learn handler is a method that will be called when a new code is
+ learned by the reader. This requires that the code be repeated several times.
+ * <p>
+ * There is no limit on the number of learn handlers that can be registered for a particular Phidget.
+ *
+ * @param l An implemetation of the {@link com.phidgets.event.LearnListener LearnListener} interface
+ */
+ public final void addLearnListener (LearnListener l)
+ {
+ synchronized (learnListeners)
+ {
+ learnListeners.add (l);
+ enableLearnEvents (true);
+ }} private LinkedList learnListeners = new LinkedList ();
+ private long nativeLearnHandler = 0;
+ public final void removeLearnListener (LearnListener l)
+ {
+ synchronized (learnListeners)
+ {
+ learnListeners.remove (l);
+ enableLearnEvents (learnListeners.size () > 0);
+ }} private void fireLearn (LearnEvent e)
+ {
+ synchronized (learnListeners)
+ {
+ for (Iterator it = learnListeners.iterator (); it.hasNext ();)
+ ((LearnListener) it.next ()).learn (e);
+ }
+ }
+ private native void enableLearnEvents (boolean b);
+ /**
+ * Adds a rawData listener. The rawData handler is a method that will be called when a raw IR data is received.
+ * <p>
+ * There is no limit on the number of rawData handlers that can be registered for a particular Phidget.
+ *
+ * @param l An implemetation of the {@link com.phidgets.event.RawDataListener RawDataListener} interface
+ */
+ public final void addRawDataListener (RawDataListener l)
+ {
+ synchronized (rawDataListeners)
+ {
+ rawDataListeners.add (l);
+ enableRawDataEvents (true);
+ }} private LinkedList rawDataListeners = new LinkedList ();
+ private long nativeRawDataHandler = 0;
+ public final void removeRawDataListener (RawDataListener l)
+ {
+ synchronized (rawDataListeners)
+ {
+ rawDataListeners.remove (l);
+ enableRawDataEvents (rawDataListeners.size () > 0);
+ }} private void fireRawData (RawDataEvent e)
+ {
+ synchronized (rawDataListeners)
+ {
+ for (Iterator it = rawDataListeners.iterator (); it.hasNext ();)
+ ((RawDataListener) it.next ()).rawData (e);
+ }
+ }
+ private native void enableRawDataEvents (boolean b);
+}
diff --git a/Java/com/phidgets/LEDPhidget.java b/Java/com/phidgets/LEDPhidget.java index a1530f3..d26ce90 100644 --- a/Java/com/phidgets/LEDPhidget.java +++ b/Java/com/phidgets/LEDPhidget.java @@ -1,6 +1,6 @@ /* - * Copyright 2012 Phidgets Inc. All rights reserved. + * Copyright 2006 Phidgets Inc. All rights reserved. */ package com.phidgets; @@ -16,9 +16,6 @@ import com.phidgets.event.*; so this number is not absolute. <p> LEDs can be controlled individually, at brightness levels from 0-100. - * See your device's User Guide for more specific API details, - * technical information, and revision details. The User Guide, along with other resources, can be found on - * the product page for your device. * * @author Phidgets Inc. */ @@ -121,23 +118,47 @@ public final class LEDPhidget extends Phidget */ public native int getLEDCount () throws PhidgetException; /** + * Deprecated. Use {@link #getBrightness getBrightness} + */ + public native int getDiscreteLED (int index) throws PhidgetException; + /** + * Deprecated. Use {@link #setBrightness setBrightness} + */ + public native void setDiscreteLED (int index, int brightness) throws PhidgetException; + /** * Returns the brightness value of an LED. This value ranges from 0-100. * @param index LED * @return brightness * @throws PhidgetException If this Phidget is not opened and attached, or if the index is out of range. * See {@link com.phidgets.Phidget#open(int) open} for information on determining if a device is attached. */ - public native int getDiscreteLED (int index) throws PhidgetException; + public native double getBrightness (int index) throws PhidgetException; /** * Sets the brightness of an LED. - * Valid values are 0-100, with 0 being off and 100 being the brightest. This 0-100 value is converted internally to a - 6-bit value (0-63) so only 64 levels of brightness are actually possible. + * Valid values are 0-100, with 0 being off and 100 being the brightest. * @param index index of the LED * @param brightness desired brightness of this LED - * @throws PhidgetException If this Phidget is not opened and attached, or if the index of brightness value are out of range. + * @throws PhidgetException If this Phidget is not opened and attached, or if the index or brightness value are out of range. * See {@link com.phidgets.Phidget#open(int) open} for information on determining if a device is attached. */ - public native void setDiscreteLED (int index, int brightness) throws PhidgetException; + public native void setBrightness (int index, double brightness) throws PhidgetException; + /** + * Returns the current limit value of an LED. This value ranges from 0-80 mA. + * @param index LED + * @return current limit + * @throws PhidgetException If this Phidget is not opened and attached, or if the index is out of range. + * See {@link com.phidgets.Phidget#open(int) open} for information on determining if a device is attached. + */ + public native double getCurrentLimit (int index) throws PhidgetException; + /** + * Sets the current limit of an LED. + * Valid values are 0-80 mA. + * @param index index of the LED + * @param limit desired current limit of this LED + * @throws PhidgetException If this Phidget is not opened and attached, or if the index or limit value are out of range. + * See {@link com.phidgets.Phidget#open(int) open} for information on determining if a device is attached. + */ + public native void setCurrentLimit (int index, double limit) throws PhidgetException; private final void enableDeviceSpecificEvents (boolean b) { } diff --git a/Java/com/phidgets/MotorControlPhidget.java b/Java/com/phidgets/MotorControlPhidget.java index 19ce88c..8539b98 100644 --- a/Java/com/phidgets/MotorControlPhidget.java +++ b/Java/com/phidgets/MotorControlPhidget.java @@ -9,16 +9,13 @@ import java.util.LinkedList; import com.phidgets.event.*; /** * This class represents a Phidget Motor Controller. All Methods - * to to control a DC motor controller and read back motor data are implemented in this class. + * to to control a motor controller and read back motor data are implemented in this class. <p> The Motor Control Phidget is able to control 1 or more DC motors. Both speed and acceleration are controllable. Speed is controlled via PWM. The size of the motors that can be driven depends on the motor controller. See your hardware documentation for more information. <p> - The motor Controller boards also have 0 or more digital inputs. - * See your device's User Guide for more specific API details, - * technical information, and revision details. The User Guide, along with other resources, can be found on - * the product page for your device. + The motor Controller boards also has 0 or more digital inputs. * * @author Phidgets Inc. */ diff --git a/Java/com/phidgets/PHSensorPhidget.java b/Java/com/phidgets/PHSensorPhidget.java index fa2d7ff..dc9ecf6 100644 --- a/Java/com/phidgets/PHSensorPhidget.java +++ b/Java/com/phidgets/PHSensorPhidget.java @@ -1,6 +1,6 @@ /* - * Copyright 2012 Phidgets Inc. All rights reserved. + * Copyright 2006 Phidgets Inc. All rights reserved. */ package com.phidgets; @@ -12,9 +12,6 @@ import com.phidgets.event.*; * to read pH data from the PH Sensor are implemented in this class. * <p> * The Phidget PH Sensor provides one standard pH sensor input. - * See your device's User Guide for more specific API details, - * technical information, and revision details. The User Guide, along with other resources, can be found on - * the product page for your device. * * @author Phidgets Inc. */ diff --git a/Java/com/phidgets/Phidget.java b/Java/com/phidgets/Phidget.java index 5faf96a..c8d0cd3 100644 --- a/Java/com/phidgets/Phidget.java +++ b/Java/com/phidgets/Phidget.java @@ -204,8 +204,8 @@ public class Phidget /* These are all current devices */ public static final int PHIDID_ACCELEROMETER_3AXIS = 0x07E; public static final int PHIDID_ADVANCEDSERVO_1MOTOR = 0x082; - public static final int PHIDID_ANALOG_4OUTPUT = 0x037; public static final int PHIDID_ADVANCEDSERVO_8MOTOR = 0x03A; + public static final int PHIDID_ANALOG_4OUTPUT = 0x037; public static final int PHIDID_BIPOLAR_STEPPER_1MOTOR = 0x07B; public static final int PHIDID_BRIDGE_4INPUT = 0x03B; public static final int PHIDID_ENCODER_1ENCODER_1INPUT = 0x04B; @@ -216,23 +216,22 @@ public class Phidget public static final int PHIDID_INTERFACEKIT_0_0_4 = 0x040; public static final int PHIDID_INTERFACEKIT_0_0_8 = 0x081; public static final int PHIDID_INTERFACEKIT_0_16_16 = 0x044; + public static final int PHIDID_INTERFACEKIT_2_2_2 = 0x036; public static final int PHIDID_INTERFACEKIT_8_8_8 = 0x045; public static final int PHIDID_INTERFACEKIT_8_8_8_w_LCD = 0x07D; public static final int PHIDID_IR = 0x04D; - public static final int PHIDID_LED_64 = 0x04A; public static final int PHIDID_LED_64_ADV = 0x04C; public static final int PHIDID_LINEAR_TOUCH = 0x076; + public static final int PHIDID_MOTORCONTROL_1MOTOR = 0x03E; public static final int PHIDID_MOTORCONTROL_HC_2MOTOR = 0x059; - public static final int PHIDID_MOTORCONTROL_LV_2MOTOR_4INPUT = 0x058; - public static final int PHIDID_MOTORCONTROL_1MOTOR = 0x03E; - public static final int PHIDID_PHSENSOR = 0x074; public static final int PHIDID_RFID_2OUTPUT = 0x031; + public static final int PHIDID_RFID_2OUTPUT_READ_WRITE = 0x034; public static final int PHIDID_ROTARY_TOUCH = 0x077; - public static final int PHIDID_SERVO_1MOTOR = 0x039; public static final int PHIDID_SPATIAL_ACCEL_3AXIS = 0x07F; public static final int PHIDID_SPATIAL_ACCEL_GYRO_COMPASS = 0x033; public static final int PHIDID_TEMPERATURESENSOR = 0x070; public static final int PHIDID_TEMPERATURESENSOR_4 = 0x032; + public static final int PHIDID_TEMPERATURESENSOR_IR = 0x03C; public static final int PHIDID_TEXTLCD_2x20_w_8_8_8 = 0x17D; public static final int PHIDID_TEXTLCD_ADAPTER = 0x03D; public static final int PHIDID_UNIPOLAR_STEPPER_4MOTOR = 0x07A; @@ -241,7 +240,11 @@ public class Phidget public static final int PHIDID_ACCELEROMETER_2AXIS = 0x071; public static final int PHIDID_INTERFACEKIT_0_8_8_w_LCD = 0x053; public static final int PHIDID_INTERFACEKIT_4_8_8 = 4; + public static final int PHIDID_LED_64 = 0x04A; + public static final int PHIDID_MOTORCONTROL_LV_2MOTOR_4INPUT = 0x058; + public static final int PHIDID_PHSENSOR = 0x074; public static final int PHIDID_RFID = 0x030; + public static final int PHIDID_SERVO_1MOTOR = 0x039; public static final int PHIDID_SERVO_1MOTOR_OLD = 2; public static final int PHIDID_SERVO_4MOTOR = 0x038; public static final int PHIDID_SERVO_4MOTOR_OLD = 3; diff --git a/Java/com/phidgets/RFIDPhidget.java b/Java/com/phidgets/RFIDPhidget.java index 20a0ee2..26f38a3 100644 --- a/Java/com/phidgets/RFIDPhidget.java +++ b/Java/com/phidgets/RFIDPhidget.java @@ -1,6 +1,6 @@ /* - * Copyright 2012 Phidgets Inc. All rights reserved. + * Copyright 2006 Phidgets Inc. All rights reserved. */ package com.phidgets; @@ -12,10 +12,7 @@ import com.phidgets.event.*; * to read tags and set outputs on the RFID reader are implemented in this class. * <p> * The Phidget RFID reader can read one tag at a time. Both tag and tagloss event handlers are provided, - * as well as control over the antenna so that multiple readers can exist in close proximity without interference. - * See your device's User Guide for more specific API details, - * technical information, and revision details. The User Guide, along with other resources, can be found on - * the product page for your device. + * as well as control over the antenna so that multiple readers can exists in close proximity without interference. * * @author Phidgets Inc. */ @@ -26,6 +23,20 @@ public final class RFIDPhidget extends Phidget super (create ()); } private static native long create () throws PhidgetException; + + /** + * EM4100 (EM4102) 40-bit. This is used with {@link #getLastTagProtocol() getSgetLastTagProtocolcreenSize} and {@link #write(String, int, boolean) write} + */ + public static final int PHIDGET_RFID_PROTOCOL_EM4100 = 1; + /** + * ISO11785 FDX-B encoding (Animal ID). This is used with {@link #getLastTagProtocol() getSgetLastTagProtocolcreenSize} and {@link #write(String, int, boolean) write} + */ + public static final int PHIDGET_RFID_PROTOCOL_ISO11785_FDX_B = 2; + /** + * PhidgetsTAG Protocol 24 character ASCII. This is used with {@link #getLastTagProtocol() getSgetLastTagProtocolcreenSize} and {@link #write(String, int, boolean) write} + */ + public static final int PHIDGET_RFID_PROTOCOL_PHIDGETS = 3; + /** * Returns the number of outputs. These are the outputs provided by the terminal block. * Older RFID readers do not have these outputs, and this method will return 0. @@ -90,6 +101,14 @@ public final class RFIDPhidget extends Phidget */ public native String getLastTag () throws PhidgetException; /** + * Returns the protocol of the last tag read. This method will only return a valid protocol after a tag has been seen. + * This method can be used even after a tag has been removed from the reader + * @return protocol + * @throws PhidgetException If this Phidget is not opened and attached. + * See {@link com.phidgets.Phidget#open(int) open} for information on determining if a device is attached. + */ + public native int getLastTagProtocol () throws PhidgetException; + /** * Returns the state of whether or not a tag is being read by the reader. * True indicated that a tag is on (or near) the reader, false indicates that one is not. * @return tag read state @@ -97,6 +116,15 @@ public final class RFIDPhidget extends Phidget * See {@link com.phidgets.Phidget#open(int) open} for information on determining if a device is attached. */ public native boolean getTagStatus () throws PhidgetException; + /** + * Writes a tag. + * @param tag tag string + * @param protocol tag protocol + * @param lock lock tag from futher writes + * @throws PhidgetException If this Phidget is not opened and attached, if the string is too malformed, or the protocol is invalid. + * See {@link com.phidgets.Phidget#open(int) open} for information on determining if a device is attached. + */ + public native void write (String tag, int protocol, boolean lock) throws PhidgetException; private final void enableDeviceSpecificEvents (boolean b) { diff --git a/Java/com/phidgets/ServoPhidget.java b/Java/com/phidgets/ServoPhidget.java index f052b15..aa9f05f 100644 --- a/Java/com/phidgets/ServoPhidget.java +++ b/Java/com/phidgets/ServoPhidget.java @@ -1,6 +1,6 @@ /* - * Copyright 2012 Phidgets Inc. All rights reserved. + * Copyright 2006 Phidgets Inc. All rights reserved. */ package com.phidgets; @@ -13,9 +13,6 @@ import com.phidgets.event.*; * <p> * The Phidget Sevo controller simply outputs varying widths of PWM, which is what * most servo motors take as an input driving signal. - * See your device's User Guide for more specific API details, - * technical information, and revision details. The User Guide, along with other resources, can be found on - * the product page for your device. * * @author Phidgets Inc. */ diff --git a/Java/com/phidgets/SpatialPhidget.java b/Java/com/phidgets/SpatialPhidget.java index 599f361..bec1de7 100644 --- a/Java/com/phidgets/SpatialPhidget.java +++ b/Java/com/phidgets/SpatialPhidget.java @@ -1,6 +1,6 @@ /*
- * Copyright 2012 Phidgets Inc. All rights reserved.
+ * Copyright 2006 Phidgets Inc. All rights reserved.
*/
package com.phidgets;
@@ -11,9 +11,6 @@ import com.phidgets.event.*; * This class represents a Phidget Spatial. All methods for a PhidgetSpatial are implemented in this class.
<p>
The Phidget Spatial may provide up to 3 axes of acceleration data, 3 axes of angular rate data and 3 axes of magnetic field data.
- * See your device's User Guide for more specific API details,
- * technical information, and revision details. The User Guide, along with other resources, can be found on
- * the product page for your device.
* @author Phidgets Inc.
*/
diff --git a/Java/com/phidgets/StepperPhidget.java b/Java/com/phidgets/StepperPhidget.java index aed6b1a..83fa772 100644 --- a/Java/com/phidgets/StepperPhidget.java +++ b/Java/com/phidgets/StepperPhidget.java @@ -1,6 +1,6 @@ /*
- * Copyright 2012 Phidgets Inc. All rights reserved.
+ * Copyright 2006 Phidgets Inc. All rights reserved.
*/
package com.phidgets;
@@ -9,14 +9,11 @@ import java.util.LinkedList; import com.phidgets.event.*;
/**
* This class represents a Phidget Stepper Controller. All methods
- * to control a stepper controller and read back stepper data are implemented in this class.
+ * to to control a stepper controller and read back stepper data are implemented in this class.
* <p>
* The Phidget Stepper is able to control 1 or more Stepper motors. Motor Acceleration and Velocity are
- * controllable, and micro-stepping is used for bipolar motors. The type and number of motors that can be controlled
+ * controllable, and micro-stepping is used. The type and number of motors that can be controlled
* depend on the Stepper Controller. Digital inputs are available on select Phidget Stepper Controllers.
- * See your device's User Guide for more specific API details,
- * technical information, and revision details. The User Guide, along with other resources, can be found on
- * the product page for your device.
*
* @author Phidgets Inc.
*/
diff --git a/Java/com/phidgets/TemperatureSensorPhidget.java b/Java/com/phidgets/TemperatureSensorPhidget.java index 83ff326..baaa589 100644 --- a/Java/com/phidgets/TemperatureSensorPhidget.java +++ b/Java/com/phidgets/TemperatureSensorPhidget.java @@ -1,6 +1,6 @@ /* - * Copyright 2012 Phidgets Inc. All rights reserved. + * Copyright 2006 Phidgets Inc. All rights reserved. */ package com.phidgets; @@ -16,9 +16,6 @@ import com.phidgets.event.*; * and calibrate the thermocouple sensed temperature. * <p> * Both the thermocouple and temperature IC temperatures can be read. Value are returned in degrees celcius. - * See your device's User Guide for more specific API details, - * technical information, and revision details. The User Guide, along with other resources, can be found on - * the product page for your device. * * @author Phidgets Inc. */ diff --git a/Java/com/phidgets/TextLCDPhidget.java b/Java/com/phidgets/TextLCDPhidget.java index 92c3790..ac4c500 100644 --- a/Java/com/phidgets/TextLCDPhidget.java +++ b/Java/com/phidgets/TextLCDPhidget.java @@ -1,6 +1,6 @@ /* - * Copyright 2012 Phidgets Inc. All rights reserved. + * Copyright 2011 Phidgets Inc. All rights reserved. */ package com.phidgets; @@ -13,9 +13,6 @@ import com.phidgets.event.*; * <p> * The TextLCD Phidget consists of a Vacuum Fluorescent display that is capable of * displaying Standard as well as custom characters in multiple rows. - * See your device's User Guide for more specific API details, - * technical information, and revision details. The User Guide, along with other resources, can be found on - * the product page for your device. * * @author Phidgets Inc. */ diff --git a/Java/com/phidgets/TextLEDPhidget.java b/Java/com/phidgets/TextLEDPhidget.java index 45e2720..a2f39c8 100644 --- a/Java/com/phidgets/TextLEDPhidget.java +++ b/Java/com/phidgets/TextLEDPhidget.java @@ -1,6 +1,6 @@ /* - * Copyright 2012 Phidgets Inc. All rights reserved. + * Copyright 2006 Phidgets Inc. All rights reserved. */ package com.phidgets; @@ -14,9 +14,6 @@ import com.phidgets.event.*; * The Text LED is a Phidget that displays text and numerals on LED * numeric display in rows. The number of rows and size of each row depends on * your configuration. - * See your device's User Guide for more specific API details, - * technical information, and revision details. The User Guide, along with other resources, can be found on - * the product page for your device. * * @author Phidgets Inc. */ diff --git a/Java/com/phidgets/WeightSensorPhidget.java b/Java/com/phidgets/WeightSensorPhidget.java index e1c5728..b2bd9e8 100644 --- a/Java/com/phidgets/WeightSensorPhidget.java +++ b/Java/com/phidgets/WeightSensorPhidget.java @@ -1,6 +1,6 @@ /* - * Copyright 2012 Phidgets Inc. All rights reserved. + * Copyright 2006 Phidgets Inc. All rights reserved. */ package com.phidgets; @@ -13,9 +13,6 @@ import com.phidgets.event.*; * <p> * The Phidget Weight Sensor is simply an electronic scale with a USB interface. * It provides one weight value, in kg. - * See your device's User Guide for more specific API details, - * technical information, and revision details. The User Guide, along with other resources, can be found on - * the product page for your device. * * @author Phidget Inc. */ diff --git a/Java/com/phidgets/event/TagGainEvent.java b/Java/com/phidgets/event/TagGainEvent.java index 6cb7a74..8639ae4 100644 --- a/Java/com/phidgets/event/TagGainEvent.java +++ b/Java/com/phidgets/event/TagGainEvent.java @@ -15,6 +15,7 @@ public class TagGainEvent { Phidget source; String value; + int protocol; /** * Class constructor. This is called internally by the phidget library when creating this event. @@ -26,6 +27,12 @@ public class TagGainEvent this.source = source; this.value = value; } + public TagGainEvent(Phidget source, String value, int protocol) + { + this.source = source; + this.value = value; + this.protocol = protocol; + } /** * Returns the source Phidget of this event. This is a reference to the Phidget object from which this @@ -39,7 +46,7 @@ public class TagGainEvent } /** - * Returns the gained tag. The tag is a 10 digit hex number represented as a string. + * Returns the gained tag. * * @return the gained tag */ @@ -48,6 +55,15 @@ public class TagGainEvent } /** + * Returns the protocol of the Tag that was lost. + * + * @return the lost tag protocol + */ + public int getProtocol() { + return protocol; + } + + /** * Returns a string containing information about the event. * * @return an informative event string diff --git a/Java/com/phidgets/event/TagLossEvent.java b/Java/com/phidgets/event/TagLossEvent.java index ccca4fe..8dcd723 100644 --- a/Java/com/phidgets/event/TagLossEvent.java +++ b/Java/com/phidgets/event/TagLossEvent.java @@ -15,6 +15,7 @@ public class TagLossEvent { Phidget source; String value; + int protocol; /** * Class constructor. This is called internally by the phidget library when creating this event. @@ -26,6 +27,12 @@ public class TagLossEvent this.source = source; this.value = value; } + public TagLossEvent(Phidget source, String value, int protocol) + { + this.source = source; + this.value = value; + this.protocol = protocol; + } /** * Returns the source Phidget of this event. This is a reference to the Phidget object from which this @@ -39,7 +46,7 @@ public class TagLossEvent } /** - * Returns the Tag that was lost. This is a 10 digit hex number as a string. + * Returns the Tag that was lost. * * @return the lost tag */ @@ -48,6 +55,15 @@ public class TagLossEvent } /** + * Returns the protocol of the Tag that was lost. + * + * @return the lost tag protocol + */ + public int getProtocol() { + return protocol; + } + + /** * Returns a string containing information about the event. * * @return an informative event string diff --git a/Java/com_phidgets_LEDPhidget.c b/Java/com_phidgets_LEDPhidget.c index 20097b9..c5fb201 100644 --- a/Java/com_phidgets_LEDPhidget.c +++ b/Java/com_phidgets_LEDPhidget.c @@ -9,10 +9,14 @@ JNI_LOAD(accel, LED) JNI_CREATE(LED) JNI_INDEXED_GETFUNC(LED, DiscreteLED, DiscreteLED, jint) JNI_INDEXED_SETFUNC(LED, DiscreteLED, DiscreteLED, jint) +JNI_INDEXED_GETFUNC(LED, Brightness, Brightness, jdouble) +JNI_INDEXED_SETFUNC(LED, Brightness, Brightness, jdouble) +JNI_INDEXED_GETFUNC(LED, CurrentLimit__I, CurrentLimitIndexed, jdouble) +JNI_INDEXED_SETFUNC(LED, CurrentLimit__ID, CurrentLimitIndexed, jdouble) JNI_GETFUNC(LED, LEDCount, LEDCount, jint) JNIEXPORT jint JNICALL -Java_com_phidgets_LEDPhidget_getCurrentLimit(JNIEnv *env, jobject obj) +Java_com_phidgets_LEDPhidget_getCurrentLimit__(JNIEnv *env, jobject obj) { CPhidgetLEDHandle h = (CPhidgetLEDHandle)(uintptr_t) (*env)->GetLongField(env, obj, handle_fid); @@ -22,7 +26,7 @@ Java_com_phidgets_LEDPhidget_getCurrentLimit(JNIEnv *env, jobject obj) PH_THROW(error); return (jint)v; } -JNI_SETFUNC(LED, CurrentLimit, CurrentLimit, jint) +JNI_SETFUNC(LED, CurrentLimit__I, CurrentLimit, jint) JNIEXPORT jint JNICALL Java_com_phidgets_LEDPhidget_getVoltage(JNIEnv *env, jobject obj) diff --git a/Java/com_phidgets_LEDPhidget.h b/Java/com_phidgets_LEDPhidget.h index be631c8..0fe8e65 100644 --- a/Java/com_phidgets_LEDPhidget.h +++ b/Java/com_phidgets_LEDPhidget.h @@ -180,7 +180,7 @@ JNIEXPORT jlong JNICALL Java_com_phidgets_LEDPhidget_create * Method: getCurrentLimit * Signature: ()I */ -JNIEXPORT jint JNICALL Java_com_phidgets_LEDPhidget_getCurrentLimit +JNIEXPORT jint JNICALL Java_com_phidgets_LEDPhidget_getCurrentLimit__ (JNIEnv *, jobject); /* @@ -188,7 +188,7 @@ JNIEXPORT jint JNICALL Java_com_phidgets_LEDPhidget_getCurrentLimit * Method: setCurrentLimit * Signature: (I)V */ -JNIEXPORT void JNICALL Java_com_phidgets_LEDPhidget_setCurrentLimit +JNIEXPORT void JNICALL Java_com_phidgets_LEDPhidget_setCurrentLimit__I (JNIEnv *, jobject, jint); /* @@ -231,6 +231,38 @@ JNIEXPORT jint JNICALL Java_com_phidgets_LEDPhidget_getDiscreteLED JNIEXPORT void JNICALL Java_com_phidgets_LEDPhidget_setDiscreteLED (JNIEnv *, jobject, jint, jint); +/* + * Class: com_phidgets_LEDPhidget + * Method: getBrightness + * Signature: (I)D + */ +JNIEXPORT jdouble JNICALL Java_com_phidgets_LEDPhidget_getBrightness + (JNIEnv *, jobject, jint); + +/* + * Class: com_phidgets_LEDPhidget + * Method: setBrightness + * Signature: (ID)V + */ +JNIEXPORT void JNICALL Java_com_phidgets_LEDPhidget_setBrightness + (JNIEnv *, jobject, jint, jdouble); + +/* + * Class: com_phidgets_LEDPhidget + * Method: getCurrentLimit + * Signature: (I)D + */ +JNIEXPORT jdouble JNICALL Java_com_phidgets_LEDPhidget_getCurrentLimit__I + (JNIEnv *, jobject, jint); + +/* + * Class: com_phidgets_LEDPhidget + * Method: setCurrentLimit + * Signature: (ID)V + */ +JNIEXPORT void JNICALL Java_com_phidgets_LEDPhidget_setCurrentLimit__ID + (JNIEnv *, jobject, jint, jdouble); + #ifdef __cplusplus } #endif diff --git a/Java/com_phidgets_RFIDPhidget.c b/Java/com_phidgets_RFIDPhidget.c index c20b8ad..cfd9b10 100644 --- a/Java/com_phidgets_RFIDPhidget.c +++ b/Java/com_phidgets_RFIDPhidget.c @@ -9,35 +9,33 @@ EVENT_VARS(tagGain, TagGain) JNI_LOAD(rfid, RFID) EVENT_VAR_SETUP(rfid, outputChange, OutputChange, IZ, V) - EVENT_VAR_SETUP(rfid, tagLoss, TagLoss, Ljava/lang/String;, V) - EVENT_VAR_SETUP(rfid, tagGain, TagGain, Ljava/lang/String;, V) + EVENT_VAR_SETUP(rfid, tagLoss, TagLoss, Ljava/lang/String;I, V) + EVENT_VAR_SETUP(rfid, tagGain, TagGain, Ljava/lang/String;I, V) } EVENT_HANDLER_INDEXED(RFID, outputChange, OutputChange, CPhidgetRFID_set_OnOutputChange_Handler, int) -static int CCONV tagLoss_handler (CPhidgetRFIDHandle h, void *arg, unsigned char *); +static int CCONV tagLoss_handler (CPhidgetRFIDHandle h, void *arg, char *, CPhidgetRFID_Protocol); JNIEXPORT void JNICALL Java_com_phidgets_RFIDPhidget_enableTagLossEvents (JNIEnv * env, jobject obj, jboolean b) { jlong gr = updateGlobalRef (env, obj, nativeTagLossHandler_fid, b); CPhidgetRFIDHandle h = (CPhidgetRFIDHandle) (uintptr_t) (*env)->GetLongField (env, obj, handle_fid); - CPhidgetRFID_set_OnTagLost_Handler (h, b ? tagLoss_handler : 0, (void *) (uintptr_t) gr); + CPhidgetRFID_set_OnTagLost2_Handler (h, b ? tagLoss_handler : 0, (void *) (uintptr_t) gr); } static int CCONV -tagLoss_handler (CPhidgetRFIDHandle h, void *arg, unsigned char *v) +tagLoss_handler (CPhidgetRFIDHandle h, void *arg, char *v, CPhidgetRFID_Protocol proto) { JNIEnv *env; jobject obj; jobject tagLossEv; - char stringbuffer[20]; jstring jb; if ((*ph_vm)->AttachCurrentThread (ph_vm, (JNIEnvPtr) &env, ((void *) 0))) JNI_ABORT_STDERR("Couldn't AttachCurrentThread"); obj = (jobject) arg; - sprintf(stringbuffer, "%02x%02x%02x%02x%02x",v[0],v[1],v[2],v[3],v[4]); - jb=(*env)->NewStringUTF(env, stringbuffer); + jb=(*env)->NewStringUTF(env, v); - if (!(tagLossEv = (*env)->NewObject (env, tagLossEvent_class, tagLossEvent_cons, obj, jb))) + if (!(tagLossEv = (*env)->NewObject (env, tagLossEvent_class, tagLossEvent_cons, obj, jb, (int)proto))) return -1; (*env)->CallVoidMethod (env, obj, fireTagLoss_mid, tagLossEv); (*env)->DeleteLocalRef (env, tagLossEv); @@ -45,28 +43,26 @@ tagLoss_handler (CPhidgetRFIDHandle h, void *arg, unsigned char *v) return 0; } -static int CCONV tagGain_handler (CPhidgetRFIDHandle h, void *arg, unsigned char *); +static int CCONV tagGain_handler (CPhidgetRFIDHandle h, void *arg, char *, CPhidgetRFID_Protocol); JNIEXPORT void JNICALL Java_com_phidgets_RFIDPhidget_enableTagGainEvents (JNIEnv * env, jobject obj, jboolean b) { jlong gr = updateGlobalRef (env, obj, nativeTagGainHandler_fid, b); CPhidgetRFIDHandle h = (CPhidgetRFIDHandle) (uintptr_t) (*env)->GetLongField (env, obj, handle_fid); - CPhidgetRFID_set_OnTag_Handler (h, b ? tagGain_handler : 0, (void *) (uintptr_t) gr); + CPhidgetRFID_set_OnTag2_Handler (h, b ? tagGain_handler : 0, (void *) (uintptr_t) gr); } static int CCONV -tagGain_handler (CPhidgetRFIDHandle h, void *arg, unsigned char *v) +tagGain_handler (CPhidgetRFIDHandle h, void *arg, char *v, CPhidgetRFID_Protocol proto) { JNIEnv *env; jobject obj; jobject tagGainEv; - char stringbuffer[20]; jstring jb; if ((*ph_vm)->AttachCurrentThread (ph_vm, (JNIEnvPtr) &env, ((void *) 0))) JNI_ABORT_STDERR("Couldn't AttachCurrentThread"); obj = (jobject) arg; - sprintf(stringbuffer, "%02x%02x%02x%02x%02x",v[0],v[1],v[2],v[3],v[4]); - jb=(*env)->NewStringUTF(env, stringbuffer); + jb=(*env)->NewStringUTF(env, v); - if (!(tagGainEv = (*env)->NewObject (env, tagGainEvent_class, tagGainEvent_cons, obj, jb))) + if (!(tagGainEv = (*env)->NewObject (env, tagGainEvent_class, tagGainEvent_cons, obj, jb, (int)proto))) return -1; (*env)->CallVoidMethod (env, obj, fireTagGain_mid, tagGainEv); (*env)->DeleteLocalRef (env, tagGainEv); @@ -91,14 +87,44 @@ Java_com_phidgets_RFIDPhidget_getLastTag (JNIEnv *env, jobject obj) CPhidgetRFIDHandle h = (CPhidgetRFIDHandle)(uintptr_t) (*env)->GetLongField( env, obj, handle_fid); int error; - unsigned char buffer[11]; - char stringbuffer[20]; + char *tag; jstring jb; - if ((error = CPhidgetRFID_getLastTag(h, (unsigned char *)&buffer))) + CPhidgetRFID_Protocol proto; + if ((error = CPhidgetRFID_getLastTag2(h, &tag, &proto))) PH_THROW(error); - sprintf(stringbuffer, "%02x%02x%02x%02x%02x",buffer[0],buffer[1],buffer[2],buffer[3],buffer[4]); - - jb=(*env)->NewStringUTF(env, stringbuffer); + jb=(*env)->NewStringUTF(env, tag); return jb; } + +JNIEXPORT jint JNICALL +Java_com_phidgets_RFIDPhidget_getLastTagProtocol (JNIEnv *env, jobject obj) +{ + CPhidgetRFIDHandle h = (CPhidgetRFIDHandle)(uintptr_t) + (*env)->GetLongField( env, obj, handle_fid); + int error; + char *tag; + CPhidgetRFID_Protocol proto; + if ((error = CPhidgetRFID_getLastTag2(h, &tag, &proto))) + PH_THROW(error); + + return (jint)proto; +} + +JNIEXPORT void JNICALL Java_com_phidgets_RFIDPhidget_write + (JNIEnv *env, jobject obj, jstring tag, jint proto, jboolean lock) +{ + int error; + + jboolean iscopy; + const char *tagString = (*env)->GetStringUTFChars( + env, tag, &iscopy); + + CPhidgetRFIDHandle h = (CPhidgetRFIDHandle)(uintptr_t) + (*env)->GetLongField(env, obj, handle_fid); + + if ((error = CPhidgetRFID_write(h, (char *)tagString, (CPhidgetRFID_Protocol)proto, (int)lock))) + PH_THROW(error); + + (*env)->ReleaseStringUTFChars(env, tag, tagString); +}
\ No newline at end of file diff --git a/Java/com_phidgets_RFIDPhidget.h b/Java/com_phidgets_RFIDPhidget.h index d6a123e..c136a58 100644 --- a/Java/com_phidgets_RFIDPhidget.h +++ b/Java/com_phidgets_RFIDPhidget.h @@ -151,6 +151,12 @@ extern "C" { #define com_phidgets_RFIDPhidget_PHIDCLASS_TEXTLED 16L #undef com_phidgets_RFIDPhidget_PHIDCLASS_WEIGHTSENSOR #define com_phidgets_RFIDPhidget_PHIDCLASS_WEIGHTSENSOR 17L +#undef com_phidgets_RFIDPhidget_PHIDGET_RFID_PROTOCOL_EM4100 +#define com_phidgets_RFIDPhidget_PHIDGET_RFID_PROTOCOL_EM4100 1L +#undef com_phidgets_RFIDPhidget_PHIDGET_RFID_PROTOCOL_ISO11785_FDX_B +#define com_phidgets_RFIDPhidget_PHIDGET_RFID_PROTOCOL_ISO11785_FDX_B 2L +#undef com_phidgets_RFIDPhidget_PHIDGET_RFID_PROTOCOL_PHIDGETS +#define com_phidgets_RFIDPhidget_PHIDGET_RFID_PROTOCOL_PHIDGETS 3L /* * Class: com_phidgets_RFIDPhidget * Method: create @@ -225,6 +231,14 @@ JNIEXPORT jstring JNICALL Java_com_phidgets_RFIDPhidget_getLastTag /* * Class: com_phidgets_RFIDPhidget + * Method: getLastTagProtocol + * Signature: ()I + */ +JNIEXPORT jint JNICALL Java_com_phidgets_RFIDPhidget_getLastTagProtocol + (JNIEnv *, jobject); + +/* + * Class: com_phidgets_RFIDPhidget * Method: getTagStatus * Signature: ()Z */ @@ -233,6 +247,14 @@ JNIEXPORT jboolean JNICALL Java_com_phidgets_RFIDPhidget_getTagStatus /* * Class: com_phidgets_RFIDPhidget + * Method: write + * Signature: (Ljava/lang/String;IZ)V + */ +JNIEXPORT void JNICALL Java_com_phidgets_RFIDPhidget_write + (JNIEnv *, jobject, jstring, jint, jboolean); + +/* + * Class: com_phidgets_RFIDPhidget * Method: enableTagGainEvents * Signature: (Z)V */ diff --git a/Java/phidget_jni.h b/Java/phidget_jni.h index 2325fd0..61c675d 100644 --- a/Java/phidget_jni.h +++ b/Java/phidget_jni.h @@ -109,6 +109,7 @@ void com_phidgets_##Pname##Phidget_OnLoad(JNIEnv *env) \ if (!(eobj = (*env)->NewObject(env, ph_exception_class, ph_exception_cons, errno, edesc))) \ JNI_ABORT_STDERR("Couldn't get NewObject ph_exception_class"); \ (*env)->Throw(env, (jthrowable)eobj); \ + (*env)->ExceptionClear(env); \ } #define JNI_INDEXED_SETFUNC(pname, fname, lfname, type) \ diff --git a/Makefile.am b/Makefile.am index 5e0ccf4..8eac0d8 100644 --- a/Makefile.am +++ b/Makefile.am @@ -382,6 +382,6 @@ deb: @cp debian/changelog.template debian/changelog @sed -i s/"VERSION"/"$(PACKAGE_VERSION)"/ debian/changelog @sed -i s/"DATE"/"$(shell date +"%a, %d %b %Y %T %z")"/ debian/changelog - @if [ -z "$(DPKG_ARCH)" ]; then dpkg-buildpackage -us -uc; else dpkg-buildpackage -us -uc -a$(DPKG_ARCH); fi + @if [ -z "$(DPKG_ARCH)" ]; then dpkg-buildpackage -I.svn -us -uc; else dpkg-buildpackage -I.svn -us -uc -a$(DPKG_ARCH); fi jni: all diff --git a/Makefile.in b/Makefile.in index 876ac80..7e31f60 100644 --- a/Makefile.in +++ b/Makefile.in @@ -1502,7 +1502,7 @@ deb: @cp debian/changelog.template debian/changelog @sed -i s/"VERSION"/"$(PACKAGE_VERSION)"/ debian/changelog @sed -i s/"DATE"/"$(shell date +"%a, %d %b %Y %T %z")"/ debian/changelog - @if [ -z "$(DPKG_ARCH)" ]; then dpkg-buildpackage -us -uc; else dpkg-buildpackage -us -uc -a$(DPKG_ARCH); fi + @if [ -z "$(DPKG_ARCH)" ]; then dpkg-buildpackage -I.svn -us -uc; else dpkg-buildpackage -I.svn -us -uc -a$(DPKG_ARCH); fi jni: all @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.68 for Phidget21 C Library 2.1.8.20120912. +# Generated by GNU Autoconf 2.68 for Phidget21 C Library 2.1.8.20121218. # # Report bugs to <support@phidgets.com>. # @@ -570,8 +570,8 @@ MAKEFLAGS= # Identity of this package. PACKAGE_NAME='Phidget21 C Library' PACKAGE_TARNAME='libphidget' -PACKAGE_VERSION='2.1.8.20120912' -PACKAGE_STRING='Phidget21 C Library 2.1.8.20120912' +PACKAGE_VERSION='2.1.8.20121218' +PACKAGE_STRING='Phidget21 C Library 2.1.8.20121218' PACKAGE_BUGREPORT='support@phidgets.com' PACKAGE_URL='www.phidgets.com' @@ -1322,7 +1322,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures Phidget21 C Library 2.1.8.20120912 to adapt to many kinds of systems. +\`configure' configures Phidget21 C Library 2.1.8.20121218 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1392,7 +1392,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of Phidget21 C Library 2.1.8.20120912:";; + short | recursive ) echo "Configuration of Phidget21 C Library 2.1.8.20121218:";; esac cat <<\_ACEOF @@ -1504,7 +1504,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -Phidget21 C Library configure 2.1.8.20120912 +Phidget21 C Library configure 2.1.8.20121218 generated by GNU Autoconf 2.68 Copyright (C) 2010 Free Software Foundation, Inc. @@ -1782,7 +1782,7 @@ cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by Phidget21 C Library $as_me 2.1.8.20120912, which was +It was created by Phidget21 C Library $as_me 2.1.8.20121218, which was generated by GNU Autoconf 2.68. Invocation command line was $ $0 $@ @@ -2597,7 +2597,7 @@ fi # Define the identity of the package. PACKAGE='libphidget' - VERSION='2.1.8.20120912' + VERSION='2.1.8.20121218' cat >>confdefs.h <<_ACEOF @@ -13224,7 +13224,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by Phidget21 C Library $as_me 2.1.8.20120912, which was +This file was extended by Phidget21 C Library $as_me 2.1.8.20121218, which was generated by GNU Autoconf 2.68. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -13282,7 +13282,7 @@ _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ -Phidget21 C Library config.status 2.1.8.20120912 +Phidget21 C Library config.status 2.1.8.20121218 configured by $0, generated by GNU Autoconf 2.68, with options \\"\$ac_cs_config\\" @@ -1698,7 +1698,7 @@ int deviceSupportsGeneralUSBProtocol(CPhidgetHandle phid) case PHIDUID_SPATIAL_ACCEL_GYRO_COMPASS_1042: case PHIDUID_SPATIAL_ACCEL_GYRO_COMPASS_1044: case PHIDUID_LED_64_ADV_M3: - case PHIDUID_RFID_2OUTPUT_ADVANCED: + case PHIDUID_RFID_2OUTPUT_READ_WRITE: return PTRUE; case PHIDUID_FIRMWARE_UPGRADE: @@ -27,6 +27,7 @@ typedef struct _CPhidget_Timestamp { * Platform independent 64-bit integer. */ typedef long long __int64; +typedef unsigned long long __uint64; #endif #include "cphidgetconstantsinternal.h" diff --git a/cphidgetattr.h b/cphidgetattr.h index 0a3c884..f54c403 100644 --- a/cphidgetattr.h +++ b/cphidgetattr.h @@ -212,6 +212,7 @@ typedef enum { PHIDID_MOTORCONTROL_1MOTOR = 0x03E, /**< Phidget 1 Motor Motor Controller (1065) */ PHIDID_MOTORCONTROL_HC_2MOTOR = 0x059, /**< Phidget 2 Motor High Current Motor Controller (1064) */ PHIDID_RFID_2OUTPUT = 0x031, /**< Phidget RFID with Digital Outputs and Onboard LED (1023) */ + PHIDID_RFID_2OUTPUT_READ_WRITE = 0x034, /**< Phidget RFID with R/W support (1024) */ PHIDID_ROTARY_TOUCH = 0x077, /**< Phidget Rotary Touch (1016) */ PHIDID_SPATIAL_ACCEL_3AXIS = 0x07F, /**< Phidget Spatial 3-axis accel (1049, 1041, 1043) */ PHIDID_SPATIAL_ACCEL_GYRO_COMPASS = 0x033, /**< Phidget Spatial 3/3/3 (1056, 1042, 1044) */ @@ -253,7 +254,6 @@ typedef enum { PHIDID_INTERFACEKIT_2_8_8 = 5, /**< Phidget Interface Kit 2/8/8 */ /* These are unreleased or prototype devices */ - PHIDID_RFID_2OUTPUT_ADVANCED = 0x034, /**< Phidget RFID with R/W support (1024) */ /* This is for internal prototyping */ PHIDID_GENERIC = 0x099 @@ -325,7 +325,7 @@ typedef enum { PHIDUID_RFID, PHIDUID_RFID_2OUTPUT_NO_ECHO, PHIDUID_RFID_2OUTPUT, - PHIDUID_RFID_2OUTPUT_ADVANCED, + PHIDUID_RFID_2OUTPUT_READ_WRITE, PHIDUID_SERVO_1MOTOR_OLD, PHIDUID_SERVO_4MOTOR_OLD, diff --git a/cphidgetconstants.c b/cphidgetconstants.c index 6857f78..2d50f85 100644 --- a/cphidgetconstants.c +++ b/cphidgetconstants.c @@ -89,7 +89,7 @@ const CPhidgetDeviceDef Phid_Device_Def[PHIDGET_DEVICE_COUNT+1] = { { PHIDID_RFID_2OUTPUT, PHIDCLASS_RFID, 0x6C2, 0x31, 0, { UFINTS(rfid, 2 ) }, "Phidget RFID 2-output"}, { PHIDID_TEMPERATURESENSOR_4, PHIDCLASS_TEMPERATURESENSOR,0x6C2, 0x32, 0, { UFINTS(temperaturesensor, 4 ) }, "Phidget Temperature Sensor 4-input"}, { PHIDID_SPATIAL_ACCEL_GYRO_COMPASS, PHIDCLASS_SPATIAL, 0x6C2, 0x33, 0, { UFINTS(spatial, 3, 3, 3 ) }, "Phidget Spatial 3/3/3"}, -{ PHIDID_RFID_2OUTPUT_ADVANCED, PHIDCLASS_RFID, 0x6C2, 0x34, 0, { UFINTS(rfid, 2 ) }, "Phidget RFID 2-output Advanced"}, +{ PHIDID_RFID_2OUTPUT_READ_WRITE, PHIDCLASS_RFID, 0x6C2, 0x34, 0, { UFINTS(rfid, 2 ) }, "Phidget RFID Read-Write"}, { PHIDID_FREQUENCYCOUNTER_2INPUT, PHIDCLASS_FREQUENCYCOUNTER, 0x6C2, 0x35, 0, { UFINTS(frequencycounter, 2 ) }, "Phidget Frequency Counter 2-input"}, { PHIDID_INTERFACEKIT_2_2_2, PHIDCLASS_INTERFACEKIT, 0x6C2, 0x36, 0, { UFINTS(ifkit, 2, 2, 2 ) }, "Phidget InterfaceKit 2/2/2"}, { PHIDID_ANALOG_4OUTPUT, PHIDCLASS_ANALOG, 0x6C2, 0x37, 0, { UFINTS(analog, 4 ) }, "Phidget Analog 4-output"}, @@ -221,7 +221,7 @@ const CPhidgetUniqueDeviceDef Phid_Unique_Device_Def[] = { {PHIDUID_RFID, PHIDID_RFID, 104, 200}, // 104 - <200 {PHIDUID_RFID_2OUTPUT_NO_ECHO, PHIDID_RFID_2OUTPUT, 200, 201}, // 200 {PHIDUID_RFID_2OUTPUT, PHIDID_RFID_2OUTPUT, 201, 300}, // 201 - <300 - {PHIDUID_RFID_2OUTPUT_ADVANCED, PHIDID_RFID_2OUTPUT_ADVANCED, 100, 200}, // 100 - <200 + {PHIDUID_RFID_2OUTPUT_READ_WRITE, PHIDID_RFID_2OUTPUT_READ_WRITE, 100, 200}, // 100 - <200 {PHIDUID_SERVO_1MOTOR_OLD, PHIDID_SERVO_1MOTOR_OLD, 200, 201}, // 200 {PHIDUID_SERVO_1MOTOR_OLD, PHIDID_SERVO_1MOTOR, 200, 201}, // 200 diff --git a/cphidgetir.h b/cphidgetir.h index 84f7738..c518335 100644 --- a/cphidgetir.h +++ b/cphidgetir.h @@ -76,7 +76,7 @@ PHIDGET21_API int CCONV CPhidgetIR_TransmitRepeat(CPhidgetIRHandle phid); * Transmits RAW data as a series of pulses and spaces.
* @param phid An attached phidget ir handle.
* @param data The data to send. The array must start and end with a pulse and each element is a positive time in us.
- * @param length The length of the data array. Maximum length is 1024, but streams should be kept much shorter, ie. < 100ms between gaps.
+ * @param length The length of the data array. Maximum length is 200, but streams should be kept much shorter, ie. < 100ms between gaps.
* @param carrierFrequency The Carrier Frequency in Hz. leave as 0 for default.
* @param dutyCycle The Duty Cycle (10-50). Leave as 0 for default.
* @param gap The gap time in us. This guarantees a gap time (no transmitting) after the data is sent, but can be set to 0.
diff --git a/cphidgetled.c b/cphidgetled.c index 5c7bfd5..bcfe54a 100644 --- a/cphidgetled.c +++ b/cphidgetled.c @@ -20,6 +20,7 @@ CPHIDGETCLEARVARS(LED) phid->nextLED_Power[i] = PUNK_DBL; phid->LED_PowerEcho[i] = PUNK_DBL; + phid->LED_CurrentLimitEcho[i] = PUNK_DBL; phid->outputEnabledEcho[i] = PUNK_BOOL; phid->ledOpenDetectEcho[i] = PUNK_BOOL; @@ -28,7 +29,11 @@ CPHIDGETCLEARVARS(LED) phid->voltage = PHIDGET_LED_VOLTAGE_2_75V; phid->currentLimit = PHIDGET_LED_CURRENT_LIMIT_20mA; phid->faultEcho = PUNK_BOOL; - phid->TSDCount=0; + for(i=0;i<4;i++) + { + phid->TSDCount[i]=0; + phid->TWarnCount[i]=0; + } phid->PGoodErrState = PFALSE; phid->powerGoodEcho = PUNK_BOOL; phid->outputEnableEcho = PUNK_BOOL; @@ -66,6 +71,7 @@ CPHIDGETINIT(LED) phid->nextLED_Power[i] = PUNK_DBL; phid->LED_PowerEcho[i] = PUNK_DBL; + phid->LED_CurrentLimitEcho[i] = PUNK_DBL; phid->outputEnabledEcho[i] = PUNK_BOOL; phid->ledOpenDetectEcho[i] = PUNK_BOOL; @@ -78,11 +84,16 @@ CPHIDGETINIT(LED) phid->powerGoodEcho = PUNK_BOOL; phid->PGoodErrState = PFALSE; phid->outputEnableEcho = PUNK_BOOL; - phid->voltageEcho = -1; - phid->currentLimitEcho = -1; + phid->voltageEcho = 0; + phid->currentLimitEcho = 0; - phid->TSDCount=0; - phid->TSDClearCount = 0; + for(i=0;i<4;i++) + { + phid->TSDCount[i]=0; + phid->TSDClearCount[i] = 0; + phid->TWarnCount[i]=0; + phid->TWarnClearCount[i] = 0; + } phid->lastOutputPacket = 0; break; default: @@ -95,7 +106,6 @@ CPHIDGETINIT(LED) switch(phid->phid.deviceUID) { case PHIDUID_LED_64_ADV: - case PHIDUID_LED_64_ADV_M3: //need two reads to get the full state CPhidget_read((CPhidgetHandle)phid); CPhidget_read((CPhidgetHandle)phid); @@ -108,11 +118,27 @@ CPHIDGETINIT(LED) phid->lastLED_Power[i] = phid->LED_PowerEcho[i]; } - if(phid->voltageEcho != -1) + if(phid->voltageEcho > 0) phid->voltage = phid->voltageEcho; - if(phid->currentLimitEcho != -1) + if(phid->currentLimitEcho > 0) phid->currentLimit = phid->currentLimitEcho; break; + case PHIDUID_LED_64_ADV_M3: + //need three reads to get the full state + CPhidget_read((CPhidgetHandle)phid); + CPhidget_read((CPhidgetHandle)phid); + CPhidget_read((CPhidgetHandle)phid); + + for(i=0;i<phid->phid.attr.led.numLEDs;i++) + { + phid->LED_Power[i] = phid->LED_PowerEcho[i]; + phid->LED_CurrentLimit[i] = phid->LED_CurrentLimitEcho[i]; + } + + if(phid->voltageEcho > 0) + phid->voltage = phid->voltageEcho; + + break; case PHIDUID_LED_64: default: break; @@ -133,130 +159,275 @@ CPHIDGETDATA(LED) switch(phid->phid.deviceUID) { case PHIDUID_LED_64_ADV: - if ((phid->phid.deviceVersion >= 100) && (phid->phid.deviceVersion < 200)) + switch(buffer[0] & 0x80) { - switch(buffer[0] & 0x80) - { - case LED64_IN_LOW_PACKET: - //PowerGood - if(buffer[0] & LED64_PGOOD_FLAG) - { - phid->PGoodErrState = PFALSE; - phid->powerGoodEcho = PTRUE; - } - else - { - phid->powerGoodEcho = PFALSE; - } + case LED64_IN_LOW_PACKET: + //PowerGood + if(buffer[0] & LED64_PGOOD_FLAG) + { + phid->PGoodErrState = PFALSE; + phid->powerGoodEcho = PTRUE; + } + else + { + phid->powerGoodEcho = PFALSE; + } - //all outputs enabled (power on/off) - if(buffer[0] & LED64_OE_FLAG) - phid->outputEnableEcho = PTRUE; - else - phid->outputEnableEcho = PFALSE; + //all outputs enabled (power on/off) + if(buffer[0] & LED64_OE_FLAG) + phid->outputEnableEcho = PTRUE; + else + phid->outputEnableEcho = PFALSE; - //fault - if(buffer[0] & LED64_FAULT_FLAG) - phid->faultEcho = PTRUE; - else - phid->faultEcho = PFALSE; + //fault + if(buffer[0] & LED64_FAULT_FLAG) + phid->faultEcho = PTRUE; + else + phid->faultEcho = PFALSE; - //current limit - if(buffer[0] & LED64_CURSELA_FLAG) - { - if(buffer[0] & LED64_CURSELB_FLAG) - phid->currentLimitEcho = PHIDGET_LED_CURRENT_LIMIT_80mA; - else - phid->currentLimitEcho = PHIDGET_LED_CURRENT_LIMIT_40mA; - } - else if (buffer[0] & LED64_CURSELB_FLAG) - phid->currentLimitEcho = PHIDGET_LED_CURRENT_LIMIT_60mA; + //current limit + if(buffer[0] & LED64_CURSELA_FLAG) + { + if(buffer[0] & LED64_CURSELB_FLAG) + phid->currentLimitEcho = PHIDGET_LED_CURRENT_LIMIT_80mA; else - phid->currentLimitEcho = PHIDGET_LED_CURRENT_LIMIT_20mA; - - //voltage - if(buffer[0] & LED64_PWRSELA_FLAG) - { - if(buffer[0] & LED64_PWRSELB_FLAG) - phid->voltageEcho = PHIDGET_LED_VOLTAGE_5_0V; - else - phid->voltageEcho = PHIDGET_LED_VOLTAGE_2_75V; - } - else if (buffer[0] & LED64_PWRSELB_FLAG) - phid->voltageEcho = PHIDGET_LED_VOLTAGE_3_9V; + phid->currentLimitEcho = PHIDGET_LED_CURRENT_LIMIT_40mA; + } + else if (buffer[0] & LED64_CURSELB_FLAG) + phid->currentLimitEcho = PHIDGET_LED_CURRENT_LIMIT_60mA; + else + phid->currentLimitEcho = PHIDGET_LED_CURRENT_LIMIT_20mA; + + //voltage + if(buffer[0] & LED64_PWRSELA_FLAG) + { + if(buffer[0] & LED64_PWRSELB_FLAG) + phid->voltageEcho = PHIDGET_LED_VOLTAGE_5_0V; else - phid->voltageEcho = PHIDGET_LED_VOLTAGE_1_7V; + phid->voltageEcho = PHIDGET_LED_VOLTAGE_2_75V; + } + else if (buffer[0] & LED64_PWRSELB_FLAG) + phid->voltageEcho = PHIDGET_LED_VOLTAGE_3_9V; + else + phid->voltageEcho = PHIDGET_LED_VOLTAGE_1_7V; + + for(i=0;i<phid->phid.attr.led.numLEDs;i++) + { + phid->outputEnabledEcho[i] = (buffer[(i/8)+1] & (1 << (i%8))) ? 1 : 0; + phid->ledOpenDetectEcho[i] = (buffer[(i/8)+9] & (1 << (i%8))) ? 1 : 0; + } + + //1st 24 LED powers + for(i=0;i<24;i++) + { + double ledPowerTemp; + ledPowerTemp = ((double)buffer[i+17] / 127.0) * 100.0; + phid->LED_PowerEcho[i] = ledPowerTemp; + } + + //We can guess that the fault is a TSD if there is no LOD + if(phid->faultEcho) + { + phid->TSDCount[0]++; + phid->TSDClearCount[0] = 30; //500ms of no faults before we clear it for(i=0;i<phid->phid.attr.led.numLEDs;i++) { - phid->outputEnabledEcho[i] = (buffer[(i/8)+1] & (1 << (i%8))) ? 1 : 0; - phid->ledOpenDetectEcho[i] = (buffer[(i/8)+9] & (1 << (i%8))) ? 1 : 0; + if(phid->ledOpenDetectEcho[i]) + phid->TSDCount[0] = 0; } - //1st 24 LED powers - for(i=0;i<24;i++) + //send out some error events on faults + //TODO: we could also send LED Open Detect? + + //we have counted three fault flags with no LODs - TSD - only one error event is thrown until this is cleared + //less then 3 counts, and it could be a false positive + //if outputs are not enabled then the fault should be guaranteed as a TSD + if(phid->TSDCount[0] == 3 || (phid->TSDCount[0] < 3 && phid->outputEnableEcho == PFALSE)) { - double ledPowerTemp; - ledPowerTemp = ((double)buffer[i+17] / 127.0) * 100.0; - phid->LED_PowerEcho[i] = ledPowerTemp; + phid->TSDCount[0] = 3; + FIRE_ERROR(EEPHIDGET_OVERTEMP, "Thermal Shutdown detected."); } + } + else + { + if(phid->TSDClearCount[0] > 0) + phid->TSDClearCount[0]--; + else + phid->TSDCount[0]=0; + } + + if(!phid->powerGoodEcho && phid->PGoodErrState == PFALSE) + { + phid->PGoodErrState = PTRUE; + FIRE_ERROR(EEPHIDGET_BADPOWER, "Bad power supply detected."); + } + + break; + case LED64_IN_HIGH_PACKET: + + //last 40 LED powers + for(i=24;i<phid->phid.attr.led.numLEDs;i++) + { + double ledPowerTemp; + ledPowerTemp = ((double)buffer[i-23] / 127.0) * 100.0; + phid->LED_PowerEcho[i] = ledPowerTemp; + } - //We can guess that the fault is a TSD if there is no LOD - if(phid->faultEcho) + break; + } + break; + case PHIDUID_LED_64_ADV_M3: + switch(buffer[0] & 0x60) + { + case LED64_M3_IN_MISC_PACKET: + //PowerGood + if(buffer[0] & LED64_PGOOD_FLAG) + { + if(phid->PGoodErrState) { - phid->TSDCount++; - phid->TSDClearCount = 30; //500ms of no faults before we clear it + FIRE_ERROR(EEPHIDGET_OK, "Good power supply detected."); + } + phid->PGoodErrState = PFALSE; + phid->powerGoodEcho = PTRUE; + } + else + { + phid->powerGoodEcho = PFALSE; + } + + //voltage + if(buffer[0] & LED64_PWRSELA_FLAG) + { + if(buffer[0] & LED64_PWRSELB_FLAG) + phid->voltageEcho = PHIDGET_LED_VOLTAGE_5_0V; + else + phid->voltageEcho = PHIDGET_LED_VOLTAGE_2_75V; + } + else if (buffer[0] & LED64_PWRSELB_FLAG) + phid->voltageEcho = PHIDGET_LED_VOLTAGE_3_9V; + else + phid->voltageEcho = PHIDGET_LED_VOLTAGE_1_7V; + + if(!phid->powerGoodEcho && phid->PGoodErrState == PFALSE) + { + phid->PGoodErrState = PTRUE; + FIRE_ERROR(EEPHIDGET_BADPOWER, "Bad power supply detected."); + } + + //Temperature Warnings + for(i=0;i<4;i++) + { + if(buffer[1] & (0x01 << i)) + { + phid->TWarnCount[i]++; + phid->TWarnClearCount[i] = 20; //480ms of no faults before we clear it - for(i=0;i<phid->phid.attr.led.numLEDs;i++) + if(phid->TWarnCount[i] == 10) //240 ms of fault before we call it + { + FIRE_ERROR(EEPHIDGET_OVERTEMP, "Temperature Warning detected on chip %d.", i); + } + else if(phid->TWarnCount[i] > 10) + phid->TWarnCount[i]--; //so we don't overflow the char + } + else + { + if(phid->TWarnClearCount[i] > 0) + phid->TWarnClearCount[i]--; + else { - if(phid->ledOpenDetectEcho[i]) - phid->TSDCount = 0; + if(phid->TWarnCount[i] >= 10) + { + FIRE_ERROR(EEPHIDGET_OK, "Temperature Warning ended on chip %d.", i); + } + phid->TWarnCount[i]=0; } + } + } - //send out some error events on faults - //TODO: we could also send LED Open Detect? + //Temperature Errors + for(i=0;i<4;i++) + { + if(buffer[1] & (0x10 << i)) + { + phid->TSDCount[i]++; + phid->TSDClearCount[i] = 20; //480ms of no faults before we clear it - //we have counted three fault flags with no LODs - TSD - only one error event is thrown until this is cleared - //less then 3 counts, and it could be a false positive - //if outputs are not enabled then the fault should be guaranteed as a TSD - if(phid->TSDCount == 3 || (phid->TSDCount < 3 && phid->outputEnableEcho == PFALSE)) + if(phid->TSDCount[i] == 10) //240 ms of fault before we call it { - phid->TSDCount = 3; - FIRE_ERROR(EEPHIDGET_OVERTEMP, "Thermal Shutdown detected."); + FIRE_ERROR(EEPHIDGET_OVERTEMP, "Temperature Error detected on chip %d.", i); } + else if(phid->TSDCount[i] > 10) + phid->TSDCount[i]--; //so we don't overflow the char } else { - if(phid->TSDClearCount > 0) - phid->TSDClearCount--; + if(phid->TSDClearCount[i] > 0) + phid->TSDClearCount[i]--; else - phid->TSDCount=0; - } - - if(!phid->powerGoodEcho && phid->PGoodErrState == PFALSE) - { - phid->PGoodErrState = PTRUE; - FIRE_ERROR(EEPHIDGET_BADPOWER, "Bad power supply detected."); + { + if(phid->TSDCount[i] >= 10) + { + FIRE_ERROR(EEPHIDGET_OK, "Temperature Error ended on chip %d.", i); + } + phid->TSDCount[i]=0; + } } + } - break; - case LED64_IN_HIGH_PACKET: - - //last 40 LED powers - for(i=24;i<phid->phid.attr.led.numLEDs;i++) + //Current Limit + for(i=0;i<64;i++) + { + int index = (i*6)/8 + 2; + int currentLimitInt = 0; + switch(i%4) { - double ledPowerTemp; - ledPowerTemp = ((double)buffer[i-23] / 127.0) * 100.0; - phid->LED_PowerEcho[i] = ledPowerTemp; + case 0: + currentLimitInt = buffer[index] & 0x3F; + break; + case 1: + currentLimitInt = ((buffer[index] >> 6) & 0x03) + ((buffer[index+1] << 2) & 0x3C); + break; + case 2: + currentLimitInt = ((buffer[index] >> 4) & 0x0F) + ((buffer[index+1] << 4) & 0x30); + break; + case 3: + currentLimitInt = (buffer[index] >> 2) & 0x3F; + break; } + phid->LED_CurrentLimitEcho[i] = (currentLimitInt / 63.0) * LED64_M3_CURRENTLIMIT; + } - break; + break; + case LED64_M3_IN_LOW_PACKET: + for(i=0;i<32;i++) + { + int ledPowerInt; + int index = (i*12)/8+9; + + if(i%2 == 0) + ledPowerInt = buffer[index] + ((buffer[index+1] & 0x0F) << 8); + else + ledPowerInt = ((buffer[index] & 0xF0) >> 4) + (buffer[index+1] << 4); + + phid->LED_PowerEcho[i] = (ledPowerInt / 4097.0) * 100.0; + } + break; + case LED64_M3_IN_HIGH_PACKET: + for(i=0;i<32;i++) + { + int ledPowerInt; + int index = (i*12)/8+9; + + if(i%2 == 0) + ledPowerInt = buffer[index] + ((buffer[index+1] & 0x0F) << 8); + else + ledPowerInt = ((buffer[index] & 0xF0) >> 4) + (buffer[index+1] << 4); + + phid->LED_PowerEcho[i+32] = (ledPowerInt / 4097.0) * 100.0; + } + break; } - } - else - return EPHIDGET_UNEXPECTED; - break; - case PHIDUID_LED_64_ADV_M3: break; case PHIDUID_LED_64: default: @@ -451,22 +622,6 @@ CGETPACKET(LED) if(phid->controlPacketWaiting) { buf[0] = LED64_M3_CONTROL_PACKET; - - //TODO: we're getting rid of this probably - switch(phid->currentLimit) - { - case PHIDGET_LED_CURRENT_LIMIT_20mA: - break; - case PHIDGET_LED_CURRENT_LIMIT_40mA: - buf[0] |= LED64_CURSELA_FLAG; - break; - case PHIDGET_LED_CURRENT_LIMIT_60mA: - buf[0] |= LED64_CURSELB_FLAG; - break; - case PHIDGET_LED_CURRENT_LIMIT_80mA: - buf[0] |= (LED64_CURSELA_FLAG | LED64_CURSELB_FLAG); - break; - } switch(phid->voltage) { @@ -550,7 +705,7 @@ CGETPACKET(LED) for(i = startIndex;i<startIndex+32;i++) { int value; - int bufIndex = (i*12)/8 + 1; + int bufIndex = ((i-startIndex)*12)/8 + 1; if(phid->changedLED_Power[i]) { @@ -668,35 +823,6 @@ CGET(LED,LEDCount,int) MASGN(phid.attr.led.numLEDs) } -CGETINDEX(LED,DiscreteLED,int) - TESTPTRS(phid,pVal) - TESTDEVICETYPE(PHIDCLASS_LED) - TESTATTACHED - TESTINDEX(phid.attr.led.numLEDs) - if(phid->LED_Power[Index] == PUNK_DBL) - { - *pVal = PUNK_INT; - return EPHIDGET_UNKNOWNVAL; - } - - *pVal = round(phid->LED_Power[Index]); - return EPHIDGET_OK; -} -CSETINDEX(LED,DiscreteLED,int) - TESTPTR(phid) - TESTDEVICETYPE(PHIDCLASS_LED) - TESTATTACHED - TESTINDEX(phid.attr.led.numLEDs) - TESTRANGE(0, 100) - - if(CPhidget_statusFlagIsSet(phid->phid.status, PHIDGET_REMOTE_FLAG)) - ADDNETWORKKEYINDEXED(Brightness, "%d", LED_Power); - else - return CPhidgetLED_sendpacket(phid, Index, (double)newVal); - - return EPHIDGET_OK; -} - CGETINDEX(LED,Brightness,double) TESTPTRS(phid,pVal) TESTDEVICETYPE(PHIDCLASS_LED) @@ -747,9 +873,9 @@ CSETINDEX(LED,CurrentLimitIndexed,double) TESTATTACHED TESTINDEX(phid.attr.led.numLEDs) - switch(phid->phid.deviceIDSpec) + switch(phid->phid.deviceUID) { - case PHIDID_LED_64_ADV: + case PHIDUID_LED_64_ADV_M3: TESTRANGE(0, LED64_M3_CURRENTLIMIT) if(CPhidget_statusFlagIsSet(phid->phid.status, PHIDGET_REMOTE_FLAG)) @@ -765,7 +891,8 @@ CSETINDEX(LED,CurrentLimitIndexed,double) CThread_mutex_unlock(&phid->phid.writelock); } break; - case PHIDID_LED_64: + case PHIDUID_LED_64_ADV: + case PHIDUID_LED_64: default: return EPHIDGET_UNSUPPORTED; } @@ -778,11 +905,12 @@ CGET(LED,CurrentLimit,CPhidgetLED_CurrentLimit) TESTDEVICETYPE(PHIDCLASS_LED) TESTATTACHED - switch(phid->phid.deviceIDSpec) + switch(phid->phid.deviceUID) { - case PHIDID_LED_64_ADV: + case PHIDUID_LED_64_ADV: MASGN(currentLimitEcho) - case PHIDID_LED_64: + case PHIDUID_LED_64_ADV_M3: + case PHIDUID_LED_64: default: return EPHIDGET_UNSUPPORTED; } @@ -792,9 +920,9 @@ CSET(LED,CurrentLimit,CPhidgetLED_CurrentLimit) TESTDEVICETYPE(PHIDCLASS_LED) TESTATTACHED - switch(phid->phid.deviceIDSpec) + switch(phid->phid.deviceUID) { - case PHIDID_LED_64_ADV: + case PHIDUID_LED_64_ADV: TESTRANGE(PHIDGET_LED_CURRENT_LIMIT_20mA, PHIDGET_LED_CURRENT_LIMIT_80mA) @@ -811,7 +939,42 @@ CSET(LED,CurrentLimit,CPhidgetLED_CurrentLimit) CThread_mutex_unlock(&phid->phid.writelock); } break; - case PHIDID_LED_64: + case PHIDUID_LED_64_ADV_M3: + + TESTRANGE(PHIDGET_LED_CURRENT_LIMIT_20mA, PHIDGET_LED_CURRENT_LIMIT_80mA) + + if(CPhidget_statusFlagIsSet(phid->phid.status, PHIDGET_REMOTE_FLAG)) + ADDNETWORKKEY(CurrentLimit, "%d", currentLimit); + else + { + int i; + double limit; + switch(newVal) + { + case PHIDGET_LED_CURRENT_LIMIT_20mA: + limit = 20; + break; + case PHIDGET_LED_CURRENT_LIMIT_40mA: + limit = 40; + break; + case PHIDGET_LED_CURRENT_LIMIT_60mA: + limit = 60; + break; + case PHIDGET_LED_CURRENT_LIMIT_80mA: + limit = 80; + break; + } + CThread_mutex_lock(&phid->phid.writelock); + CThread_mutex_lock(&phid->phid.outputLock); + for(i=0;i<phid->phid.attr.led.numLEDs;i++) + phid->LED_CurrentLimit[i] = limit; + phid->controlPacketWaiting = PTRUE; + CThread_mutex_unlock(&phid->phid.outputLock); + CThread_set_event(&phid->phid.writeAvailableEvent); + CThread_mutex_unlock(&phid->phid.writelock); + } + break; + case PHIDUID_LED_64: default: return EPHIDGET_UNSUPPORTED; } @@ -870,3 +1033,13 @@ CSET(LED,Voltage,CPhidgetLED_Voltage) CGET(LED,NumLEDs,int) return CPhidgetLED_getLEDCount(phid, pVal); } +CGETINDEX(LED,DiscreteLED,int) + double val; + int ret; + ret = CPhidgetLED_getBrightness(phid, Index, &val); + *pVal = (int)round(val); + return ret; +} +CSETINDEX(LED,DiscreteLED,int) + return CPhidgetLED_setBrightness(phid, Index, (double)newVal); +} diff --git a/cphidgetled.h b/cphidgetled.h index e9ec6fe..ddce0e5 100644 --- a/cphidgetled.h +++ b/cphidgetled.h @@ -36,20 +36,7 @@ typedef enum { * @param count The led count. */ CHDRGET(LED,LEDCount,int *count) -/** - * Gets the brightness of an LED. - * @param phid An attached phidget LED handle. - * @param index The LED index. - * @param brightness The LED brightness (0-100). - */ -CHDRGETINDEX(LED,DiscreteLED,int *brightness) -/** - * Sets the brightness of an LED. - * @param phid An attached phidget LED handle. - * @param index The LED index. - * @param brightness The LED brightness (0-100). - */ -CHDRSETINDEX(LED,DiscreteLED,int brightness) + /** * Gets the current limit. This is for all ouputs. * @param phid An attached phidget LED handle. @@ -74,17 +61,39 @@ CHDRGET(LED,Voltage,CPhidgetLED_Voltage *voltage) * @param voltage The Output Voltage. */ CHDRSET(LED,Voltage,CPhidgetLED_Voltage voltage) - -//Only exposed in debug library for now -#if !defined(EXTERNALPROTO) || defined(DEBUG) +/** + * Gets the brightness of an LED. + * @param phid An attached phidget LED handle. + * @param index The LED index. + * @param brightness The LED brightness (0-100). + */ CHDRGETINDEX(LED,Brightness,double *brightness) +/** + * Sets the brightness of an LED. + * @param phid An attached phidget LED handle. + * @param index The LED index. + * @param brightness The LED brightness (0-100). + */ CHDRSETINDEX(LED,Brightness,double brightness) +/** + * Gets the current limit of an LED. + * @param phid An attached phidget LED handle. + * @param index The LED index. + * @param limit The LED current limit (0-80 mA). + */ CHDRGETINDEX(LED,CurrentLimitIndexed,double *limit) +/** + * Sets the current limit of an LED. + * @param phid An attached phidget LED handle. + * @param index The LED index. + * @param limit The LED current limit (0-80 mA). + */ CHDRSETINDEX(LED,CurrentLimitIndexed,double limit) -#endif #ifndef REMOVE_DEPRECATED DEP_CHDRGET("Deprecated - use CPhidgetLED_getLEDCount",LED,NumLEDs,int *) +DEP_CHDRGETINDEX("Deprecated - use CPhidgetLED_getBrightness",LED,DiscreteLED,int *brightness) +DEP_CHDRSETINDEX("Deprecated - use CPhidgetLED_getBrightness",LED,DiscreteLED,int brightness) #endif #ifndef EXTERNALPROTO @@ -96,6 +105,7 @@ DEP_CHDRGET("Deprecated - use CPhidgetLED_getLEDCount",LED,NumLEDs,int *) #define LED64_CONTROL_PACKET 0x40 #define LED64_OUTLOW_PACKET 0x80 #define LED64_OUTHIGH_PACKET 0xc0 + #define LED64_M3_OUT_LOW_PACKET 0x00 #define LED64_M3_OUT_HIGH_PACKET 0x20 #define LED64_M3_CONTROL_PACKET 0x40 @@ -103,8 +113,10 @@ DEP_CHDRGET("Deprecated - use CPhidgetLED_getLEDCount",LED,NumLEDs,int *) //IN Packet Types #define LED64_IN_LOW_PACKET 0x00 #define LED64_IN_HIGH_PACKET 0x80 + #define LED64_M3_IN_LOW_PACKET 0x00 -#define LED64_M3_IN_HIGH_PACKET 0x40 +#define LED64_M3_IN_HIGH_PACKET 0x20 +#define LED64_M3_IN_MISC_PACKET 0x40 //Flags #define LED64_PGOOD_FLAG 0x01 @@ -116,7 +128,7 @@ DEP_CHDRGET("Deprecated - use CPhidgetLED_getLEDCount",LED,NumLEDs,int *) #define LED64_OE_FLAG 0x40 //M3 LED64 -#define LED64_M3_CURRENTLIMIT 80 //80 mA fixed TODO: make sure this is right! +#define LED64_M3_CURRENTLIMIT 80 //80 mA max struct _CPhidgetLED { @@ -133,6 +145,7 @@ struct _CPhidgetLED unsigned char changeRequests; double LED_PowerEcho[LED_MAXLEDS]; + double LED_CurrentLimitEcho[LED_MAXLEDS]; unsigned char outputEnabledEcho[LED_MAXLEDS]; unsigned char ledOpenDetectEcho[LED_MAXLEDS]; unsigned char powerGoodEcho; @@ -141,7 +154,7 @@ struct _CPhidgetLED CPhidgetLED_Voltage voltageEcho; CPhidgetLED_CurrentLimit currentLimitEcho; - unsigned char TSDCount, TSDClearCount, PGoodErrState; + unsigned char TSDCount[4], TSDClearCount[4], TWarnCount[4], TWarnClearCount[4], PGoodErrState; unsigned char controlPacketWaiting; unsigned char lastOutputPacket; diff --git a/cphidgetmanager.c b/cphidgetmanager.c index d0f918b..7471deb 100644 --- a/cphidgetmanager.c +++ b/cphidgetmanager.c @@ -177,7 +177,7 @@ static int sendInitialEvents() int CPhidgetManager_poll() { CPhidgetList *curList = 0, *detachList = 0; - CPhidgetList *trav = 0; + CPhidgetList *trav = 0, *trav2 = 0; CPhidgetHandle foundPhidget; if(!managerLockInitialized) @@ -203,8 +203,7 @@ int CPhidgetManager_poll() } for (trav=curList; trav; trav = trav->next) { - if(CList_findInList((CListHandle)AttachedDevices, trav->phid, CPhidget_areExtraEqual, NULL) == - EPHIDGET_NOTFOUND) + if(CList_findInList((CListHandle)AttachedDevices, trav->phid, CPhidget_areExtraEqual, NULL) == EPHIDGET_NOTFOUND) { CPhidgetAttachEvent(trav->phid); } @@ -215,15 +214,27 @@ int CPhidgetManager_poll() CThread_mutex_lock(&activeDevicesLock); if(CList_findInList((CListHandle)ActiveDevices, trav->phid, CPhidget_areEqual, (void **)&foundPhidget) == EPHIDGET_OK) { - if(CPhidget_statusFlagIsSet(foundPhidget->status, PHIDGET_ATTACHED_FLAG)) + if(CPhidget_statusFlagIsSet(foundPhidget->status, PHIDGET_ATTACHED_FLAG) + && CPhidget_statusFlagIsSet(foundPhidget->status, PHIDGET_USB_ERROR_FLAG)) { - if(CPhidget_statusFlagIsSet(foundPhidget->status, PHIDGET_USB_ERROR_FLAG)) + LOG(PHIDGET_LOG_WARNING,"PHIDGET_USB_ERROR_FLAG is set - cycling device through a detach"); + CList_addToList((CListHandle *)&detachList, trav->phid, CPhidget_areEqual); + + //if this is a composite device, we must find it's pair and detach that as well. + //same serial, but different interface num + for (trav2=curList; trav2; trav2 = trav2->next) { - LOG(PHIDGET_LOG_WARNING,"PHIDGET_USB_ERROR_FLAG is set - cycling device through a detach"); - CList_addToList((CListHandle *)&detachList, trav->phid, CPhidget_areEqual); + if(trav->phid->serialNumber == trav2->phid->serialNumber + && trav->phid->deviceDef->pdd_iid != trav2->phid->deviceDef->pdd_iid) + { + LOG(PHIDGET_LOG_WARNING,"PHIDGET_USB_ERROR_FLAG is set - cycling composite device 2nd interface through a detach"); + CList_addToList((CListHandle *)&detachList, trav2->phid, CPhidget_areEqual); + } } } } + + CThread_mutex_unlock(&activeDevicesLock); } for (trav=detachList; trav; trav = trav->next) diff --git a/cphidgetrfid.c b/cphidgetrfid.c index 718653d..3d177ba 100644 --- a/cphidgetrfid.c +++ b/cphidgetrfid.c @@ -7,72 +7,12 @@ // === Internal Functions === // CThread_func_return_t tagTimerThreadFunction(CThread_func_arg_t userPtr); - static int analyze_data(CPhidgetRFIDHandle phid); +static int tagEvent_fromEM4100Data(CPhidgetRFIDHandle phid, unsigned char *data); +#ifdef RFID_HITAGS_SUPPORT static int analyze_data_AC(CPhidgetRFIDHandle phid); -static int sendRAWData(CPhidgetRFIDHandle phid, unsigned char *data, int bitlength); -static int advancedTagEventForOldReaders(CPhidgetRFIDHandle phid, unsigned char *data); - -//Hitag S Commands static int HitagS_UID_REQUEST(CPhidgetRFIDHandle phid); -static int HitagS_AC_SEQUENCE(CPhidgetRFIDHandle phid, CPhidgetRFID_HitagACHandle ac); - -#define ABS(x) ((x) < 0 ? -(x) : (x)) -#define pdiff(a, b) ( ABS((a) - (b)) / (double)( ((a) + (b)) / 2.0 ) ) - -int CPhidgetRFID_Tag_areEqual(void *arg1, void *arg2) -{ - CPhidgetRFID_TagHandle tag1 = (CPhidgetRFID_TagHandle)arg1; - CPhidgetRFID_TagHandle tag2 = (CPhidgetRFID_TagHandle)arg2; - - if(!tag1 || !tag2) - return PFALSE; - - if(!strcmp(tag1->tagString, tag2->tagString) - && tag1->tagInfo.tagType == tag2->tagInfo.tagType - && tag1->tagInfo.bitRate == tag2->tagInfo.bitRate - && tag1->tagInfo.encoding == tag2->tagInfo.encoding) - return PTRUE; - else - return PFALSE; -} - -void CPhidgetRFID_Tag_free(void *arg) -{ - CPhidgetRFID_TagHandle tag = (CPhidgetRFID_TagHandle)arg; - - if(!tag) - return; - - free(tag); tag = NULL; - return; -} - -int CPhidgetRFID_HitagAC_areEqual(void *arg1, void *arg2) -{ - CPhidgetRFID_HitagACHandle ac1 = (CPhidgetRFID_HitagACHandle)arg1; - CPhidgetRFID_HitagACHandle ac2 = (CPhidgetRFID_HitagACHandle)arg2; - - if(!ac1 || !ac2) - return PFALSE; - - if(!memcmp(ac1->uid, ac2->uid, 4) - && ac1->colPos == ac2->colPos) - return PTRUE; - else - return PFALSE; -} - -void CPhidgetRFID_HitagAC_free(void *arg) -{ - CPhidgetRFID_HitagACHandle ac = (CPhidgetRFID_HitagACHandle)arg; - - if(!ac) - return; - - free(ac); ac = NULL; - return; -} +#endif //clearVars - sets all device variables to unknown state CPHIDGETCLEARVARS(RFID) @@ -81,11 +21,7 @@ CPHIDGETCLEARVARS(RFID) phid->antennaEchoState = PUNI_BOOL; phid->ledEchoState = PUNI_BOOL; phid->tagPresent = PUNI_BOOL; - phid->fullStateEcho = PUNK_BOOL; - phid->ledState = PUNK_BOOL; - phid->antennaState = PUNK_BOOL; phid->lastTagValid = PUNI_BOOL; - for (i = 0; i<RFID_MAXOUTPUTS; i++) { phid->outputEchoState[i] = PUNI_BOOL; @@ -98,47 +34,36 @@ CPHIDGETCLEARVARS(RFID) // used during attach initialization - on every attach CPHIDGETINIT(RFID) int i = 0; - unsigned char buffer[8] = { 0 }; int result; TESTPTR(phid); + //make sure the tagTimerThread isn't running + if (phid->tagTimerThread.thread_status == PTRUE) + { + phid->tagTimerThread.thread_status = PFALSE; + CThread_join(&phid->tagTimerThread); + } + phid->tagTimerThread.thread_status = PFALSE; + //Make sure no old writes are still pending phid->outputPacketLen = 0; //setup anything device specific - switch(phid->phid.deviceIDSpec) + switch(phid->phid.deviceUID) { - case PHIDID_RFID: - if (phid->phid.deviceVersion < 200) - { - phid->fullStateEcho = PFALSE; - phid->antennaEchoState = PTRUE; - } - else - return EPHIDGET_BADVERSION; + case PHIDUID_RFID_OLD: + case PHIDUID_RFID: + phid->fullStateEcho = PFALSE; + phid->antennaEchoState = PTRUE; break; - case PHIDID_RFID_2OUTPUT: //2-output RFID - if ((phid->phid.deviceVersion >= 200) && (phid->phid.deviceVersion < 201)) - { - phid->antennaEchoState = PUNK_BOOL; - phid->fullStateEcho = PFALSE; - } - else if ((phid->phid.deviceVersion >= 201) && (phid->phid.deviceVersion < 300)) - { - phid->antennaEchoState = PUNK_BOOL; - phid->fullStateEcho = PTRUE; - } - else - return EPHIDGET_BADVERSION; + case PHIDUID_RFID_2OUTPUT_NO_ECHO: + phid->fullStateEcho = PFALSE; + phid->antennaEchoState = PUNK_BOOL; break; - case PHIDID_RFID_2OUTPUT_ADVANCED: //2-output RFID (Advanced) - if ((phid->phid.deviceVersion >= 100) && (phid->phid.deviceVersion < 200)) - { - phid->antennaEchoState = PUNK_BOOL; - phid->fullStateEcho = PTRUE; - } - else - return EPHIDGET_BADVERSION; + case PHIDUID_RFID_2OUTPUT: + case PHIDUID_RFID_2OUTPUT_READ_WRITE: + phid->fullStateEcho = PTRUE; + phid->antennaEchoState = PUNK_BOOL; break; default: return EPHIDGET_UNEXPECTED; @@ -149,68 +74,66 @@ CPHIDGETINIT(RFID) { phid->outputEchoState[i] = PUNK_BOOL; } + phid->ledEchoState = PUNK_BOOL; phid->tagPresent = PUNK_BOOL; - ZEROMEM(phid->lastTag, 10); + ZEROMEM(&phid->lastTag, sizeof(CPhidgetRFID_Tag)); + ZEROMEM(&phid->pendingTag, sizeof(CPhidgetRFID_Tag)); phid->tagEventPending = PFALSE; + phid->lastTagValid = PFALSE; - phid->frequencyEcho = PUNK_INT; phid->pregapClocksEcho = PUNK_INT; - phid->postgapClocksEcho = PUNK_INT; + phid->prepulseClocksEcho = PUNK_INT; phid->zeroClocksEcho = PUNK_INT; phid->oneClocksEcho = PUNK_INT; phid->spaceClocksEcho = PUNK_INT; + phid->postgapClocksEcho = PUNK_INT; + phid->eofpulseClocksEcho = PUNK_INT; + phid->listenDuringEOFEcho = PUNK_BOOL; + phid->_4097ConfEcho = PUNK_INT; phid->dataReadPtr = 0; phid->dataWritePtr = 0; - phid->dataReadACPtr = 0; - phid->userReadPtr = 0; phid->manReadPtr = 0; - phid->manEventReadPtr = 0; phid->manWritePtr = 0; phid->biphaseReadPtr = 0; phid->biphaseWritePtr = 0; - - phid->ACCodingOK = PFALSE; - - phid->tagAdvancedCount = PUNK_INT; - phid->polling = PTRUE; + phid->shortClocks = phid->longClocks = 0; - CThread_mutex_lock(&phid->tagthreadlock); - if(phid->tagAdvancedList) - CList_emptyList((CListHandle *)&phid->tagAdvancedList, PTRUE, CPhidgetRFID_Tag_free); - phid->tagAdvancedList = NULL; - CThread_mutex_unlock(&phid->tagthreadlock); - phid->lastTagAdvanced.tagString[0] = '\0'; - - phid->one = phid->two = phid->oneCount = phid->twoCount = 0; + phid->manLockedIn = PFALSE; + phid->biphaseLockedIn = PFALSE; + phid->manShortChange = PFALSE; + phid->biphaseShortChange = PFALSE; - phid->manLockedIn = 0; - phid->biphaseLockedIn = 0; - phid->manShortChange = 0; - phid->biphaseShortChange = 0; + CThread_reset_event(&phid->tagAvailableEvent); - //This needs to always have a valid time -#ifdef _WINDOWS - GetSystemTime(&phid->lastDataTime); -#else - gettimeofday(&phid->lastDataTime,NULL); +#ifdef RFID_HITAGS_SUPPORT + phid->dataReadACPtr = 0; + phid->ACCodingOK = PFALSE; + phid->polling = PFALSE; + setTimeNow(&phid->lastDataTime); + setTimeNow(&phid->hitagReqTime); +#endif + +#ifdef RFID_RAWDATA_API_SUPPORT + phid->userReadPtr = 0; + phid->manEventReadPtr = 0; + phid->lastManEventLong = PFALSE; #endif //send out any initial pre-read packets - switch(phid->phid.deviceIDSpec) { - case PHIDID_RFID: - if (phid->phid.deviceVersion <= 103) - { - ZEROMEM(buffer,8); - LOG(PHIDGET_LOG_INFO,"Sending workaround startup packet"); - if ((result = CUSBSendPacket((CPhidgetHandle)phid, buffer)) != EPHIDGET_OK) - return result; - } + switch(phid->phid.deviceUID) { + case PHIDUID_RFID_OLD: + { + unsigned char buffer[8] = { 0 }; + ZEROMEM(buffer,8); + LOG(PHIDGET_LOG_INFO,"Sending workaround startup packet"); + if ((result = CUSBSendPacket((CPhidgetHandle)phid, buffer)) != EPHIDGET_OK) + return result; break; - case PHIDID_RFID_2OUTPUT: + } default: break; } @@ -229,13 +152,35 @@ CPHIDGETINIT(RFID) CPhidget_read((CPhidgetHandle)phid); } + switch(phid->phid.deviceUID) + { + case PHIDUID_RFID_2OUTPUT_READ_WRITE: + //Did we get some data? Wait for a tag + if(phid->dataWritePtr != 0) + { + int readtries = 30; //This should be enough data to guarantee detection of a tag. + while(readtries-- > 0) + { + CPhidget_read((CPhidgetHandle)phid); + if(phid->tagPresent != PUNK_BOOL) + break; + } + } + break; + default: + break; + } + //if the antenna is on, and tagPresent is unknown, then it is false if(phid->antennaEchoState == PTRUE && phid->tagPresent == PUNK_BOOL) phid->tagPresent = PFALSE; - //if the antenna is on, and tagCount is unknown, then it is false - if(phid->antennaEchoState == PTRUE && phid->tagAdvancedCount == PUNK_INT) - phid->tagAdvancedCount = 0; + //So that we can get the tag in the attach handler + if(phid->tagPresent == PTRUE) + { + phid->lastTag = phid->pendingTag; + phid->lastTagValid = PTRUE; + } //recover what we can - if anything isn't filled out, it's PUNK anyways for (i = 0; i<phid->phid.attr.rfid.numOutputs; i++) @@ -250,263 +195,216 @@ CPHIDGETINIT(RFID) phid->zeroClocks = phid->zeroClocksEcho; phid->oneClocks = phid->oneClocksEcho; phid->spaceClocks = phid->spaceClocksEcho; + phid->eofpulseClocks = phid->eofpulseClocksEcho; + phid->prepulseClocks = phid->prepulseClocksEcho; + phid->listenDuringEOF = phid->listenDuringEOFEcho; phid->_4097Conf = phid->_4097ConfEcho; - //make sure the tagTimerThread isn't running - if (phid->tagTimerThread.thread_status == PTRUE) - { - phid->tagTimerThread.thread_status = PFALSE; - CThread_join(&phid->tagTimerThread); - } - return EPHIDGET_OK; } //dataInput - parses device packets CPHIDGETDATA(RFID) int i = 0, j = 0; - unsigned char newTag = PFALSE, newOutputs = PFALSE; - unsigned char tagData[5]; + unsigned char newStateData = PFALSE; unsigned char outputs[RFID_MAXOUTPUTS]; - unsigned char lastOutputs[RFID_MAXOUTPUTS]; - unsigned char antennaState = 0, ledState = 0; - unsigned char gotData = PFALSE; + unsigned char antennaState, ledState; if (length<0) return EPHIDGET_INVALIDARG; TESTPTR(phid); TESTPTR(buffer); - ZEROMEM(tagData, sizeof(tagData)); - ZEROMEM(outputs, sizeof(outputs)); - ZEROMEM(lastOutputs, sizeof(lastOutputs)); - //Parse device packets - store data locally - switch(phid->phid.deviceIDSpec) + switch(phid->phid.deviceUID) { - case PHIDID_RFID: - if (phid->phid.deviceVersion < 200) - { - gotData = PTRUE; - CThread_mutex_lock(&phid->tagthreadlock); - setTimeNow(&phid->lastTagTime); - advancedTagEventForOldReaders(phid, buffer+1); - if(!memcmp(phid->lastTag, buffer+1, 5) && phid->tagPresent == PTRUE) - newTag = PFALSE; - else if(!memcmp("\0\0\0\0\0", buffer+1, 5)) - newTag = PFALSE; - else - { - memcpy(tagData, buffer+1, 5); - newTag = PTRUE; - } - CThread_mutex_unlock(&phid->tagthreadlock); - } - else - return EPHIDGET_UNEXPECTED; + case PHIDUID_RFID_OLD: + case PHIDUID_RFID: + // Enything other then all 0's means a tag is detected + if(memcmp("\0\0\0\0\0", buffer+1, 5)) + tagEvent_fromEM4100Data(phid, buffer+1); break; - case PHIDID_RFID_2OUTPUT: - if ((phid->phid.deviceVersion >= 200) && (phid->phid.deviceVersion < 300)) - { - switch(buffer[0]) - { - case RFID_PACKET_TAG: - gotData = PTRUE; - CThread_mutex_lock(&phid->tagthreadlock); - setTimeNow(&phid->lastTagTime); - advancedTagEventForOldReaders(phid, buffer+1); - if(!memcmp(phid->lastTag, buffer+1, 5) && phid->tagPresent == PTRUE) - newTag = PFALSE; - else if(!memcmp("\0\0\0\0\0", buffer+1, 5)) - newTag = PFALSE; - else - { - memcpy(tagData, buffer+1, 5); - newTag = PTRUE; - } - CThread_mutex_unlock(&phid->tagthreadlock); - break; - case RFID_PACKET_OUTPUT_ECHO: - if(phid->fullStateEcho) - { - newOutputs = PTRUE; - - for (i = 0, j = 0x01; i < phid->phid.attr.rfid.numOutputs; i++, j<<=1) - { - if (buffer[1] & j) - outputs[i] = PTRUE; - else - outputs[i] = PFALSE; - } - - if(buffer[1] & RFID_LED_FLAG) - ledState = PTRUE; - else - ledState = PFALSE; - - if(buffer[1] & RFID_ANTENNA_FLAG) - antennaState = PTRUE; - else - antennaState = PFALSE; - } - break; - default: - return EPHIDGET_UNEXPECTED; - } - } - else - return EPHIDGET_UNEXPECTED; - break; - // RFID with decoding in software and write support - case PHIDID_RFID_2OUTPUT_ADVANCED: - if ((phid->phid.deviceVersion >= 100) && (phid->phid.deviceVersion < 200)) + case PHIDUID_RFID_2OUTPUT_NO_ECHO: + case PHIDUID_RFID_2OUTPUT: + switch(buffer[0]) { - int dataLength = 0; - int data[RFID_MAX_DATA_PER_PACKET]; - switch(buffer[0] & 0x40) - { - case RFID_READ_DATA_IN_PACKET: - gotData = PTRUE; - phid->frequencyEcho = buffer[1] * 1000; - - //move RFID data into local storage - dataLength = buffer[0]; - for(i = 0; i < dataLength; i++) - { - data[i] = buffer[i+2]; - phid->dataBuffer[phid->dataWritePtr] = buffer[i+2]; - - phid->dataWritePtr++; - phid->dataWritePtr &= RFID_DATA_ARRAY_MASK; - - //if we run into data that hasn't been read... too bad, we overwrite it and adjust the read pointer - if(phid->dataWritePtr == phid->dataReadPtr) - { - phid->dataReadPtr++; - phid->dataReadPtr &= RFID_DATA_ARRAY_MASK; - } - if(phid->dataWritePtr == phid->dataReadACPtr) - { - phid->dataReadACPtr++; - phid->dataReadACPtr &= RFID_DATA_ARRAY_MASK; - } - } - - break; - case RFID_ECHO_IN_PACKET: - newOutputs = PTRUE; - phid->frequencyEcho = buffer[1] * 1000; - - //LOG(PHIDGET_LOG_DEBUG, "Frequency: %d", phid->frequencyEcho); - - phid->pregapClocksEcho = buffer[2]; - phid->postgapClocksEcho = buffer[3]; - phid->zeroClocksEcho = buffer[4]; - phid->oneClocksEcho = buffer[5]; - phid->spaceClocksEcho = buffer[6]; + case RFID_PACKET_TAG: + // Enything other then all 0's means a tag is detected + if(memcmp("\0\0\0\0\0", buffer+1, 5)) + tagEvent_fromEM4100Data(phid, buffer+1); + break; + case RFID_PACKET_OUTPUT_ECHO: + if(phid->fullStateEcho) + { + newStateData = PTRUE; for (i = 0, j = 0x01; i < phid->phid.attr.rfid.numOutputs; i++, j<<=1) { - if (buffer[7] & j) + if (buffer[1] & j) outputs[i] = PTRUE; else outputs[i] = PFALSE; } - if(buffer[7] & RFID_LED_FLAG) + if(buffer[1] & RFID_LED_FLAG) ledState = PTRUE; else ledState = PFALSE; - if(buffer[7] & RFID_ANTENNA_FLAG) + if(buffer[1] & RFID_ANTENNA_FLAG) antennaState = PTRUE; else antennaState = PFALSE; + } + break; + default: + return EPHIDGET_UNEXPECTED; + } + break; + + // RFID with decoding in software and write support + case PHIDUID_RFID_2OUTPUT_READ_WRITE: + { + int dataLength = 0; + int dataOffset = 1; + int data[RFID_MAX_DATA_PER_PACKET]; + switch(buffer[0] & 0x40) + { + case RFID_ECHO_IN_PACKET: + dataOffset = 11; + newStateData = PTRUE; + + //Don't bother - we don't use it. + //phid->frequencyEcho = buffer[1] * 1000; + + phid->pregapClocksEcho = buffer[2]; + phid->prepulseClocksEcho = buffer[7]; + phid->zeroClocksEcho = buffer[4]; + phid->oneClocksEcho = buffer[5]; + phid->spaceClocksEcho = buffer[6]; + phid->postgapClocksEcho = buffer[3]; + phid->eofpulseClocksEcho = buffer[8]; + + for (i = 0, j = 0x01; i < phid->phid.attr.rfid.numOutputs; i++, j<<=1) + { + if (buffer[9] & j) + outputs[i] = PTRUE; + else + outputs[i] = PFALSE; + } - phid->_4097ConfEcho = buffer[8]; + if(buffer[9] & RFID_LED_FLAG) + ledState = PTRUE; + else + ledState = PFALSE; - //space in data - if(buffer[9]) - { - //Manchester event with space - unsigned char manEventData[1]; - manEventData[0] = PUNK_BOOL; + if(buffer[9] & RFID_ANTENNA_FLAG) + antennaState = PTRUE; + else + antennaState = PFALSE; + + if(buffer[9] & RFID_LISTEN_DURING_EOF_FLAG) + phid->listenDuringEOFEcho = PTRUE; + else + phid->listenDuringEOFEcho = PFALSE; - FIRE(ManchesterData, manEventData, 1); + phid->_4097ConfEcho = buffer[10]; - //Add a space in the buffer - only if it's not already a space + //NOTE: Fall Through + case RFID_READ_DATA_IN_PACKET: + + //move RFID data into local storage + dataLength = buffer[0] & 0x3F; + for(i = 0; i < dataLength; i++) + { + data[i] = buffer[i+dataOffset] << 1; + if((data[i] & 0xFE) == 0xFE) + { + data[i] = PUNK_INT; phid->dataBuffer[phid->dataWritePtr] = PUNK_INT; - phid->dataWritePtr++; - phid->dataWritePtr &= RFID_DATA_ARRAY_MASK; - - //if we run into data that hasn't been read... too bad, we overwrite it and adjust the read pointer - if(phid->dataWritePtr == phid->dataReadPtr) - { - phid->dataReadPtr++; - phid->dataReadPtr &= RFID_DATA_ARRAY_MASK; - } - if(phid->dataWritePtr == phid->dataReadACPtr) - { - phid->dataReadACPtr++; - phid->dataReadACPtr &= RFID_DATA_ARRAY_MASK; - } - dataLength = 1; - data[0] = PUNK_INT; } else - gotData = PTRUE; + { + // convert to data lengths that we expect to deal with internally + int polarity = data[i] & 0x100; + int clocks = data[i] & 0xff; + + if(clocks >= 10 && clocks <= 22) + phid->dataBuffer[phid->dataWritePtr] = polarity | 16; + else if(clocks >= 26 && clocks <= 40) + phid->dataBuffer[phid->dataWritePtr] = polarity | 32; + else if(clocks >= 42 && clocks <= 54) + phid->dataBuffer[phid->dataWritePtr] = polarity | 48; + else if(clocks >= 56 && clocks <= 72) + phid->dataBuffer[phid->dataWritePtr] = polarity | 64; + else if(clocks >= 120 && clocks <= 136) + phid->dataBuffer[phid->dataWritePtr] = polarity | 128; + else + phid->dataBuffer[phid->dataWritePtr] = PUNK_INT; + } - break; - default: - return EPHIDGET_UNEXPECTED; - } + phid->dataWritePtr++; + phid->dataWritePtr &= RFID_DATA_ARRAY_MASK; - if(dataLength) - { - //send out raw data event - FIRE(RawData, data, dataLength); + //if we run into data that hasn't been read... too bad, we overwrite it and adjust the read pointer + if(phid->dataWritePtr == phid->dataReadPtr) + { + phid->dataReadPtr++; + phid->dataReadPtr &= RFID_DATA_ARRAY_MASK; + } +#ifdef RFID_HITAGS_SUPPORT + if(phid->dataWritePtr == phid->dataReadACPtr) + { + phid->dataReadACPtr++; + phid->dataReadACPtr &= RFID_DATA_ARRAY_MASK; + } +#endif + } - //analyze data - analyze_data(phid); - if(phid->ACCodingOK) - analyze_data_AC(phid); - else - phid->dataReadACPtr = phid->dataWritePtr; - } + break; + default: + return EPHIDGET_UNEXPECTED; + } + + if(dataLength) + { + +#ifdef RFID_RAWDATA_API_SUPPORT + FIRE(RawData, data, dataLength); +#endif + + //analyze data + analyze_data(phid); + +#ifdef RFID_HITAGS_SUPPORT + setTimeNow(&phid->lastDataTime); + if(phid->ACCodingOK) + analyze_data_AC(phid); + else + phid->dataReadACPtr = phid->dataWritePtr; +#endif } - else - return EPHIDGET_UNEXPECTED; break; + } default: return EPHIDGET_UNEXPECTED; } - if(gotData) - setTimeNow(&phid->lastDataTime); - //Make sure values are within defined range, and store to structure - if(newOutputs) + if(newStateData) { + unsigned char lastOutputs[RFID_MAXOUTPUTS]; + for (i = 0; i < phid->phid.attr.rfid.numOutputs; i++) { lastOutputs[i] = phid->outputEchoState[i]; phid->outputEchoState[i] = outputs[i]; } + phid->ledEchoState = ledState; phid->antennaEchoState = antennaState; - } - CThread_mutex_lock(&phid->tagthreadlock); - if(newTag && !phid->tagEventPending) - { - memcpy(phid->pendingTag, tagData, 5); - phid->tagEventPending = PTRUE; - CThread_set_event(&phid->tagAvailableEvent); - } - CThread_mutex_unlock(&phid->tagthreadlock); - //Events - if(newOutputs) - { + //Events for (i = 0; i < phid->phid.attr.rfid.numOutputs; i++) { if(lastOutputs[i] != phid->outputEchoState[i]) @@ -529,13 +427,24 @@ CPHIDGETINITEVENTS(RFID) } } - //Initial tag events are sent from the tagTimerThread + //Initial non-remote tag events are sent from the tagTimerThread //Don't start the tag thread if this is a networked Phidget CThread_mutex_lock(&phid->phid.lock); if(CPhidget_statusFlagIsSet(phid->phid.status, PHIDGET_ATTACHED_FLAG)) { - if(!CPhidget_statusFlagIsSet(phid->phid.status, PHIDGET_REMOTE_FLAG)) + //For remote - if there is a tag present, send the tag event here + if(CPhidget_statusFlagIsSet(phid->phid.status, PHIDGET_REMOTE_FLAG)) + { + CThread_mutex_unlock(&phid->phid.lock); + if(phid->tagPresent == PTRUE && phid->lastTagValid == PTRUE) + { + if(phid->lastTag.protocol == PHIDGET_RFID_PROTOCOL_EM4100) + FIRE(Tag, phid->lastTag.tagData); + FIRE(Tag2, phid->lastTag.tagString, phid->lastTag.protocol); + } + } + else { CThread_mutex_unlock(&phid->phid.lock); //Start the tagTimerThread - do it here because we are about to start the read thread, and that will keep it active @@ -546,13 +455,6 @@ CPHIDGETINITEVENTS(RFID) return EPHIDGET_UNEXPECTED; } } - //For remote - if there is a tag present, send the tag event here - else - { - CThread_mutex_unlock(&phid->phid.lock); - if(phid->tagPresent == PTRUE) - FIRE(Tag, phid->lastTag); - } } else { @@ -584,8 +486,6 @@ int CPhidgetRFID_free(CPhidgetHandle phidG) CPhidgetRFIDHandle phid = (CPhidgetRFIDHandle)phidG; CThread_mutex_destroy(&phid->tagthreadlock); CThread_destroy_event(&phid->tagAvailableEvent); - CThread_destroy_event(&phid->respEvent); - CThread_destroy_event(&phid->respEvent2); return EPHIDGET_OK; } @@ -601,75 +501,91 @@ CMAKEPACKET(RFID) TESTPTRS(phid, buffer); - switch(phid->phid.deviceIDSpec) + switch(phid->phid.deviceUID) { - case PHIDID_RFID_2OUTPUT: //4-output RFID - if ((phid->phid.deviceVersion >= 200) && (phid->phid.deviceVersion < 300)) + case PHIDUID_RFID_2OUTPUT_NO_ECHO: + case PHIDUID_RFID_2OUTPUT: + //have to make sure that everything to be sent has some sort of default value if the user hasn't set a value + for (i = 0; i < phid->phid.attr.rfid.numOutputs; i++) { - //have to make sure that everything to be sent has some sort of default value if the user hasn't set a value - for (i = 0; i < phid->phid.attr.rfid.numOutputs; i++) - { - if (phid->outputState[i] == PUNK_BOOL) - phid->outputState[i] = PFALSE; - } - if(phid->antennaState == PUNK_BOOL) - phid->antennaState = PFALSE; - if(phid->ledState == PUNK_BOOL) - phid->ledState = PFALSE; + if (phid->outputState[i] == PUNK_BOOL) + phid->outputState[i] = PFALSE; + } + if(phid->antennaState == PUNK_BOOL) + phid->antennaState = PFALSE; + if(phid->ledState == PUNK_BOOL) + phid->ledState = PFALSE; - //construct the packet - for (i = 0, j = 1; i < phid->phid.attr.rfid.numOutputs; i++, j<<=1) - { - if (phid->outputState[i]) - buffer[0] |= j; - } - if(phid->ledState == PTRUE) - buffer[0] |= RFID_LED_FLAG; - if(phid->antennaState == PTRUE) - buffer[0] |= RFID_ANTENNA_FLAG; + //construct the packet + for (i = 0, j = 1; i < phid->phid.attr.rfid.numOutputs; i++, j<<=1) + { + if (phid->outputState[i]) + buffer[0] |= j; } - else - return EPHIDGET_UNEXPECTED; + if(phid->ledState == PTRUE) + buffer[0] |= RFID_LED_FLAG; + if(phid->antennaState == PTRUE) + buffer[0] |= RFID_ANTENNA_FLAG; break; - case PHIDID_RFID_2OUTPUT_ADVANCED: //4-output RFID Advanced - if ((phid->phid.deviceVersion >= 100) && (phid->phid.deviceVersion < 200)) + case PHIDUID_RFID_2OUTPUT_READ_WRITE: + //have to make sure that everything to be sent has some sort of default value if the user hasn't set a value + for (i = 0; i < phid->phid.attr.rfid.numOutputs; i++) { - //have to make sure that everything to be sent has some sort of default value if the user hasn't set a value - for (i = 0; i < phid->phid.attr.rfid.numOutputs; i++) - { - if (phid->outputState[i] == PUNK_BOOL) - phid->outputState[i] = PFALSE; - } - if(phid->antennaState == PUNK_BOOL) - phid->antennaState = PFALSE; - if(phid->ledState == PUNK_BOOL) - phid->ledState = PFALSE; - - //construct the packet - for (i = 0, j = 1; i < phid->phid.attr.rfid.numOutputs; i++, j<<=1) - { - if (phid->outputState[i]) - buffer[7] |= j; - } - if(phid->ledState == PTRUE) - buffer[7] |= RFID_LED_FLAG; - if(phid->antennaState == PTRUE) - buffer[7] |= RFID_ANTENNA_FLAG; - - //TODO: make sure these are actually all valid - buffer[0] = RFID_CONTROL_OUT_PACKET; - buffer[1] = phid->pregapClocks; - buffer[2] = phid->postgapClocks; - buffer[3] = phid->zeroClocks; - buffer[4] = phid->oneClocks; - buffer[5] = phid->spaceClocks; - buffer[6] = phid->_4097Conf; + if (phid->outputState[i] == PUNK_BOOL) + phid->outputState[i] = PFALSE; } + if(phid->antennaState == PUNK_BOOL) + phid->antennaState = PFALSE; + if(phid->ledState == PUNK_BOOL) + phid->ledState = PFALSE; + + // Default write timing to T5577 + if(phid->pregapClocks == PUNK_INT) + phid->pregapClocks = RFID_T5577_StartGap; + if(phid->prepulseClocks == PUNK_INT) + phid->prepulseClocks = RFID_T5577_PrePulse; + if(phid->zeroClocks == PUNK_INT) + phid->zeroClocks = RFID_T5577_Zero; + if(phid->oneClocks == PUNK_INT) + phid->oneClocks = RFID_T5577_One; + if(phid->spaceClocks == PUNK_INT) + phid->spaceClocks = RFID_T5577_WriteGap; + if(phid->postgapClocks == PUNK_INT) + phid->postgapClocks = RFID_T5577_EndGap; + if(phid->eofpulseClocks == PUNK_INT) + phid->eofpulseClocks = RFID_T5577_EOF; + if(phid->listenDuringEOF == PUNK_BOOL) + phid->listenDuringEOF = PFALSE; + + //construct the packet + for (i = 0, j = 1; i < phid->phid.attr.rfid.numOutputs; i++, j<<=1) + { + if (phid->outputState[i]) + buffer[0] |= j; + } + if(phid->ledState == PTRUE) + buffer[0] |= RFID_LED_FLAG; + if(phid->antennaState == PTRUE) + buffer[0] |= RFID_ANTENNA_FLAG; + + if(phid->antennaState == PTRUE) + phid->_4097Conf = RFID_4097_DefaultON; else - return EPHIDGET_UNEXPECTED; + phid->_4097Conf = RFID_4097_PowerDown; + + buffer[0] |= RFID_CONTROL_OUT_PACKET; + buffer[1] = (phid->pregapClocks-1) & 0x3F; + buffer[1] |= ((phid->postgapClocks-1) << 2) & 0xC0; + buffer[2] = (phid->postgapClocks-1) & 0x0F; + buffer[2] |= ((phid->spaceClocks-1) << 2) & 0xF0; + buffer[3] = (phid->spaceClocks-1) & 0x03; + buffer[3] |= ((phid->zeroClocks-1) << 1) & 0xFC; + buffer[4] = (phid->zeroClocks-1) & 0x01; + buffer[4] |= ((phid->oneClocks-1) << 1) & 0xFE; + buffer[5] = phid->prepulseClocks; + buffer[6] = phid->eofpulseClocks; + buffer[7] = phid->_4097Conf; break; - case PHIDID_RFID: - return EPHIDGET_UNSUPPORTED; //this version does not have outputs default: return EPHIDGET_UNEXPECTED; } @@ -681,15 +597,11 @@ CMAKEPACKET(RFID) CThread_func_return_t tagTimerThreadFunction(CThread_func_arg_t userPtr) { CPhidgetRFIDHandle phid = (CPhidgetRFIDHandle)userPtr; - CPhidgetRFID_TagList *trav = 0, *tagLostList = 0, *tagFoundList = 0; if(!phid) return (CThread_func_return_t)EPHIDGET_INVALIDARG; LOG(PHIDGET_LOG_INFO,"tagTimerThread running"); - //Set this before creation - //phid->tagTimerThread.thread_status = PTRUE; - while (CPhidget_statusFlagIsSet(phid->phid.status, PHIDGET_ATTACHED_FLAG) && phid->tagTimerThread.thread_status == PTRUE) { //sleeps for up to 50ms, but can be signalled externally to return immediately @@ -697,120 +609,71 @@ CThread_func_return_t tagTimerThreadFunction(CThread_func_arg_t userPtr) CThread_reset_event(&phid->tagAvailableEvent); //Tag events - //Old-style + CThread_mutex_lock(&phid->tagthreadlock); if(phid->tagEventPending) { - phid->tagPresent = PTRUE; - FIRE(Tag, phid->pendingTag); - CThread_mutex_lock(&phid->tagthreadlock); - setTimeNow(&phid->lastTagTime); - - //so they can access the last tag from this tag event - memcpy(phid->lastTag, phid->pendingTag, 5); - phid->tagEventPending = PFALSE; CThread_mutex_unlock(&phid->tagthreadlock); - } - //New-style - CThread_mutex_lock(&phid->tagthreadlock); - for (trav=phid->tagAdvancedList; trav; trav = trav->next) - { - if(trav->tag->tagEventPending == PTRUE) - CList_addToList((CListHandle *)&tagFoundList, trav->tag, CPhidgetRFID_Tag_areEqual); - } - for (trav=tagFoundList; trav; trav = trav->next) - { - if(phid->tagAdvancedCount == PUNK_INT) - phid->tagAdvancedCount = 0; - phid->tagAdvancedCount++; + if(phid->pendingTag.protocol == PHIDGET_RFID_PROTOCOL_EM4100) + FIRE(Tag, phid->pendingTag.tagData); + FIRE(Tag2, phid->pendingTag.tagString, phid->pendingTag.protocol); - CThread_mutex_unlock(&phid->tagthreadlock); - FIRE(TagAdvanced, trav->tag->tagString, &trav->tag->tagInfo); + //Fill in lastTag after the event so that LAST tag (not current tag) is avialable in the event CThread_mutex_lock(&phid->tagthreadlock); - setTimeNow(&trav->tag->lastTagTime); - - //so they can access the last tag from this tag event - memcpy(&phid->lastTagAdvanced, trav->tag, sizeof(CPhidgetRFID_Tag)); - trav->tag->tagEventPending = PFALSE; + phid->lastTag = phid->pendingTag; + phid->lastTagValid = PTRUE; + phid->tagEventPending = PFALSE; } - CList_emptyList((CListHandle *)&tagFoundList, PFALSE, NULL); CThread_mutex_unlock(&phid->tagthreadlock); //TAG Lost events - //Old-style + CThread_mutex_lock(&phid->tagthreadlock); if(phid->tagPresent != PFALSE) { /* check for tag lost */ - - CThread_mutex_lock(&phid->tagthreadlock); +#ifdef RFID_HITAGS_SUPPORT + if((timeSince(&phid->lastTagTime) > 0.2 && phid->lastTag.protocol != PHIDGET_RFID_PROTOCOL_HITAGS_UID) + || (timeSince(&phid->lastTagTime) > 0.5 && phid->lastTag.protocol == PHIDGET_RFID_PROTOCOL_HITAGS_UID)) +#else if(timeSince(&phid->lastTagTime) > 0.2) +#endif { if (phid->tagPresent == PTRUE) { phid->tagPresent = PFALSE; CThread_mutex_unlock(&phid->tagthreadlock); - FIRE(TagLost, phid->lastTag); + + if(phid->pendingTag.protocol == PHIDGET_RFID_PROTOCOL_EM4100) + FIRE(TagLost, phid->lastTag.tagData); + FIRE(TagLost2, phid->lastTag.tagString, phid->lastTag.protocol); + CThread_mutex_lock(&phid->tagthreadlock); } else if(phid->antennaEchoState == PTRUE) //could be PUNK_BOOL - don't send event, just set to PFALSE (but only if the antenna is on) phid->tagPresent = PFALSE; } - CThread_mutex_unlock(&phid->tagthreadlock); - } - //New-style - if(phid->tagAdvancedCount != 0) - { - if(phid->tagAdvancedCount != PUNK_INT) - { - CThread_mutex_lock(&phid->tagthreadlock); - for (trav=phid->tagAdvancedList; trav; trav = trav->next) - { - if((timeSince(&trav->tag->lastTagTime) > 0.2 && trav->tag->tagInfo.tagType != PHIDGET_RFID_TAG_HITAGS) - || (timeSince(&trav->tag->lastTagTime) > 0.5 && trav->tag->tagInfo.tagType == PHIDGET_RFID_TAG_HITAGS)) - CList_addToList((CListHandle *)&tagLostList, trav->tag, CPhidgetRFID_Tag_areEqual); - } - for (trav=tagLostList; trav; trav = trav->next) - { - CList_removeFromList((CListHandle *)&phid->tagAdvancedList, trav->tag, CPhidgetRFID_Tag_areEqual, PFALSE, NULL); - phid->tagAdvancedCount--; - CThread_mutex_unlock(&phid->tagthreadlock); - FIRE(TagLostAdvanced, trav->tag->tagString, &trav->tag->tagInfo); - CThread_mutex_lock(&phid->tagthreadlock); - } - CList_emptyList((CListHandle *)&tagLostList, PTRUE, CPhidgetRFID_Tag_free); - CThread_mutex_unlock(&phid->tagthreadlock); - } - else if(phid->antennaEchoState == PTRUE) - phid->tagAdvancedCount = 0; } + CThread_mutex_unlock(&phid->tagthreadlock); +#ifdef RFID_HITAGS_SUPPORT //Actively look for tags if we haven't gotten data for a while (Hitag) + CThread_mutex_lock(&phid->tagthreadlock); if(phid->antennaEchoState == PTRUE && phid->polling == PTRUE) { - switch(phid->phid.deviceIDSpec) + switch(phid->phid.deviceUID) { - case PHIDID_RFID_2OUTPUT_ADVANCED: //2-output RFID Advanced - if ((phid->phid.deviceVersion >= 100) && (phid->phid.deviceVersion < 200)) + case PHIDUID_RFID_2OUTPUT_READ_WRITE: + if(timeSince(&phid->hitagReqTime) > 0.1 && timeSince(&phid->lastDataTime) > 0.1) //100ms { - CThread_mutex_lock(&phid->tagthreadlock); - if(timeSince(&phid->hitagReqTime) > 0.1) //100ms - { - if(timeSince(&phid->lastDataTime) > 0.1) //100ms - { - HitagS_UID_REQUEST(phid); - } - } - CThread_mutex_unlock(&phid->tagthreadlock); + HitagS_UID_REQUEST(phid); } - else - return (CThread_func_return_t)EPHIDGET_UNEXPECTED; break; + //Cannot send data - case PHIDID_RFID_2OUTPUT: - case PHIDID_RFID: - break; default: - return (CThread_func_return_t)EPHIDGET_UNEXPECTED; + break; } } + CThread_mutex_unlock(&phid->tagthreadlock); +#endif } LOG(PHIDGET_LOG_INFO,"tagTimerThread exiting normally"); @@ -818,6 +681,67 @@ CThread_func_return_t tagTimerThreadFunction(CThread_func_arg_t userPtr) return (CThread_func_return_t)EPHIDGET_OK; } +static int tagEvent(CPhidgetRFIDHandle phid, CPhidgetRFID_TagHandle tagPtr) +{ +again: + CThread_mutex_lock(&phid->tagthreadlock); + + //update time + setTimeNow(&phid->lastTagTime); + + //See if there is a current tag, and if it matches this tag + if(phid->tagPresent != PTRUE || + (phid->lastTagValid && strcmp(phid->lastTag.tagString, tagPtr->tagString) && phid->lastTag.protocol == tagPtr->protocol)) + { + //Wait for tagEventPending to be false if it's true + if(phid->tagEventPending == PTRUE) + { + CThread_mutex_unlock(&phid->tagthreadlock); + SLEEP(10); + goto again; + } + + phid->pendingTag = *tagPtr; + phid->tagEventPending = PTRUE; + CThread_set_event(&phid->tagAvailableEvent); + } + + phid->tagPresent = PTRUE; + + CThread_mutex_unlock(&phid->tagthreadlock); + + return EPHIDGET_OK; +} + +static int tagEvent_fromEM4100Data(CPhidgetRFIDHandle phid, unsigned char *data) +{ + CPhidgetRFID_Tag tag; + ZEROMEM(&tag, sizeof(CPhidgetRFID_Tag)); + snprintf(tag.tagString, RFID_MAX_TAG_STRING_LEN, "%02x%02x%02x%02x%02x",data[0],data[1],data[2],data[3],data[4]); + tag.protocol = PHIDGET_RFID_PROTOCOL_EM4100; + memcpy(tag.tagData, data, 5); + return tagEvent(phid, &tag); +} + +static int waitForTag(CPhidgetRFIDHandle phid, char *tagString, int timeout) +{ + //Wait for this tag to show up + while(timeout > 0) + { + CThread_mutex_lock(&phid->tagthreadlock); + if(!strncmp(phid->pendingTag.tagString, tagString, RFID_MAX_TAG_STRING_LEN)) + { + CThread_mutex_unlock(&phid->tagthreadlock); + return EPHIDGET_OK; + } + CThread_mutex_unlock(&phid->tagthreadlock); + SLEEP(50); + timeout-=50; + } + + return EPHIDGET_TIMEOUT; +} + static int sendRAWData(CPhidgetRFIDHandle phid, unsigned char *data, int bitlength) { unsigned char buffer[10]; @@ -857,229 +781,210 @@ static int sendRAWData(CPhidgetRFIDHandle phid, unsigned char *data, int bitleng return EPHIDGET_OK; } -static void resetHitagACBuffer(CPhidgetRFIDHandle phid) +static void resetValuesFromSpace(CPhidgetRFIDHandle phid) { - phid->dataReadACPtr = phid->dataWritePtr; - phid->ACCodingOK = PTRUE; -} + phid->shortClocks = phid->longClocks = 0; + phid->manLockedIn = 0; + phid->manReadPtr = 0; + phid->manWritePtr = 0; + phid->biphaseReadPtr = 0; + phid->biphaseWritePtr = 0; + phid->manShortChange = 0; + phid->biphaseShortChange = 0; + phid->biphaseLockedIn = 0; -//Hitag CRC -#define CRC_PRESET 0xFF -#define CRC_POLYNOM 0x1D -static void calc_crc_hitag(unsigned char * crc, - unsigned char data, - unsigned char Bitcount) -{ - *crc ^= data; //crc = crc (exor) data - do - { - if( *crc & 0x80 ) // if (MSB-CRC == 1) - { - *crc<<=1; // CRC = CRC Bit-shift left - *crc ^= CRC_POLYNOM; // CRC = CRC (exor) CRC_POLYNOM - } - else - *crc<<=1; // CRC = CRC Bit-shift left - } while(--Bitcount); -} -static unsigned char hitagCRC8(unsigned char *data, int dataBits) -{ - unsigned char crc; - int i; - int dataLength = dataBits / 8; - if(dataBits%8 != 0) - dataLength++; - crc = CRC_PRESET; /* initialize crc algorithm */ +#ifdef RFID_RAWDATA_API_SUPPORT + phid->manEventReadPtr = 0; - for(i=0; i<dataLength; i++) + //Manchester event with space + if(phid->lastManEventLong == PFALSE) { - calc_crc_hitag(&crc, data[i], ((dataBits > 8) ? 8 : dataBits)); - dataBits -= 8; + unsigned char manEventData[1]; + phid->lastManEventLong = PTRUE; + manEventData[0] = PUNK_BOOL; + FIRE(ManchesterData, manEventData, 1); } - - return crc; +#endif } -static int HitagS_WRITE(CPhidgetRFIDHandle phid, int page, unsigned char *data, unsigned char blockWrite) +//ISO11785 CRC +static void CRC_16_CCITT_update(unsigned short *crc, unsigned char x) { - int res; - unsigned char buf[] = {0,0,0}; - unsigned char crc; - - buf[0] = (blockWrite ? 0x90 : 0x80) | page >> 4; - buf[1] = page << 4; - crc = hitagCRC8(buf, 12); - buf[1] |= crc >> 4; - buf[2] = crc << 4; - - //make sure it's been at least 50ms since last hitag request - CThread_mutex_lock(&phid->tagthreadlock); - while(timeSince(&phid->hitagReqTime) < 0.01) //50ms - SLEEP(10); - - phid->hitagState = RFID_HITAG_STATE_WRITE; - phid->hitagOffset = page; - - phid->manShortChange=0; - phid->manLockedIn = 1; - phid->manReadPtr = phid->manWritePtr; - - //Send a Hitag S Command - res = CPhidgetRFID_writeRaw(phid, buf, 20, 7, 7, 7, 13, 21); - - //Don't send it again for at least 100ms - setTimeNow(&phid->hitagReqTime); - CThread_mutex_unlock(&phid->tagthreadlock); - - //Wait for ACK - - //Send page data - - return res; + unsigned short crc_new = (unsigned char)((*crc) >> 8) | ((*crc) << 8); + crc_new ^= x; + crc_new ^= (unsigned char)(crc_new & 0xff) >> 4; + crc_new ^= crc_new << 12; + crc_new ^= (crc_new & 0xff) << 5; + (*crc) = crc_new; } -static int HitagS_READ(CPhidgetRFIDHandle phid, int page, unsigned char blockRead) +//Reverse all bits +static __uint64 +reverse(__uint64 x) { - int res; - unsigned char buf[] = {0,0,0}; - unsigned char crc; - - buf[0] = (blockRead ? 0xD0 : 0xC0) | page >> 4; - buf[1] = page << 4; - crc = hitagCRC8(buf, 12); - buf[1] |= crc >> 4; - buf[2] = crc << 4; - - //make sure it's been at least 50ms since last hitag request - CThread_mutex_lock(&phid->tagthreadlock); - while(timeSince(&phid->hitagReqTime) < 0.01) //50ms - SLEEP(10); - - phid->hitagState = RFID_HITAG_STATE_READ; - phid->hitagOffset = page; - - phid->manShortChange=0; - phid->manLockedIn = 1; - phid->manReadPtr = phid->manWritePtr; - - //Send a Hitag S Command - res = CPhidgetRFID_writeRaw(phid, buf, 20, 7, 7, 7, 13, 21); - - //Don't send it again for at least 100ms - setTimeNow(&phid->hitagReqTime); - CThread_mutex_unlock(&phid->tagthreadlock); - - return res; + x = (((x & 0xaaaaaaaaaaaaaaaaLL) >> 1) | ((x & 0x5555555555555555LL) << 1)); + x = (((x & 0xccccccccccccccccLL) >> 2) | ((x & 0x3333333333333333LL) << 2)); + x = (((x & 0xf0f0f0f0f0f0f0f0LL) >> 4) | ((x & 0x0f0f0f0f0f0f0f0fLL) << 4)); + x = (((x & 0xff00ff00ff00ff00LL) >> 8) | ((x & 0x00ff00ff00ff00ffLL) << 8)); + x = (((x & 0xffff0000ffff0000LL) >> 16) | ((x & 0x0000ffff0000ffffLL) << 16)); + return((x >> 32) | (x << 32)); } -static int HitagS_SELECT(CPhidgetRFIDHandle phid, unsigned char *UID) +/* Takes the tagString in 10-digit hex, and produces data for programming. + * blockData are 32-bit blocks. + * blockDataLen will be 2 when we return, as EM4100 takes 64-bits. + */ +static int encodeEM4100(char *tagString, unsigned int *blockData, int *blockDataLen) { - int res; - unsigned char buf[] = {0,0,0,0,0,0}; - unsigned char crc; - int k,i; - - if(!UID) - return EPHIDGET_INVALIDARG; - if(strlen((char *)UID)!=8) + __int64 tagData, mask; + __uint64 encodedTagData = 0; + int i,j,row,col; + TESTPTRS(tagString, blockData) + TESTPTR(blockDataLen) + if(*blockDataLen < 2) return EPHIDGET_INVALIDARG; + if(strlen(tagString) != 10 ) + if(!(strlen(tagString) == 12 && tagString[0] == '0' && tagString[1] == 'x')) + return EPHIDGET_INVALIDARG; - for(i=0,k=5;i<32;i++,k++) + tagData = strtoll(tagString, NULL, 16); + + //9 leading 1's + encodedTagData = 0xFF80000000000000LL; + //Data + for(i=0, mask=0x0078000000000000LL, j=15; i<10; i++, j--, mask>>=5) { - buf[k/8] |= ((hexval(UID[i/4]) >> (3-(i%4))) & 0x01) << (7-(k%8)); + encodedTagData |= ((tagData << j) & mask); } - crc = hitagCRC8(buf, 37); - for(i=0;i<8;i++,k++) + //Parity + for(i=0, row=1, col=1; i<40; i++, col++) { - buf[k/8] |= (crc >> (7-(i%8))) << (7-(k%8)); + if(col>4) { col=1; row++; } + + //column parity + encodedTagData ^= ((tagData & 0x1) << col); + //row parity + encodedTagData ^= ((tagData & 0x1) << (row*5)); + + tagData>>=1; } - //make sure it's been at least 50ms since last hitag request - CThread_mutex_lock(&phid->tagthreadlock); - while(timeSince(&phid->hitagReqTime) < 0.05) //50ms - SLEEP(10); - - phid->hitagState = RFID_HITAG_STATE_SELECT; - - phid->manShortChange=0; - phid->manLockedIn = 1; - phid->manReadPtr = phid->manWritePtr; - - //Send a Hitag S AC Sequence Command - res = CPhidgetRFID_writeRaw(phid, buf, k, 7, 7, 7, 13, 21); - - //Don't send it again for at least 100ms - setTimeNow(&phid->hitagReqTime); - CThread_mutex_unlock(&phid->tagthreadlock); + blockData[0] = (int)(encodedTagData >> 32); + blockData[1] = (int)encodedTagData; + *blockDataLen = 2; - return res; + return EPHIDGET_OK; } -static int HitagS_UID_REQUEST(CPhidgetRFIDHandle phid) + +/* Takes the tagString in 15-digit decimal, and produces data for programming. + * blockData are 32-bit blocks. + * blockDataLen will be 4 when we return, as FDX-B takes 128-bits. + */ +static int encodeISO11785_FDX_B(char *tagString, unsigned int *blockData, int *blockDataLen) { - int res; - //Send a Hitag S UID Request Command - unsigned char buf[] = { 0xC0 }; + __uint64 tagData, encodedTagData[2] = {0,0}, mask, uniqueID; + unsigned short crc = 0x0000; + unsigned long countryCode; + char countryCodeStr[4]; + int i,j; + TESTPTRS(tagString, blockData) + TESTPTR(blockDataLen) + if(*blockDataLen < 4) + return EPHIDGET_INVALIDARG; + if(strlen(tagString) != 15 ) + return EPHIDGET_INVALIDARG; - //make sure it's been at least 50ms since last hitag request - CThread_mutex_lock(&phid->tagthreadlock); - while(timeSince(&phid->hitagReqTime) < 0.05) //50ms - SLEEP(10); + //Get uniqueID + uniqueID = (__uint64)strtoll(tagString+3, NULL, 10); + //must be 38-bit or less + if(uniqueID > 0x3FFFFFFFFFLL) + return EPHIDGET_INVALIDARG; - phid->hitagState = RFID_HITAG_STATE_UID_REQUEST; + //Get Country Code + memcpy(countryCodeStr, tagString, 3); + countryCodeStr[3] = '\0'; + countryCode = strtoul(countryCodeStr, NULL, 10); + + //Create ISO11784 64-bit data + tagData = (((__uint64)countryCode) << 38) | uniqueID; + //Add the animal bit + tagData |= 0x8000000000000000LL; + //Reverse because order is LSB 1st. + tagData = reverse(tagData); + //Calculate CRC + for(i=0,j=7*8;i<8;i++,j-=8) + CRC_16_CCITT_update(&crc, (unsigned char)((tagData>>j) & 0xFF)); + + //Put it into the FDX-B Format + + //Header and control bits + encodedTagData[0] = 0x0020100804020100LL; + encodedTagData[1] = 0x8040201008040201LL; + //Data + for(i=0, mask = 0x001FE00000000000LL, j=11; i<6; i++, mask >>= 9, j++) + encodedTagData[0] |= ((tagData >> j) & mask); + for(i=0, mask = 0x7F80000000000000LL, j=47; i<2; i++, mask >>= 9, j--) + encodedTagData[1] |= ((tagData << j) & mask); + //CRC + encodedTagData[1] |= ((((__uint64)crc) << 29) & 0x00001FE000000000LL); + encodedTagData[1] |= ((((__uint64)crc) << 28) & 0x0000000FF0000000LL); + + blockData[0] = (int)(encodedTagData[0] >> 32); + blockData[1] = (int)encodedTagData[0]; + blockData[2] = (int)(encodedTagData[1] >> 32); + blockData[3] = (int)encodedTagData[1]; + *blockDataLen = 4; - //Empty AC List - if(phid->hitagACList) - CList_emptyList((CListHandle *)&phid->hitagACList, PTRUE, CPhidgetRFID_HitagAC_free); - phid->hitagACList = NULL; + return EPHIDGET_OK; +} - resetHitagACBuffer(phid); - res = CPhidgetRFID_writeRaw(phid, buf, 5, 7, 7, 7, 13, 21); +/* Takes the tagString in ASCII up to 24 characters, and produces data for programming. + * blockData are 32-bit blocks. + * blockDataLen will be 7 when we return, as PHIDGETS_TAG takes 224-bits. + */ +static int encodePHIDGETS_TAG(char *tagString, unsigned int *blockData, int *blockDataLen) +{ + char tagData[24]; + int len, i, j; + unsigned short crc; + TESTPTRS(tagString, blockData) + TESTPTR(blockDataLen) + if(*blockDataLen < 7) + return EPHIDGET_INVALIDARG; + if(strlen(tagString) > 24 ) + return EPHIDGET_INVALIDARG; - //Don't send it again for at least 100ms - setTimeNow(&phid->hitagReqTime); - CThread_mutex_unlock(&phid->tagthreadlock); + //copy of string. + len = strlen(tagString); + ZEROMEM(tagData, 24); + memcpy(tagData, tagString, len); - return res; -} -static int HitagS_AC_SEQUENCE(CPhidgetRFIDHandle phid, CPhidgetRFID_HitagACHandle ac) -{ - int res; - unsigned char buf[] = {0,0,0,0,0,0}; - unsigned char crc; - int k,i; + //Calculate CRC + crc=0; + for(i=0;i<24;i++) + CRC_16_CCITT_update(&crc, (unsigned char)tagData[i]); - buf[0] = (ac->colPos) << 3; - for(i=0,k=5;i<ac->colPos;i++,k++) + //Header, control bits and CRC + blockData[0] = 0x00040201; + blockData[0] |= (((unsigned int)crc) << 2 & 0x0003FC00); + blockData[0] |= (((unsigned int)crc) << 1 & 0x000001FE); + //Control bits + for(i=1;i<7;i++) + blockData[i] = 0x01010101; + //Data + for(i=0,j=184;i<24;i++,j-=8) { - buf[k/8] |= (ac->uid[i/8] >> (7-(i%8))) << (7-(k%8)); + int block = i/4+1; + int shift = (j%32)+1; + blockData[block] |= (tagData[i] << shift); } - crc = hitagCRC8(buf, ac->colPos+5); - for(i=0;i<8;i++,k++) - { - buf[k/8] |= (crc >> (7-(i%8))) << (7-(k%8)); - } - - //make sure it's been at least 50ms since last hitag request - CThread_mutex_lock(&phid->tagthreadlock); - while(timeSince(&phid->hitagReqTime) < 0.05) //50ms - SLEEP(10); - - memcpy(&phid->lastHitagAC, ac, sizeof(CPhidgetRFID_HitagAC)); - //Send a Hitag S AC Sequence Command - phid->hitagState = RFID_HITAG_STATE_AC_SEQUENCE; - - resetHitagACBuffer(phid); - res = CPhidgetRFID_writeRaw(phid, buf, k, 7, 7, 7, 13, 21); - - //Don't send it again for at least 100ms - setTimeNow(&phid->hitagReqTime); - CThread_mutex_unlock(&phid->tagthreadlock); + *blockDataLen = 7; - return res; + return EPHIDGET_OK; } -static int decodeEM4102(CPhidgetRFIDHandle phid, unsigned char *data, int *startPtr, int *endPtr, CPhidgetRFID_TagHandle tag) +static int decodeEM4100(CPhidgetRFIDHandle phid, unsigned char *data, int *startPtr, int *endPtr, CPhidgetRFID_TagHandle tag) { int i, foundStart, k, j; int myReadPtr = *startPtr; @@ -1116,7 +1021,7 @@ start: } //Got here? - We found the start pattern - //Now decode the EM4102 data + //Now decode the EM4100 data for(i=0;i<64;i++) { em4103data[i] = data[(myReadPtr + i) & RFID_DATA_ARRAY_MASK]; @@ -1157,22 +1062,11 @@ start: j++; //skip row parity bit } - //Old style Tag event for EM4102 - CThread_mutex_lock(&phid->tagthreadlock); - setTimeNow(&phid->lastTagTime); - if((memcmp(phid->lastTag, decodedData, 5) || phid->tagPresent == PFALSE) - && memcmp("\0\0\0\0\0", decodedData, 5) - && !phid->tagEventPending) - { - memcpy(phid->pendingTag, decodedData, 5); - phid->tagEventPending = PTRUE; - CThread_set_event(&phid->tagAvailableEvent); - } - CThread_mutex_unlock(&phid->tagthreadlock); - //Update the tag struct for the advanced tag event - snprintf(tag->tagString, 255, "%02x%02x%02x%02x%02x",decodedData[0],decodedData[1],decodedData[2],decodedData[3],decodedData[4]); - tag->tagInfo.tagType = PHIDGET_RFID_TAG_EM4102; + //Update the tag struct for the tag2 event + snprintf(tag->tagString, RFID_MAX_TAG_STRING_LEN, "%02x%02x%02x%02x%02x",decodedData[0],decodedData[1],decodedData[2],decodedData[3],decodedData[4]); + tag->protocol = PHIDGET_RFID_PROTOCOL_EM4100; + memcpy(tag->tagData, decodedData, 5); //update master read pointer (*startPtr)+=64; @@ -1185,19 +1079,7 @@ tryagain: goto start; } -//ISO11785 CRC -void -CRC_16_CCITT_update(unsigned short *crc, unsigned char x) -{ - unsigned short crc_new = (unsigned char)((*crc) >> 8) | ((*crc) << 8); - crc_new ^= x; - crc_new ^= (unsigned char)(crc_new & 0xff) >> 4; - crc_new ^= crc_new << 12; - crc_new ^= (crc_new & 0xff) << 5; - (*crc) = crc_new; -} - -static int decodeISO11785(CPhidgetRFIDHandle phid, unsigned char *data, int *startPtr, int *endPtr, CPhidgetRFID_TagHandle tag) +static int decodeISO11785_FDX_B(CPhidgetRFIDHandle phid, unsigned char *data, int *startPtr, int *endPtr, CPhidgetRFID_TagHandle tag) { int i, foundStart, k; int myReadPtr = *startPtr; @@ -1305,8 +1187,8 @@ start: (((__uint64)iso11785dataReversed[6]) << 8) + ((__uint64)iso11785dataReversed[7])) & 0x3FFFFFFFFFll;// 38 bit - bits 27-63 - snprintf(tag->tagString, 255, "%03d%012lld",countryCode, UID); - tag->tagInfo.tagType = PHIDGET_RFID_TAG_ISO11784; + snprintf(tag->tagString, RFID_MAX_TAG_STRING_LEN, "%03d%012lld",countryCode, UID); + tag->protocol = PHIDGET_RFID_PROTOCOL_ISO11785_FDX_B; } //update master read pointer @@ -1320,271 +1202,119 @@ tryagain: goto start; } -static int decodeHitagUID(CPhidgetRFIDHandle phid, unsigned char *data, int bytesInQueue, CPhidgetRFID_TagHandle tag, int *collisionPos) -{ - int i, k; - int myReadPtr = 0; - unsigned int HitagUID; - int sofBits = 3; - int expectedBytes = 0; - - if(phid->hitagState == RFID_HITAG_STATE_UID_REQUEST) - expectedBytes = 35; - else if(phid->hitagState == RFID_HITAG_STATE_AC_SEQUENCE) - expectedBytes = 35 - phid->lastHitagAC.colPos; - - *collisionPos = -1; - - //UID is 32 bits, plus SOF == '111' - if(bytesInQueue != expectedBytes) - return EPHIDGET_NOTFOUND; - - //verify SOF - for(i=0;i<sofBits;i++) - { - if(data[(myReadPtr + i) & RFID_DATA_ARRAY_MASK] != 1) - return EPHIDGET_NOTFOUND; - } - - //advance past SOF - myReadPtr += sofBits; - myReadPtr &= RFID_DATA_ARRAY_MASK; - - HitagUID = 0; - - //if AC Sequence, read in bits from last AC - for(k=0;k<(32-(expectedBytes-sofBits));k++) - { - HitagUID |= (phid->lastHitagAC.uid[k/8] >> (7-(k%8))) << (31-k); - } - - for(i=0;i<(expectedBytes-sofBits);k++,i++) - { - //check for a collision - if(data[(myReadPtr + i) & RFID_DATA_ARRAY_MASK] == PUNK_BOOL) - { - *collisionPos = k; - return EPHIDGET_NOTFOUND; - } - HitagUID |= data[(myReadPtr + i) & RFID_DATA_ARRAY_MASK] << (31-k); - } - - //We're good! - snprintf(tag->tagString, 255, "%08x",HitagUID); - tag->tagInfo.tagType = PHIDGET_RFID_TAG_HITAGS; - - return EPHIDGET_OK; -} - -static int decodeHitagACKResponse(CPhidgetRFIDHandle phid, unsigned char *data, int *startPtr, int *endPtr) +static int decodePHIDGETS_TAG(CPhidgetRFIDHandle phid, unsigned char *data, int *startPtr, int *endPtr, CPhidgetRFID_TagHandle tag) { + int i, foundStart, k; int myReadPtr = *startPtr; + char tagData[24]; int bytesInQueue; - int i; - int sofBits = 5; //SOF is really 6-bit but we only see it as 5-bit - int expectedBytes = 7; - + unsigned short crcCalc = 0x0000, crcRead = 0x0000; + //Look for the starting pattern of 13 zeroes and 1 one +start: bytesInQueue = *endPtr - myReadPtr; if(myReadPtr > *endPtr) bytesInQueue += RFID_DATA_ARRAY_SIZE; - //printf("maybe(read).. %d\n", bytesInQueue); - //print_buffer(data, *startPtr, *endPtr); - - if(bytesInQueue != expectedBytes) - return EPHIDGET_NOTFOUND; - - //verify SOF - for(i=0;i<sofBits;i++) + while(myReadPtr != *endPtr) { - if(data[(myReadPtr + i) & RFID_DATA_ARRAY_MASK] != 1) + //full sequence is 224 bits + if(bytesInQueue < 224) + return EPHIDGET_NOTFOUND; + foundStart = 1; + + for(i=0;i<13;i++) { - phid->respStatus = EPHIDGET_NOTFOUND; - goto done; + if(data[(myReadPtr + i) & RFID_DATA_ARRAY_MASK] != 0) + { + foundStart = 0; + break; + } } - } - - //Data should be '01' - if(data[(myReadPtr + 5) & RFID_DATA_ARRAY_MASK] != 0 - || data[(myReadPtr + 6) & RFID_DATA_ARRAY_MASK] != 1) - { - phid->respStatus = EPHIDGET_NOTFOUND; - goto done; - } - - phid->respStatus = EPHIDGET_OK; -done: - CThread_set_event(&phid->respEvent); - return phid->respStatus; -} - -static int decodeHitagReadResponse(CPhidgetRFIDHandle phid, unsigned char *data, int *startPtr, int *endPtr) -{ - int myReadPtr = *startPtr; - int bytesInQueue; - unsigned char buf[] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; - int i,k; - int sofBits = 5; //SOF is really 6-bit but we only see it as 5-bit - int expectedBytes = 141; - unsigned char crcExpected = 0, crcFound = 0; - CPhidgetRFID_TagHandle tag = phid->respData; - - bytesInQueue = *endPtr - myReadPtr; - if(myReadPtr > *endPtr) - bytesInQueue += RFID_DATA_ARRAY_SIZE; - - //printf("maybe(read).. %d\n", bytesInQueue); - //print_buffer(data, *startPtr, *endPtr); - - if(bytesInQueue != expectedBytes) - return EPHIDGET_NOTFOUND; - - //verify SOF - for(i=0;i<sofBits;i++) - { - if(data[(myReadPtr + i) & RFID_DATA_ARRAY_MASK] != 1) + if(data[(myReadPtr + 13) & RFID_DATA_ARRAY_MASK] != 1) { - phid->respStatus = EPHIDGET_NOTFOUND; - goto done; + foundStart = 0; } - } - - //advance past SOF - myReadPtr += sofBits; - myReadPtr &= RFID_DATA_ARRAY_MASK; + if(foundStart) + break; - for(k=0;k<128;k++) - { - buf[k/8] |= data[(myReadPtr + k) & RFID_DATA_ARRAY_MASK] << (7-(k%8)); - } - for(i=0;i<8;k++,i++) - { - crcFound |= data[(myReadPtr + k) & RFID_DATA_ARRAY_MASK] << (7-i); - } - crcExpected = hitagCRC8(buf, 128); + myReadPtr++; + myReadPtr &= RFID_DATA_ARRAY_MASK; - if(crcFound != crcExpected) - { - LOG(PHIDGET_LOG_WARNING, "Hitag Read response has bad CRC (%02x, %02x)",crcFound, crcExpected); - phid->respStatus = EPHIDGET_NOTFOUND; - goto done; + bytesInQueue--; } - //We're good! transfer Read data - memcpy(tag->tagData + phid->hitagOffset * 4, buf, 16); - tag->tagDataValid = PTRUE; - - //update timer - setTimeNow(&tag->lastTagTime); - - phid->respStatus = EPHIDGET_OK; -done: - CThread_set_event(&phid->respEvent); - return phid->respStatus; -} - -static int decodeHitagSelectResponse(CPhidgetRFIDHandle phid, unsigned char *data, int *startPtr, int *endPtr) -{ - int myReadPtr = *startPtr; - int bytesInQueue; - unsigned char buf[] = {0,0,0,0}; - int i,k; - int sofBits = 5; //SOF is really 6-bit but we only see it as 5-bit - int expectedBytes = 45; - unsigned char crcExpected = 0, crcFound = 0; - CPhidgetRFID_TagHandle tag = phid->respData; - - bytesInQueue = *endPtr - myReadPtr; - if(myReadPtr > *endPtr) - bytesInQueue += RFID_DATA_ARRAY_SIZE; - - //printf("maybe.. %d\n", bytesInQueue); - //print_buffer(data, *startPtr, *endPtr); + //advance past header + myReadPtr += 14; + myReadPtr &= RFID_DATA_ARRAY_MASK; - if(bytesInQueue != expectedBytes) - return EPHIDGET_NOTFOUND; + //Got here? - We found the start pattern - //verify SOF - for(i=0;i<sofBits;i++) + //Pull out the CRC + for(k=0,i=0;i<16;i++,k++) { - if(data[(myReadPtr + i) & RFID_DATA_ARRAY_MASK] != 1) + if(i>0 && i%8 == 0) { - phid->respStatus = EPHIDGET_NOTFOUND; - goto done; + if(data[(myReadPtr + k) & RFID_DATA_ARRAY_MASK] != 1) goto tryagain; + k++; } - } - - //advance past SOF - myReadPtr += sofBits; - myReadPtr &= RFID_DATA_ARRAY_MASK; + crcRead |= data[(myReadPtr + k) & RFID_DATA_ARRAY_MASK] << (15-i); + } + if(data[(myReadPtr + k) & RFID_DATA_ARRAY_MASK] != 1) goto tryagain; + k++; - for(k=0;k<32;k++) - { - buf[k/8] |= data[(myReadPtr + k) & RFID_DATA_ARRAY_MASK] << (7-(k%8)); - } - for(i=0;i<8;k++,i++) + //Now decode the PHIDGETS_TAG data + //every block of 7 is followed by a '1' + memset(tagData, 0, 24); + for(i=0;i<192;i++,k++) { - crcFound |= data[(myReadPtr + k) & RFID_DATA_ARRAY_MASK] << (7-i); + //Check for control bit + if((i+1)%8 == 0) + { + if(data[(myReadPtr + k) & RFID_DATA_ARRAY_MASK] != 1) + goto tryagain; + } + //pull out data + else + { + tagData[i/8] |= data[(myReadPtr + k) & RFID_DATA_ARRAY_MASK] << (6-(i%8)); + } } - crcExpected = hitagCRC8(buf, 32); - if(crcFound != crcExpected) - { - LOG(PHIDGET_LOG_WARNING, "Hitag Select response has bad CRC (%02x, %02x)",crcFound, crcExpected); - phid->respStatus = EPHIDGET_NOTFOUND; - goto done; - } + //Calculate CRC + crcCalc = 0; + for(i=0;i<24;i++) + CRC_16_CCITT_update(&crcCalc, (unsigned char)tagData[i]); - //We're good! fill in structure - //Memory size - switch(buf[0] & 0x03) + if(crcCalc != crcRead) { - case 0x00: - tag->tagOptions.memSize = 32; - break; - case 0x01: - tag->tagOptions.memSize = 256; - break; - case 0x02: - tag->tagOptions.memSize = 2048; - break; - case 0x03: - default: - phid->respStatus = EPHIDGET_UNEXPECTED; - goto done; + //FAIL + goto tryagain; } - //AUT bit - if(buf[1] & 0x80) - tag->tagOptions.encrypted = PTRUE; - else - tag->tagOptions.encrypted = PFALSE; - //LCON bit - if(buf[1] & 0x02) - tag->tagOptions.writable = PFALSE; - else - tag->tagOptions.writable = PTRUE; - tag->tagOptionsValid = PTRUE; + //We're good! + memcpy(tag->tagString, tagData, 24); + tag->tagString[24] = '\0'; + tag->protocol = PHIDGET_RFID_PROTOCOL_PHIDGETS; - //update timer - setTimeNow(&tag->lastTagTime); + //update master read pointer + (*startPtr) += 224; + (*startPtr) &= RFID_DATA_ARRAY_MASK; + return EPHIDGET_OK; - phid->respStatus = EPHIDGET_OK; -done: - CThread_set_event(&phid->respEvent); - return phid->respStatus; +tryagain: + myReadPtr++; + myReadPtr &= RFID_DATA_ARRAY_MASK; + goto start; } -static int add_biphase_data(CPhidgetRFIDHandle phid, int readToPtr, int shortClocks, int longClocks) +static int add_biphase_data(CPhidgetRFIDHandle phid, int readToPtr) { int myReadPtr = phid->dataReadPtr; while(myReadPtr != readToPtr) { - int clocks = phid->dataBuffer[myReadPtr] & 0x7F; - //int polarity = (phid->dataBuffer[myReadPtr] & 0x80) ? 1 : 0; + int clocks = phid->dataBuffer[myReadPtr] & 0xFF; - //1 - if (pdiff(clocks, longClocks) < 0.3) { + if (clocks == phid->longClocks) { phid->biphaseBuffer[phid->biphaseWritePtr] = 1; @@ -1600,7 +1330,7 @@ static int add_biphase_data(CPhidgetRFIDHandle phid, int readToPtr, int shortClo phid->biphaseLockedIn = 1; phid->biphaseShortChange = 0; } - else if (pdiff(clocks, shortClocks) < 0.3) { + else if (clocks == phid->shortClocks) { if (phid->biphaseLockedIn && phid->biphaseShortChange) { phid->biphaseBuffer[phid->biphaseWritePtr] = 0; @@ -1632,15 +1362,26 @@ static int add_biphase_data(CPhidgetRFIDHandle phid, int readToPtr, int shortClo return EPHIDGET_OK; } -static int add_manchester_data(CPhidgetRFIDHandle phid, int readToPtr, int shortClocks, int longClocks) +static int add_manchester_data(CPhidgetRFIDHandle phid, int readToPtr) { int myReadPtr = phid->dataReadPtr; while(myReadPtr != readToPtr) { - int clocks = phid->dataBuffer[myReadPtr] & 0x7F; - int polarity = (phid->dataBuffer[myReadPtr] & 0x80) ? 1 : 0; + int clocks = phid->dataBuffer[myReadPtr] & 0xFF; + int polarity = (phid->dataBuffer[myReadPtr] & 0x100) ? 1 : 0; - if (pdiff(clocks, longClocks) < 0.3) { + if (clocks == phid->longClocks) + { + //We're out of sync - re-sync + if(phid->manShortChange) + { + phid->manReadPtr = phid->manWritePtr; + phid->manReadPtr &= RFID_DATA_ARRAY_MASK; +#ifdef RFID_RAWDATA_API_SUPPORT + phid->manEventReadPtr = phid->manWritePtr; + phid->manEventReadPtr &= RFID_DATA_ARRAY_MASK; +#endif + } if (polarity) phid->manBuffer[phid->manWritePtr] = 1; @@ -1650,59 +1391,427 @@ static int add_manchester_data(CPhidgetRFIDHandle phid, int readToPtr, int short phid->manWritePtr++; phid->manWritePtr &= RFID_DATA_ARRAY_MASK; + //TODO: is there a danger of these actually happening?? if(phid->manWritePtr == phid->manReadPtr) { phid->manReadPtr++; phid->manReadPtr &= RFID_DATA_ARRAY_MASK; } +#ifdef RFID_RAWDATA_API_SUPPORT if(phid->manWritePtr == phid->manEventReadPtr) { phid->manEventReadPtr++; phid->manEventReadPtr &= RFID_DATA_ARRAY_MASK; } +#endif phid->manLockedIn = 1; phid->manShortChange = 0; - } - else if (pdiff(clocks, shortClocks) < 0.3) { - if (phid->manLockedIn && phid->manShortChange) { - if (polarity) - phid->manBuffer[phid->manWritePtr] = 1; - else - phid->manBuffer[phid->manWritePtr] = 0; - - phid->manWritePtr++; - phid->manWritePtr &= RFID_DATA_ARRAY_MASK; - - if(phid->manWritePtr == phid->manReadPtr) + } + // Short clocks + else + { + if(!phid->manLockedIn) + { + if(polarity) { - phid->manReadPtr++; - phid->manReadPtr &= RFID_DATA_ARRAY_MASK; + phid->manShortChange=1; + phid->manLockedIn = 1; } - - if(phid->manWritePtr == phid->manEventReadPtr) + } + else + { + if(phid->manShortChange) { - phid->manEventReadPtr++; - phid->manEventReadPtr &= RFID_DATA_ARRAY_MASK; - } + if (polarity) + phid->manBuffer[phid->manWritePtr] = 1; + else + phid->manBuffer[phid->manWritePtr] = 0; + + phid->manWritePtr++; + phid->manWritePtr &= RFID_DATA_ARRAY_MASK; + + if(phid->manWritePtr == phid->manReadPtr) + { + phid->manReadPtr++; + phid->manReadPtr &= RFID_DATA_ARRAY_MASK; + } + +#ifdef RFID_RAWDATA_API_SUPPORT + if(phid->manWritePtr == phid->manEventReadPtr) + { + phid->manEventReadPtr++; + phid->manEventReadPtr &= RFID_DATA_ARRAY_MASK; + } +#endif - phid->manShortChange=0; + phid->manShortChange=0; + } + else + phid->manShortChange=1; } - else - phid->manShortChange=1; } - else { - phid->manLockedIn = 0; - //invalid - phid->manReadPtr = phid->manEventReadPtr = phid->manWritePtr; - //This is not Manchester encoded data - return EPHIDGET_NOTFOUND; + + myReadPtr++; + myReadPtr &= RFID_DATA_ARRAY_MASK; + } + return EPHIDGET_OK; +} + +//Analyses streaming data in Manchester or Biphase coding +static int analyze_data(CPhidgetRFIDHandle phid) +{ + int bytesToRead = 0, bytesRead = 0; + int temp, clocks; + int myReadPtr; + CPhidgetRFID_Tag tag; + + //read till we have real data +start: + while(phid->dataReadPtr != phid->dataWritePtr) + { + if(phid->dataBuffer[phid->dataReadPtr] == PUNK_INT) + { + //LOG(PHIDGET_LOG_DEBUG, "LONG"); + phid->dataReadPtr++; + phid->dataReadPtr &= RFID_DATA_ARRAY_MASK; + resetValuesFromSpace(phid); + } + else + break; + } + + //Make sure we have enough data to do something useful with.. + bytesToRead = phid->dataWritePtr - phid->dataReadPtr; + if(phid->dataReadPtr > phid->dataWritePtr) + bytesToRead += RFID_DATA_ARRAY_SIZE; + + //then read till we have a space or run out of data - figure out data rate + bytesRead = 0; + myReadPtr = phid->dataReadPtr; + while(myReadPtr != phid->dataWritePtr) + { + if(phid->dataBuffer[myReadPtr] == PUNK_INT) + break; + + clocks = (phid->dataBuffer[myReadPtr] & 0xFF); + + if(!phid->shortClocks) + { + phid->shortClocks = clocks; + } + else if(clocks != phid->shortClocks) + { + if(!phid->longClocks) + { + if(phid->shortClocks * 2 == clocks || phid->shortClocks / 2 == clocks) + phid->longClocks = clocks; + else + //found a values that doesn't work - error + goto update_readPtr_restart; + } + else if(clocks != phid->longClocks) + //found a values that doesn't work - error + goto update_readPtr_restart; } myReadPtr++; myReadPtr &= RFID_DATA_ARRAY_MASK; + bytesRead++; + } + + //We haven't seen a one and a two!! + if(phid->shortClocks == 0 || phid->longClocks == 0) + { + //got a gap? move on to more data + if(bytesRead != bytesToRead) + goto check_done; + + //otherwise, wait for more data + return EPHIDGET_OK; + } + + //Order them by size + if(phid->longClocks < phid->shortClocks) + { + temp = phid->longClocks; + phid->longClocks = phid->shortClocks; + phid->shortClocks = temp; + } + + ZEROMEM(&tag, sizeof(CPhidgetRFID_Tag)); + + //Shift data into Manchester and Biphase decoders, update read ptr + if(!add_manchester_data(phid, myReadPtr)) + { +#ifdef RFID_RAWDATA_API_SUPPORT + unsigned char manEventData[RFID_DATA_ARRAY_SIZE]; + int manEventDataWritePtr = 0; +#endif + + if(!decodeEM4100(phid, phid->manBuffer, &phid->manReadPtr, &phid->manWritePtr, &tag)) + tagEvent(phid, &tag); + +#ifdef RFID_RAWDATA_API_SUPPORT + //Manchester data event + while(phid->manEventReadPtr != phid->manWritePtr) + { + manEventData[manEventDataWritePtr++] = phid->manBuffer[phid->manEventReadPtr]; + phid->manEventReadPtr++; + phid->manEventReadPtr&=RFID_DATA_ARRAY_MASK; + } + if(manEventDataWritePtr) + { + phid->lastManEventLong = PFALSE; + FIRE(ManchesterData, manEventData, manEventDataWritePtr); + } + } + //Manchester event with space + else if(phid->lastManEventLong == PFALSE) + { + unsigned char manEventData[1]; + phid->lastManEventLong = PTRUE; + manEventData[0] = PUNK_BOOL; + FIRE(ManchesterData, manEventData, 1); +#endif + } + + if(!add_biphase_data(phid, myReadPtr)) + { + if(!decodePHIDGETS_TAG(phid, phid->biphaseBuffer, &phid->biphaseReadPtr, &phid->biphaseWritePtr, &tag)) + tagEvent(phid, &tag); + if(!decodeISO11785_FDX_B(phid, phid->biphaseBuffer, &phid->biphaseReadPtr, &phid->biphaseWritePtr, &tag)) + tagEvent(phid, &tag); + } + +check_done: + //update read pointer + phid->dataReadPtr = myReadPtr; + + //If there is more data, loop around + if(phid->dataReadPtr != phid->dataWritePtr) + goto start; + + return EPHIDGET_OK; + + //ran into a bad pulse length or a gap - reset stuff +update_readPtr_restart: + phid->dataReadPtr++; + phid->dataReadPtr &= RFID_DATA_ARRAY_MASK; + resetValuesFromSpace(phid); + + goto start; +} + +static int T5577_WriteBlock(CPhidgetRFIDHandle phid, int page, int block, unsigned int data, int lockpage) +{ + int res = EPHIDGET_OK; + unsigned char byteData[5]; + + byteData[0] = ((0x02 | (page & 0x01)) << 6); //OpCode + byteData[0] |= ((lockpage ? 0x01 : 0x00) << 5); //Lock + byteData[0] |= ((data >> 27) & 0x1F); //Data 31:27 + byteData[1] = ((data >> 19) & 0xFF); //Data 26:19 + byteData[2] = ((data >> 11) & 0xFF); //Data 18:11 + byteData[3] = ((data >> 3) & 0xFF); //Data 10:3 + byteData[4] = ((data << 5) & 0xE0); //Data 2:0 + byteData[4] |= ((block & 0x07) << 2); //Block (0-7) + + res = CPhidgetRFID_writeRaw(phid, byteData, 38, + RFID_T5577_StartGap, + RFID_T5577_WriteGap, + RFID_T5577_EndGap, + RFID_T5577_Zero, + RFID_T5577_One, + RFID_T5577_PrePulse, + RFID_T5577_EOF, + PFALSE); + + return res; +} + +static int T5577_Reset(CPhidgetRFIDHandle phid) +{ + int res = EPHIDGET_OK; + unsigned char byteData[1]; + + byteData[0] = 0x00; //OpCode + + res = CPhidgetRFID_writeRaw(phid, byteData, 2, + RFID_T5577_StartGap, + RFID_T5577_WriteGap, + RFID_T5577_EndGap, + RFID_T5577_Zero, + RFID_T5577_One, + RFID_T5577_PrePulse, + RFID_T5577_EOF, + PFALSE); + + return res; +} + +/* Programs a T5577 using the specified protocol and data + * data: Tag string. + * lock: lock the T5577 so it cannot be reprogrammed. + */ +static int T5577_WriteTag(CPhidgetRFIDHandle phid, CPhidgetRFID_Protocol protocol, char *tagString, int lock) +{ + int ret = EPHIDGET_OK, i; + unsigned int data[7]; + int dataLen = 7; + unsigned int configBlock; + + switch(protocol) + { + case PHIDGET_RFID_PROTOCOL_EM4100: + if((ret = encodeEM4100(tagString, data, &dataLen)) != EPHIDGET_OK) + return ret; + configBlock = 0x00148040; // RF/63, manchester, Maxblock = 2 + break; + case PHIDGET_RFID_PROTOCOL_ISO11785_FDX_B: + if((ret = encodeISO11785_FDX_B(tagString, data, &dataLen)) != EPHIDGET_OK) + return ret; + configBlock = 0x603F8080; // RF/32, differential bi-phase, Maxblock = 4 + break; + case PHIDGET_RFID_PROTOCOL_PHIDGETS: + if((ret = encodePHIDGETS_TAG(tagString, data, &dataLen)) != EPHIDGET_OK) + return ret; + configBlock = 0x603F80E0; // RF/32, differential bi-phase, Maxblock = 7 + break; + default: + return EPHIDGET_INVALIDARG; + } + + //Write Data + for(i=0;i<dataLen;i++) + { + if((ret = T5577_WriteBlock(phid, 0, i+1, data[i], lock)) != EPHIDGET_OK) + return ret; + SLEEP(50); //some time beetween writes! + } + //Write config + if((ret = T5577_WriteBlock(phid, 0, 0, configBlock, lock)) != EPHIDGET_OK) + return ret; + + SLEEP(50); //some time beetween writes! + //Reset Chip + if((ret = T5577_Reset(phid)) != EPHIDGET_OK) + return ret; + + return ret; +} + +#ifdef RFID_HITAGS_SUPPORT +#define ABS(x) ((x) < 0 ? -(x) : (x)) +#define pdiff(a, b) ( ABS((a) - (b)) / (double)( ((a) + (b)) / 2.0 ) ) + +static void resetHitagACBuffer(CPhidgetRFIDHandle phid) +{ + phid->dataReadACPtr = phid->dataWritePtr; + phid->ACCodingOK = PTRUE; +} + +//Hitag CRC +#define CRC_PRESET 0xFF +#define CRC_POLYNOM 0x1D +static void calc_crc_hitag(unsigned char * crc, + unsigned char data, + unsigned char Bitcount) +{ + *crc ^= data; //crc = crc (exor) data + do + { + if( *crc & 0x80 ) // if (MSB-CRC == 1) + { + *crc<<=1; // CRC = CRC Bit-shift left + *crc ^= CRC_POLYNOM; // CRC = CRC (exor) CRC_POLYNOM + } + else + *crc<<=1; // CRC = CRC Bit-shift left + } while(--Bitcount); +} +static unsigned char hitagCRC8(unsigned char *data, int dataBits) +{ + unsigned char crc; + int i; + int dataLength = dataBits / 8; + if(dataBits%8 != 0) + dataLength++; + crc = CRC_PRESET; /* initialize crc algorithm */ + + for(i=0; i<dataLength; i++) + { + calc_crc_hitag(&crc, data[i], ((dataBits > 8) ? 8 : dataBits)); + dataBits -= 8; + } + + return crc; +} + +static int HitagS_UID_REQUEST(CPhidgetRFIDHandle phid) +{ + int res; + //Send a Hitag S UID Request Command + unsigned char buf[] = { 0xC0 }; + + //make sure it's been at least 50ms since last hitag request + while(timeSince(&phid->hitagReqTime) < 0.05) //50ms + SLEEP(10); + + resetHitagACBuffer(phid); + res = CPhidgetRFID_writeRaw(phid, buf, 5, 7, 7, 7, 13, 21, 0, 64, PTRUE); + + //Don't send it again for at least 100ms + setTimeNow(&phid->hitagReqTime); + + return res; +} + +static int decodeHitagUID(CPhidgetRFIDHandle phid, unsigned char *data, int bytesInQueue, CPhidgetRFID_TagHandle tag, int *collisionPos) +{ + int i, k; + int myReadPtr = 0; + unsigned int HitagUID; + int sofBits = 3; + int expectedBytes = 0; + + expectedBytes = 35; + + *collisionPos = -1; + + //UID is 32 bits, plus SOF == '111' + if(bytesInQueue != expectedBytes) + return EPHIDGET_NOTFOUND; + + //verify SOF + for(i=0;i<sofBits;i++) + { + if(data[(myReadPtr + i) & RFID_DATA_ARRAY_MASK] != 1) + return EPHIDGET_NOTFOUND; + } + + //advance past SOF + myReadPtr += sofBits; + myReadPtr &= RFID_DATA_ARRAY_MASK; + + HitagUID = 0; + + for(i=0,k=0;i<(expectedBytes-sofBits);k++,i++) + { + //check for a collision + if(data[(myReadPtr + i) & RFID_DATA_ARRAY_MASK] == PUNK_BOOL) + { + *collisionPos = k; + return EPHIDGET_NOTFOUND; + } + HitagUID |= data[(myReadPtr + i) & RFID_DATA_ARRAY_MASK] << (31-k); } + + //We're good! + snprintf(tag->tagString, RFID_MAX_TAG_STRING_LEN, "%08x",HitagUID); + tag->protocol = PHIDGET_RFID_PROTOCOL_HITAGS_UID; + return EPHIDGET_OK; } @@ -1721,20 +1830,17 @@ static int decodeACdata(CPhidgetRFIDHandle phid, unsigned char *acBuffer, int *a int acWritePtr = 0; unsigned char acBitLocation = 0; - if(phid->hitagState == RFID_HITAG_STATE_UID_REQUEST) - lastIndex = 34; - else if(phid->hitagState == RFID_HITAG_STATE_AC_SEQUENCE) - lastIndex = 34 - phid->lastHitagAC.colPos; + lastIndex = 34; if(*acBufferSize < lastIndex+1) goto fail; //if the first pulse is low, we need to add a high pulse before it - if(!(phid->dataBuffer[phid->dataReadACPtr] & 0x80)) + if(!(phid->dataBuffer[phid->dataReadACPtr] & 0x100)) { myReadPtr--; myReadPtr &= RFID_DATA_ARRAY_MASK; - phid->dataBuffer[myReadPtr] = (shortClocks/2) | 0x80; + phid->dataBuffer[myReadPtr] = (shortClocks/2) | 0x100; } bytesToRead = readToPtr - myReadPtr; @@ -1748,10 +1854,10 @@ static int decodeACdata(CPhidgetRFIDHandle phid, unsigned char *acBuffer, int *a for(i=0;i<bytesToRead;i+=2) { - clocks1 = phid->dataBuffer[myReadPtr] & 0x7F; - polarity1 = (phid->dataBuffer[myReadPtr] & 0x80) ? 1 : 0; - clocks2 = phid->dataBuffer[(myReadPtr+1) & RFID_DATA_ARRAY_MASK] & 0x7F; - polarity2 = (phid->dataBuffer[(myReadPtr+1) & RFID_DATA_ARRAY_MASK] & 0x80) ? 1 : 0; + clocks1 = phid->dataBuffer[myReadPtr] & 0xFF; + polarity1 = (phid->dataBuffer[myReadPtr] & 0x100) ? 1 : 0; + clocks2 = phid->dataBuffer[(myReadPtr+1) & RFID_DATA_ARRAY_MASK] & 0xFF; + polarity2 = (phid->dataBuffer[(myReadPtr+1) & RFID_DATA_ARRAY_MASK] & 0x100) ? 1 : 0; clocks = clocks1 + clocks2; @@ -1759,7 +1865,7 @@ static int decodeACdata(CPhidgetRFIDHandle phid, unsigned char *acBuffer, int *a goto fail; //the first pulse can be long - if (pdiff(clocks, shortClocks) < 0.2 || acWritePtr == 0) + if (clocks == shortClocks || acWritePtr == 0) { if(acBitLocation == 1) { @@ -1769,7 +1875,7 @@ static int decodeACdata(CPhidgetRFIDHandle phid, unsigned char *acBuffer, int *a } acBitLocation ^= 1; } - else if(pdiff(clocks, longClocks) < 0.2) + else if(clocks == longClocks) { if(acBitLocation == 1) { @@ -1807,13 +1913,13 @@ static int decodeACdata(CPhidgetRFIDHandle phid, unsigned char *acBuffer, int *a //last low pulse won't be seen because we idle low if(acWritePtr == lastIndex && myReadPtr == ((readToPtr-1) & RFID_DATA_ARRAY_MASK)) { - clocks = phid->dataBuffer[myReadPtr] & 0x7F; - polarity1 = (phid->dataBuffer[myReadPtr] & 0x80) ? 1 : 0; + clocks = phid->dataBuffer[myReadPtr] & 0xFF; + polarity1 = (phid->dataBuffer[myReadPtr] & 0x100) ? 1 : 0; if(polarity1 != 1) goto fail; - if(pdiff(clocks, shortClocks/2) < 0.4) + if(clocks == shortClocks/2) { if(acBitLocation==1) { @@ -1824,7 +1930,7 @@ static int decodeACdata(CPhidgetRFIDHandle phid, unsigned char *acBuffer, int *a else acBitLocation ^= 1; } - else if(pdiff(clocks, longClocks/2) < 0.3) + else if(clocks == shortClocks) { if(acBitLocation==1) goto fail; @@ -1832,7 +1938,7 @@ static int decodeACdata(CPhidgetRFIDHandle phid, unsigned char *acBuffer, int *a acBuffer[acWritePtr] = PFALSE; acWritePtr++; } - else if(pdiff(clocks, (longClocks/4)*3) < 0.25) + else if(clocks, shortClocks * 1.5) { if(acBitLocation==1) goto fail; @@ -1858,257 +1964,6 @@ fail: return EPHIDGET_NOTFOUND; } -//NOTE: tag is a local variable, we need to make a copy of it before adding it to lists, etc. -static int advanced_tag_event(CPhidgetRFIDHandle phid, CPhidgetRFID_TagHandle tagPtr, int lock) -{ - CPhidgetRFID_TagHandle tag; - //Add to the tag list here, remove from the tag list in the tagTimerThreadFunction - if(lock) - CThread_mutex_lock(&phid->tagthreadlock); - if(CList_findInList((CListHandle)phid->tagAdvancedList, tagPtr, CPhidgetRFID_Tag_areEqual, (void**)&tag) == EPHIDGET_NOTFOUND) - { - //make a copy - tag = (CPhidgetRFID_TagHandle)malloc(sizeof(*tag)); - memcpy(tag, tagPtr, sizeof(*tag)); - tag->tagEventPending = PTRUE; - CThread_set_event(&phid->tagAvailableEvent); - CList_addToList((CListHandle *)&phid->tagAdvancedList, tag, CPhidgetRFID_Tag_areEqual); - } - - setTimeNow(&tag->lastTagTime); - if(lock) - CThread_mutex_unlock(&phid->tagthreadlock); - - return EPHIDGET_OK; -} - -//Analyses streaming data in Manchester or Biphase coding -static int analyze_data(CPhidgetRFIDHandle phid) -{ - int bytesToRead = 0, bytesRead = 0; - int temp, one, two; - int myReadPtr; - CPhidgetRFID_Tag tag; - - //read till we have real data -start: - while(phid->dataReadPtr != phid->dataWritePtr) - { - if(phid->dataBuffer[phid->dataReadPtr] == PUNK_INT) - { - phid->dataReadPtr++; - phid->dataReadPtr &= RFID_DATA_ARRAY_MASK; - phid->atGap = PTRUE; - - phid->one = phid->two = phid->oneCount = phid->twoCount = 0; - } - else - break; - } - myReadPtr = phid->dataReadPtr; - - //Make sure we have enough data to do something useful with.. - bytesToRead = phid->dataWritePtr - phid->dataReadPtr; - if(phid->dataReadPtr > phid->dataWritePtr) - bytesToRead += RFID_DATA_ARRAY_SIZE; - - if(bytesToRead < 32 && phid->atGap) - return EPHIDGET_OK; - - //then read till we have a space or run out of data - figure out data rate - one = two = 0; - bytesRead = 0; - while(myReadPtr != phid->dataWritePtr) - { - if(phid->dataBuffer[myReadPtr] == PUNK_INT) - break; - - if(phid->one == 0) - { - phid->one = phid->dataBuffer[myReadPtr] & 0x7F; - phid->oneCount++; - } - else - { - temp = round((double)((double)phid->one / (double)phid->oneCount)); - if(pdiff(temp, phid->dataBuffer[myReadPtr] & 0x7F) < 0.3) - { - phid->one += phid->dataBuffer[myReadPtr] & 0x7F; - phid->oneCount++; - } - else - { - if(phid->two == 0) - { - temp = round((double)((double)phid->one / (double)phid->oneCount)); - if(pdiff(temp * 2, phid->dataBuffer[myReadPtr] & 0x7F) < 0.3 - || pdiff(temp / 2, phid->dataBuffer[myReadPtr] & 0x7F) < 0.3) - { - phid->two = phid->dataBuffer[myReadPtr] & 0x7F; - phid->twoCount++; - } - else - { - goto update_readPtr_restart; - } - } - else - { - temp = round((double)((double)phid->two / (double)phid->twoCount)); - if(pdiff(temp, phid->dataBuffer[myReadPtr] & 0x7F) < 0.3) - { - phid->two += phid->dataBuffer[myReadPtr] & 0x7F; - phid->twoCount++; - } - else - { - goto update_readPtr_restart; - } - } - } - } - - myReadPtr++; - myReadPtr &= RFID_DATA_ARRAY_MASK; - bytesRead++; - } - - if(bytesRead < bytesToRead) - { - goto update_readPtr_restart; - } - - //don't let the one and two counters get too big - if(phid->oneCount >= RFID_DATA_ARRAY_SIZE) - { - phid->one = round((double)((double)phid->one / 2.0)); - phid->oneCount = phid->oneCount / 2; - } - if(phid->twoCount >= RFID_DATA_ARRAY_SIZE) - { - phid->two = round((double)((double)phid->two / 2.0)); - phid->twoCount = phid->twoCount / 2; - } - - if(phid->one) - one = round((double)((double)phid->one / (double)phid->oneCount)); - if(phid->two) - two = round((double)((double)phid->two / (double)phid->twoCount)); - - //Order them by size - if(two < one) - { - temp = two; - two = one; - one = temp; - } - - //printf("One: %3d Two: %3d Bytes: %4d\n",one, two, bytesToRead); - - ZEROMEM(&tag, sizeof(CPhidgetRFID_Tag)); - //Normalize the data rate we supply to the user to be a power of 2 - //TODO: are there any tags which use a bitrate that's not a power of two? - //Yes - Q5 can have an arbitrary data rate - temp=1; - tag.tagInfo.bitRate = two; - while(temp<two) - { - temp*=2; - if(pdiff(temp, two) < 0.3) - { - tag.tagInfo.bitRate = temp; - break; - } - } - if(tag.tagInfo.bitRate == 128) - printf("hmm\n"); //TODO: are we actually going to do something about this? - - //Shift data into Manchester and Biphase decoders, update read ptr - if(phid->hitagState == RFID_HITAG_STATE_SELECT - || phid->hitagState == RFID_HITAG_STATE_READ - || phid->hitagState == RFID_HITAG_STATE_WRITE) - { - if(phid->manReadPtr == phid->manWritePtr) - { - //may have to advance one to make things work - if(phid->dataBuffer[phid->dataReadPtr] & 0x80 && pdiff(phid->dataBuffer[phid->dataReadPtr] & 0x7F, 16) < 0.3) - phid->dataReadPtr = ((phid->dataReadPtr + 1) & RFID_DATA_ARRAY_MASK); - } - } - if(!add_manchester_data(phid, myReadPtr, one, two)) - { - unsigned char manEventData[RFID_DATA_ARRAY_SIZE]; - int manEventDataWritePtr = 0; - - tag.tagInfo.encoding = PHIDGET_RFID_ENCODING_MANCHESTER; - - //Manchester data event - while(phid->manEventReadPtr != phid->manWritePtr) - { - manEventData[manEventDataWritePtr++] = phid->manBuffer[phid->manEventReadPtr]; - phid->manEventReadPtr++; - phid->manEventReadPtr&=RFID_DATA_ARRAY_MASK; - } - if(manEventDataWritePtr) - FIRE(ManchesterData, manEventData, manEventDataWritePtr); - - if(phid->hitagState == RFID_HITAG_STATE_SELECT) - { - //try to decode a Hitag SELECT response - decodeHitagSelectResponse(phid, phid->manBuffer, &phid->manReadPtr, &phid->manWritePtr); - } - if(phid->hitagState == RFID_HITAG_STATE_READ) - { - //try to decode a Hitag READ response - decodeHitagReadResponse(phid, phid->manBuffer, &phid->manReadPtr, &phid->manWritePtr); - } - if(phid->hitagState == RFID_HITAG_STATE_WRITE) - { - //try to decode a Hitag WRITE response - decodeHitagACKResponse(phid, phid->manBuffer, &phid->manReadPtr, &phid->manWritePtr); - } - if(!decodeEM4102(phid, phid->manBuffer, &phid->manReadPtr, &phid->manWritePtr, &tag)) - advanced_tag_event(phid, &tag, PTRUE); - if(!decodeISO11785(phid, phid->manBuffer, &phid->manReadPtr, &phid->manWritePtr, &tag)) - advanced_tag_event(phid, &tag, PTRUE); - } - else - { - //Manchester event with space - unsigned char manEventData[1]; - manEventData[0] = PUNK_BOOL; - phid->manEventReadPtr = phid->manWritePtr; - - FIRE(ManchesterData, manEventData, 1); - } - if(!add_biphase_data(phid, myReadPtr, one, two)) - { - tag.tagInfo.encoding = PHIDGET_RFID_ENCODING_BIPHASE; - if(!decodeEM4102(phid, phid->biphaseBuffer, &phid->biphaseReadPtr, &phid->biphaseWritePtr, &tag)) - advanced_tag_event(phid, &tag, PTRUE); - if(!decodeISO11785(phid, phid->biphaseBuffer, &phid->biphaseReadPtr, &phid->biphaseWritePtr, &tag)) - advanced_tag_event(phid, &tag, PTRUE); - } - - //update read pointer - phid->dataReadPtr = myReadPtr; - phid->atGap = PFALSE; - - return EPHIDGET_OK; - - //ran into a bad pulse length or a gap - reset stuff -update_readPtr_restart: - phid->one = phid->two = phid->oneCount = phid->twoCount = 0; - phid->dataReadPtr = myReadPtr; - phid->atGap = PTRUE; - phid->manReadPtr = 0; - phid->manEventReadPtr = 0; - phid->manWritePtr = 0; - phid->biphaseReadPtr = 0; - phid->biphaseWritePtr = 0; - goto start; -} - //Analyses data for Hitag AC coding static int analyze_data_AC(CPhidgetRFIDHandle phid) { @@ -2164,44 +2019,9 @@ static int analyze_data_AC(CPhidgetRFIDHandle phid) phid->ACCodingOK = PFALSE; - //printf("%d ",phid->acWritePtr); - tag.tagInfo.encoding = PHIDGET_RFID_ENCODING_AC; - tag.tagInfo.bitRate = 64; if(!decodeHitagUID(phid, acBuffer, acBufferSize, &tag, &collision)) { - advanced_tag_event(phid, &tag, PTRUE); - //TODO: select tag? - //printf("Got Hitag Tag: %s\n",tag.tagString); - - //Any pending AC commands? - if(phid->hitagACList) - { - CPhidgetRFID_HitagACHandle ac = phid->hitagACList[0].hitagAC; - HitagS_AC_SEQUENCE(phid, ac); - CList_removeFromList((CListHandle *)&phid->hitagACList, ac, CPhidgetRFID_HitagAC_areEqual, PTRUE, CPhidgetRFID_HitagAC_free); - } - } - else if(collision != -1) - { - int k; - CPhidgetRFID_HitagACHandle ac = (CPhidgetRFID_HitagACHandle)malloc(sizeof(CPhidgetRFID_HitagAC)); - ZEROMEM(ac, sizeof(CPhidgetRFID_HitagAC)); - //printf("Got Hitag Collision: %d\n",collision); - - for(k=0;k<collision;k++) - { - ac->uid[k/8] |= acBuffer[k+3] << (7-(k%8)); - } - //choose 1 for the collision position - ac->uid[k/8] |= 1 << (7-(k%8)); - - ac->colPos = collision+1; - - HitagS_AC_SEQUENCE(phid, ac); - - //add AC with 0 to queue - ac->uid[k/8] &= ~(1 << (7-(k%8))); - CList_addToList((CListHandle *)&phid->hitagACList, ac, CPhidgetRFID_HitagAC_areEqual); + tagEvent(phid, &tag); } } @@ -2210,18 +2030,7 @@ static int analyze_data_AC(CPhidgetRFIDHandle phid) return EPHIDGET_OK; } - -static int advancedTagEventForOldReaders(CPhidgetRFIDHandle phid, unsigned char *data) -{ - CPhidgetRFID_Tag tag; - ZEROMEM(&tag, sizeof(CPhidgetRFID_Tag)); - tag.tagInfo.bitRate = 64; - tag.tagInfo.encoding = PHIDGET_RFID_ENCODING_MANCHESTER; - snprintf(tag.tagString, 255, "%02x%02x%02x%02x%02x",data[0],data[1],data[2],data[3],data[4]); - tag.tagInfo.tagType = PHIDGET_RFID_TAG_EM4102; - return advanced_tag_event(phid, &tag, PFALSE); -} - +#endif // === Exported Functions === // @@ -2229,8 +2038,6 @@ static int advancedTagEventForOldReaders(CPhidgetRFIDHandle phid, unsigned char CCREATE_EXTRA(RFID, PHIDCLASS_RFID) CThread_mutex_init(&phid->tagthreadlock); CThread_create_event(&phid->tagAvailableEvent); - CThread_create_event(&phid->respEvent); - CThread_create_event(&phid->respEvent2); phid->phid.fptrClose = CPhidgetRFID_close; phid->phid.fptrFree = CPhidgetRFID_free; return EPHIDGET_OK; @@ -2238,12 +2045,17 @@ CCREATE_EXTRA(RFID, PHIDCLASS_RFID) //event setup functions CFHANDLE(RFID, OutputChange, int, int) -CFHANDLE(RFID, Tag, unsigned char *) -CFHANDLE(RFID, TagLost, unsigned char *) +CFHANDLE(RFID, Tag2, char *tagString, CPhidgetRFID_Protocol protocol) +CFHANDLE(RFID, TagLost2, char *tagString, CPhidgetRFID_Protocol protocol) +#ifdef RFID_RAWDATA_API_SUPPORT CFHANDLE(RFID, ManchesterData, unsigned char *data, int dataLength) CFHANDLE(RFID, RawData, int *data, int dataLength) -CFHANDLE(RFID, TagAdvanced, char *tagString, CPhidgetRFID_TagInfoHandle tagInfo) -CFHANDLE(RFID, TagLostAdvanced, char *tagString, CPhidgetRFID_TagInfoHandle tagInfo) +#else +PHIDGET21_API int CCONV CPhidgetRFID_set_OnManchesterData_Handler(CPhidgetRFIDHandle phidA, int (CCONV *fptr)(CPhidgetRFIDHandle, void *userPtr, unsigned char *data, int dataLength), void *userPtr) +{return EPHIDGET_UNSUPPORTED;} +PHIDGET21_API int CCONV CPhidgetRFID_set_OnRawData_Handler(CPhidgetRFIDHandle phidA, int (CCONV *fptr)(CPhidgetRFIDHandle, void *userPtr, int *data, int dataLength), void *userPtr) +{return EPHIDGET_UNSUPPORTED;} +#endif CGET(RFID,OutputCount,int) TESTPTRS(phid,pVal) @@ -2258,9 +2070,9 @@ CGETINDEX(RFID,OutputState,int) TESTDEVICETYPE(PHIDCLASS_RFID) TESTATTACHED TESTINDEX(phid.attr.rfid.numOutputs) - TESTMASGN(outputState[Index], PUNK_BOOL) + TESTMASGN(outputEchoState[Index], PUNK_BOOL) - MASGN(outputState[Index]) + MASGN(outputEchoState[Index]) } CSETINDEX(RFID,OutputState,int) TESTPTR(phid) @@ -2302,9 +2114,11 @@ CSET(RFID,AntennaOn,int) TESTDEVICETYPE(PHIDCLASS_RFID) TESTATTACHED - switch(phid->phid.deviceIDSpec) + switch(phid->phid.deviceUID) { - case PHIDID_RFID_2OUTPUT: + case PHIDUID_RFID_2OUTPUT_NO_ECHO: + case PHIDUID_RFID_2OUTPUT: + case PHIDUID_RFID_2OUTPUT_READ_WRITE: TESTRANGE(PFALSE, PTRUE) if(CPhidget_statusFlagIsSet(phid->phid.status, PHIDGET_REMOTE_FLAG)) @@ -2313,41 +2127,11 @@ CSET(RFID,AntennaOn,int) { SENDPACKET(RFID, antennaState); //echo back state if the device doesn't - if (!(phid->fullStateEcho)) + if (phid->fullStateEcho == PFALSE) phid->antennaEchoState = newVal; } return EPHIDGET_OK; - case PHIDID_RFID_2OUTPUT_ADVANCED: - if(CPhidget_statusFlagIsSet(phid->phid.status, PHIDGET_REMOTE_FLAG)) - ADDNETWORKKEY(AntennaOn, "%d", antennaState); - else - { - unsigned char *buffer; - int ret = 0; - if(!(buffer = malloc(phid->phid.outputReportByteLength))) return EPHIDGET_NOMEMORY; - ZEROMEM(buffer, phid->phid.outputReportByteLength); - CThread_mutex_lock(&phid->phid.writelock); - - phid->antennaState = newVal; - if(newVal) - { - //phid->_4097Conf = RFID_4097_AmpDemod | RFID_4097_Active | RFID_4097_DataOut | RFID_4097_IntPLL | RFID_4097_FastStart | RFID_4097_Gain960; - phid->_4097Conf = RFID_4097_AmpDemod | RFID_4097_Active | RFID_4097_DataOut | RFID_4097_IntPLL | RFID_4097_FastStart | RFID_4097_Gain120; - } - else - { - phid->_4097Conf = RFID_4097_PowerDown; - } - if((ret = CPhidgetRFID_makePacket(phid, buffer))) goto done2; - if((ret = CPhidgetRFID_sendpacket(phid, buffer))) goto done2; - done2: - CThread_mutex_unlock(&phid->phid.writelock); - free(buffer); - if(ret) return ret; - } - return EPHIDGET_OK; - case PHIDID_RFID: default: return EPHIDGET_UNSUPPORTED; } @@ -2358,13 +2142,13 @@ CGET(RFID,LEDOn,int) TESTDEVICETYPE(PHIDCLASS_RFID) TESTATTACHED - switch(phid->phid.deviceIDSpec) + switch(phid->phid.deviceUID) { - case PHIDID_RFID_2OUTPUT: - case PHIDID_RFID_2OUTPUT_ADVANCED: + case PHIDUID_RFID_2OUTPUT_NO_ECHO: + case PHIDUID_RFID_2OUTPUT: + case PHIDUID_RFID_2OUTPUT_READ_WRITE: TESTMASGN(ledEchoState, PUNK_BOOL) MASGN(ledEchoState) - case PHIDID_RFID: default: return EPHIDGET_UNSUPPORTED; } @@ -2374,10 +2158,11 @@ CSET(RFID,LEDOn,int) TESTDEVICETYPE(PHIDCLASS_RFID) TESTATTACHED - switch(phid->phid.deviceIDSpec) + switch(phid->phid.deviceUID) { - case PHIDID_RFID_2OUTPUT: - case PHIDID_RFID_2OUTPUT_ADVANCED: + case PHIDUID_RFID_2OUTPUT_NO_ECHO: + case PHIDUID_RFID_2OUTPUT: + case PHIDUID_RFID_2OUTPUT_READ_WRITE: TESTRANGE(PFALSE, PTRUE) if(CPhidget_statusFlagIsSet(phid->phid.status, PHIDGET_REMOTE_FLAG)) @@ -2390,7 +2175,6 @@ CSET(RFID,LEDOn,int) phid->ledEchoState = newVal; } return EPHIDGET_OK; - case PHIDID_RFID: default: return EPHIDGET_UNSUPPORTED; } @@ -2401,29 +2185,42 @@ CSET(RFID,PollingOn,int) TESTDEVICETYPE(PHIDCLASS_RFID) TESTATTACHED - switch(phid->phid.deviceIDSpec) +#ifdef RFID_HITAGS_SUPPORT + switch(phid->phid.deviceUID) { - case PHIDID_RFID_2OUTPUT_ADVANCED: - phid->polling = newVal; - return EPHIDGET_OK; - case PHIDID_RFID_2OUTPUT: - case PHIDID_RFID: + case PHIDUID_RFID_2OUTPUT_READ_WRITE: + if(CPhidget_statusFlagIsSet(phid->phid.status, PHIDGET_REMOTE_FLAG)) + return EPHIDGET_UNSUPPORTED; //TODO? maybe just don't enable over webservice. + else + { + phid->polling = newVal; + return EPHIDGET_OK; + } default: return EPHIDGET_UNSUPPORTED; } +#else + return EPHIDGET_UNSUPPORTED; +#endif } -CGET(RFID, LastTag, unsigned char) - TESTPTRS(phid,pVal) + +PHIDGET21_API int CCONV CPhidgetRFID_getLastTag2(CPhidgetRFIDHandle phid, char **tagString, CPhidgetRFID_Protocol *protocol) +{ + TESTPTRS(phid,tagString) + TESTPTR(protocol) TESTDEVICETYPE(PHIDCLASS_RFID) TESTATTACHED - //if it's all 0's - it's not yet available - if(!memcmp("\0\0\0\0\0", phid->lastTag, 5)) - return EPHIDGET_UNKNOWNVAL; - - memcpy(pVal, phid->lastTag, 5); - - return EPHIDGET_OK; + CThread_mutex_lock(&phid->tagthreadlock); + if(phid->lastTagValid == PTRUE) + { + *tagString = phid->lastTag.tagString; + *protocol = phid->lastTag.protocol; + CThread_mutex_unlock(&phid->tagthreadlock); + return EPHIDGET_OK; + } + CThread_mutex_unlock(&phid->tagthreadlock); + return EPHIDGET_UNKNOWNVAL; } CGET(RFID, TagStatus, int) @@ -2431,361 +2228,186 @@ CGET(RFID, TagStatus, int) TESTDEVICETYPE(PHIDCLASS_RFID) TESTATTACHED - if(phid->tagPresent == PUNK_BOOL && phid->tagAdvancedCount == PUNK_INT) - { - *pVal = PUNK_BOOL; - return EPHIDGET_UNKNOWNVAL; - } + *pVal = phid->tagPresent; - if(phid->tagPresent == PTRUE || (phid->tagAdvancedCount > 0 && phid->tagAdvancedCount != PUNK_INT)) - *pVal = PTRUE; - else - *pVal = PFALSE; + if(*pVal == PUNK_BOOL) + return EPHIDGET_UNKNOWNVAL; return EPHIDGET_OK; } -PHIDGET21_API int CCONV CPhidgetRFID_writeRaw(CPhidgetRFIDHandle phid, unsigned char *data, int bitlength, int pregap, int space, int postgap, int zero, int one) +PHIDGET21_API int CCONV CPhidgetRFID_writeRaw(CPhidgetRFIDHandle phid, unsigned char *data, int bitlength, + int pregap, int space, int postgap, int zero, int one, int prepulse, int eof, int listenDuringEOF) { int retval; TESTPTR(phid) TESTDEVICETYPE(PHIDCLASS_RFID) TESTATTACHED - if(pregap < (2) || pregap > (255)) return EPHIDGET_INVALIDARG; - if(space < (2) || space > (255)) return EPHIDGET_INVALIDARG; - if(postgap < (2) || postgap > (255)) return EPHIDGET_INVALIDARG; - if(zero < (5) || zero > (255)) return EPHIDGET_INVALIDARG; - if(one < (5) || one > (255)) return EPHIDGET_INVALIDARG; - if(CPhidget_statusFlagIsSet(phid->phid.status, PHIDGET_REMOTE_FLAG)) - ;//ADDNETWORKKEYINDEXED(Acceleration, "%lE", motorAcceleration); //TODO - else + switch(phid->phid.deviceUID) { - unsigned char *buffer; - int ret = 0; - if(!(buffer = malloc(phid->phid.outputReportByteLength))) return EPHIDGET_NOMEMORY; - ZEROMEM(buffer, phid->phid.outputReportByteLength); - CThread_mutex_lock(&phid->phid.writelock); - - phid->pregapClocks = pregap; - phid->postgapClocks = postgap; - phid->spaceClocks = space; - phid->zeroClocks = zero; - phid->oneClocks = one; + case PHIDUID_RFID_2OUTPUT_READ_WRITE: + //limit spaces to 64 clocks + if(pregap < (2) || pregap > (64)) return EPHIDGET_INVALIDARG; + if(space < (2) || space > (64)) return EPHIDGET_INVALIDARG; + if(postgap < (2) || postgap > (64)) return EPHIDGET_INVALIDARG; + //pulses can be up to 256 clocks + if(zero < (4) || zero > (128)) return EPHIDGET_INVALIDARG; + if(one < (4) || one > (128)) return EPHIDGET_INVALIDARG; + if(prepulse < (0) || prepulse > (255)) return EPHIDGET_INVALIDARG; + if(eof < (0) || eof > (255)) return EPHIDGET_INVALIDARG; + if(listenDuringEOF < (PFALSE) || listenDuringEOF > (PTRUE)) return EPHIDGET_INVALIDARG; - //Send timing - if((ret = CPhidgetRFID_makePacket(phid, buffer))) goto done2; - if((ret = CPhidgetRFID_sendpacket(phid, buffer))) goto done2; - - //send data - if((retval = sendRAWData(phid, data, bitlength))) goto done2; - - done2: - CThread_mutex_unlock(&phid->phid.writelock); - free(buffer); - if(ret) return ret; - } + if(CPhidget_statusFlagIsSet(phid->phid.status, PHIDGET_REMOTE_FLAG)) + return EPHIDGET_UNSUPPORTED;//TODO + else + { + unsigned char *buffer; + int ret = 0; + if(!(buffer = malloc(phid->phid.outputReportByteLength))) return EPHIDGET_NOMEMORY; + ZEROMEM(buffer, phid->phid.outputReportByteLength); + CThread_mutex_lock(&phid->phid.writelock); - return EPHIDGET_OK; -} + phid->pregapClocks = pregap; + phid->postgapClocks = postgap; + phid->spaceClocks = space; + phid->zeroClocks = zero; + phid->oneClocks = one; + phid->prepulseClocks = prepulse; + phid->eofpulseClocks = eof; + phid->listenDuringEOF = listenDuringEOF; -PHIDGET21_API int CCONV CPhidgetRFID_getRawData(CPhidgetRFIDHandle phid, int *data, int *dataLength) -{ - int i; - TESTPTR(phid) - TESTDEVICETYPE(PHIDCLASS_RFID) - TESTATTACHED + //Send timing + if((ret = CPhidgetRFID_makePacket(phid, buffer))) goto done2; + if((ret = CPhidgetRFID_sendpacket(phid, buffer))) goto done2; - //make sure length is even so we only send out data with starting space and ending pulse - if((*dataLength % 2) == 1) - (*dataLength)--; + //send data + if((retval = sendRAWData(phid, data, bitlength))) goto done2; - for(i=0;i<*dataLength;i++) - { - if(phid->userReadPtr == phid->dataWritePtr) - break; + done2: + CThread_mutex_unlock(&phid->phid.writelock); + free(buffer); + if(ret) return ret; + } - data[i] = phid->dataBuffer[phid->userReadPtr]; - phid->userReadPtr = (phid->userReadPtr + 1) & RFID_DATA_ARRAY_MASK; - } + return EPHIDGET_OK; - //make sure i is even so that we don't end with a pulse - if((i % 2) == 1) - { - //negate the pulse if we added it - i--; - phid->userReadPtr = (phid->userReadPtr - 1) & RFID_DATA_ARRAY_MASK; + default: + return EPHIDGET_UNSUPPORTED; } - - *dataLength = i; - - return EPHIDGET_OK; } -PHIDGET21_API int CCONV CPhidgetRFID_getTagOptions(CPhidgetRFIDHandle phid, char *tagString, CPhidgetRFID_TagOptionsHandle options) +PHIDGET21_API int CCONV CPhidgetRFID_getRawData(CPhidgetRFIDHandle phid, int *data, int *dataLength) { - int ret = EPHIDGET_OK, wait_return = 0; - CPhidgetRFID_TagList *trav = 0; - CPhidgetRFID_TagHandle tag = 0; - TESTPTRS(phid,tagString) - TESTPTR(options) + TESTPTR(phid) TESTDEVICETYPE(PHIDCLASS_RFID) TESTATTACHED - //1st find it in the list - not there? can't get options. - CThread_mutex_lock(&phid->tagthreadlock); - for (trav=phid->tagAdvancedList; trav; trav = trav->next) - { - if(!strcmp(trav->tag->tagString, tagString)) - tag = trav->tag; - } - if(!tag) - { - CThread_mutex_unlock(&phid->tagthreadlock); - return EPHIDGET_NOTFOUND; - } - - //Do we need to poll for the options? yes for Hitag - if(!tag->tagOptionsValid) +#ifdef RFID_RAWDATA_API_SUPPORT + switch(phid->phid.deviceUID) { - switch(tag->tagInfo.tagType) + case PHIDUID_RFID_2OUTPUT_READ_WRITE: { - case PHIDGET_RFID_TAG_HITAGS: - CThread_mutex_unlock(&phid->tagthreadlock); - - phid->respData = tag; - CThread_reset_event(&phid->respEvent); - HitagS_SELECT(phid, (unsigned char *)tagString); - - wait_return = CThread_wait_on_event(&phid->respEvent, 500); - switch (wait_return) { - case WAIT_TIMEOUT: - ret = EPHIDGET_TIMEOUT; - break; - case WAIT_OBJECT_0: - ret = phid->respStatus; - break; - default: - ret = EPHIDGET_UNEXPECTED; - break; - } - - CThread_reset_event(&phid->respEvent); - - CThread_mutex_lock(&phid->tagthreadlock); - break; - case PHIDGET_RFID_TAG_ISO11784: - break; - case PHIDGET_RFID_TAG_EM4102: - break; - default: - CThread_mutex_unlock(&phid->tagthreadlock); - return EPHIDGET_UNEXPECTED; - } - } - //copy over options - memcpy(options, &tag->tagOptions, sizeof(CPhidgetRFID_TagOptions)); - - CThread_mutex_unlock(&phid->tagthreadlock); - return ret; -} - -PHIDGET21_API int CCONV CPhidgetRFID_read(CPhidgetRFIDHandle phid, char *tagString, unsigned char *data, int *dataLength, char *password) -{ - int ret = EPHIDGET_OK, wait_return = 0, i; - CPhidgetRFID_TagList *trav = 0; - CPhidgetRFID_TagHandle tag = 0; - CPhidgetRFID_TagOptions options; - TESTPTRS(phid,tagString) - TESTPTR(data) - TESTDEVICETYPE(PHIDCLASS_RFID) - TESTATTACHED - - //1st find it in the list - not there? can't get options. - CThread_mutex_lock(&phid->tagthreadlock); - for (trav=phid->tagAdvancedList; trav; trav = trav->next) - { - if(!strcmp(trav->tag->tagString, tagString)) - tag = trav->tag; - } - if(!tag) - { - CThread_mutex_unlock(&phid->tagthreadlock); - return EPHIDGET_NOTFOUND; - } + int i; + //make sure length is even so we only send out data with starting space and ending pulse + if((*dataLength % 2) == 1) + (*dataLength)--; - switch(tag->tagInfo.tagType) - { - case PHIDGET_RFID_TAG_HITAGS: - if(tag->tagOptions.memSize == 32) + for(i=0;i<*dataLength;i++) { - ret = EPHIDGET_UNSUPPORTED; - break; - } - //Do we need to select the tag first? - if(!tag->tagOptionsValid) - { - CThread_mutex_unlock(&phid->tagthreadlock); - if((ret = CPhidgetRFID_getTagOptions(phid, tagString, &options))) - return ret; - CThread_mutex_lock(&phid->tagthreadlock); + if(phid->userReadPtr == phid->dataWritePtr) + break; + + data[i] = phid->dataBuffer[phid->userReadPtr]; + phid->userReadPtr = (phid->userReadPtr + 1) & RFID_DATA_ARRAY_MASK; } - //Now do the reads - if(!tag->tagDataValid) + //make sure i is even so that we don't end with a pulse + if((i % 2) == 1) { - CThread_mutex_unlock(&phid->tagthreadlock); - phid->respData = tag; - CThread_reset_event(&phid->respEvent); - //reading blocks - 4 pages/block, 32 bits/page - for(i=0;i<tag->tagOptions.memSize/32;i+=4) - { - HitagS_READ(phid, i, PTRUE); - - wait_return = CThread_wait_on_event(&phid->respEvent, 1000); - switch (wait_return) { - case WAIT_TIMEOUT: - return EPHIDGET_TIMEOUT; - case WAIT_OBJECT_0: - if((ret = phid->respStatus)) - return ret; - break; - default: - return EPHIDGET_UNEXPECTED; - } + //negate the pulse if we added it + i--; + phid->userReadPtr = (phid->userReadPtr - 1) & RFID_DATA_ARRAY_MASK; + } - CThread_reset_event(&phid->respEvent); - } + *dataLength = i; - CThread_mutex_lock(&phid->tagthreadlock); - } - //copy over data - ignore 1st 8 bytes, it's UID and configuration - //TODO: if Authentication is turned on, we lose even more space - if(*dataLength > tag->tagOptions.memSize/8 - 8) - *dataLength = tag->tagOptions.memSize/8 - 8; - memcpy(data, tag->tagData + 8, *dataLength); + return EPHIDGET_OK; + } - break; - case PHIDGET_RFID_TAG_ISO11784: - ret = EPHIDGET_UNSUPPORTED; - break; - case PHIDGET_RFID_TAG_EM4102: - ret = EPHIDGET_UNSUPPORTED; - break; default: - ret = EPHIDGET_UNEXPECTED; - break; + return EPHIDGET_UNSUPPORTED; } - - CThread_mutex_unlock(&phid->tagthreadlock); - return ret; +#else + return EPHIDGET_UNSUPPORTED; +#endif } -PHIDGET21_API int CCONV CPhidgetRFID_write(CPhidgetRFIDHandle phid, char *tagString, unsigned char *data, int dataLength, int offset, char *password) +PHIDGET21_API int CCONV CPhidgetRFID_write(CPhidgetRFIDHandle phid, char *tagString, CPhidgetRFID_Protocol protocol, int lock) { - int ret = EPHIDGET_OK, wait_return = 0, i, writePage, writeSize; - CPhidgetRFID_TagList *trav = 0; - CPhidgetRFID_TagHandle tag = 0; - CPhidgetRFID_TagOptions options; - unsigned char readData[256]; - int readDataSize = 256; - TESTPTRS(phid,tagString) - TESTPTR(data) + int ret = EPHIDGET_OK; + char newVal[50]; + TESTPTRS(phid,tagString) TESTDEVICETYPE(PHIDCLASS_RFID) TESTATTACHED - //1st find it in the list - not there? can't get options. - CThread_mutex_lock(&phid->tagthreadlock); - for (trav=phid->tagAdvancedList; trav; trav = trav->next) - { - if(!strcmp(trav->tag->tagString, tagString)) - tag = trav->tag; - } - if(!tag) - { - CThread_mutex_unlock(&phid->tagthreadlock); - return EPHIDGET_NOTFOUND; - } - - switch(tag->tagInfo.tagType) + switch(phid->phid.deviceUID) { - case PHIDGET_RFID_TAG_HITAGS: + case PHIDUID_RFID_2OUTPUT_READ_WRITE: + if(protocol < (PHIDGET_RFID_PROTOCOL_EM4100) || protocol > (PHIDGET_RFID_PROTOCOL_PHIDGETS)) + return EPHIDGET_INVALIDARG; + if(lock < (PFALSE) || lock > (PTRUE)) + return EPHIDGET_INVALIDARG; - if(tag->tagOptions.memSize == 32) + if(CPhidget_statusFlagIsSet(phid->phid.status, PHIDGET_REMOTE_FLAG)) { - ret = EPHIDGET_UNSUPPORTED; - break; + sprintf(newVal, "%d/%d/%s", protocol, lock, tagString); + ADDNETWORKKEY(WriteTag, "%s", remoteWrite); } - //Do we need to select the tag first? - if(!tag->tagOptionsValid) + else { + CThread_mutex_lock(&phid->tagthreadlock); + ret = T5577_WriteTag(phid, protocol, tagString, lock); CThread_mutex_unlock(&phid->tagthreadlock); - if((ret = CPhidgetRFID_getTagOptions(phid, tagString, &options))) + if(ret != EPHIDGET_OK) return ret; - CThread_mutex_lock(&phid->tagthreadlock); - } - - if(offset+dataLength > (tag->tagOptions.memSize/8)-8) - return EPHIDGET_INVALIDARG; - - //Need to read in the tag first - CThread_mutex_unlock(&phid->tagthreadlock); - if((ret = CPhidgetRFID_read(phid, tagString, readData, &readDataSize, password))) - return ret; - CThread_mutex_lock(&phid->tagthreadlock); - - //Now do the writes - CThread_mutex_unlock(&phid->tagthreadlock); - phid->respData = tag; - CThread_reset_event(&phid->respEvent); - - //need to start the write on a page border - //these are in pages (4 bytes) - writePage = offset/4; - writeSize = dataLength/4 + (dataLength%4 ? 1 : 0) + offset%4; - - //replace what the user wants to write - memcpy(readData+offset, data, dataLength); - - for(i=writePage;i<writePage+writeSize;i+=(i%4 ? i%4 : 4)) - { - HitagS_WRITE(phid, i, readData+i, PTRUE); - - wait_return = CThread_wait_on_event(&phid->respEvent, 500); - switch (wait_return) { - case WAIT_TIMEOUT: - return EPHIDGET_TIMEOUT; - case WAIT_OBJECT_0: - if((ret = phid->respStatus)) - return ret; - break; - default: - return EPHIDGET_UNEXPECTED; - } - - CThread_reset_event(&phid->respEvent); + return waitForTag(phid, tagString, 500); } - CThread_mutex_lock(&phid->tagthreadlock); - - break; - case PHIDGET_RFID_TAG_ISO11784: - ret = EPHIDGET_UNSUPPORTED; - break; - case PHIDGET_RFID_TAG_EM4102: - ret = EPHIDGET_UNSUPPORTED; break; + default: - ret = EPHIDGET_UNEXPECTED; - break; + return EPHIDGET_UNSUPPORTED; } - CThread_mutex_unlock(&phid->tagthreadlock); - return ret; + return EPHIDGET_OK; } // === Deprecated Functions === // +CFHANDLE(RFID, Tag, unsigned char *) +CFHANDLE(RFID, TagLost, unsigned char *) CGET(RFID,NumOutputs,int) return CPhidgetRFID_getOutputCount(phid, pVal); } +CGET(RFID, LastTag, unsigned char) + int ret = EPHIDGET_OK; + TESTPTRS(phid,pVal) + TESTDEVICETYPE(PHIDCLASS_RFID) + TESTATTACHED + + //This function only work if the last tag was EM4100 + CThread_mutex_lock(&phid->tagthreadlock); + if(phid->lastTagValid) + { + if(phid->lastTag.protocol == PHIDGET_RFID_PROTOCOL_EM4100) + memcpy(pVal, phid->lastTag.tagData, 5); + else + ret = EPHIDGET_UNSUPPORTED; //unsupported for the protocol of the last tag + } + else + ret = EPHIDGET_UNKNOWNVAL; + CThread_mutex_unlock(&phid->tagthreadlock); + + return ret; +} diff --git a/cphidgetrfid.h b/cphidgetrfid.h index 1dcdafd..a9b5761 100644 --- a/cphidgetrfid.h +++ b/cphidgetrfid.h @@ -11,6 +11,23 @@ DPHANDLE(RFID) CHDRSTANDARD(RFID) +#ifdef DEBUG +#define RFID_HITAGS_SUPPORT +#define RFID_RAWDATA_API_SUPPORT +#endif + +/** + * RFID encoding protocols supported by the PhidgetRFID Read-Write + */ +typedef enum { + PHIDGET_RFID_PROTOCOL_EM4100 = 1, /**< EM4100 (EM4102) 40-bit */ + PHIDGET_RFID_PROTOCOL_ISO11785_FDX_B, /**< ISO11785 FDX-B encoding (Animal ID) */ + PHIDGET_RFID_PROTOCOL_PHIDGETS, /**< PhidgetsTAG Protocol 24 character ASCII */ +#ifdef RFID_HITAGS_SUPPORT + PHIDGET_RFID_PROTOCOL_HITAGS_UID /**< HiTag S UID */ +#endif +} CPhidgetRFID_Protocol; + /** * Gets the number of outputs supported by this board. * @param phid An attached phidget rfid handle. @@ -67,78 +84,65 @@ CHDRSET(RFID,LEDOn,int LEDState) /** * Gets the last tag read by the reader. This tag may or may not still be on the reader. * @param phid An attached phidget rfid handle. - * @param tag The tag. This must be an unsigned char array of size 5. + * @param tagString A pointer which will be set to point to a char array containing the tag string. + * @param protocol The tag protocol. */ -CHDRGET(RFID,LastTag,unsigned char *tag) +CHDRGET(RFID,LastTag2,char **tagString, CPhidgetRFID_Protocol *protocol) /** * Gets the tag present status. This is whether or not a tag is being read by the reader. * @param phid An attached phidget rfid handle. * @param status The tag status. Possible values are \ref PTRUE and \ref PFALSE. */ CHDRGET(RFID,TagStatus,int *status) + +/** + * Program a tag. This requires a T5577 tag. + * @param phid An attached phidget rfid handle. + * @param tagString The tag data to write. + * EM4100 (40-bit hex): "90fd32987b" + * FDX-B (15 digit decimal): "999000000003471" + * Phidgets (7-bit ASCII, up to 24 characters): "I'm a PHIDGET tag" + * @param protocol The tag protocol to write + * @param lock Lock the tag so that it cannot be written again. + */ +PHIDGET21_API int CCONV CPhidgetRFID_write(CPhidgetRFIDHandle phid, char *tagString, CPhidgetRFID_Protocol protocol, int lock); + /** * Set a tag handler. This is called when a tag is first detected by the reader. * @param phid An attached phidget rfid handle. * @param fptr Callback function pointer. * @param userPtr A pointer for use by the user - this value is passed back into the callback function. */ -CHDREVENT(RFID,Tag,unsigned char *tag) +CHDREVENT(RFID, Tag2, char *tagString, CPhidgetRFID_Protocol protocol) /** * Set a tag lost handler. This is called when a tag is no longer detected by the reader. * @param phid An attached phidget rfid handle. * @param fptr Callback function pointer. * @param userPtr A pointer for use by the user - this value is passed back into the callback function. */ -CHDREVENT(RFID,TagLost,unsigned char *tag) +CHDREVENT(RFID, TagLost2, char *tagString, CPhidgetRFID_Protocol protocol) #ifndef REMOVE_DEPRECATED DEP_CHDRGET("Deprecated - use CPhidgetRFID_getOutputCount",RFID,NumOutputs,int *) +DEP_CHDRGET("Deprecated - use CPhidgetRFID_getLastTag2",RFID,LastTag,unsigned char *tag) +DEP_CHDREVENT("Deprecated - use CPhidgetRFID_set_OnTag2_Handler",RFID,Tag,unsigned char *tag) +DEP_CHDREVENT("Deprecated - use CPhidgetRFID_set_OnTagLost2_Handler",RFID,TagLost,unsigned char *tag) #endif -//These are for a prototype device - hide until it's released -#if !defined(EXTERNALPROTO) || defined(DEBUG) - -typedef enum { - PHIDGET_RFID_ENCODING_MANCHESTER = 1, - PHIDGET_RFID_ENCODING_BIPHASE, - PHIDGET_RFID_ENCODING_AC -} CPhidgetRFID_Encoding; - -typedef enum { - PHIDGET_RFID_TAG_ISO11784 = 1, - PHIDGET_RFID_TAG_EM4102, - PHIDGET_RFID_TAG_HITAGS -} CPhidgetRFID_TagType; - -typedef struct _CPhidgetRFID_TagInfo -{ - int bitRate; - CPhidgetRFID_TagType tagType; - CPhidgetRFID_Encoding encoding; -} CPhidgetRFID_TagInfo, *CPhidgetRFID_TagInfoHandle; - -typedef struct _CPhidgetRFID_TagOptions -{ - unsigned char writable; - unsigned char encrypted; - int memSize; -} CPhidgetRFID_TagOptions, *CPhidgetRFID_TagOptionsHandle; - - +/* Keep these hidden - unofficial API, not supported. */ +#if !defined(EXTERNALPROTO) || defined(RFID_HITAGS_SUPPORT) +/* poll for HiTag S tags */ CHDRSET(RFID,PollingOn,int pollingState) - -PHIDGET21_API int CCONV CPhidgetRFID_writeRaw(CPhidgetRFIDHandle phid, unsigned char *data, int bitlength, int pregap, int space, int postgap, int zero, int one); +#endif +#if !defined(EXTERNALPROTO) || defined(RFID_RAWDATA_API_SUPPORT) +/* Write raw data to a tag */ +PHIDGET21_API int CCONV CPhidgetRFID_writeRaw(CPhidgetRFIDHandle phid, unsigned char *data, int bitlength, int pregap, int space, int postgap, int zero, int one, int prepulse, int eof, int listenDuringEOF); +/* Read in raw data from tags */ PHIDGET21_API int CCONV CPhidgetRFID_getRawData(CPhidgetRFIDHandle phid, int *data, int *dataLength); - -PHIDGET21_API int CCONV CPhidgetRFID_getTagOptions(CPhidgetRFIDHandle phid, char *tagString, CPhidgetRFID_TagOptionsHandle options); -PHIDGET21_API int CCONV CPhidgetRFID_read(CPhidgetRFIDHandle phid, char *tagString, unsigned char *data, int *dataLength, char *password); -PHIDGET21_API int CCONV CPhidgetRFID_write(CPhidgetRFIDHandle phid, char *tagString, unsigned char *data, int dataLength, int offset, char *password); - +/* Raw data event */ CHDREVENT(RFID, RawData, int *data, int dataLength) +/* Manchester data event */ CHDREVENT(RFID, ManchesterData, unsigned char *data, int dataLength) -CHDREVENT(RFID, TagAdvanced, char *tagString, CPhidgetRFID_TagInfoHandle tagInfo) -CHDREVENT(RFID, TagLostAdvanced, char *tagString, CPhidgetRFID_TagInfoHandle tagInfo) - #endif #ifndef EXTERNALPROTO @@ -148,15 +152,23 @@ CHDREVENT(RFID, TagLostAdvanced, char *tagString, CPhidgetRFID_TagInfoHandle tag #define RFID_LED_FLAG 0x04 #define RFID_ANTENNA_FLAG 0x08 +#define RFID_LISTEN_DURING_EOF_FLAG 0x10 -//RFID Advanced Constants #define RFID_WRITE_DATA_OUT_PACKET 0x00 #define RFID_CONTROL_OUT_PACKET 0x40 #define RFID_READ_DATA_IN_PACKET 0x00 #define RFID_ECHO_IN_PACKET 0x40 -//4097 constants +#define RFID_MAX_DATA_PER_PACKET 63 + +#define RFID_DATA_ARRAY_SIZE 1024 +#define RFID_DATA_ARRAY_MASK 0x3ff + +#define RFID_MAXOUTPUTS 2 + + +/* 4097 constants */ #define RFID_4097_AmpDemod 0x00 //Amplitude demodulation #define RFID_4097_PhaseDemod 0x01 //Phase demodulation @@ -178,151 +190,133 @@ CHDREVENT(RFID, TagLostAdvanced, char *tagString, CPhidgetRFID_TagInfoHandle tag #define RFID_4097_TestMode 0x80 -#define RFID_MAX_DATA_PER_PACKET 62 +#define RFID_4097_DefaultON (RFID_4097_AmpDemod | RFID_4097_Active | RFID_4097_DataOut | RFID_4097_IntPLL | RFID_4097_FastStart | RFID_4097_Gain960) -#define RFID_DATA_ARRAY_SIZE 2048 -#define RFID_DATA_ARRAY_MASK 0x7ff -#define RFID_MAXOUTPUTS 2 +/* T5577 Write Timing Constants */ +#define RFID_T5577_StartGap 30 +#define RFID_T5577_WriteGap 15 +#define RFID_T5577_EndGap 15 +#define RFID_T5577_Zero 24 +#define RFID_T5577_One 56 +#define RFID_T5577_EOF 100 +#define RFID_T5577_PrePulse (136 + RFID_T5577_Zero) -typedef enum _CPhidgetRFID_Hitag_State -{ - RFID_HITAG_STATE_NONE = 0, - RFID_HITAG_STATE_UID_REQUEST, - RFID_HITAG_STATE_AC_SEQUENCE, - RFID_HITAG_STATE_SELECT, - RFID_HITAG_STATE_READ, - RFID_HITAG_STATE_WRITE +#ifdef RFID_HITAGS_SUPPORT +typedef enum { + PHIDGET_RFID_TAG_READONLY = 1, + PHIDGET_RFID_TAG_HITAGS +} CPhidgetRFID_TagType; +#endif -} CPhidgetRFID_Hitag_State; +typedef enum { + PHIDGET_RFID_ENCODING_MANCHESTER = 1, + PHIDGET_RFID_ENCODING_BIPHASE, +#ifdef RFID_HITAGS_SUPPORT + PHIDGET_RFID_ENCODING_AC +#endif +} CPhidgetRFID_Encoding; +#define RFID_MAX_TAG_STRING_LEN 25 typedef struct _CPhidgetRFID_Tag { - char tagString[256]; - CPhidgetRFID_TagInfo tagInfo; - TIME lastTagTime; - unsigned char tagEventPending; - unsigned char tagOptionsValid; - CPhidgetRFID_TagOptions tagOptions; - unsigned char tagDataValid; - unsigned char tagData[256]; + CPhidgetRFID_Protocol protocol; + char tagString[RFID_MAX_TAG_STRING_LEN]; + unsigned char tagData[10]; //used for old EM4100 events +#ifdef RFID_HITAGS_SUPPORT + CPhidgetRFID_TagType tagType; +#endif } CPhidgetRFID_Tag, *CPhidgetRFID_TagHandle; -typedef struct _CPhidgetRFID_TagList -{ - struct _CPhidgetRFID_TagList *next; - CPhidgetRFID_TagHandle tag; -} CPhidgetRFID_TagList, *CPhidgetRFID_TagListHandle; - -typedef struct _CPhidgetRFID_HitagAC -{ - unsigned char uid[4]; - int colPos; -} CPhidgetRFID_HitagAC, *CPhidgetRFID_HitagACHandle; - -typedef struct _CPhidgetRFID_HitagACList -{ - struct _CPhidgetRFID_HitagACList *next; - CPhidgetRFID_HitagACHandle hitagAC; -} CPhidgetRFID_HitagACList, *CPhidgetRFID_HitagACListHandle; - struct _CPhidgetRFID { CPhidget phid; int (CCONV *fptrOutputChange)(CPhidgetRFIDHandle, void *, int, int); int (CCONV *fptrTag)(CPhidgetRFIDHandle, void *, unsigned char *); int (CCONV *fptrTagLost)(CPhidgetRFIDHandle, void *, unsigned char *); - int (CCONV *fptrRawData)(CPhidgetRFIDHandle, void *, int *, int); - int (CCONV *fptrManchesterData)(CPhidgetRFIDHandle, void *, unsigned char *, int); - int (CCONV *fptrTagAdvanced)(CPhidgetRFIDHandle, void *, char *, CPhidgetRFID_TagInfoHandle); - int (CCONV *fptrTagLostAdvanced)(CPhidgetRFIDHandle, void *, char *, CPhidgetRFID_TagInfoHandle); + int (CCONV *fptrTag2)(CPhidgetRFIDHandle, void *, char *, CPhidgetRFID_Protocol); + int (CCONV *fptrTagLost2)(CPhidgetRFIDHandle, void *, char *, CPhidgetRFID_Protocol); void *fptrOutputChangeptr; void *fptrTagptr; void *fptrTagLostptr; + void *fptrTag2ptr; + void *fptrTagLost2ptr; + +#ifdef RFID_RAWDATA_API_SUPPORT + int (CCONV *fptrRawData)(CPhidgetRFIDHandle, void *, int *, int); + int (CCONV *fptrManchesterData)(CPhidgetRFIDHandle, void *, unsigned char *, int); void *fptrRawDataptr; void *fptrManchesterDataptr; - void *fptrTagAdvancedptr; - void *fptrTagLostAdvancedptr; +#endif - // Values returned from the device + /* State */ unsigned char outputEchoState[RFID_MAXOUTPUTS]; unsigned char antennaEchoState; unsigned char ledEchoState; - + int spaceClocks, pregapClocks, postgapClocks, oneClocks, zeroClocks, prepulseClocks, eofpulseClocks; + unsigned char listenDuringEOF; + int _4097Conf; + + /* State Echo */ unsigned char outputState[RFID_MAXOUTPUTS]; unsigned char antennaState; unsigned char ledState; - - unsigned char lastTag[5]; - unsigned char lastTagValid; - TIME lastTagTime; - unsigned char tagPresent; - //unsigned char tagEvent; - unsigned char pendingTag[5]; - unsigned char tagEventPending; - - EVENT tagAvailableEvent; - - void *respData; - int respStatus; - EVENT respEvent; - EVENT respEvent2; - - //Advanced Tag Events - int tagAdvancedCount; - CThread_mutex_t tagthreadlock; /* protects tag thread access to things */ - CPhidgetRFID_TagListHandle tagAdvancedList; - CPhidgetRFID_Tag lastTagAdvanced; - TIME lastDataTime; - TIME hitagReqTime; - - unsigned char ACCodingOK; + int spaceClocksEcho, pregapClocksEcho, postgapClocksEcho, oneClocksEcho, zeroClocksEcho, prepulseClocksEcho, eofpulseClocksEcho; + unsigned char listenDuringEOFEcho; + int _4097ConfEcho; unsigned char fullStateEcho; - + CThread tagTimerThread; + CThread_mutex_t tagthreadlock; /* protects tag thread access to things */ + EVENT tagAvailableEvent; - //RFID Advanced stuff - int spaceClocks, pregapClocks, postgapClocks, oneClocks, zeroClocks; - int spaceClocksEcho, pregapClocksEcho, postgapClocksEcho, oneClocksEcho, zeroClocksEcho; - int _4097Conf, _4097ConfEcho; - int frequencyEcho; + /* Tag event */ + CPhidgetRFID_Tag lastTag; + unsigned char lastTagValid; + TIME lastTagTime; + unsigned char tagPresent; + CPhidgetRFID_Tag pendingTag; + unsigned char tagEventPending; + /* Raw data buffer */ int dataBuffer[RFID_DATA_ARRAY_SIZE]; - int dataBufferNormalized[RFID_DATA_ARRAY_SIZE]; - unsigned int dataReadPtr, dataWritePtr, dataReadACPtr; - unsigned int userReadPtr; //for the getRawData function + unsigned int dataReadPtr, dataWritePtr; + int shortClocks, longClocks; + + /* Manchester decoder */ unsigned char manBuffer[RFID_DATA_ARRAY_SIZE]; int manReadPtr, manWritePtr; - - unsigned char biphaseBuffer[RFID_DATA_ARRAY_SIZE]; - int biphaseReadPtr, biphaseWritePtr; - unsigned char manLockedIn; unsigned char manShortChange; + /* BiPhase Decoder */ + unsigned char biphaseBuffer[RFID_DATA_ARRAY_SIZE]; + int biphaseReadPtr, biphaseWritePtr; unsigned char biphaseLockedIn; unsigned char biphaseShortChange; - int one, two; - int oneCount, twoCount; - - CPhidgetRFID_Hitag_State hitagState; - int hitagOffset; - - //Hitag AC queue - CPhidgetRFID_HitagACListHandle hitagACList; - CPhidgetRFID_HitagAC lastHitagAC; +#ifdef RFID_HITAGS_SUPPORT + TIME lastDataTime; + unsigned int dataReadACPtr; + TIME hitagReqTime; + unsigned char polling; + unsigned char ACCodingOK; +#endif +#ifdef RFID_RAWDATA_API_SUPPORT + unsigned int userReadPtr; + int manEventReadPtr; + unsigned char lastManEventLong; +#endif - unsigned char atGap, polling; + //for remote write + char *remoteWrite; unsigned char outputPacket[MAX_OUT_PACKET_SIZE]; unsigned int outputPacketLen; - int manEventReadPtr; - } typedef CPhidgetRFIDInfo; #endif diff --git a/cphidgetstepper.c b/cphidgetstepper.c index 966da07..55bc9f8 100644 --- a/cphidgetstepper.c +++ b/cphidgetstepper.c @@ -81,7 +81,6 @@ CPHIDGETINIT(Stepper) break; case PHIDUID_STEPPER_BIPOLAR_1MOTOR_M3: phid->microSteps = 16; - //phid->motorSpeedMax = 262144; //8x 1062_1 phid->motorSpeedMax = 250000; //nice round number phid->motorSpeedMin = 0; phid->accelerationMax = 10000000; @@ -1,3 +1,4 @@ #ifdef __cplusplus } #endif +#endif
\ No newline at end of file @@ -1,3 +1,6 @@ +#ifndef PHIDGET_H +#define PHIDGET_H + #ifdef __cplusplus extern "C" { #endif diff --git a/csocketevents.c b/csocketevents.c index e1e32e1..85b840b 100644 --- a/csocketevents.c +++ b/csocketevents.c @@ -886,6 +886,17 @@ PWC_SETKEYS(LED) INC_KEYCOUNT(currentLimitEcho, -1) phid->currentLimitEcho = value; } + else if(KEYNAME("CurrentLimitIndexed")) + { + if(CHKINDEX(led.numLEDs, LED_MAXLEDS)) + { + GET_DOUBLE_VAL; + INC_KEYCOUNT(LED_CurrentLimit[index], PUNI_DBL) + phid->LED_CurrentLimit[index] = value; + } + else + ret = EPHIDGET_OUTOFBOUNDS; + } else{ PWC_BAD_SETTYPE(LED); } @@ -1181,46 +1192,68 @@ PWC_SETKEYS(RFID) } else if(KEYNAME("LastTag")) { - unsigned char tagData[5]; + char *endPtr; + CPhidgetRFID_Tag tag = {0}; + tag.protocol = (CPhidgetRFID_Protocol)strtol(state, &endPtr, 10); + strncpy(tag.tagString, endPtr+1, 25); + INC_KEYCOUNT(lastTagValid, PUNI_BOOL) - phid->lastTagValid = PTRUE; + if(tag.protocol != 0) + phid->lastTagValid = PTRUE; + else + phid->lastTagValid = PFALSE; - tagData[0] = (hexval(state[0])<<4)|hexval(state[1]); - tagData[1] = (hexval(state[2])<<4)|hexval(state[3]); - tagData[2] = (hexval(state[4])<<4)|hexval(state[5]); - tagData[3] = (hexval(state[6])<<4)|hexval(state[7]); - tagData[4] = (hexval(state[8])<<4)|hexval(state[9]); + if(tag.protocol == PHIDGET_RFID_PROTOCOL_EM4100) + { + tag.tagData[0] = (hexval(tag.tagString[0])<<4)|hexval(tag.tagString[1]); + tag.tagData[1] = (hexval(tag.tagString[2])<<4)|hexval(tag.tagString[3]); + tag.tagData[2] = (hexval(tag.tagString[4])<<4)|hexval(tag.tagString[5]); + tag.tagData[3] = (hexval(tag.tagString[6])<<4)|hexval(tag.tagString[7]); + tag.tagData[4] = (hexval(tag.tagString[8])<<4)|hexval(tag.tagString[9]); + } - memcpy(phid->lastTag, tagData, 5); + phid->lastTag = tag; } - else if(KEYNAME("Tag")) + else if(KEYNAME("Tag2")) { - unsigned char tagData[5]; - //always increment on tagPresent==PUNI_BOOL before setting it! + char *endPtr; + CPhidgetRFID_Tag tag = {0}; + tag.protocol = (CPhidgetRFID_Protocol)strtol(state, &endPtr, 10); + strncpy(tag.tagString, endPtr+1, 25); + INC_KEYCOUNT(tagPresent, PUNI_BOOL) - phid->tagPresent = 1; + phid->tagPresent = PTRUE; - tagData[0] = (hexval(state[0])<<4)|hexval(state[1]); - tagData[1] = (hexval(state[2])<<4)|hexval(state[3]); - tagData[2] = (hexval(state[4])<<4)|hexval(state[5]); - tagData[3] = (hexval(state[6])<<4)|hexval(state[7]); - tagData[4] = (hexval(state[8])<<4)|hexval(state[9]); + INC_KEYCOUNT(lastTagValid, PUNI_BOOL) + phid->lastTagValid = PTRUE; - FIRE(Tag, tagData); + if(tag.protocol == PHIDGET_RFID_PROTOCOL_EM4100) + { + tag.tagData[0] = (hexval(tag.tagString[0])<<4)|hexval(tag.tagString[1]); + tag.tagData[1] = (hexval(tag.tagString[2])<<4)|hexval(tag.tagString[3]); + tag.tagData[2] = (hexval(tag.tagString[4])<<4)|hexval(tag.tagString[5]); + tag.tagData[3] = (hexval(tag.tagString[6])<<4)|hexval(tag.tagString[7]); + tag.tagData[4] = (hexval(tag.tagString[8])<<4)|hexval(tag.tagString[9]); + FIRE(Tag, tag.tagData); + } + + FIRE(Tag2, tag.tagString, tag.protocol); - memcpy(phid->lastTag, tagData, 5); + phid->lastTag = tag; } - else if(KEYNAME("TagLoss")) + else if(KEYNAME("TagLoss2")) { - //always increment on tagPresent==PUNI_BOOL before setting it! INC_KEYCOUNT(tagPresent, PUNI_BOOL) - phid->tagPresent = 0; - FIRE(TagLost, phid->lastTag); + phid->tagPresent = PFALSE; + + if(phid->lastTag.protocol == PHIDGET_RFID_PROTOCOL_EM4100) + FIRE(TagLost, phid->lastTag.tagData); + FIRE(TagLost2, phid->lastTag.tagString, phid->lastTag.protocol); } else if(KEYNAME("TagState")) { GET_INT_VAL; - //always increment on tagPresent==PUNI_BOOL before setting it! + INC_KEYCOUNT(tagPresent, PUNI_BOOL) phid->tagPresent = value; } diff --git a/csocketopen.c b/csocketopen.c index 4c12f5d..412a685 100644 --- a/csocketopen.c +++ b/csocketopen.c @@ -52,8 +52,11 @@ * * 1.0.9 * -support for openLabelRemote and openLabelRemoteIP +* +* 1.0.10 +* -support for 1024, 1032 */ -const char *ws_protocol_ver = "1.0.9"; +const char *ws_protocol_ver = "1.0.10"; /*void DNSServiceResolve_CallBack( DNSServiceRef sdRef, diff --git a/debian/changelog b/debian/changelog index 5b3f8c0..a580e1a 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,4 +1,4 @@ -libphidget21 (2.1.8.20120912-1~bpo60+1) squeeze-backports; urgency=low +libphidget21 (2.1.8.20121218-1~bpo60+1) squeeze-backports; urgency=low * Initial release (Closes: #670984) diff --git a/labview/phidget_labview.c b/labview/phidget_labview.c index 380915b..64f6cae 100644 --- a/labview/phidget_labview.c +++ b/labview/phidget_labview.c @@ -140,23 +140,12 @@ LV_CFHANDLE_BODY(RFID, TagLost, lvUInt8Array, void *userPtr, unsigned char *val1 DSDisposePtr(data);
return EPHIDGET_OK;
}
-LV_CFHANDLE_BODY(RFID, RawData, lvInt32Array, void *userPtr, int *val1, int val2)
- data->val1=(lvArrInt32DH)DSNewHandle(sizeof(int32)+val2*sizeof(int32));
- (*(data->val1))->length = val2;
- memcpy((*(data->val1))->data, val1, val2 * sizeof(int32));
-
- ret = PostLVUserEvent(ev, data);
-
- DSDisposeHandle(data->val1);
- DSDisposePtr(data);
- return EPHIDGET_OK;
-}
-LV_CFHANDLE_BODY(RFID, TagAdvanced, lvRFIDTagAdvanced, void *userPtr, char *val1, CPhidgetRFID_TagInfoHandle val2)
+LV_CFHANDLE_BODY(RFID, Tag2, lvRFIDTag2, void *userPtr, char *val1, CPhidgetRFID_Protocol val2)
data->val1=(LStrHandle)DSNewHandle(sizeof(int32)+255*sizeof(char));
memset(LStrBuf(*data->val1),'\0',255);
snprintf((char*)LStrBuf(*data->val1),255,"%s",val1);
LStrLen(*data->val1)=strlen(val1);
- data->val2 = *val2;
+ data->val2 = val2;
ret = PostLVUserEvent(ev, data);
@@ -164,12 +153,12 @@ LV_CFHANDLE_BODY(RFID, TagAdvanced, lvRFIDTagAdvanced, void *userPtr, char *val1 DSDisposePtr(data);
return EPHIDGET_OK;
}
-LV_CFHANDLE_BODY(RFID, TagLostAdvanced, lvRFIDTagAdvanced, void *userPtr, char *val1, CPhidgetRFID_TagInfoHandle val2)
+LV_CFHANDLE_BODY(RFID, TagLost2, lvRFIDTag2, void *userPtr, char *val1, CPhidgetRFID_Protocol val2)
data->val1=(LStrHandle)DSNewHandle(sizeof(int32)+255*sizeof(char));
memset(LStrBuf(*data->val1),'\0',255);
snprintf((char*)LStrBuf(*data->val1),255,"%s",val1);
LStrLen(*data->val1)=strlen(val1);
- data->val2 = *val2;
+ data->val2 = val2;
ret = PostLVUserEvent(ev, data);
@@ -397,9 +386,8 @@ LV_NULL_FUNC(PHSensor, PHChange) LV_NULL_FUNC(RFID, OutputChange)
LV_NULL_FUNC(RFID, Tag)
LV_NULL_FUNC(RFID, TagLost)
-LV_NULL_FUNC(RFID, RawData)
-LV_NULL_FUNC(RFID, TagAdvanced)
-LV_NULL_FUNC(RFID, TagLostAdvanced)
+LV_NULL_FUNC(RFID, Tag2)
+LV_NULL_FUNC(RFID, TagLost2)
LV_NULL_FUNC(Servo, PositionChange)
diff --git a/labview/phidget_labview.h b/labview/phidget_labview.h index fa96571..fff459d 100644 --- a/labview/phidget_labview.h +++ b/labview/phidget_labview.h @@ -255,13 +255,13 @@ typedef struct _lvIRLearn { } lvIRLearn;
/**
- * Used for Labview events that return an rfid tag (advanced)
+ * Used for Labview events that return an rfid tag (v2)
*/
-typedef struct _lvRFIDTagAdvanced {
- int32 nothing; /**< Not Used */
+typedef struct _lvRFIDTag2 {
LStrHandle val1; /**< Tag String */
- CPhidgetRFID_TagInfo val2; /**< tag properties */
-} lvRFIDTagAdvanced;
+ CPhidgetRFID_Protocol val2; /**< tag protocol */
+ int32 nothing; /**< Not Used */
+} lvRFIDTag2;
/**
* Used for Labview events that return spatial data
@@ -550,19 +550,19 @@ LV_CHDREVENT(RFID, TagLost) */
LV_CHDREVENT(RFID, RawData)
/**
- * Sets up a Labview event callback for the TagAdvanced event.
- * Event callback returns an \ref _lvRFIDTagAdvanced.
+ * Sets up a Labview event callback for the Tag2 event.
+ * Event callback returns an \ref _lvRFIDTag2.
* @param phid An attached phidget handle.
* @param lvEventRef Lavbiew user event ref
*/
-LV_CHDREVENT(RFID, TagAdvanced)
+LV_CHDREVENT(RFID, Tag2)
/**
- * Sets up a Labview event callback for the TagLostAdvanced event.
- * Event callback returns an \ref _lvRFIDTagAdvanced.
+ * Sets up a Labview event callback for the TagLost2 event.
+ * Event callback returns an \ref _lvRFIDTag2.
* @param phid An attached phidget handle.
* @param lvEventRef Lavbiew user event ref
*/
-LV_CHDREVENT(RFID, TagLostAdvanced)
+LV_CHDREVENT(RFID, TagLost2)
/**
* Sets up a Labview event callback for the PositionChange event.
diff --git a/linux/cusblinux-1.0.c b/linux/cusblinux-1.0.c index 0e3a5e8..8ac2381 100644 --- a/linux/cusblinux-1.0.c +++ b/linux/cusblinux-1.0.c @@ -540,7 +540,7 @@ int CUSBBuildList(CPhidgetList **curList) { } //if(udev) else { - LOG(PHIDGET_LOG_WARNING, "libusb_open failed with error code: %d", ret); + LOG(PHIDGET_LOG_WARNING, "libusb_open failed in CUSBBuildList with error code: %d", ret); LOG(PHIDGET_LOG_INFO, "This usually means you need to run as root, or install the udev rules."); free(phid); libusb_close(handle); @@ -748,7 +748,7 @@ int CUSBOpenHandle(CPhidgetHandle phid) } /* udev open */ else { - LOG(PHIDGET_LOG_WARNING, "libusb_open failed with error code: %d", ret); + LOG(PHIDGET_LOG_WARNING, "libusb_open failed in CUSBOpenHandle with error code: %d", ret); LOG(PHIDGET_LOG_INFO, "This usually means you need to run as root, or install the udev rules."); libusb_close(handle); } diff --git a/phidget21.h b/phidget21.h index 6793b3f..3a85c04 100644 --- a/phidget21.h +++ b/phidget21.h @@ -1,3 +1,6 @@ +#ifndef PHIDGET_H +#define PHIDGET_H + #ifdef __cplusplus extern "C" { #endif @@ -70,6 +73,7 @@ typedef enum { PHIDID_MOTORCONTROL_1MOTOR = 0x03E, PHIDID_MOTORCONTROL_HC_2MOTOR = 0x059, PHIDID_RFID_2OUTPUT = 0x031, + PHIDID_RFID_2OUTPUT_READ_WRITE = 0x034, PHIDID_ROTARY_TOUCH = 0x077, PHIDID_SPATIAL_ACCEL_3AXIS = 0x07F, PHIDID_SPATIAL_ACCEL_GYRO_COMPASS = 0x033, @@ -147,7 +151,7 @@ typedef enum { PHIDUID_RFID, PHIDUID_RFID_2OUTPUT_NO_ECHO, PHIDUID_RFID_2OUTPUT, - PHIDUID_RFID_2OUTPUT_ADVANCED, + PHIDUID_RFID_2OUTPUT_READ_WRITE, PHIDUID_SERVO_1MOTOR_OLD, PHIDUID_SERVO_4MOTOR_OLD, PHIDUID_SERVO_1MOTOR_NO_ECHO, @@ -557,12 +561,14 @@ typedef enum { PHIDGET_LED_VOLTAGE_5_0V } CPhidgetLED_Voltage; int CPhidgetLED_getLEDCount(CPhidgetLEDHandle phid, int *count); - int CPhidgetLED_getDiscreteLED(CPhidgetLEDHandle phid, int index, int *brightness); - int CPhidgetLED_setDiscreteLED(CPhidgetLEDHandle phid, int index, int brightness); int CPhidgetLED_getCurrentLimit(CPhidgetLEDHandle phid, CPhidgetLED_CurrentLimit *currentLimit); int CPhidgetLED_setCurrentLimit(CPhidgetLEDHandle phid, CPhidgetLED_CurrentLimit currentLimit); int CPhidgetLED_getVoltage(CPhidgetLEDHandle phid, CPhidgetLED_Voltage *voltage); int CPhidgetLED_setVoltage(CPhidgetLEDHandle phid, CPhidgetLED_Voltage voltage); + int CPhidgetLED_getBrightness(CPhidgetLEDHandle phid, int index, double *brightness); + int CPhidgetLED_setBrightness(CPhidgetLEDHandle phid, int index, double brightness); + int CPhidgetLED_getCurrentLimitIndexed(CPhidgetLEDHandle phid, int index, double *limit); + int CPhidgetLED_setCurrentLimitIndexed(CPhidgetLEDHandle phid, int index, double limit); typedef struct _CPhidgetMotorControl *CPhidgetMotorControlHandle; int CPhidgetMotorControl_create(CPhidgetMotorControlHandle *phid); int CPhidgetMotorControl_getMotorCount(CPhidgetMotorControlHandle phid, int *count); @@ -611,6 +617,11 @@ typedef struct _CPhidgetPHSensor *CPhidgetPHSensorHandle; int CPhidgetPHSensor_setTemperature(CPhidgetPHSensorHandle phid, double temperature); typedef struct _CPhidgetRFID *CPhidgetRFIDHandle; int CPhidgetRFID_create(CPhidgetRFIDHandle *phid); +typedef enum { + PHIDGET_RFID_PROTOCOL_EM4100 = 1, + PHIDGET_RFID_PROTOCOL_ISO11785_FDX_B, + PHIDGET_RFID_PROTOCOL_PHIDGETS, +} CPhidgetRFID_Protocol; int CPhidgetRFID_getOutputCount(CPhidgetRFIDHandle phid, int *count); int CPhidgetRFID_getOutputState(CPhidgetRFIDHandle phid, int index, int *outputState); int CPhidgetRFID_setOutputState(CPhidgetRFIDHandle phid, int index, int outputState); @@ -619,10 +630,11 @@ typedef struct _CPhidgetRFID *CPhidgetRFIDHandle; int CPhidgetRFID_setAntennaOn(CPhidgetRFIDHandle phid, int antennaState); int CPhidgetRFID_getLEDOn(CPhidgetRFIDHandle phid, int *LEDState); int CPhidgetRFID_setLEDOn(CPhidgetRFIDHandle phid, int LEDState); - int CPhidgetRFID_getLastTag(CPhidgetRFIDHandle phid, unsigned char *tag); + int CPhidgetRFID_getLastTag2(CPhidgetRFIDHandle phid, char **tagString, CPhidgetRFID_Protocol *protocol); int CPhidgetRFID_getTagStatus(CPhidgetRFIDHandle phid, int *status); - int CPhidgetRFID_set_OnTag_Handler(CPhidgetRFIDHandle phid, int ( *fptr)(CPhidgetRFIDHandle phid, void *userPtr, unsigned char *tag), void *userPtr); - int CPhidgetRFID_set_OnTagLost_Handler(CPhidgetRFIDHandle phid, int ( *fptr)(CPhidgetRFIDHandle phid, void *userPtr, unsigned char *tag), void *userPtr); + int CPhidgetRFID_write(CPhidgetRFIDHandle phid, char *tagString, CPhidgetRFID_Protocol protocol, int lock); + int CPhidgetRFID_set_OnTag2_Handler(CPhidgetRFIDHandle phid, int ( *fptr)(CPhidgetRFIDHandle phid, void *userPtr, char *tagString, CPhidgetRFID_Protocol protocol), void *userPtr); + int CPhidgetRFID_set_OnTagLost2_Handler(CPhidgetRFIDHandle phid, int ( *fptr)(CPhidgetRFIDHandle phid, void *userPtr, char *tagString, CPhidgetRFID_Protocol protocol), void *userPtr); typedef struct _CPhidgetServo *CPhidgetServoHandle; int CPhidgetServo_create(CPhidgetServoHandle *phid); int CPhidgetServo_getMotorCount(CPhidgetServoHandle phid, int *count); @@ -862,3 +874,4 @@ typedef struct _CPhidgetWeightSensor *CPhidgetWeightSensorHandle; #ifdef __cplusplus } #endif +#endif
\ No newline at end of file @@ -124,6 +124,7 @@ #define snprintf _snprintf #define strtoll (__int64)_strtoi64 + #define strtoull (__int64)_strtoui64 #define CCONV __stdcall #define CCONV_CDECL __cdecl @@ -206,8 +207,6 @@ #define SOCKET_ERROR -1 #endif typedef void *OVERLAPPED; - //typedef long long __int64; - typedef unsigned long long __uint64; typedef struct timeval TIME; @@ -1,2 +1,2 @@ #!/bin/bash -echo -n 2.1.8.20120912 +echo -n 2.1.8.20121218 |