// Invoke the HasReadData event; called whenever the Read completes: protected virtual void OnDataReadComplete(AsyncInputReportArgs e) { if (HasReadData != null) { HasReadData(this, e); } }
// This will be called whenever the data is read from the board: private void DataReadCompleteHandler(object sender, AsyncInputReportArgs aira) { // do some quick sanity checking here to avoid exceptions: uint parkingSensorsCount = (uint)aira.InputBuffer[23]; switch (parkingSensorsCount) { case 0: case 32: case 64: break; default: return; } switch (aira.InputBuffer[9]) { case 0: case 1: break; default: return; } /* Tracer.Trace("PM Command: Async data arrived. " + DateTime.Now); StringBuilder byteValue = new StringBuilder(); byteValue.Append("DataReadCompleteHandler(): Input Report Data: "); for (int count = 0; count <= aira.InputBuffer.Length - 1; count++) { // Display bytes as 2-character Hex strings. byteValue.AppendFormat("{0:X02} ", aira.InputBuffer[count]); } Tracer.Trace(byteValue.ToString()); */ int servo1target = intFromBuffer(aira.InputBuffer, 1); int servo2target = intFromBuffer(aira.InputBuffer, 3); int ping1value = intFromBuffer(aira.InputBuffer, 5); int ping2value = intFromBuffer(aira.InputBuffer, 7); SensorsState sensState = new SensorsState(); bool fromPingScanStop = aira.InputBuffer[9] > 0; // infrared distance sensors: sensState.irbE1 = aira.InputBuffer[10]; sensState.irbE2 = aira.InputBuffer[11]; sensState.irbE3 = aira.InputBuffer[12]; sensState.irbE4 = aira.InputBuffer[13]; sensState.irbO1 = aira.InputBuffer[14]; sensState.irbO2 = aira.InputBuffer[15]; sensState.irbO3 = aira.InputBuffer[16]; sensState.irbO4 = aira.InputBuffer[17]; sensState.compassHeading = (((uint)aira.InputBuffer[18] << 8) + (uint)aira.InputBuffer[19]) / 10.0d; sensState.accelX = ProximityBoard.toAccel(aira.InputBuffer[20]); sensState.accelY = ProximityBoard.toAccel(aira.InputBuffer[21]); sensState.accelZ = ProximityBoard.toAccel(aira.InputBuffer[22]); // ultrasound car parking sensors - bytes 23 to 31 (only first 4 bytes used, next 4 are reserved for 8-sensor device): sensState.parkingSensorsCount = parkingSensorsCount; // 32 or 0 for invalid for (int i = 0; i < parkingSensorsCount / 8; i++) { sensState.parkingSensors[i] = aira.InputBuffer[24 + i]; } sensState.mapParkingSensorsData(); sensState.mapPotValueData(aira.InputBuffer[28], aira.InputBuffer[29]); // LSB, MSB // calibration for POT data (pin 2 RA0/AN0 on PIC4550): // 0v = 0 // 1v = 220 // 2v = 415 // 3v = 630 // 4v = 835 // 4.88v = 1023 AsyncInputFrameArgs args = new AsyncInputFrameArgs(servo1target, servo2target, ping1value, ping2value, fromPingScanStop, sensState); OnDataFrameComplete(args); if (inDataContinuousMode) { // initiate next read: ReadFromDevice(new EventHandler<AsyncInputReportArgs>(DataReadCompleteHandler), INPUT_CONT_REPORT_ID); } }
/// <summary> /// reads an Input report from the device using interrupt transfers. /// </summary> /// /// <param name="hidHandle"> the handle for learning about the device and exchanging Feature reports. </param> /// <param name="readHandle"> the handle for reading Input reports from the device. </param> /// <param name="writeHandle"> the handle for writing Output reports to the device. </param> /// <param name="myDeviceDetected"> tells whether the device is currently attached. </param> /// <param name="inputReportBuffer"> contains the requested report. </param> /// <param name="success"> read success </param> public override void Read(SafeFileHandle hidHandle, SafeFileHandle readHandle, SafeFileHandle writeHandle, ref Boolean myDeviceDetected, ref Byte[] inputReportBuffer, ref Boolean success) { IntPtr eventObject = IntPtr.Zero; NativeOverlapped HidOverlapped = new NativeOverlapped(); IntPtr nonManagedBuffer = IntPtr.Zero; IntPtr nonManagedOverlapped = IntPtr.Zero; Int32 numberOfBytesRead = 0; Int32 result = 0; try { // Set up the overlapped structure for ReadFile. PrepareForOverlappedTransfer( ref HidOverlapped, ref eventObject ); // Allocate memory for the input buffer and overlapped structure. nonManagedBuffer = Marshal.AllocHGlobal(inputReportBuffer.Length); nonManagedOverlapped = Marshal.AllocHGlobal(Marshal.SizeOf(HidOverlapped)); Marshal.StructureToPtr(HidOverlapped, nonManagedOverlapped, false); // *** // API function: ReadFile // Purpose: Attempts to read an Input report from the device. // Accepts: // A device handle returned by CreateFile // (for overlapped I/O, CreateFile must have been called with FILE_FLAG_OVERLAPPED), // A pointer to a buffer for storing the report. // The Input report length in bytes returned by HidP_GetCaps, // A pointer to a variable that will hold the number of bytes read. // An overlapped structure whose hEvent member is set to an event object. // Returns: the report in ReadBuffer. // The overlapped call returns immediately, even if the data hasn't been received yet. // To read multiple reports with one ReadFile, increase the size of ReadBuffer // and use NumberOfBytesRead to determine how many reports were returned. // Use a larger buffer if the application can't keep up with reading each report // individually. // *** success = FileIO.ReadFile(readHandle, nonManagedBuffer, inputReportBuffer.Length, ref numberOfBytesRead, nonManagedOverlapped); if (!success) { //Tracer.Trace("waiting for ReadFile"); // API function: WaitForSingleObject // Purpose: waits for at least one report or a timeout. // Used with overlapped ReadFile. // Accepts: // An event object created with CreateEvent // A timeout value in milliseconds. // Returns: A result code. result = FileIO.WaitForSingleObject(eventObject, 3000); // Find out if ReadFile completed or timeout. switch (result) { case (System.Int32)FileIO.WAIT_OBJECT_0: // ReadFile has completed success = true; //Tracer.Trace("ReadFile completed successfully."); // Get the number of bytes read. // API function: GetOverlappedResult // Purpose: gets the result of an overlapped operation. // Accepts: // A device handle returned by CreateFile. // A pointer to an overlapped structure. // A pointer to a variable to hold the number of bytes read. // False to return immediately. // Returns: non-zero on success and the number of bytes read. FileIO.GetOverlappedResult(readHandle, nonManagedOverlapped, ref numberOfBytesRead, false); break; case FileIO.WAIT_TIMEOUT: // Cancel the operation on timeout CancelTransfer(hidHandle, readHandle, writeHandle, eventObject); Tracer.Error("Readfile timeout"); success = false; myDeviceDetected = false; break; default: // Cancel the operation on other error. CancelTransfer(hidHandle, readHandle, writeHandle, eventObject); Tracer.Error("Readfile undefined error"); success = false; myDeviceDetected = false; break; } } if (success) { // A report was received. // Copy the received data to inputReportBuffer for the application to use. Marshal.Copy(nonManagedBuffer, inputReportBuffer, 0, numberOfBytesRead); AsyncInputReportArgs args = new AsyncInputReportArgs(); args.InputBuffer = inputReportBuffer; OnDataReadComplete(args); } } catch ( Exception ex ) { DisplayException( MODULE_NAME, ex ); throw ; } }
/// <summary> /// reads an Input report from the device using interrupt transfers. /// </summary> /// /// <param name="hidHandle"> the handle for learning about the device and exchanging Feature reports. </param> /// <param name="readHandle"> the handle for reading Input reports from the device. </param> /// <param name="writeHandle"> the handle for writing Output reports to the device. </param> /// <param name="myDeviceDetected"> tells whether the device is currently attached. </param> /// <param name="inputReportBuffer"> contains the requested report. </param> /// <param name="success"> read success </param> public override void Read(SafeFileHandle hidHandle, SafeFileHandle readHandle, SafeFileHandle writeHandle, ref Boolean myDeviceDetected, ref Byte[] inputReportBuffer, ref Boolean success) { IntPtr eventObject = IntPtr.Zero; NativeOverlapped HidOverlapped = new NativeOverlapped(); IntPtr nonManagedBuffer = IntPtr.Zero; IntPtr nonManagedOverlapped = IntPtr.Zero; Int32 numberOfBytesRead = 0; Int32 result = 0; try { // Set up the overlapped structure for ReadFile. PrepareForOverlappedTransfer(ref HidOverlapped, ref eventObject); // Allocate memory for the input buffer and overlapped structure. nonManagedBuffer = Marshal.AllocHGlobal(inputReportBuffer.Length); nonManagedOverlapped = Marshal.AllocHGlobal(Marshal.SizeOf(HidOverlapped)); Marshal.StructureToPtr(HidOverlapped, nonManagedOverlapped, false); // *** // API function: ReadFile // Purpose: Attempts to read an Input report from the device. // Accepts: // A device handle returned by CreateFile // (for overlapped I/O, CreateFile must have been called with FILE_FLAG_OVERLAPPED), // A pointer to a buffer for storing the report. // The Input report length in bytes returned by HidP_GetCaps, // A pointer to a variable that will hold the number of bytes read. // An overlapped structure whose hEvent member is set to an event object. // Returns: the report in ReadBuffer. // The overlapped call returns immediately, even if the data hasn't been received yet. // To read multiple reports with one ReadFile, increase the size of ReadBuffer // and use NumberOfBytesRead to determine how many reports were returned. // Use a larger buffer if the application can't keep up with reading each report // individually. // *** success = FileIO.ReadFile(readHandle, nonManagedBuffer, inputReportBuffer.Length, ref numberOfBytesRead, nonManagedOverlapped); if (!success) { //Tracer.Trace("waiting for ReadFile"); // API function: WaitForSingleObject // Purpose: waits for at least one report or a timeout. // Used with overlapped ReadFile. // Accepts: // An event object created with CreateEvent // A timeout value in milliseconds. // Returns: A result code. result = FileIO.WaitForSingleObject(eventObject, 3000); // Find out if ReadFile completed or timeout. switch (result) { case (System.Int32)FileIO.WAIT_OBJECT_0: // ReadFile has completed success = true; //Tracer.Trace("ReadFile completed successfully."); // Get the number of bytes read. // API function: GetOverlappedResult // Purpose: gets the result of an overlapped operation. // Accepts: // A device handle returned by CreateFile. // A pointer to an overlapped structure. // A pointer to a variable to hold the number of bytes read. // False to return immediately. // Returns: non-zero on success and the number of bytes read. FileIO.GetOverlappedResult(readHandle, nonManagedOverlapped, ref numberOfBytesRead, false); break; case FileIO.WAIT_TIMEOUT: // Cancel the operation on timeout CancelTransfer(hidHandle, readHandle, writeHandle, eventObject); Tracer.Error("Readfile timeout"); success = false; myDeviceDetected = false; break; default: // Cancel the operation on other error. CancelTransfer(hidHandle, readHandle, writeHandle, eventObject); Tracer.Error("Readfile undefined error"); success = false; myDeviceDetected = false; break; } } if (success) { // A report was received. // Copy the received data to inputReportBuffer for the application to use. Marshal.Copy(nonManagedBuffer, inputReportBuffer, 0, numberOfBytesRead); AsyncInputReportArgs args = new AsyncInputReportArgs(); args.InputBuffer = inputReportBuffer; OnDataReadComplete(args); } } catch (Exception ex) { DisplayException(MODULE_NAME, ex); throw; } }