public MFTestResults CompositeDeviceTest() { MFTestResults testResult = MFTestResults.Pass; // Gain access to all USB controllers UsbController[] controllers = UsbController.GetControllers(); // Set up all buttons to be monitored buttons.up = new InputPort((Cpu.Pin) 43, true, Port.ResistorMode.Disabled); buttons.down = new InputPort((Cpu.Pin) 42, true, Port.ResistorMode.Disabled); buttons.left = new InputPort((Cpu.Pin) 48, true, Port.ResistorMode.Disabled); buttons.right = new InputPort((Cpu.Pin) 44, true, Port.ResistorMode.Disabled); buttons.b1 = new InputPort((Cpu.Pin) 40, true, Port.ResistorMode.Disabled); buttons.b2 = new InputPort((Cpu.Pin) 45, true, Port.ResistorMode.Disabled); buttons.b3 = new InputPort((Cpu.Pin) 46, true, Port.ResistorMode.Disabled); buttons.done = new InputPort((Cpu.Pin) 47, true, Port.ResistorMode.Disabled); // Use the first available USB controller if it exists if (controllers.Length < 1) { Debug.Print("No USB controllers exist for this device - we're done!"); return(MFTestResults.Skip); } UsbController UsbPort = controllers[0]; // Configure the USB port and open streams to both interfaces if (!ConfigureMouseAndPinger(UsbPort)) // If USB configure fails, we're done { testResult = MFTestResults.Fail; } UsbStream pinger = UsbPort.CreateUsbStream(1, 2); // Pinger writes to endpoint 1 and reads from endpoint 2 UsbStream mouse = UsbPort.CreateUsbStream(3, UsbStream.NullEndpoint); // Mouse is write only to endpoint 3 MouseAndPingerLoop(mouse, pinger); // Behave like both a mouse and "TinyBooter // Done being a mouse and a pinger. Start being just a pinger pinger.Close(); mouse.Close(); UsbPort.Stop(); Thread.Sleep(500); // Keep USB port disconnected for half a second to be sure host has seen if (!ConfigurePinger(UsbPort)) { testResult = MFTestResults.Fail; } pinger = UsbPort.CreateUsbStream(1, 2); // Pinger writes to endpoint 1 and reads from endpoint 2 PingerLoop(pinger); // Done being just a pinger. Start being a mouse and pinger again pinger.Close(); UsbPort.Stop(); Thread.Sleep(500); // Keep USB port disconnected for half a second to be sure host has seen return(testResult); }
static bool SendMouseReport(UsbStream stream, bool button1, bool button2, bool button3, byte Xmovement, byte Ymovement) { byte[] report = new byte[3]; report[0] = (byte)((button1 ? 1 : 0) | (button2 ? 2 : 0) | (button3 ? 4 : 0)); report[1] = Xmovement; report[2] = Ymovement; stream.Write(report, 0, 3); return(true); }
static void MouseAndPingerLoop(UsbStream mouse, UsbStream pinger) { // Allocate in and out packets for "TinyBooter" simulation WireProtocol.WP_Packet inPacket; // Allocate packet for Pinger input UInt16 seq = 0; // Initialize Pinger packet sequence number // While done button is not pressed while (buttons.done.Read()) { // Perform these operations once every 10 milliseconds (actually a bit more than 10 milliseconds) // We've asked the host to query for mouse info at least every 10 milliseconds, but it actually // queries every 8 milliseconds - it's OK not to respond to every query. Thread.Sleep(10); byte xChange = 0; byte yChange = 0; // Make the mouse move by 3 steps each sample time if any movement button is pressed if (!buttons.up.Read()) { yChange = 0xFD; } if (!buttons.down.Read()) { yChange = 3; } if (!buttons.left.Read()) { xChange = 0xFD; } if (!buttons.right.Read()) { xChange = 3; } // Report to host the condition of "movement" or of the buttons SendMouseReport(mouse, !buttons.b1.Read(), !buttons.b2.Read(), !buttons.b3.Read(), xChange, yChange); // If a good WireProtocol packet was received from the host if (WireProtocol.ReadPacket(pinger, out inPacket)) { RespondToPacket(pinger, inPacket, seq); } } // Wait for the done button to be released while (!buttons.done.Read()) { ; } }
// Sends the given WP_Packet (header) and public static void SendPacket(UsbStream stream, WP_Packet packet, byte[] data) { int index; // Create a buffer whose size is large enough to contain both the WP_Packet (header) // and data so that they may be sent as a single packet. byte[] buffer = new byte[WP_Packet.packetSize + data.Length]; // Marshal the signature string into the buffer for (index = 0; index < packet.m_signature.Length && index < WP_Packet.m_crcHeader_offset; index++) { buffer[index] = (byte)packet.m_signature[index]; } while (index++ < WP_Packet.m_crcHeader_offset) { buffer[index] = 0; // Fill to end with zeros } // Marshal the WP_Packet (header) into the buffer. Note that the CRC values start as zero // so that the CRC of the WP_Packet (header) may be computed the same for host and target. WriteUINT32(buffer, WP_Packet.m_crcHeader_offset, 0); WriteUINT32(buffer, WP_Packet.m_crcData_offset, 0); WriteUINT32(buffer, WP_Packet.m_cmd_offset, (UInt32)packet.m_cmd); WriteUINT16(buffer, WP_Packet.m_seq_offset, packet.m_seq); WriteUINT16(buffer, WP_Packet.m_seqReply_offset, packet.m_seqReply); WriteUINT32(buffer, WP_Packet.m_flags_offset, packet.m_flags); WriteUINT32(buffer, WP_Packet.m_size_offset, (UInt32)data.Length); // Copy the data to the buffer for (int i = 0; i < data.Length; i++) { buffer[WP_Packet.packetSize + i] = data[i]; } // Calculate the CRC of the data if (data.Length != 0) { packet.m_crcData = SUPPORT_ComputeCRC(data, 0, data.Length, 0); WriteUINT32(buffer, WP_Packet.m_crcData_offset, packet.m_crcData); } // Calculate the CRC of the packet header packet.m_crcHeader = SUPPORT_ComputeCRC(buffer, 0, WP_Packet.packetSize, 0); WriteUINT32(buffer, WP_Packet.m_crcHeader_offset, packet.m_crcHeader); // Write out the complete packet to the USB stream stream.Write(buffer, 0, buffer.Length); }
// Check the given UsbStream for a valid WireProtocol packet (header). Returns true // along with the WP_Packet (header) if available. Returns false if nothing valid received as yet. public static bool ReadPacket(UsbStream stream, out WP_Packet packet) { packet = new WP_Packet(); byte[] buffer = new byte[WP_Packet.packetSize]; // Size of marshalled WP_Packet int nRead; // Read in enough data for a complete WP_Packet (header) nRead = stream.Read(buffer, 0, WP_Packet.packetSize); // If there were not enough bytes to fill the complete WP_Packet, it's no good if (nRead != WP_Packet.packetSize) { return(false); } // Unmarshal the signature string from the buffer to the WP_Packet packet.m_signature = ""; for (int i = 0; (i < WP_Packet.m_crcHeader_offset) && (buffer[i] != 0); i++) { packet.m_signature += (char)buffer[i]; } // Unmarshal the rest of the buffer into the WP_Packet structure. packet.m_crcHeader = ReadUINT32(buffer, WP_Packet.m_crcHeader_offset); packet.m_crcData = ReadUINT32(buffer, WP_Packet.m_crcData_offset); packet.m_seq = ReadUINT16(buffer, WP_Packet.m_seq_offset); packet.m_seqReply = ReadUINT16(buffer, WP_Packet.m_seqReply_offset); packet.m_flags = ReadUINT32(buffer, WP_Packet.m_flags_offset); packet.m_size = ReadUINT32(buffer, WP_Packet.m_size_offset); packet.m_cmd = (Commands)ReadUINT32(buffer, WP_Packet.m_cmd_offset); // The header CRC must first be zeroed to calculate the correct header CRC WriteUINT32(buffer, WP_Packet.m_crcHeader_offset, 0); // If the calculated CRC does not match that of the packet, it is no good if (packet.m_crcHeader != SUPPORT_ComputeCRC(buffer, 0, WP_Packet.packetSize, 0)) { return(false); } return(true); }
// Accepts only a good packet. If the packet is a Ping, the Ping response (ACK) is sent. // Otherwise, the command is NAK'ed. static bool RespondToPacket(UsbStream pinger, WireProtocol.WP_Packet inPacket, UInt16 seq) { WireProtocol.WP_Packet outPacket = new WireProtocol.WP_Packet(); // Allocate space for any data following the packet int size = (int)(inPacket.m_size & 0xFFFF); byte[] buffer = new byte[size]; // Read in the data that came with the packet if (inPacket.m_size != 0) { pinger.Read(buffer, 0, size); } // Fill in the blanks of the response packet outPacket.m_signature = "MSdbgV1"; // Standard target signature outPacket.m_cmd = inPacket.m_cmd; // Show which command this is a response to outPacket.m_seq = seq++; // Keep track of the target message sequence number outPacket.m_seqReply = inPacket.m_seq; // Show which host packet sequence number this is a response to // If the host packet was a Ping if (inPacket.m_cmd == WireProtocol.Commands.Ping) { byte[] data = new byte[8]; // The Ping has an 8 byte data response outPacket.m_flags = 0x8003; // Return a low-priority ACK for (int i = 0; i < 8; i++) { data[i] = 0; // Initialize all bytes of the data response to zero } data[0] = 1; // This tells the host that we are TinyBooter data[4] = 2; // This is an innoccuous flag value WireProtocol.SendPacket(pinger, outPacket, data); // Send response to the Ping } else { outPacket.m_flags = 0x4003; // Return a low-priority NACK WireProtocol.SendPacket(pinger, outPacket, new byte[0]); // Signal to the host that we don't know what to do with the command } return(true); }
public bool Open() { bool succeed = true; started = false; UsbController[] usbControllers = UsbController.GetControllers(); if (usbControllers.Length < 1) { succeed = false; } if (succeed) { usbController = usbControllers[0]; try { succeed = ConfigureHID(); if (succeed) { succeed = usbController.Start(); } if (succeed) { stream = usbController.CreateUsbStream(WRITE_ENDPOINT, READ_ENDPOINT); } } catch (Exception) { succeed = false; } } started = true; return(succeed); }
static void PingerLoop(UsbStream pinger) { // Allocate in and out packets for "TinyBooter" simulation WireProtocol.WP_Packet inPacket; // Allocate packet for Pinger input UInt16 seq = 0; // Initialize Pinger packet sequence number // While the done button is not pressed while (buttons.done.Read()) { Thread.Sleep(10); // No need to respond in a hurry if (WireProtocol.ReadPacket(pinger, out inPacket)) { RespondToPacket(pinger, inPacket, seq); } } // Wait for the done button to be released while (!buttons.done.Read()) { ; } }
/// <summary> /// Execution entry point. /// </summary> public static void Main() { // Gain access to all USB controllers. UsbController[] controllers = UsbController.GetControllers(); HardwareProvider hwProvider = new HardwareProvider(); // Set up all buttons to be monitored. buttons.Up = new InputPort(hwProvider.GetButtonPins(Button.VK_UP), true, Port.ResistorMode.Disabled); buttons.Down = new InputPort(hwProvider.GetButtonPins(Button.VK_DOWN), true, Port.ResistorMode.Disabled); buttons.Left = new InputPort(hwProvider.GetButtonPins(Button.VK_LEFT), true, Port.ResistorMode.Disabled); buttons.Right = new InputPort(hwProvider.GetButtonPins(Button.VK_RIGHT), true, Port.ResistorMode.Disabled); buttons.LeftMouseButton = new InputPort(hwProvider.GetButtonPins(Button.VK_BACK), true, Port.ResistorMode.Disabled); buttons.RightMouseButton = new InputPort(hwProvider.GetButtonPins(Button.VK_HOME), true, Port.ResistorMode.Disabled); buttons.Toggle = new InputPort(hwProvider.GetButtonPins(Button.VK_SELECT), true, Port.ResistorMode.Disabled); buttons.Done = new InputPort(hwProvider.GetButtonPins(Button.VK_MENU), true, Port.ResistorMode.Disabled); // Use the first available USB controller, if it exists. if (controllers.Length < 1) { Debug.Print("No USB controllers exist for this device - we're done."); return; } UsbController UsbPort = controllers[0]; UsbStream mouseStream = null; if (UsbPort.Status == UsbController.PortState.Running) { Debug.Print( "USB controller 0 is up and running - are you debugging with USB?"); Debug.Print( "Make sure your platform supports overriding the debug transport."); Thread.Sleep(500); } try { ConfigureUsbPort(UsbPort, true); mouseStream = UsbPort.CreateUsbStream(3, UsbStream.NullEndpoint); } catch (Exception e) { Debug.Print( "Mouse stream could not be created due to exception " + e.Message); Debug.Print( "Perhaps your native configuration does not contain endpoint 3?"); return; } // Be a mouse until the Done button is pressed. MouseLoop(UsbPort, mouseStream); mouseStream.Close(); }
/// <summary> /// /// </summary> /// <param name="port"></param> /// <param name="mouse"></param> static void MouseLoop(UsbController port, UsbStream mouse) { // Mouse report storage. byte[] report = new byte[5]; // Offsets into mouse report storage. const byte BUTTONS = 0; const byte X_MOVEMENT = 1; const byte Y_MOVEMENT = 2; // Size of mouse movement for each report (every 10 mS). const byte mouseStep = 3; bool fAddMouse = true; // While the Done button is not pressed... while (buttons.Done.Read()) { // Perform this operation once every 10 milliseconds (actually a // bit more than 10 milliseconds). We've asked the host to // query for mouse info at least every 10 milliseconds, but it // actually queries every 8 milliseconds - it's OK not to // respond to every query. Thread.Sleep(10); report[X_MOVEMENT] = 0; // Zero X movement report[Y_MOVEMENT] = 0; // Zero Y movement // Add X,Y movement to the mouse report. if (!buttons.Left.Read()) { report[X_MOVEMENT] -= mouseStep; } if (!buttons.Right.Read()) { report[X_MOVEMENT] += mouseStep; } if (!buttons.Up.Read()) { report[Y_MOVEMENT] -= mouseStep; } if (!buttons.Down.Read()) { report[Y_MOVEMENT] += mouseStep; } if (!buttons.Toggle.Read()) { if (mouse != null) { mouse.Dispose(); mouse = null; } fAddMouse = !fAddMouse; ConfigureUsbPort(port, fAddMouse); if (fAddMouse) { mouse = port.CreateUsbStream(3, UsbStream.NullEndpoint); } } // Add the button state to the mouse report. report[BUTTONS] = (byte)((!buttons.LeftMouseButton.Read() ? 1 : 0) | (!buttons.RightMouseButton.Read() ? 2 : 0)); if (mouse != null) { // Send the mouse report to the host. mouse.Write(report, 0, 3); } } // Wait for the Done button to be released. while (!buttons.Done.Read()) { ; } }
public static bool Init() { Cdc vsp = new Cdc(); //activedevice is null Controller.ActiveDevice = vsp; // Send "Hello world!" to PC every second. (Append a new line too) //byte[] bytes = System.Text.Encoding.UTF8.GetBytes("Hello world!\r\n"); while (true) { // Check if connected to PC if (Controller.State != UsbController.PortState.Running) { Debug.Print("Waiting to connect to PC..."); } else { break; } //else //{ // vsp.Stream.Write(bytes, 0, bytes.Length); //} Thread.Sleep(500); } // See if the hardware supports USB UsbController[] controllers = UsbController.GetControllers(); // Bail out if USB is not supported on this hardware! if (0 == controllers.Length) { Debug.Print("USB is not supported on this hardware!"); return(false); } foreach (UsbController controller in controllers) { if (controller.Status != UsbController.PortState.Stopped) { controller.Stop(); Thread.Sleep(1000); } } // Find a free USB controller UsbController usbController = null; foreach (UsbController controller in controllers) { if (controller.Status == UsbController.PortState.Stopped) { usbController = controller; break; } } // If no free USB controller if (null == usbController) { Debug.Print("All available USB controllers already in use. Set the device to use Ethernet or Serial debugging."); return(false); } try { // Configure the USB controller if (ConfigureUSBController(usbController)) { usbStream = usbController.CreateUsbStream(WRITE_EP, READ_EP); usbStream.ReadTimeout = 60000; usbStream.WriteTimeout = 60000; } else { throw new Exception(); } } catch (Exception) { Debug.Print("USB stream could not be created, error " + usbController.ConfigurationError.ToString()); return(false); } return(true); }