📄 mprreader.cs
字号:
/// </summary>
/// <param name="sel">SL bit set to: SL, Not SL or Either.</param>
/// <param name="session">Which session to use for inventory.</param>
/// <param name="target">Target tags with session inventoried bit set to A or B.</param>
/// <param name="startingQ">Sets Q parameter for first inventory round.</param>
/// <param name="accessPassword">32-bit access password. If none in tag, set to 0x00000000.</param>
/// <param name="lockMask">Specify which of the lockAction bits to use.</param>
/// <param name="lockAction">Specify what actions to take and on which memory banks.</param>
/// <returns>An Inventory of Tags, the Data section of which includes the result of the lock.</returns>
public Inventory Gen2Lock(byte sel, byte session, byte target, byte startingQ, uint accessPassword,
ushort lockMask, ushort lockAction)
{
TagsRead = new Inventory();
byteList Params = new byteList((byte)Gen2Subcommands.Lock, ActiveAntenna, TxPower, sel, session, target, startingQ);
Params.Add(accessPassword);
Params.Add(lockMask);
Params.Add(lockAction);
MPRMsg aMsg = comm.Send(CmdCode.Gen2Command, Params);
if (!ProcMsgStat(aMsg))
return null;
return Gen2AccessParse(aMsg.DataBytes);
}
/// <summary>
/// Inventory and Kill all Tags matching the Selection and Query criteria, provided that the Kill Password matches.
/// </summary>
/// <param name="sel">SL bit set to: SL, Not SL or Either.</param>
/// <param name="session">Which session to use for inventory.</param>
/// <param name="target">Target tags with session inventoried bit set to A or B.</param>
/// <param name="startingQ">Sets Q parameter for first inventory round.</param>
/// <param name="killPassword">32-bit Kill password.</param>
/// <param name="RFU">This byte is reserved for future use and should be set to 0.</param>
/// <returns>An Inventory of Tags, the Data section of which includes the result of the kill.</returns>
public Inventory Gen2Kill(byte sel, byte session, byte target, byte startingQ, uint killPassword, byte RFU)
{
TagsRead = new Inventory();
byteList Params = new byteList((byte)Gen2Subcommands.Kill, ActiveAntenna, TxPower, sel, session, target, startingQ);
Params.Add(killPassword);
Params.Add(RFU);
MPRMsg aMsg = comm.Send(CmdCode.Gen2Command, Params);
if (!ProcMsgStat(aMsg))
return null;
return Gen2AccessParse(aMsg.DataBytes);
}
#endregion
#region Select List
/// <summary>
/// Read all Select Records in Select List.
/// </summary>
/// <returns>null if an error occurred, otherwise the current SelectList</returns>
public SelectList SelectListRead()
{
byteList Params = new byteList((byte)Gen2Subcommands.SelectRead);
MPRMsg aMsg = comm.Send(CmdCode.Gen2Command, Params);
if (!ProcMsgStat(aMsg))
return null;
return Gen2SelectListParse(aMsg.DataBytes);
}
/// <summary>
/// Add a Select Record to the Select List.
/// </summary>
/// <param name="sr">The Select Record to Add.</param>
/// <returns>-1 on Select List Full. -2 on any other error. index of newly added Select Record on success </returns>
public int SelectListAdd(SelectRecord sr)
{
byteList Params = new byteList((byte)Gen2Subcommands.SelectAdd, sr.Target, sr.Action, sr.MemBank);
Params.Add(sr.Pointer);
Params.Add(sr.Length);
Params.Add(sr.Mask);
Params.Add(sr.Truncate);
MPRMsg aMsg = comm.Send(CmdCode.Gen2Command, Params);
if (!ProcMsgStat(aMsg))
{
if (aMsg.Error == ErrorCode.Gen2SelectListFull)
return -1;
else
return -2;
} else if (aMsg.DataBytes.Count != 1) // Response should contain a single byte.
return -2;
else
return aMsg.DataBytes[0]; // Return this Select Record's new index
}
/// <summary>
/// Remove a Select Record from the Select List. Removed record at index provided.
/// </summary>
/// <param name="index">index, in Select List, of Select Record to remove.</param>
/// <returns>-1 on unknown Select List Index. -2 on any other error. 0 on success.</returns>
public int SelectListRemove(byte index)
{
MPRMsg aMsg = comm.Send(CmdCode.Gen2Command, new byteList((byte)Gen2Subcommands.SelectRemove, index));
if (!ProcMsgStat(aMsg))
{
if (aMsg.Error == ErrorCode.Gen2UnknownSelectRecord)
return -1;
else
return -2;
}
else if (aMsg.DataBytes.Count != 0) // Response should contain a single byte.
return -2;
else
return 0;
}
#endregion
#endregion
/// <summary>
/// The MPR Series Reader can be reset by twiddling with the serial port.
/// </summary>
/// <param name="EnterBootloader">Whether to enter the bootloader.</param>
public void Reset(bool EnterBootloader)
{
comm.ResetMPR(EnterBootloader);
}
#region Bootloader Commands
/// <summary>
/// A shortcut for entering the Bootloader (same as Reset(true))
/// </summary>
public void EnterBootloader()
{
Reset(true);
}
/// <summary>
///
/// </summary>
/// <returns></returns>
public bool SendEnterBootloadCommand()
{
MPRMsg aMsg = comm.Send(CmdCode.EnterBootloader, new byteList());
// There should be no response data
return ProcMsgStat(aMsg);
}
/// <summary>
/// Given a Stream, enter the bootloader
/// launch a new Thread (from the ThreadPool)
/// and send the Stream to the MPR's bootloader.
/// </summary>
/// <param name="FWStream">The Stream to send to the MPR bootloader.</param>
public void BeginBootloadFromStream(Stream FWStream)
{
// EnterBootloader();
FWStream.Seek(0, SeekOrigin.Begin);
ThreadPool.QueueUserWorkItem(new WaitCallback(BootloadFromStream), FWStream);
}
/// <summary>
/// Send each row of the Stream to the MPR bootloader.
/// Will fail if parameter oStream is not a valid Stream,
/// or MPR not already in the bootloader.
/// </summary>
/// <param name="oStream">A Stream passed as an object</param>
private void BootloadFromStream(object oStream)
{
try
{
Stream FWStream = oStream as Stream;
// Create an instance of StreamReader to read from a file.
// The using statement also closes the StreamReader.
using (StreamReader sr = new StreamReader(FWStream))
{
string line;
// Read lines from the file until the end of the file is reached.
while ((line = sr.ReadLine()) != null)
{
comm.SendBLLine(line);
}
}
}
catch (InvalidCastException) {}
}
#endregion
/// <summary>
/// A Generic pass-through method to send raw packets to the MPR.
/// </summary>
/// <param name="cmd">Any byte to be interpreted as the command.</param>
/// <param name="paramList">A list of byte parameters for the command.</param>
/// <returns>Whether a valid response is received or not.</returns>
public bool GenericCommand(byte cmd, byteList paramList)
{
MPRMsg aMsg = comm.Send((CmdCode)cmd, paramList);
// There should be no response data
return ProcMsgStat(aMsg);
}
#region GPIO
/// <summary>
///
/// </summary>
/// <param name="mask"></param>
/// <param name="direction"></param>
/// <param name="data"></param>
/// <returns></returns>
public byte GPIOcommand(byte mask, byte direction, byte data)
{
MPRMsg aMsg = comm.Send(CmdCode.GPIO, new byteList(new byte[] {mask, direction, data}));
if (ProcMsgStat(aMsg))
return aMsg.DataBytes[0];
else
return 0;
}
#endregion
/// <summary>
/// Clear the Inventory by removing all tags.
/// </summary>
public void ClearInventory()
{
lock (TagsRead)
{
// Start at end of Inventory and work back towards beginning,
// removing all expired tags.
for (int index = TagsRead.Count - 1; index >= 0; index--)
{
RFIDTag RemovedTag = TagsRead[index];
TagsRead.RemoveAt(index);
if (TagRemoved != null)
TagRemoved(RemovedTag);
}
}
}
#endregion
#region Public Properties
private int mprBootupTime = 70;
/// <summary>
/// The amount of time (milliseconds), after power-up, that the MPR
/// needs to boot before it can reply to messages on the
/// serial port.
///
/// Defaults to 50 ms.
/// </summary>
public int MPRBootupTime
{
get {return mprBootupTime;}
set {mprBootupTime = value;}
}
private byte activeAntenna = 0;
/// <summary>
/// The active antenna can be either A or B.
/// Antenna A is the left antenna port when looking down on the card, with the antenna ports facing up.
/// </summary>
public byte ActiveAntenna
{
get { return activeAntenna; }
set
{
if (activeAntenna != value)
{
activeAntenna = value;
if (ActiveAntennaChanged != null)
ActiveAntennaChanged(this, new EventArgs());
}
}
}
private byte txPower = 255;
/// <summary>
/// The Tx Power can range from 15-27 dBm for MPR5000/MPR6000,
/// and 18-30 dBm for MPR7000/MPR7100.
/// Ranges are stored in card NVS, and can be read back.
/// </summary>
public byte TxPower
{
get { return txPower; }
set
{
if (txPower != value)
{
txPower = value;
if (TxPowerChanged != null)
TxPowerChanged(this, new EventArgs());
}
}
}
private int txPowerMin = 0;
/// <summary>
/// The minimum TxPower, as read from the MPR.
/// </summary>
public int TxPowerMin { get { return txPowerMin; } }
private int txPowerMax = 255;
/// <summary>
/// The maximum TxPower, as read from the MPR.
/// </summary>
public int TxPowerMax { get { return txPowerMax; } }
/// <summary>
/// Singulation Field for Class0 commands
/// </summary>
private byte singulationField = 0;
/// <summary>
/// The Class0 Singulation Field can be 0, 1 or 2 for
/// 0 = ID0 (Generated Random ID)
/// 1 = ID1 (Static Random ID)
/// 2 = ID2 (the EPC Code itself)
/// Used by the MPR to determine how to singulate tags.
/// </summary>
public byte Class0SingulationField
{
get { return singulationField; }
set
{
if (value != singulationField)
{
singulationField = value;
if (Class0SingulationFieldChanged != null)
Class0SingulationFieldChanged(this, new EventArgs());
}
}
}
/// <summary>
/// Inventory Type for Class 1
/// </summary>
private byte class1InventoryType = 0;
/// <summary>
/// The Class 1 Inventory Type can be 0, 1 or 2 for
/// 0 = Read Tags WP
/// 1 = Read Tags
/// 2 = Read Single Tag
/// Used by the MPR to determine how to singulate Class 1 tags.
/// </summary>
public byte Class1InventoryType
{
get { return class1InventoryType; }
set
{
if (value != class1InventoryType)
{
class1InventoryType = value;
if (Class1InventoryTypeChanged != null)
Class1InventoryTypeChanged(this, new EventArgs());
}
}
}
/// <summary>
/// Tag Length Option (only used with Class 1)
/// </summary>
private TagLengthOptionEnum tagLengthOption = TagLengthOptionEnum.EPC_NoParam;//_NoParam;
/// <summary>
/// The Tag Length Option can be 0, 1, 2, 3 or -1
/// -1: Use EPC Header, but do not include parameter in command
/// 0: Use EPC Header
/// 1: Only inventory 64-bit tags
/// 2: Only inventory 96-bit tags
/// 3: Make best guess of tag ID length
/// </summary>
public TagLengthOptionEnum TagLengthOption
{
get { return tagLengthOption; }
set
{
if (value != tagLengthOption)
{
tagLengthOption = value;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -