Copyright | © Patrick Pelletier 2017 |
---|---|
License | MIT |
Maintainer | code@funwithsoftware.org |
Portability | POSIX, Windows |
Safe Haskell | None |
Language | Haskell2010 |
This module is a Haskell binding to the "Mercury API" C API for
ThingMagic RFID readers. It is especially geared toward the
SparkFun Simultaneous RFID Reader,
which uses ThingMagic's M6e Nano module, but it should work with other
ThingMagic readers. (Though currently, only support for serial readers
is compiled in.) Most of the function and type names are the same as
their counterparts in the C API, with the TMR_
prefix dropped. For more
in-depth, language-independent documentation of Mercury API, see
Mercury API Programmers Guide.
This module is intended to be imported qualified
, e. g.
import qualified System.Hardware.MercuryApi as TMR
- create :: Text -> IO Reader
- connect :: Reader -> IO ()
- read :: Reader -> Word32 -> IO [TagReadData]
- executeTagOp :: Reader -> TagOp -> Maybe TagFilter -> IO ByteString
- reboot :: Reader -> IO ()
- destroy :: Reader -> IO ()
- withReader :: Text -> (Reader -> IO a) -> IO a
- paramList :: Reader -> IO [Param]
- paramGet :: ParamValue a => Reader -> Param -> IO a
- paramSet :: ParamValue a => Reader -> Param -> a -> IO ()
- paramSetBasics :: Reader -> Region -> Int32 -> [AntennaPort] -> IO ()
- paramSetReadPlanFilter :: Reader -> Maybe TagFilter -> IO ()
- paramSetReadPlanTagop :: Reader -> Maybe TagOp -> IO ()
- addTransportListener :: Reader -> TransportListener -> IO TransportListenerId
- removeTransportListener :: Reader -> TransportListenerId -> IO ()
- gpiGet :: Reader -> IO [GpioPin]
- gpoSet :: Reader -> [GpioPin] -> IO ()
- firmwareLoad :: Reader -> ByteString -> IO ()
- firmwareLoadFile :: Reader -> FilePath -> IO ()
- hexListener :: Handle -> IO TransportListener
- opcodeListener :: Handle -> IO TransportListener
- packBytesIntoWords :: ByteString -> [Word16]
- passwordToWords :: GEN2_Password -> [Word16]
- mkFilterGen2 :: GEN2_Bank -> Word32 -> ByteString -> TagFilter
- paramName :: Param -> Text
- paramID :: Text -> Param
- paramType :: Param -> ParamType
- paramUnits :: Param -> Maybe Text
- bytesToHex :: ByteString -> Text
- bytesToHexWithSpaces :: ByteString -> Text
- hexToBytes :: Text -> Maybe ByteString
- displayTimestamp :: MillisecondsSinceEpoch -> Text
- displayLocalTimestamp :: MillisecondsSinceEpoch -> IO Text
- displayData :: ByteString -> [Text]
- displayGpio :: [GpioPin] -> [Text]
- displayTagData :: TagData -> [Text]
- displayTagReadData :: TagReadData -> [Text]
- displayParamType :: ParamType -> Text
- displayRegion :: Region -> Text
- displayRegionDescription :: Region -> Text
- parseRegion :: Text -> Maybe Region
- apiVersion :: Text
- sparkFunAntennas :: [AntennaPort]
- defaultReadPlan :: ReadPlan
- killPasswordAddress :: Word32
- accessPasswordAddress :: Word32
- data Reader
- class ParamValue a
- data TransportListenerId
- type TransportListener = TransportDirection -> ByteString -> Word32 -> IO ()
- type PinNumber = Word8
- type AntennaPort = Word8
- type GEN2_Password = Word32
- type MillisecondsSinceEpoch = Word64
- data MercuryException = MercuryException {
- meStatusType :: StatusType
- meStatus :: Status
- meMessage :: Text
- meLocation :: Text
- meParam :: Text
- meUri :: Text
- data ReadPlan = SimpleReadPlan {
- rpWeight :: !Word32
- rpEnableAutonomousRead :: !Bool
- rpAntennas :: ![AntennaPort]
- rpProtocol :: !TagProtocol
- rpFilter :: !(Maybe TagFilter)
- rpTagop :: !(Maybe TagOp)
- rpUseFastSearch :: !Bool
- rpStopOnCount :: !(Maybe Word32)
- rpTriggerRead :: !(Maybe [Word8])
- data TagOp
- = TagOp_GEN2_ReadData {
- opBank :: !GEN2_Bank
- opExtraBanks :: ![GEN2_Bank]
- opWordAddress :: !Word32
- opLen :: !Word8
- | TagOp_GEN2_WriteTag { }
- | TagOp_GEN2_WriteData { }
- | TagOp_GEN2_Lock {
- opMask :: ![GEN2_LockBits]
- opAction :: ![GEN2_LockBits]
- opAccessPassword :: !GEN2_Password
- | TagOp_GEN2_Kill { }
- | TagOp_GEN2_BlockWrite { }
- | TagOp_GEN2_BlockErase { }
- | TagOp_GEN2_BlockPermaLock {
- opBank :: !GEN2_Bank
- opBlockPtr :: !Word32
- opReadWrite :: !ReadWrite
- = TagOp_GEN2_ReadData {
- data TagFilter
- = TagFilterEPC TagData
- | TagFilterGen2 {
- tfInvert :: !Bool
- tfFilterOn :: !FilterOn
- tfBitPointer :: !Word32
- tfMaskBitLength :: !Word16
- tfMask :: !ByteString
- data FilterOn
- data TagReadData = TagReadData {
- trTag :: !TagData
- trMetadataFlags :: ![MetadataFlag]
- trPhase :: !Word16
- trAntenna :: !AntennaPort
- trGpio :: ![GpioPin]
- trReadCount :: !Word32
- trRssi :: !Int32
- trFrequency :: !Word32
- trTimestamp :: !MillisecondsSinceEpoch
- trData :: !ByteString
- trEpcMemData :: !ByteString
- trTidMemData :: !ByteString
- trUserMemData :: !ByteString
- trReservedMemData :: !ByteString
- data GpioPin = GpioPin {}
- data TagData = TagData {
- tdEpc :: !ByteString
- tdProtocol :: !TagProtocol
- tdCrc :: !Word16
- tdGen2 :: !(Maybe GEN2_TagData)
- newtype GEN2_TagData = GEN2_TagData {
- g2Pc :: ByteString
- data ReadWrite
- data StatusType
- data Status
- = SUCCESS
- | ERROR_MSG_WRONG_NUMBER_OF_DATA
- | ERROR_INVALID_OPCODE
- | ERROR_UNIMPLEMENTED_OPCODE
- | ERROR_MSG_POWER_TOO_HIGH
- | ERROR_MSG_INVALID_FREQ_RECEIVED
- | ERROR_MSG_INVALID_PARAMETER_VALUE
- | ERROR_MSG_POWER_TOO_LOW
- | ERROR_UNIMPLEMENTED_FEATURE
- | ERROR_INVALID_BAUD_RATE
- | ERROR_INVALID_REGION
- | ERROR_INVALID_LICENSE_KEY
- | ERROR_BL_INVALID_IMAGE_CRC
- | ERROR_BL_INVALID_APP_END_ADDR
- | ERROR_FLASH_BAD_ERASE_PASSWORD
- | ERROR_FLASH_BAD_WRITE_PASSWORD
- | ERROR_FLASH_UNDEFINED_SECTOR
- | ERROR_FLASH_ILLEGAL_SECTOR
- | ERROR_FLASH_WRITE_TO_NON_ERASED_AREA
- | ERROR_FLASH_WRITE_TO_ILLEGAL_SECTOR
- | ERROR_FLASH_VERIFY_FAILED
- | ERROR_NO_TAGS_FOUND
- | ERROR_NO_PROTOCOL_DEFINED
- | ERROR_INVALID_PROTOCOL_SPECIFIED
- | ERROR_WRITE_PASSED_LOCK_FAILED
- | ERROR_PROTOCOL_NO_DATA_READ
- | ERROR_AFE_NOT_ON
- | ERROR_PROTOCOL_WRITE_FAILED
- | ERROR_NOT_IMPLEMENTED_FOR_THIS_PROTOCOL
- | ERROR_PROTOCOL_INVALID_WRITE_DATA
- | ERROR_PROTOCOL_INVALID_ADDRESS
- | ERROR_GENERAL_TAG_ERROR
- | ERROR_DATA_TOO_LARGE
- | ERROR_PROTOCOL_INVALID_KILL_PASSWORD
- | ERROR_PROTOCOL_KILL_FAILED
- | ERROR_PROTOCOL_BIT_DECODING_FAILED
- | ERROR_PROTOCOL_INVALID_EPC
- | ERROR_PROTOCOL_INVALID_NUM_DATA
- | ERROR_GEN2_PROTOCOL_OTHER_ERROR
- | ERROR_GEN2_PROTOCOL_MEMORY_OVERRUN_BAD_PC
- | ERROR_GEN2_PROTOCOL_MEMORY_LOCKED
- | ERROR_GEN2_PROTOCOL_V2_AUTHEN_FAILED
- | ERROR_GEN2_PROTOCOL_V2_UNTRACE_FAILED
- | ERROR_GEN2_PROTOCOL_INSUFFICIENT_POWER
- | ERROR_GEN2_PROTOCOL_NON_SPECIFIC_ERROR
- | ERROR_GEN2_PROTOCOL_UNKNOWN_ERROR
- | ERROR_AHAL_INVALID_FREQ
- | ERROR_AHAL_CHANNEL_OCCUPIED
- | ERROR_AHAL_TRANSMITTER_ON
- | ERROR_ANTENNA_NOT_CONNECTED
- | ERROR_TEMPERATURE_EXCEED_LIMITS
- | ERROR_HIGH_RETURN_LOSS
- | ERROR_INVALID_ANTENNA_CONFIG
- | ERROR_TAG_ID_BUFFER_NOT_ENOUGH_TAGS_AVAILABLE
- | ERROR_TAG_ID_BUFFER_FULL
- | ERROR_TAG_ID_BUFFER_REPEATED_TAG_ID
- | ERROR_TAG_ID_BUFFER_NUM_TAG_TOO_LARGE
- | ERROR_TAG_ID_BUFFER_AUTH_REQUEST
- | ERROR_SYSTEM_UNKNOWN_ERROR
- | ERROR_TM_ASSERT_FAILED
- | ERROR_TIMEOUT
- | ERROR_NO_HOST
- | ERROR_LLRP
- | ERROR_PARSE
- | ERROR_DEVICE_RESET
- | ERROR_CRC_ERROR
- | ERROR_INVALID
- | ERROR_UNIMPLEMENTED
- | ERROR_UNSUPPORTED
- | ERROR_NO_ANTENNA
- | ERROR_READONLY
- | ERROR_TOO_BIG
- | ERROR_NO_THREADS
- | ERROR_NO_TAGS
- | ERROR_NOT_FOUND
- | ERROR_FIRMWARE_FORMAT
- | ERROR_TRYAGAIN
- | ERROR_OUT_OF_MEMORY
- | ERROR_INVALID_WRITE_MODE
- | ERROR_ILLEGAL_VALUE
- | ERROR_END_OF_READING
- | ERROR_UNSUPPORTED_READER_TYPE
- | ERROR_BUFFER_OVERFLOW
- | ERROR_LOADSAVE_CONFIG
- | ERROR_AUTOREAD_ENABLED
- | ERROR_FIRMWARE_UPDATE_ON_AUTOREAD
- | ERROR_TIMESTAMP_NULL
- | ERROR_LLRP_GETTYPEREGISTRY
- | ERROR_LLRP_CONNECTIONFAILED
- | ERROR_LLRP_SENDIO_ERROR
- | ERROR_LLRP_RECEIVEIO_ERROR
- | ERROR_LLRP_RECEIVE_TIMEOUT
- | ERROR_LLRP_MSG_PARSE_ERROR
- | ERROR_LLRP_ALREADY_CONNECTED
- | ERROR_LLRP_INVALID_RFMODE
- | ERROR_LLRP_UNDEFINED_VALUE
- | ERROR_LLRP_READER_ERROR
- | ERROR_LLRP_READER_CONNECTION_LOST
- | ERROR_LLRP_CLIENT_CONNECTION_EXISTS
- | ERROR_ALREADY_DESTROYED
- | ERROR_INVALID_PARAM_TYPE
- | ERROR_UNIMPLEMENTED_PARAM
- | ERROR_UNKNOWN Word32
- data Param
- = PARAM_NONE
- | PARAM_BAUDRATE
- | PARAM_COMMANDTIMEOUT
- | PARAM_CURRENTTIME
- | PARAM_READER_DESCRIPTION
- | PARAM_EXTENDEDEPC
- | PARAM_READER_HOSTNAME
- | PARAM_LICENSE_KEY
- | PARAM_LICENSED_FEATURES
- | PARAM_METADATAFLAG
- | PARAM_POWERMODE
- | PARAM_PROBEBAUDRATES
- | PARAM_READER_STATISTICS
- | PARAM_READER_STATS
- | PARAM_TRANSPORTTIMEOUT
- | PARAM_URI
- | PARAM_USER_CONFIG
- | PARAM_USERMODE
- | PARAM_ANTENNA_CHECKPORT
- | PARAM_ANTENNA_CONNECTEDPORTLIST
- | PARAM_ANTENNA_PORTLIST
- | PARAM_ANTENNA_PORTSWITCHGPOS
- | PARAM_ANTENNA_RETURNLOSS
- | PARAM_ANTENNA_SETTLINGTIMELIST
- | PARAM_ANTENNA_TXRXMAP
- | PARAM_GEN2_BLF
- | PARAM_GEN2_ACCESSPASSWORD
- | PARAM_GEN2_BAP
- | PARAM_GEN2_PROTOCOLEXTENSION
- | PARAM_GEN2_Q
- | PARAM_GEN2_SESSION
- | PARAM_GEN2_TAGENCODING
- | PARAM_GEN2_TARGET
- | PARAM_GEN2_TARI
- | PARAM_READER_WRITE_EARLY_EXIT
- | PARAM_GEN2_WRITEMODE
- | PARAM_READER_WRITE_REPLY_TIMEOUT
- | PARAM_GPIO_INPUTLIST
- | PARAM_GPIO_OUTPUTLIST
- | PARAM_ISO180006B_BLF
- | PARAM_ISO180006B_DELIMITER
- | PARAM_ISO180006B_MODULATION_DEPTH
- | PARAM_RADIO_ENABLEPOWERSAVE
- | PARAM_RADIO_ENABLESJC
- | PARAM_RADIO_PORTREADPOWERLIST
- | PARAM_RADIO_PORTWRITEPOWERLIST
- | PARAM_RADIO_POWERMAX
- | PARAM_RADIO_POWERMIN
- | PARAM_RADIO_READPOWER
- | PARAM_RADIO_TEMPERATURE
- | PARAM_RADIO_WRITEPOWER
- | PARAM_READ_ASYNCOFFTIME
- | PARAM_READ_ASYNCONTIME
- | PARAM_READ_PLAN
- | PARAM_REGION_HOPTABLE
- | PARAM_REGION_HOPTIME
- | PARAM_REGION_ID
- | PARAM_REGION_SUPPORTEDREGIONS
- | PARAM_REGION_LBT_ENABLE
- | PARAM_READER_STATS_ENABLE
- | PARAM_STATUS_ENABLE_ANTENNAREPORT
- | PARAM_STATUS_ENABLE_FREQUENCYREPORT
- | PARAM_STATUS_ENABLE_TEMPERATUREREPORT
- | PARAM_TAGREADDATA_ENABLEREADFILTER
- | PARAM_TAGREADDATA_READFILTERTIMEOUT
- | PARAM_TAGREADDATA_RECORDHIGHESTRSSI
- | PARAM_TAGREADDATA_REPORTRSSIINDBM
- | PARAM_TAGREADATA_TAGOPFAILURECOUNT
- | PARAM_TAGREADATA_TAGOPSUCCESSCOUNT
- | PARAM_TAGREADDATA_UNIQUEBYANTENNA
- | PARAM_TAGREADDATA_UNIQUEBYDATA
- | PARAM_TAGREADDATA_UNIQUEBYPROTOCOL
- | PARAM_TAGOP_ANTENNA
- | PARAM_TAGOP_PROTOCOL
- | PARAM_TRIGGER_READ_GPI
- | PARAM_VERSION_HARDWARE
- | PARAM_VERSION_MODEL
- | PARAM_PRODUCT_GROUP
- | PARAM_PRODUCT_GROUP_ID
- | PARAM_PRODUCT_ID
- | PARAM_VERSION_SERIAL
- | PARAM_VERSION_SOFTWARE
- | PARAM_VERSION_SUPPORTEDPROTOCOLS
- | PARAM_SELECTED_PROTOCOLS
- data ParamType
- = ParamTypeBool
- | ParamTypeGEN2_WriteMode
- | ParamTypeInt16
- | ParamTypeInt32
- | ParamTypeInt8
- | ParamTypeMetadataFlagList
- | ParamTypePowerMode
- | ParamTypeReadPlan
- | ParamTypeRegion
- | ParamTypeRegionList
- | ParamTypeTagProtocol
- | ParamTypeTagProtocolList
- | ParamTypeText
- | ParamTypeWord16
- | ParamTypeWord32
- | ParamTypeWord32List
- | ParamTypeWord8
- | ParamTypeWord8List
- | ParamTypeUnimplemented
- data Region
- data TagProtocol
- data MetadataFlag
- data GEN2_Bank
- data GEN2_LockBits
- data GEN2_WriteMode
- data PowerMode
- data TransportDirection
Reader
:: Text | a reader URI, such as |
-> IO Reader |
Create a new Reader
with the specified URI. The reader is
not contacted at this point. On Mac OS X, be sure to use the
serial device that starts with cu.
, not the one that starts with
tty.
.
connect :: Reader -> IO () Source #
Establishes the connection to the reader at the URI specified in
the create
call. The existence of a reader at the address is
verified and the reader is brought into a state appropriate for
performing RF operations.
:: Reader | The reader being operated on |
-> Word32 | The number of milliseconds to search for tags |
-> IO [TagReadData] |
Search for tags for a fixed duration. Follows the ReadPlan
stored in PARAM_READ_PLAN
.
executeTagOp :: Reader -> TagOp -> Maybe TagFilter -> IO ByteString Source #
Directly executes a TagOp
command.
Operates on the first tag found, with applicable tag filtering.
The call returns immediately after finding one tag
and operating on it, unless the command timeout expires first.
The operation is performed on the antenna specified in the
PARAM_TAGOP_ANTENNA
parameter.
PARAM_TAGOP_PROTOCOL
specifies the protocol to be used.
Some TagOps return data, while others will just return an
empty ByteString
.
destroy :: Reader -> IO () Source #
Closes the connection to the reader and releases any resources
that have been consumed by the reader structure. Any further
operations performed on the reader will fail with
ERROR_ALREADY_DESTROYED
. On finalization of the Reader
,
destroy
will be called automatically if it has not already been called.
:: Text | a reader URI, such as |
-> (Reader -> IO a) | computation to run with Reader |
-> IO a |
Create a new Reader
with the specified URI, pass it to the given
computation, and destroy it when the computation exits.
Parameters
Although paramGet
and paramSet
are very flexible, they only
check that the parameter type is correct at runtime. You may
prefer to use the functions in System.Hardware.MercuryApi.Params,
which ensure the correct type at compile time.
paramGet :: ParamValue a => Reader -> Param -> IO a Source #
Gets the value of a reader parameter. Throws MercuryException
with a meStatus
of ERROR_INVALID_PARAM_TYPE
if the parameter value
is not of the correct type (sadly, this is only checked at runtime) or
ERROR_UNIMPLEMENTED_PARAM
if the parameter has not yet been implemented
in the Haskell binding. Can also propagate errors from the C API, such
as ERROR_UNSUPPORTED
.
paramSet :: ParamValue a => Reader -> Param -> a -> IO () Source #
Sets the value of a reader parameter. Throws MercuryException
with a meStatus
of ERROR_INVALID_PARAM_TYPE
if the parameter value
is not of the correct type (sadly, this is only checked at runtime) or
ERROR_UNIMPLEMENTED_PARAM
if the parameter has not yet been implemented
in the Haskell binding. Can also propagate errors from the C API, such
as ERROR_UNSUPPORTED
or ERROR_READONLY
.
:: Reader | The reader being operated on |
-> Region | The region |
-> Int32 | Power in centi-dBm |
-> [AntennaPort] | Antenna list |
-> IO () |
Convenience function to set some of the most essential parameters.
The specified Region
is written into PARAM_REGION_ID
.
The specified power level is written into PARAM_RADIO_READPOWER
and PARAM_RADIO_WRITEPOWER
. The specified antenna list is
written into the rpAntennas
field of PARAM_READ_PLAN
, and the first
antenna in the list is written into PARAM_TAGOP_ANTENNA
. For the
SparkFun Simultaneous RFID Reader,
the antenna list should be sparkFunAntennas
, and if powering the reader
off USB, the power level should be 500
(5 dBm).
(Higher power levels can be used with a separate power supply.)
paramSetReadPlanFilter :: Reader -> Maybe TagFilter -> IO () Source #
Sets the rpFilter
field of the PARAM_READ_PLAN
parameter,
while leaving the rest of the read plan unchanged.
paramSetReadPlanTagop :: Reader -> Maybe TagOp -> IO () Source #
Sets the rpTagop
field of the PARAM_READ_PLAN
parameter,
while leaving the rest of the read plan unchanged.
Listeners
Transport listeners can be used to monitor the raw serial data
going to and from the reader, for debugging purposes. A listener
that prints the data to a Handle
is available from hexListener
or opcodeListener
.
:: Reader | The reader to operate on. |
-> TransportListener | The listener to call. |
-> IO TransportListenerId | A unique identifier which can be used to remove the listener later. |
Add a listener to the list of functions that will be called for each message sent to or recieved from the reader.
removeTransportListener Source #
:: Reader | The reader to operate on. |
-> TransportListenerId | The return value of a call
to |
-> IO () |
Remove a listener from the list of functions that will be called for each message sent to or recieved from the reader.
GPIO
The M6e Nano has 4 GPIO pins that can be controlled by software,
numbered 1-4. On the
SparkFun Simultaneous RFID Reader,
GPIO 1 is available on the GPIO1 pin, and GPIOs 2, 3, and 4 are available
on the LV2, LV3, and LV4 pins. The GPIO1 pin is 5V, but
the LV pins are 3.3V only.
To configure GPIOs as inputs or outputs, use PARAM_GPIO_INPUTLIST
and PARAM_GPIO_OUTPUTLIST
.
Firmware
Firmware for the M6e Nano can be obtained here.
:: Reader | The reader being operated on |
-> ByteString | The binary firmware image to install |
-> IO () |
Attempts to install firmware on the reader, then restart and reinitialize.
Like firmwareLoad
, but loads firmware from a file.
(e. g. NanoFW-1.7.1.2.sim
)
Utility functions
Listeners
hexListener :: Handle -> IO TransportListener Source #
Given a Handle
, returns a TransportListener
which prints
transport data to that handle in hex. If the handle is a terminal,
prints transmitted data in magenta and received data in cyan.
opcodeListener :: Handle -> IO TransportListener Source #
Identical to hexListener
, but also prints the opcode of each packet,
and a timestamp. (The timestamp is relative to an arbitrary point in
time, so is only useful for computing differences between timestamps.)
Data helpers
packBytesIntoWords :: ByteString -> [Word16] Source #
Convert a ByteString
into a list of Word16
, in big-endian
order. Padded with 0 if the number of bytes is odd.
passwordToWords :: GEN2_Password -> [Word16] Source #
Split a password into two 16-bit words, suitable for writing into reserved memory.
:: GEN2_Bank | The bank to filter on |
-> Word32 | The location (in bits) at which to begin comparing the mask |
-> ByteString | The mask value to compare with the specified region of tag memory |
-> TagFilter |
Create a TagFilterGen2
with the most common settings
Parameters
paramName :: Param -> Text Source #
Return the string name (e. g. "/reader/read/plan")
corresponding to a Param
.
paramID :: Text -> Param Source #
Return the Param
corresponding to a string name
(e. g. "/reader/read/plan"). Returns PARAM_NONE
if no such
parameter exists.
paramUnits :: Param -> Maybe Text Source #
For parameters which are expressed in physical units,
returns a string describing the units. Returns Nothing
for parameters which are not expressed in physical units.
This can be useful for displaying in a user interface,
for example.
Hex conversion
bytesToHex :: ByteString -> Text Source #
Convert a ByteString
, such as a tag EPC, into a hexadecimal string.
bytesToHexWithSpaces :: ByteString -> Text Source #
Like bytesToHex
, but with a space between each byte.
hexToBytes :: Text -> Maybe ByteString Source #
Convert a hexadecimal string (without spaces) into a
ByteString
. The hex string may optionally include a "0x"
prefix, which will be ignored. If the input cannot be parsed as a
hex string, returns Nothing
.
Display
Some functions to format data in a more human-friendly
format than show
.
:: MillisecondsSinceEpoch | milliseconds since 1/1/1970 UTC |
-> Text |
Convert a timestamp into ISO 8601 format in UTC.
displayLocalTimestamp Source #
:: MillisecondsSinceEpoch | milliseconds since 1/1/1970 UTC |
-> IO Text |
Convert a timestamp into ISO 8601 format in the local timezone.
displayData :: ByteString -> [Text] Source #
Format a ByteString
as 16 bytes per line, with both hex and ascii
on the line.
displayGpio :: [GpioPin] -> [Text] Source #
Convert a list of GpioPin
to a human-readable list of lines.
displayTagReadData :: TagReadData -> [Text] Source #
Convert a TagReadData
to a human-readable list of lines.
displayParamType :: ParamType -> Text Source #
A textual representation of the Haskell type corresponding
to a particular ParamType
.
displayRegion :: Region -> Text Source #
displayRegionDescription :: Region -> Text Source #
A description of the given region, useful for a user interface.
Constants
apiVersion :: Text Source #
Version number of the Mercury API C library.
sparkFunAntennas :: [AntennaPort] Source #
The constant [1]
, which is the correct value for rpAntennas
when using the
SparkFun Simultaneous RFID Reader.
defaultReadPlan :: ReadPlan Source #
The read plan that the reader starts out with by default.
This has reasonable settings for most things, except for the
antennas, which need to be set. (e. g. set rpAntennas
to
sparkFunAntennas
)
killPasswordAddress :: Word32 Source #
Word address of kill password in reserved memory.
accessPasswordAddress :: Word32 Source #
Word address of access password in reserved memory.
Types
Opaque types
An opaque type which represents a connection to an RFID reader.
Note that Reader
is not threadsafe, so if you want to use a
Reader
from more than one thread, you will need to implement
your own locking.
class ParamValue a Source #
A class for types which can be used as parameter values.
pType, pGet, pSet
data TransportListenerId Source #
An opaque type which can be passed to removeTransportListener
to remove a transport listener.
Typedefs
type TransportListener Source #
= TransportDirection | Direction of data transmission |
-> ByteString | Binary data sent or received |
-> Word32 | Timeout |
-> IO () |
A function which can be installed via addTransportListener
to be called every time Mercury API sends or receives data on
the serial port.
type AntennaPort = Word8 Source #
An antenna number. On the SparkFun Simultaneous RFID Reader, there is a single antenna with the number 1.
type GEN2_Password = Word32 Source #
A 32-bit password (access or kill) in the Gen2 protocol.
type MillisecondsSinceEpoch = Word64 Source #
milliseconds since 1/1/1970 UTC
Records
data MercuryException Source #
Represents any error that can occur in a MercuryApi call,
except for those which can be represented by IOException
.
MercuryException | |
|
A ReadPlan record specifies the antennas, protocols, and filters to use for a search (read).
Currently, only SimpleReadPlan
is supported.
SimpleReadPlan | |
|
An operation that can be performed on a tag. Can be used
as an argument to executeTagOp
,
or can be embedded into a ReadPlan
.
(However, on the M6e Nano, only TagOp_GEN2_ReadData
may be
embedded in a ReadPlan
.)
TagOp_GEN2_ReadData | |
| |
TagOp_GEN2_WriteTag | |
TagOp_GEN2_WriteData | |
TagOp_GEN2_Lock | |
| |
TagOp_GEN2_Kill | |
| |
TagOp_GEN2_BlockWrite | |
TagOp_GEN2_BlockErase | |
TagOp_GEN2_BlockPermaLock | |
|
Filter on EPC data, or on Gen2-specific information.
TagFilterEPC TagData | |
TagFilterGen2 | |
|
Filter on EPC length, or on a Gen2 bank.
data TagReadData Source #
A record to represent a read of an RFID tag. Provides access to the metadata of the read event, such as the time of the read, the antenna that read the tag, and the number of times the tag was seen by the air protocol.
TagReadData | |
|
The identity and state of a single GPIO pin.
A record to represent RFID tags.
TagData | |
|
Indicates whether to read or write the lock bits in
TagOp_GEN2_BlockPermaLock
.
Enums
data StatusType Source #
Indicates a general category of error.
SUCCESS_TYPE | |
ERROR_TYPE_COMM | |
ERROR_TYPE_CODE | |
ERROR_TYPE_MISC | |
ERROR_TYPE_LLRP | |
ERROR_TYPE_BINDING | An error which originates from the Haskell binding, not the underlying C library. |
ERROR_TYPE_UNKNOWN | Not a recognized status type |
A specific error encountered by the C API or the Haskell binding.
SUCCESS | Success! (Never thrown in an exception) |
ERROR_MSG_WRONG_NUMBER_OF_DATA | Invalid number of arguments |
ERROR_INVALID_OPCODE | Command opcode not recognized. |
ERROR_UNIMPLEMENTED_OPCODE | Command opcode recognized, but is not supported. |
ERROR_MSG_POWER_TOO_HIGH | Requested power setting is above the allowed maximum. |
ERROR_MSG_INVALID_FREQ_RECEIVED | Requested frequency is outside the allowed range. |
ERROR_MSG_INVALID_PARAMETER_VALUE | Parameter value is outside the allowed range. |
ERROR_MSG_POWER_TOO_LOW | Requested power setting is below the allowed minimum. |
ERROR_UNIMPLEMENTED_FEATURE | Command not supported. |
ERROR_INVALID_BAUD_RATE | Requested serial speed is not supported. |
ERROR_INVALID_REGION | Region is not supported. |
ERROR_INVALID_LICENSE_KEY | License key code is invalid |
ERROR_BL_INVALID_IMAGE_CRC | Firmware is corrupt: Checksum doesn't match content. |
ERROR_BL_INVALID_APP_END_ADDR | Serial protocol status code for this exception. |
ERROR_FLASH_BAD_ERASE_PASSWORD | Internal reader error. Contact support. |
ERROR_FLASH_BAD_WRITE_PASSWORD | Internal reader error. Contact support. |
ERROR_FLASH_UNDEFINED_SECTOR | Internal reader error. Contact support. |
ERROR_FLASH_ILLEGAL_SECTOR | Internal reader error. Contact support. |
ERROR_FLASH_WRITE_TO_NON_ERASED_AREA | Internal reader error. Contact support. |
ERROR_FLASH_WRITE_TO_ILLEGAL_SECTOR | Internal reader error. Contact support. |
ERROR_FLASH_VERIFY_FAILED | Internal reader error. Contact support. |
ERROR_NO_TAGS_FOUND | Reader was asked to find tags, but none were detected. |
ERROR_NO_PROTOCOL_DEFINED | RFID protocol has not been configured. |
ERROR_INVALID_PROTOCOL_SPECIFIED | Requested RFID protocol is not recognized. |
ERROR_WRITE_PASSED_LOCK_FAILED | Lock failed after write operation |
ERROR_PROTOCOL_NO_DATA_READ | Tag data was requested, but could not be read. |
ERROR_AFE_NOT_ON | AFE not on - reader not sufficiently configured |
ERROR_PROTOCOL_WRITE_FAILED | Write to tag failed. |
ERROR_NOT_IMPLEMENTED_FOR_THIS_PROTOCOL | Command is not supported in the current RFID protocol. |
ERROR_PROTOCOL_INVALID_WRITE_DATA | Data does not conform to protocol standards. |
ERROR_PROTOCOL_INVALID_ADDRESS | Requested data address is outside the valid range. |
ERROR_GENERAL_TAG_ERROR | Unknown error during RFID operation. |
ERROR_DATA_TOO_LARGE | Read Tag Data was asked for more data than it supports. |
ERROR_PROTOCOL_INVALID_KILL_PASSWORD | Incorrect password was provided to Kill Tag. |
ERROR_PROTOCOL_KILL_FAILED | Kill failed for unknown reason. |
ERROR_PROTOCOL_BIT_DECODING_FAILED | Internal reader error. Contact support. |
ERROR_PROTOCOL_INVALID_EPC | Internal reader error. Contact support. |
ERROR_PROTOCOL_INVALID_NUM_DATA | Internal reader error. Contact support. |
ERROR_GEN2_PROTOCOL_OTHER_ERROR | Internal reader error. Contact support. |
ERROR_GEN2_PROTOCOL_MEMORY_OVERRUN_BAD_PC | Internal reader error. Contact support. |
ERROR_GEN2_PROTOCOL_MEMORY_LOCKED | Internal reader error. Contact support. |
ERROR_GEN2_PROTOCOL_V2_AUTHEN_FAILED | Authentication failed with specified key. |
ERROR_GEN2_PROTOCOL_V2_UNTRACE_FAILED | Untrace operation failed. |
ERROR_GEN2_PROTOCOL_INSUFFICIENT_POWER | Internal reader error. Contact support. |
ERROR_GEN2_PROTOCOL_NON_SPECIFIC_ERROR | Internal reader error. Contact support. |
ERROR_GEN2_PROTOCOL_UNKNOWN_ERROR | Internal reader error. Contact support. |
ERROR_AHAL_INVALID_FREQ | A command was received to set a frequency outside the specified range. |
ERROR_AHAL_CHANNEL_OCCUPIED | With LBT enabled an attempt was made to set the frequency to an occupied channel. |
ERROR_AHAL_TRANSMITTER_ON | Checking antenna status while CW is on is not allowed. |
ERROR_ANTENNA_NOT_CONNECTED | Antenna not detected during pre-transmit safety test. |
ERROR_TEMPERATURE_EXCEED_LIMITS | Reader temperature outside safe range. |
ERROR_HIGH_RETURN_LOSS | Excess power detected at transmitter port, usually due to antenna tuning mismatch. |
ERROR_INVALID_ANTENNA_CONFIG | Invalid antenna configuration |
ERROR_TAG_ID_BUFFER_NOT_ENOUGH_TAGS_AVAILABLE | Asked for more tags than were available in the buffer. |
ERROR_TAG_ID_BUFFER_FULL | Too many tags are in buffer. Remove some with Get Tag ID Buffer or Clear Tag ID Buffer. |
ERROR_TAG_ID_BUFFER_REPEATED_TAG_ID | Internal error -- reader is trying to insert a duplicate tag record. Contact support. |
ERROR_TAG_ID_BUFFER_NUM_TAG_TOO_LARGE | Asked for tags than a single transaction can handle. |
ERROR_TAG_ID_BUFFER_AUTH_REQUEST | Blocked response to get additional data from host. |
ERROR_SYSTEM_UNKNOWN_ERROR | Internal reader error. Contact support. |
ERROR_TM_ASSERT_FAILED | Internal reader error. Contact support. |
ERROR_TIMEOUT | Timeout |
ERROR_NO_HOST | No matching host found |
ERROR_LLRP | LLRP error |
ERROR_PARSE | Error parsing device response |
ERROR_DEVICE_RESET | Device was reset externally |
ERROR_CRC_ERROR | CRC Error |
ERROR_INVALID | Invalid argument |
ERROR_UNIMPLEMENTED | Unimplemented operation |
ERROR_UNSUPPORTED | Unsupported operation |
ERROR_NO_ANTENNA | No antenna or invalid antenna |
ERROR_READONLY | Value is read-only |
ERROR_TOO_BIG | Value too big |
ERROR_NO_THREADS | Thread initialization failed |
ERROR_NO_TAGS | No tags to be retrieved |
ERROR_NOT_FOUND | Key not found |
ERROR_FIRMWARE_FORMAT | Size or format of firmware image is incorrect |
ERROR_TRYAGAIN | Temporary error, try again |
ERROR_OUT_OF_MEMORY | Out of memory |
ERROR_INVALID_WRITE_MODE | Invalid write mode |
ERROR_ILLEGAL_VALUE | Illegal value |
ERROR_END_OF_READING | |
ERROR_UNSUPPORTED_READER_TYPE | Unsupported reader type |
ERROR_BUFFER_OVERFLOW | Buffer overflow |
ERROR_LOADSAVE_CONFIG | |
ERROR_AUTOREAD_ENABLED | Autonomous mode is enabled on reader. Please disable it |
ERROR_FIRMWARE_UPDATE_ON_AUTOREAD | Firmware update is successful. Autonomous mode is already enabled on reader |
ERROR_TIMESTAMP_NULL | Timestamp cannot be null |
ERROR_LLRP_GETTYPEREGISTRY | LLRP Reader GetTypeRegistry Failed |
ERROR_LLRP_CONNECTIONFAILED | LLRP Reader Connection attempt is failed |
ERROR_LLRP_SENDIO_ERROR | LLRP Reader Send Messages failed |
ERROR_LLRP_RECEIVEIO_ERROR | LLRP Reader Receive Messages failed |
ERROR_LLRP_RECEIVE_TIMEOUT | LLRP Reader Receive Messages Timeout |
ERROR_LLRP_MSG_PARSE_ERROR | Error parsing LLRP message |
ERROR_LLRP_ALREADY_CONNECTED | Already connected to reader |
ERROR_LLRP_INVALID_RFMODE | Specified RF Mode operation is not supported |
ERROR_LLRP_UNDEFINED_VALUE | Undefined Value |
ERROR_LLRP_READER_ERROR | LLRP reader unknown error |
ERROR_LLRP_READER_CONNECTION_LOST | LLRP reader connection lost |
ERROR_LLRP_CLIENT_CONNECTION_EXISTS | LLRP Reader Connection attempt is failed, A Client initiated connection already exists |
ERROR_ALREADY_DESTROYED | Attempt to use reader after it was destroyed. |
ERROR_INVALID_PARAM_TYPE | The parameter value was not of the type expected. |
ERROR_UNIMPLEMENTED_PARAM | The given parameter is not yet implemented in the Haskell binding. |
ERROR_UNKNOWN Word32 | C API returned an unrecognized status code |
Reader parameters which you can get and set. The names are the same as the names of the enum in the C API. (Unfortunately, these do not correspond to the "path"-style names in any systematic way.) Each parameter is listed with its "path", and the Haskell type which is used to store it. Some parameters are also listed with the physical units the parameter is in. Not all parameters are implemented in the Haskell binding. Please file a Github issue if there is a parameter you need which is not implemented.
PARAM_NONE | No such parameter - used as a return value from |
PARAM_BAUDRATE |
|
PARAM_COMMANDTIMEOUT |
|
PARAM_CURRENTTIME |
|
PARAM_READER_DESCRIPTION |
|
PARAM_EXTENDEDEPC |
|
PARAM_READER_HOSTNAME |
|
PARAM_LICENSE_KEY |
|
PARAM_LICENSED_FEATURES |
|
PARAM_METADATAFLAG |
|
PARAM_POWERMODE |
|
PARAM_PROBEBAUDRATES |
|
PARAM_READER_STATISTICS |
|
PARAM_READER_STATS |
|
PARAM_TRANSPORTTIMEOUT |
|
PARAM_URI |
|
PARAM_USER_CONFIG |
|
PARAM_USERMODE |
|
PARAM_ANTENNA_CHECKPORT |
|
PARAM_ANTENNA_CONNECTEDPORTLIST |
|
PARAM_ANTENNA_PORTLIST |
|
PARAM_ANTENNA_PORTSWITCHGPOS |
|
PARAM_ANTENNA_RETURNLOSS |
|
PARAM_ANTENNA_SETTLINGTIMELIST |
|
PARAM_ANTENNA_TXRXMAP |
|
PARAM_GEN2_BLF |
|
PARAM_GEN2_ACCESSPASSWORD |
|
PARAM_GEN2_BAP |
|
PARAM_GEN2_PROTOCOLEXTENSION |
|
PARAM_GEN2_Q |
|
PARAM_GEN2_SESSION |
|
PARAM_GEN2_TAGENCODING |
|
PARAM_GEN2_TARGET |
|
PARAM_GEN2_TARI |
|
PARAM_READER_WRITE_EARLY_EXIT |
|
PARAM_GEN2_WRITEMODE |
|
PARAM_READER_WRITE_REPLY_TIMEOUT |
|
PARAM_GPIO_INPUTLIST | |
PARAM_GPIO_OUTPUTLIST | |
PARAM_ISO180006B_BLF |
|
PARAM_ISO180006B_DELIMITER |
|
PARAM_ISO180006B_MODULATION_DEPTH |
|
PARAM_RADIO_ENABLEPOWERSAVE |
|
PARAM_RADIO_ENABLESJC |
|
PARAM_RADIO_PORTREADPOWERLIST |
|
PARAM_RADIO_PORTWRITEPOWERLIST |
|
PARAM_RADIO_POWERMAX |
|
PARAM_RADIO_POWERMIN |
|
PARAM_RADIO_READPOWER |
|
PARAM_RADIO_TEMPERATURE |
|
PARAM_RADIO_WRITEPOWER |
|
PARAM_READ_ASYNCOFFTIME |
|
PARAM_READ_ASYNCONTIME |
|
PARAM_READ_PLAN |
|
PARAM_REGION_HOPTABLE |
|
PARAM_REGION_HOPTIME |
|
PARAM_REGION_ID |
|
PARAM_REGION_SUPPORTEDREGIONS |
|
PARAM_REGION_LBT_ENABLE |
|
PARAM_READER_STATS_ENABLE |
|
PARAM_STATUS_ENABLE_ANTENNAREPORT |
|
PARAM_STATUS_ENABLE_FREQUENCYREPORT |
|
PARAM_STATUS_ENABLE_TEMPERATUREREPORT |
|
PARAM_TAGREADDATA_ENABLEREADFILTER |
|
PARAM_TAGREADDATA_READFILTERTIMEOUT |
|
PARAM_TAGREADDATA_RECORDHIGHESTRSSI |
|
PARAM_TAGREADDATA_REPORTRSSIINDBM |
|
PARAM_TAGREADATA_TAGOPFAILURECOUNT |
|
PARAM_TAGREADATA_TAGOPSUCCESSCOUNT |
|
PARAM_TAGREADDATA_UNIQUEBYANTENNA |
|
PARAM_TAGREADDATA_UNIQUEBYDATA |
|
PARAM_TAGREADDATA_UNIQUEBYPROTOCOL |
|
PARAM_TAGOP_ANTENNA |
|
PARAM_TAGOP_PROTOCOL |
|
PARAM_TRIGGER_READ_GPI | |
PARAM_VERSION_HARDWARE |
|
PARAM_VERSION_MODEL |
|
PARAM_PRODUCT_GROUP |
|
PARAM_PRODUCT_GROUP_ID |
|
PARAM_PRODUCT_ID |
|
PARAM_VERSION_SERIAL |
|
PARAM_VERSION_SOFTWARE |
|
PARAM_VERSION_SUPPORTEDPROTOCOLS |
|
PARAM_SELECTED_PROTOCOLS |
The Haskell data type expected for a particular parameter.
RFID regulatory regions
REGION_NONE | Unspecified region |
REGION_NA | North America |
REGION_EU | European Union |
REGION_KR | Korea |
REGION_IN | India |
REGION_JP | Japan |
REGION_PRC | People's Republic of China |
REGION_EU2 | European Union 2 |
REGION_EU3 | European Union 3 |
REGION_KR2 | Korea 2 |
REGION_PRC2 | People's Republic of China(840MHZ) |
REGION_AU | Australia |
REGION_NZ | New Zealand !!EXPERIMENTAL!! |
REGION_NA2 | Reduced FCC region |
REGION_NA3 | 5MHZ FCC band |
REGION_IS | Israel |
REGION_OPEN | Open |
data TagProtocol Source #
The protocol used by an RFID tag. Only TAG_PROTOCOL_GEN2
is supported by the M6e Nano, and therefore the Haskell
binding currently only supports that protocol.
data MetadataFlag Source #
Various metadata parameters which can be requested
in PARAM_METADATAFLAG
.
Gen2 memory banks
GEN2_BANK_RESERVED | Reserved bank (kill and access passwords) |
GEN2_BANK_EPC | EPC memory bank |
GEN2_BANK_TID | TID memory bank |
GEN2_BANK_USER | User memory bank |
data GEN2_LockBits Source #
Memory lock bits
GEN2_LOCK_BITS_USER_PERM | User memory bank lock permalock bit |
GEN2_LOCK_BITS_USER | User memory bank lock bit |
GEN2_LOCK_BITS_TID_PERM | TID memory bank lock permalock bit |
GEN2_LOCK_BITS_TID | TID memory bank lock bit |
GEN2_LOCK_BITS_EPC_PERM | EPC memory bank lock permalock bit |
GEN2_LOCK_BITS_EPC | EPC memory bank lock bit |
GEN2_LOCK_BITS_ACCESS_PERM | Access password lock permalock bit |
GEN2_LOCK_BITS_ACCESS | Access password lock bit |
GEN2_LOCK_BITS_KILL_PERM | Kill password lock permalock bit |
GEN2_LOCK_BITS_KILL | Kill password lock bit |
data GEN2_WriteMode Source #
Whether to use word write or block write for
TagOp_GEN2_WriteData
.
Value for parameter PARAM_POWERMODE
. On the M6e Nano,
POWER_MODE_MINSAVE
, POWER_MODE_MEDSAVE
, and
POWER_MODE_MAXSAVE
are all the same.
data TransportDirection Source #
The direction of data travel. Passed to TransportListener
.