⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mprreader.cs

📁 WJ Communications RFID example code
💻 CS
📖 第 1 页 / 共 5 页
字号:
		/// </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 + -