Last active
August 29, 2015 13:57
-
-
Save ismell/9390416 to your computer and use it in GitHub Desktop.
CyAPI Corruption Issue
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
;;----------------------------------------------------------------------------- | |
;; File: dscr.a51 | |
;; Contents: This file contains descriptor data tables. | |
;; | |
;; $Archive: /USB/Examples/Fx2lp/bulkloop/dscr.a51 $ | |
;; $Date: 9/01/03 8:51p $ | |
;; $Revision: 3 $ | |
;; | |
;; | |
;;----------------------------------------------------------------------------- | |
;; Copyright 2003, Cypress Semiconductor Corporation | |
;;-----------------------------------------------------------------------------;;----------------------------------------------------------------------------- | |
DSCR_DEVICE = 1 ;; Descriptor type: Device | |
DSCR_CONFIG = 2 ;; Descriptor type: Configuration | |
DSCR_STRING = 3 ;; Descriptor type: String | |
DSCR_INTRFC = 4 ;; Descriptor type: Interface | |
DSCR_ENDPNT = 5 ;; Descriptor type: Endpoint | |
DSCR_DEVQUAL = 6 ;; Descriptor type: Device Qualifier | |
DSCR_DEVICE_LEN = 18 | |
DSCR_CONFIG_LEN = 9 | |
DSCR_INTRFC_LEN = 9 | |
DSCR_ENDPNT_LEN = 7 | |
DSCR_DEVQUAL_LEN = 10 | |
ET_CONTROL = 0 ;; Endpoint type: Control | |
ET_ISO = 1 ;; Endpoint type: Isochronous | |
ET_BULK = 2 ;; Endpoint type: Bulk | |
ET_INT = 3 ;; Endpoint type: Interrupt | |
.module DSCR | |
.globl _DeviceDscr, _DeviceQualDscr, _HighSpeedConfigDscr, _FullSpeedConfigDscr, _StringDscr, _UserDscr | |
;DSCR SEGMENT CODE PAGE | |
.area DSCR (CODE,ABS) | |
.org 0x100 | |
;;----------------------------------------------------------------------------- | |
;; Global Variables | |
;;----------------------------------------------------------------------------- | |
; rseg DSCR ;; locate the descriptor table in on-part memory. | |
.even ; descriptors must be 2-byte aligned for SUDPTR{H,L} to work | |
_DeviceDscr: | |
.db DSCR_DEVICE_LEN ;; Descriptor length | |
.db DSCR_DEVICE ;; Decriptor type | |
.dw 0x0002 ;; Specification Version (BCD) | |
.db 0x00 ;; Device class | |
.db 0x00 ;; Device sub-class | |
.db 0x00 ;; Device sub-sub-class | |
.db 64 ;; Maximum packet size | |
.dw 0xB404 ;; Vendor ID | |
.dw 0xF100 ;; Product ID (Sample Device) | |
.dw 0x0000 ;; Product version ID | |
.db 1 ;; Manufacturer string index | |
.db 2 ;; Product string index | |
.db 0 ;; Serial number string index | |
.db 1 ;; Number of configurations | |
.even ; descriptors must be 2-byte aligned for SUDPTR{H,L} to work | |
_DeviceQualDscr: | |
.db DSCR_DEVQUAL_LEN ;; Descriptor length | |
.db DSCR_DEVQUAL ;; Decriptor type | |
.dw 0x0002 ;; Specification Version (BCD) | |
.db 0x00 ;; Device class | |
.db 0x00 ;; Device sub-class | |
.db 0x00 ;; Device sub-sub-class | |
.db 64 ;; Maximum packet size | |
.db 1 ;; Number of configurations | |
.db 0 ;; Reserved | |
.even ; descriptors must be 2-byte aligned for SUDPTR{H,L} to work | |
_HighSpeedConfigDscr: | |
.db DSCR_CONFIG_LEN ;; Descriptor length | |
.db DSCR_CONFIG ;; Descriptor type | |
.db (HighSpeedConfigDscr_End-_HighSpeedConfigDscr) % 256 ;; Total Length (LSB) | |
.db (HighSpeedConfigDscr_End-_HighSpeedConfigDscr) / 256 ;; Total Length (MSB) | |
.db 1 ;; Number of interfaces | |
.db 1 ;; Configuration number | |
.db 0 ;; Configuration string | |
.db 0xA0 ;; Attributes (b7 - buspwr, b6 - selfpwr, b5 - rwu) | |
.db 50 ;; Power r=irement (div 2 ma) | |
;; Interface Descriptor | |
.db DSCR_INTRFC_LEN ;; Descriptor length | |
.db DSCR_INTRFC ;; Descriptor type | |
.db 0 ;; Zero-based index of this interface | |
.db 0 ;; Alternate setting | |
.db 2 ;; Number of end points | |
.db 0xff ;; Interface class | |
.db 0x00 ;; Interface sub class | |
.db 0x00 ;; Interface sub sub class | |
.db 0 ;; Interface descriptor string index | |
;; Endpoint Descriptor | |
.db DSCR_ENDPNT_LEN ;; Descriptor length | |
.db DSCR_ENDPNT ;; Descriptor type | |
.db 0x02 ;; Endpoint number, and direction | |
.db ET_BULK ;; Endpoint type | |
.db 0x00 ;; Maximun packet size (LSB) | |
.db 0x02 ;; Max packect size (MSB) | |
.db 0x00 ;; Polling interval | |
;; Endpoint Descriptor | |
.db DSCR_ENDPNT_LEN ;; Descriptor length | |
.db DSCR_ENDPNT ;; Descriptor type | |
.db 0x86 ;; Endpoint number, and direction | |
.db ET_INT ;; Endpoint type | |
.db 0x00 ;; Maximun packet size (LSB) | |
.db 0x02 ;; Max packect size (MSB) | |
.db 0x01 ;; Polling interval | |
HighSpeedConfigDscr_End: | |
.even ; descriptors must be 2-byte aligned for SUDPTR{H,L} to work | |
_FullSpeedConfigDscr: | |
.db DSCR_CONFIG_LEN ;; Descriptor length | |
.db DSCR_CONFIG ;; Descriptor type | |
.db (FullSpeedConfigDscr_End-_FullSpeedConfigDscr) % 256 ;; Total Length (LSB) | |
.db (FullSpeedConfigDscr_End-_FullSpeedConfigDscr) / 256 ;; Total Length (MSB) | |
.db 1 ;; Number of interfaces | |
.db 1 ;; Configuration number | |
.db 0 ;; Configuration string | |
.db 0xA0 ;; Attributes (b7 - buspwr, b6 - selfpwr, b5 - rwu) | |
.db 50 ;; Power r=irement (div 2 ma) | |
;; Interface Descriptor | |
.db DSCR_INTRFC_LEN ;; Descriptor length | |
.db DSCR_INTRFC ;; Descriptor type | |
.db 0 ;; Zero-based index of this interface | |
.db 0 ;; Alternate setting | |
.db 2 ;; Number of end points | |
.db 0xff ;; Interface class | |
.db 0x00 ;; Interface sub class | |
.db 0x00 ;; Interface sub sub class | |
.db 0 ;; Interface descriptor string index | |
;; Endpoint Descriptor | |
.db DSCR_ENDPNT_LEN ;; Descriptor length | |
.db DSCR_ENDPNT ;; Descriptor type | |
.db 0x04 ;; Endpoint number, and direction | |
.db ET_BULK ;; Endpoint type | |
.db 0x40 ;; Maximun packet size (LSB) | |
.db 0x00 ;; Max packect size (MSB) | |
.db 0x00 ;; Polling interval | |
;; Endpoint Descriptor | |
.db DSCR_ENDPNT_LEN ;; Descriptor length | |
.db DSCR_ENDPNT ;; Descriptor type | |
.db 0x88 ;; Endpoint number, and direction | |
.db ET_INT ;; Endpoint type | |
.db 0x40 ;; Maximun packet size (LSB) | |
.db 0x00 ;; Max packect size (MSB) | |
.db 0x01 ;; Polling interval | |
FullSpeedConfigDscr_End: | |
.even ; descriptors must be 2-byte aligned for SUDPTR{H,L} to work | |
_StringDscr: | |
.even ; descriptors must be 2-byte aligned for SUDPTR{H,L} to work | |
_StringDscr0: | |
.db StringDscr0_End-_StringDscr0 ;; String descriptor length | |
.db DSCR_STRING | |
.db 0x09,0x04 | |
StringDscr0_End: | |
.even ; descriptors must be 2-byte aligned for SUDPTR{H,L} to work | |
_StringDscr1: | |
.db StringDscr1_End-_StringDscr1 ;; String descriptor length | |
.db DSCR_STRING | |
.db 'C',00 | |
.db 'y',00 | |
.db 'p',00 | |
.db 'r',00 | |
.db 'e',00 | |
.db 's',00 | |
.db 's',00 | |
StringDscr1_End: | |
.even ; descriptors must be 2-byte aligned for SUDPTR{H,L} to work | |
_StringDscr2: | |
.db StringDscr2_End-_StringDscr2 ;; Descriptor length | |
.db DSCR_STRING | |
.db 'E',00 | |
.db 'Z',00 | |
.db '-',00 | |
.db 'U',00 | |
.db 'S',00 | |
.db 'B',00 | |
.db ' ',00 | |
.db 'F',00 | |
.db 'X',00 | |
.db '2',00 | |
.db ' ',00 | |
.db 'G',00 | |
.db 'P',00 | |
.db 'I',00 | |
.db 'F',00 | |
.db ' ',00 | |
.db 't',00 | |
.db 'o',00 | |
.db ' ',00 | |
.db 'E',00 | |
.db 'x',00 | |
.db 't',00 | |
.db ' ',00 | |
.db 'F',00 | |
.db 'I',00 | |
.db 'F',00 | |
.db 'O',00 | |
.db ' ',00 | |
.db 'E',00 | |
.db 'x',00 | |
.db 'a',00 | |
.db 'm',00 | |
.db 'p',00 | |
.db 'l',00 | |
.db 'e',00 | |
.db ' ',00 | |
.db 'u',00 | |
.db 's',00 | |
.db 'i',00 | |
.db 'n',00 | |
.db 'g',00 | |
.db ' ',00 | |
.db 'S',00 | |
.db 'i',00 | |
.db 'n',00 | |
.db 'g',00 | |
.db 'l',00 | |
.db 'e',00 | |
.db ' ',00 | |
.db 'T',00 | |
.db 'r',00 | |
.db 'a',00 | |
.db 'n',00 | |
.db 's',00 | |
.db 'a',00 | |
.db 'c',00 | |
.db 't',00 | |
.db 'i',00 | |
.db 'o',00 | |
.db 'n',00 | |
.db 's',00 | |
StringDscr2_End: | |
.even ; descriptors must be 2-byte aligned for SUDPTR{H,L} to work | |
_UserDscr: | |
.dw 0x0000 | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Drawing; | |
using System.Collections; | |
using System.ComponentModel; | |
using System.Windows.Forms; | |
using System.Data; | |
using System.Threading; | |
using CyUSB; | |
using System.Runtime.InteropServices; | |
using System.Collections.Concurrent; | |
using System.Text; | |
using XInputDotNetPure; | |
namespace Streamer | |
{ | |
public class Form1 : System.Windows.Forms.Form | |
{ | |
bool bVista; | |
private System.Diagnostics.PerformanceCounter CpuCounter; | |
USBDeviceList usbDevices; | |
CyUSBDevice MyDevice; | |
CyUSBEndPoint InEndPoint; | |
CyUSBEndPoint OutEndPoint; | |
DateTime t1, t2; | |
TimeSpan elapsed; | |
double XferBytes; | |
long xferRate; | |
static byte DefaultBufInitValue = 0xA5; | |
int BufSz; | |
int QueueSz; | |
int PPX; | |
int IsoPktBlockSize; | |
int Successes; | |
int Failures; | |
Thread tListen; | |
Thread tRead; | |
bool bRunning; | |
ConcurrentQueue<String> pendingPrints; | |
// These are needed for Thread to update the UI | |
delegate void UpdateUICallback(); | |
UpdateUICallback updateUI; | |
private TextBox logOutput; | |
private Panel panel1; | |
private GroupBox groupBox2; | |
private RadioButton isControllerButton; | |
private RadioButton isMasterButton; | |
private RadioButton isPassiveButton; | |
private Panel panel2; | |
private System.Windows.Forms.Timer updateTimer; | |
private CheckBox enableLoggingButton; | |
private FlowLayoutPanel flowLayoutPanel1; | |
private Label label6; | |
private Label requestDeviceInfoLabel; | |
private Label label7; | |
private Label getConditionLabel; | |
private Label label8; | |
private Label dataTransferLabel; | |
private Label otherDescLabel; | |
private Label otherLabel; | |
// These are needed to close the app from the Thread exception(exception handling) | |
delegate void ExceptionCallback(); | |
ExceptionCallback handleException; | |
public Form1() | |
{ | |
bVista = (Environment.OSVersion.Version.Major == 6); | |
// Required for Windows Form Designer support | |
InitializeComponent(); | |
// Late setup of the CPU monitor - (Bails-out if in Vista) | |
InitializePeformanceMonitor(); | |
// Hide the CPU load monitor if running in Windows Vista | |
// Detecting the CPU load is a security violation in Vista | |
CPULoadBox.Visible = !bVista; | |
// Setup the callback routine for updating the UI | |
updateUI = new UpdateUICallback(StatusUpdate); | |
// Setup the callback routine for NullReference exception handling | |
handleException = new ExceptionCallback(ThreadException); | |
// Create the list of USB devices attached to the CyUSB3.sys driver. | |
usbDevices = new USBDeviceList(CyConst.DEVICES_CYUSB); | |
//Assign event handlers for device attachment and device removal. | |
usbDevices.DeviceAttached += new EventHandler(usbDevices_DeviceAttached); | |
usbDevices.DeviceRemoved += new EventHandler(usbDevices_DeviceRemoved); | |
//Set and search the device with VID-PID 04b4-1003 and if found, selects the end point | |
SetDevice(); | |
} | |
/*Summary | |
This is the event handler for device removal. This method resets the device count and searches for the device with | |
VID-PID 04b4-1003 | |
*/ | |
void usbDevices_DeviceRemoved(object sender, EventArgs e) | |
{ | |
MyDevice = null; | |
InEndPoint = null; | |
OutEndPoint = null; | |
SetDevice(); | |
} | |
/*Summary | |
This is the event handler for device attachment. This method searches for the device with | |
VID-PID 04b4-00F1 | |
*/ | |
void usbDevices_DeviceAttached(object sender, EventArgs e) | |
{ | |
SetDevice(); | |
} | |
/*Summary | |
Search the device with VID-PID 04b4-00F1 and if found, select the end point | |
*/ | |
private void SetDevice() | |
{ | |
USBDevice dev = usbDevices[0x04B4, 0x00F1]; | |
if (dev != null) | |
{ | |
MyDevice = (CyUSBDevice)dev; | |
GetEndpointsOfNode(MyDevice.Tree); | |
PpxBox.Text = "4"; | |
QueueBox.SelectedItem = "8"; | |
if (EndPointsComboBox.Items.Count > 0) | |
{ | |
EndPointsComboBox.SelectedIndex = EndPointsComboBox.Items.Count - 1; | |
StartBtn.Enabled = true; | |
} | |
Text = MyDevice.FriendlyName; | |
} | |
else | |
{ | |
StartBtn.Enabled = false; | |
EndPointsComboBox.Items.Clear(); | |
EndPointsComboBox.Text = ""; | |
Text = "C# Streamer - no device"; | |
} | |
} | |
/*Summary | |
Recursive routine populates EndPointsComboBox with strings | |
representing all the endpoints in the device. | |
*/ | |
private void GetEndpointsOfNode(TreeNode devTree) | |
{ | |
foreach (TreeNode node in devTree.Nodes) | |
{ | |
if (node.Nodes.Count > 0) | |
GetEndpointsOfNode(node); | |
else | |
{ | |
CyUSBEndPoint ept = node.Tag as CyUSBEndPoint; | |
if (ept == null) | |
{ | |
//return; | |
} | |
else if (!node.Text.Contains("Control")) | |
{ | |
CyUSBInterface ifc = node.Parent.Tag as CyUSBInterface; | |
string s = string.Format("ALT-{0}, {1} Byte {2}", ifc.bAlternateSetting, ept.MaxPktSize, node.Text); | |
EndPointsComboBox.Items.Add(s); | |
} | |
} | |
} | |
} | |
/*Summary | |
Clean up any resources being used. | |
*/ | |
protected override void Dispose(bool disposing) | |
{ | |
if (disposing) | |
{ | |
if (components != null) | |
{ | |
components.Dispose(); | |
} | |
} | |
base.Dispose(disposing); | |
} | |
/*Summary | |
This method is used to do the initialization for detecting the CPU load | |
*/ | |
private void InitializePeformanceMonitor() | |
{ | |
// This isn't allowed in Vista. | |
if (bVista) return; | |
CpuCounter = new System.Diagnostics.PerformanceCounter(); | |
((System.ComponentModel.ISupportInitialize)(CpuCounter)).BeginInit(); | |
CpuCounter.CategoryName = "Processor"; | |
CpuCounter.CounterName = "% Processor Time"; | |
CpuCounter.InstanceName = "_Total"; | |
((System.ComponentModel.ISupportInitialize)(CpuCounter)).EndInit(); | |
} | |
#region Windows Form Designer generated code | |
private System.Windows.Forms.MainMenu mainMenu; | |
private System.Windows.Forms.MenuItem menuItem1; | |
private System.Windows.Forms.MenuItem menuItem2; | |
private System.Windows.Forms.MenuItem ExitItem; | |
private System.Windows.Forms.MenuItem menuItem3; | |
private System.Windows.Forms.MenuItem AboutItem; | |
private System.Windows.Forms.Label label1; | |
private System.Windows.Forms.Label label2; | |
private System.Windows.Forms.Label label3; | |
private System.Windows.Forms.Label label4; | |
private System.Windows.Forms.ComboBox PpxBox; | |
private System.Windows.Forms.ComboBox QueueBox; | |
private System.Windows.Forms.TextBox SuccessBox; | |
private System.Windows.Forms.GroupBox groupBox1; | |
private System.Windows.Forms.ProgressBar ProgressBar; | |
private System.Windows.Forms.Button StartBtn; | |
private System.Windows.Forms.Label ThroughputLabel; | |
private System.Windows.Forms.TextBox FailuresBox; | |
private ComboBox EndPointsComboBox; | |
private Label label5; | |
private GroupBox CPULoadBox; | |
private Label CpuLabel; | |
private ProgressBar CpuBar; | |
private System.Windows.Forms.Timer PerfTimer; | |
private IContainer components; | |
/// <summary> | |
/// Required method for Designer support - do not modify | |
/// the contents of this method with the code editor. | |
/// </summary> | |
private void InitializeComponent() | |
{ | |
this.components = new System.ComponentModel.Container(); | |
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(Form1)); | |
this.mainMenu = new System.Windows.Forms.MainMenu(this.components); | |
this.menuItem1 = new System.Windows.Forms.MenuItem(); | |
this.menuItem2 = new System.Windows.Forms.MenuItem(); | |
this.ExitItem = new System.Windows.Forms.MenuItem(); | |
this.menuItem3 = new System.Windows.Forms.MenuItem(); | |
this.AboutItem = new System.Windows.Forms.MenuItem(); | |
this.label1 = new System.Windows.Forms.Label(); | |
this.label2 = new System.Windows.Forms.Label(); | |
this.label3 = new System.Windows.Forms.Label(); | |
this.label4 = new System.Windows.Forms.Label(); | |
this.PpxBox = new System.Windows.Forms.ComboBox(); | |
this.QueueBox = new System.Windows.Forms.ComboBox(); | |
this.SuccessBox = new System.Windows.Forms.TextBox(); | |
this.FailuresBox = new System.Windows.Forms.TextBox(); | |
this.groupBox1 = new System.Windows.Forms.GroupBox(); | |
this.ThroughputLabel = new System.Windows.Forms.Label(); | |
this.ProgressBar = new System.Windows.Forms.ProgressBar(); | |
this.StartBtn = new System.Windows.Forms.Button(); | |
this.EndPointsComboBox = new System.Windows.Forms.ComboBox(); | |
this.label5 = new System.Windows.Forms.Label(); | |
this.CPULoadBox = new System.Windows.Forms.GroupBox(); | |
this.CpuLabel = new System.Windows.Forms.Label(); | |
this.CpuBar = new System.Windows.Forms.ProgressBar(); | |
this.PerfTimer = new System.Windows.Forms.Timer(this.components); | |
this.logOutput = new System.Windows.Forms.TextBox(); | |
this.panel1 = new System.Windows.Forms.Panel(); | |
this.groupBox2 = new System.Windows.Forms.GroupBox(); | |
this.isControllerButton = new System.Windows.Forms.RadioButton(); | |
this.isMasterButton = new System.Windows.Forms.RadioButton(); | |
this.isPassiveButton = new System.Windows.Forms.RadioButton(); | |
this.panel2 = new System.Windows.Forms.Panel(); | |
this.updateTimer = new System.Windows.Forms.Timer(this.components); | |
this.enableLoggingButton = new System.Windows.Forms.CheckBox(); | |
this.flowLayoutPanel1 = new System.Windows.Forms.FlowLayoutPanel(); | |
this.label6 = new System.Windows.Forms.Label(); | |
this.requestDeviceInfoLabel = new System.Windows.Forms.Label(); | |
this.label7 = new System.Windows.Forms.Label(); | |
this.getConditionLabel = new System.Windows.Forms.Label(); | |
this.label8 = new System.Windows.Forms.Label(); | |
this.dataTransferLabel = new System.Windows.Forms.Label(); | |
this.otherDescLabel = new System.Windows.Forms.Label(); | |
this.otherLabel = new System.Windows.Forms.Label(); | |
this.groupBox1.SuspendLayout(); | |
this.CPULoadBox.SuspendLayout(); | |
this.panel1.SuspendLayout(); | |
this.groupBox2.SuspendLayout(); | |
this.panel2.SuspendLayout(); | |
this.flowLayoutPanel1.SuspendLayout(); | |
this.SuspendLayout(); | |
// | |
// mainMenu | |
// | |
this.mainMenu.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] { | |
this.menuItem1, | |
this.menuItem3}); | |
// | |
// menuItem1 | |
// | |
this.menuItem1.Index = 0; | |
this.menuItem1.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] { | |
this.menuItem2, | |
this.ExitItem}); | |
this.menuItem1.Text = "File"; | |
// | |
// menuItem2 | |
// | |
this.menuItem2.Index = 0; | |
this.menuItem2.Text = "-"; | |
// | |
// ExitItem | |
// | |
this.ExitItem.Index = 1; | |
this.ExitItem.Text = "Exit"; | |
this.ExitItem.Click += new System.EventHandler(this.ExitItem_Click); | |
// | |
// menuItem3 | |
// | |
this.menuItem3.Index = 1; | |
this.menuItem3.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] { | |
this.AboutItem}); | |
this.menuItem3.Text = "Help"; | |
// | |
// AboutItem | |
// | |
this.AboutItem.Index = 0; | |
this.AboutItem.Text = "About"; | |
this.AboutItem.Click += new System.EventHandler(this.AboutItem_Click); | |
// | |
// label1 | |
// | |
this.label1.Location = new System.Drawing.Point(9, 57); | |
this.label1.Name = "label1"; | |
this.label1.Size = new System.Drawing.Size(89, 16); | |
this.label1.TabIndex = 0; | |
this.label1.Text = "Packets per Xfer"; | |
this.label1.TextAlign = System.Drawing.ContentAlignment.BottomLeft; | |
// | |
// label2 | |
// | |
this.label2.Location = new System.Drawing.Point(9, 96); | |
this.label2.Name = "label2"; | |
this.label2.Size = new System.Drawing.Size(89, 17); | |
this.label2.TabIndex = 1; | |
this.label2.Text = "Xfers to Queue"; | |
this.label2.TextAlign = System.Drawing.ContentAlignment.BottomLeft; | |
// | |
// label3 | |
// | |
this.label3.Location = new System.Drawing.Point(208, 57); | |
this.label3.Name = "label3"; | |
this.label3.Size = new System.Drawing.Size(64, 17); | |
this.label3.TabIndex = 2; | |
this.label3.Text = "Successes"; | |
this.label3.TextAlign = System.Drawing.ContentAlignment.BottomLeft; | |
// | |
// label4 | |
// | |
this.label4.Location = new System.Drawing.Point(208, 98); | |
this.label4.Name = "label4"; | |
this.label4.Size = new System.Drawing.Size(64, 16); | |
this.label4.TabIndex = 3; | |
this.label4.Text = "Failures"; | |
this.label4.TextAlign = System.Drawing.ContentAlignment.BottomLeft; | |
// | |
// PpxBox | |
// | |
this.PpxBox.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; | |
this.PpxBox.Items.AddRange(new object[] { | |
"1", | |
"2", | |
"4", | |
"8", | |
"16", | |
"32", | |
"64", | |
"128", | |
"256", | |
"512"}); | |
this.PpxBox.Location = new System.Drawing.Point(104, 57); | |
this.PpxBox.Name = "PpxBox"; | |
this.PpxBox.Size = new System.Drawing.Size(64, 21); | |
this.PpxBox.TabIndex = 1; | |
this.PpxBox.SelectedIndexChanged += new System.EventHandler(this.PpxBox_SelectedIndexChanged); | |
// | |
// QueueBox | |
// | |
this.QueueBox.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; | |
this.QueueBox.Items.AddRange(new object[] { | |
"1", | |
"2", | |
"4", | |
"8", | |
"16", | |
"32", | |
"64", | |
"128"}); | |
this.QueueBox.Location = new System.Drawing.Point(104, 96); | |
this.QueueBox.Name = "QueueBox"; | |
this.QueueBox.Size = new System.Drawing.Size(64, 21); | |
this.QueueBox.TabIndex = 2; | |
// | |
// SuccessBox | |
// | |
this.SuccessBox.Location = new System.Drawing.Point(272, 57); | |
this.SuccessBox.Name = "SuccessBox"; | |
this.SuccessBox.Size = new System.Drawing.Size(72, 20); | |
this.SuccessBox.TabIndex = 6; | |
this.SuccessBox.TabStop = false; | |
this.SuccessBox.Text = "0"; | |
this.SuccessBox.TextAlign = System.Windows.Forms.HorizontalAlignment.Right; | |
// | |
// FailuresBox | |
// | |
this.FailuresBox.Location = new System.Drawing.Point(272, 97); | |
this.FailuresBox.Name = "FailuresBox"; | |
this.FailuresBox.Size = new System.Drawing.Size(72, 20); | |
this.FailuresBox.TabIndex = 7; | |
this.FailuresBox.TabStop = false; | |
this.FailuresBox.Text = "0"; | |
this.FailuresBox.TextAlign = System.Windows.Forms.HorizontalAlignment.Right; | |
// | |
// groupBox1 | |
// | |
this.groupBox1.Controls.Add(this.ThroughputLabel); | |
this.groupBox1.Controls.Add(this.ProgressBar); | |
this.groupBox1.Location = new System.Drawing.Point(14, 255); | |
this.groupBox1.Name = "groupBox1"; | |
this.groupBox1.Size = new System.Drawing.Size(330, 62); | |
this.groupBox1.TabIndex = 8; | |
this.groupBox1.TabStop = false; | |
this.groupBox1.Text = " Throughput (KB/s) "; | |
// | |
// ThroughputLabel | |
// | |
this.ThroughputLabel.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0))); | |
this.ThroughputLabel.Location = new System.Drawing.Point(114, 38); | |
this.ThroughputLabel.Name = "ThroughputLabel"; | |
this.ThroughputLabel.Size = new System.Drawing.Size(100, 16); | |
this.ThroughputLabel.TabIndex = 1; | |
this.ThroughputLabel.Text = "0"; | |
this.ThroughputLabel.TextAlign = System.Drawing.ContentAlignment.BottomCenter; | |
// | |
// ProgressBar | |
// | |
this.ProgressBar.ForeColor = System.Drawing.SystemColors.HotTrack; | |
this.ProgressBar.Location = new System.Drawing.Point(16, 25); | |
this.ProgressBar.Maximum = 500000; | |
this.ProgressBar.Name = "ProgressBar"; | |
this.ProgressBar.Size = new System.Drawing.Size(294, 10); | |
this.ProgressBar.TabIndex = 0; | |
// | |
// StartBtn | |
// | |
this.StartBtn.BackColor = System.Drawing.Color.Aquamarine; | |
this.StartBtn.Location = new System.Drawing.Point(218, 219); | |
this.StartBtn.Name = "StartBtn"; | |
this.StartBtn.Size = new System.Drawing.Size(128, 20); | |
this.StartBtn.TabIndex = 3; | |
this.StartBtn.Text = "Start"; | |
this.StartBtn.UseVisualStyleBackColor = false; | |
this.StartBtn.Click += new System.EventHandler(this.StartBtn_Click); | |
// | |
// EndPointsComboBox | |
// | |
this.EndPointsComboBox.DropDownHeight = 120; | |
this.EndPointsComboBox.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; | |
this.EndPointsComboBox.Enabled = false; | |
this.EndPointsComboBox.FormattingEnabled = true; | |
this.EndPointsComboBox.IntegralHeight = false; | |
this.EndPointsComboBox.Location = new System.Drawing.Point(104, 14); | |
this.EndPointsComboBox.Name = "EndPointsComboBox"; | |
this.EndPointsComboBox.Size = new System.Drawing.Size(240, 21); | |
this.EndPointsComboBox.TabIndex = 0; | |
this.EndPointsComboBox.SelectedIndexChanged += new System.EventHandler(this.EndPointsComboBox_SelectedIndexChanged); | |
// | |
// label5 | |
// | |
this.label5.AutoSize = true; | |
this.label5.Location = new System.Drawing.Point(9, 17); | |
this.label5.Name = "label5"; | |
this.label5.Size = new System.Drawing.Size(94, 13); | |
this.label5.TabIndex = 11; | |
this.label5.Text = "Endpoint . . . . . . . "; | |
// | |
// CPULoadBox | |
// | |
this.CPULoadBox.Controls.Add(this.CpuLabel); | |
this.CPULoadBox.Controls.Add(this.CpuBar); | |
this.CPULoadBox.Location = new System.Drawing.Point(14, 334); | |
this.CPULoadBox.Name = "CPULoadBox"; | |
this.CPULoadBox.Size = new System.Drawing.Size(330, 60); | |
this.CPULoadBox.TabIndex = 12; | |
this.CPULoadBox.TabStop = false; | |
this.CPULoadBox.Text = " CPU Load "; | |
// | |
// CpuLabel | |
// | |
this.CpuLabel.AutoSize = true; | |
this.CpuLabel.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0))); | |
this.CpuLabel.Location = new System.Drawing.Point(150, 41); | |
this.CpuLabel.Name = "CpuLabel"; | |
this.CpuLabel.Size = new System.Drawing.Size(27, 13); | |
this.CpuLabel.TabIndex = 1; | |
this.CpuLabel.Text = "0 %"; | |
this.CpuLabel.TextAlign = System.Drawing.ContentAlignment.MiddleCenter; | |
// | |
// CpuBar | |
// | |
this.CpuBar.ForeColor = System.Drawing.Color.ForestGreen; | |
this.CpuBar.Location = new System.Drawing.Point(16, 28); | |
this.CpuBar.Name = "CpuBar"; | |
this.CpuBar.Size = new System.Drawing.Size(294, 10); | |
this.CpuBar.Step = 1; | |
this.CpuBar.TabIndex = 0; | |
// | |
// PerfTimer | |
// | |
this.PerfTimer.Enabled = true; | |
this.PerfTimer.Interval = 500; | |
this.PerfTimer.Tick += new System.EventHandler(this.PerfTimer_Tick); | |
// | |
// logOutput | |
// | |
this.logOutput.Dock = System.Windows.Forms.DockStyle.Fill; | |
this.logOutput.Font = new System.Drawing.Font("Consolas", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); | |
this.logOutput.Location = new System.Drawing.Point(0, 0); | |
this.logOutput.Multiline = true; | |
this.logOutput.Name = "logOutput"; | |
this.logOutput.ReadOnly = true; | |
this.logOutput.ScrollBars = System.Windows.Forms.ScrollBars.Vertical; | |
this.logOutput.Size = new System.Drawing.Size(461, 442); | |
this.logOutput.TabIndex = 13; | |
// | |
// panel1 | |
// | |
this.panel1.Controls.Add(this.enableLoggingButton); | |
this.panel1.Controls.Add(this.groupBox2); | |
this.panel1.Controls.Add(this.CPULoadBox); | |
this.panel1.Controls.Add(this.label5); | |
this.panel1.Controls.Add(this.EndPointsComboBox); | |
this.panel1.Controls.Add(this.StartBtn); | |
this.panel1.Controls.Add(this.groupBox1); | |
this.panel1.Controls.Add(this.FailuresBox); | |
this.panel1.Controls.Add(this.SuccessBox); | |
this.panel1.Controls.Add(this.QueueBox); | |
this.panel1.Controls.Add(this.PpxBox); | |
this.panel1.Controls.Add(this.label4); | |
this.panel1.Controls.Add(this.label3); | |
this.panel1.Controls.Add(this.label2); | |
this.panel1.Controls.Add(this.label1); | |
this.panel1.Dock = System.Windows.Forms.DockStyle.Left; | |
this.panel1.Location = new System.Drawing.Point(0, 0); | |
this.panel1.Name = "panel1"; | |
this.panel1.Size = new System.Drawing.Size(351, 442); | |
this.panel1.TabIndex = 14; | |
// | |
// groupBox2 | |
// | |
this.groupBox2.Controls.Add(this.isControllerButton); | |
this.groupBox2.Controls.Add(this.isMasterButton); | |
this.groupBox2.Controls.Add(this.isPassiveButton); | |
this.groupBox2.Location = new System.Drawing.Point(12, 133); | |
this.groupBox2.Name = "groupBox2"; | |
this.groupBox2.Size = new System.Drawing.Size(329, 40); | |
this.groupBox2.TabIndex = 13; | |
this.groupBox2.TabStop = false; | |
this.groupBox2.Text = "Mode"; | |
// | |
// isControllerButton | |
// | |
this.isControllerButton.AutoSize = true; | |
this.isControllerButton.Checked = true; | |
this.isControllerButton.Location = new System.Drawing.Point(254, 17); | |
this.isControllerButton.Name = "isControllerButton"; | |
this.isControllerButton.Size = new System.Drawing.Size(69, 17); | |
this.isControllerButton.TabIndex = 2; | |
this.isControllerButton.TabStop = true; | |
this.isControllerButton.Text = "Controller"; | |
this.isControllerButton.UseVisualStyleBackColor = true; | |
// | |
// isMasterButton | |
// | |
this.isMasterButton.AutoSize = true; | |
this.isMasterButton.Enabled = false; | |
this.isMasterButton.Location = new System.Drawing.Point(131, 17); | |
this.isMasterButton.Name = "isMasterButton"; | |
this.isMasterButton.Size = new System.Drawing.Size(57, 17); | |
this.isMasterButton.TabIndex = 1; | |
this.isMasterButton.Text = "Master"; | |
this.isMasterButton.UseVisualStyleBackColor = true; | |
// | |
// isPassiveButton | |
// | |
this.isPassiveButton.AutoSize = true; | |
this.isPassiveButton.Location = new System.Drawing.Point(7, 17); | |
this.isPassiveButton.Name = "isPassiveButton"; | |
this.isPassiveButton.Size = new System.Drawing.Size(62, 17); | |
this.isPassiveButton.TabIndex = 0; | |
this.isPassiveButton.Text = "Passive"; | |
this.isPassiveButton.UseVisualStyleBackColor = true; | |
// | |
// panel2 | |
// | |
this.panel2.Controls.Add(this.flowLayoutPanel1); | |
this.panel2.Controls.Add(this.logOutput); | |
this.panel2.Dock = System.Windows.Forms.DockStyle.Fill; | |
this.panel2.Location = new System.Drawing.Point(351, 0); | |
this.panel2.Name = "panel2"; | |
this.panel2.Size = new System.Drawing.Size(461, 442); | |
this.panel2.TabIndex = 15; | |
// | |
// updateTimer | |
// | |
this.updateTimer.Tick += new System.EventHandler(this.updateTimer_Tick); | |
// | |
// enableLoggingButton | |
// | |
this.enableLoggingButton.AutoSize = true; | |
this.enableLoggingButton.Location = new System.Drawing.Point(12, 180); | |
this.enableLoggingButton.Name = "enableLoggingButton"; | |
this.enableLoggingButton.Size = new System.Drawing.Size(64, 17); | |
this.enableLoggingButton.TabIndex = 14; | |
this.enableLoggingButton.Text = "Logging"; | |
this.enableLoggingButton.UseVisualStyleBackColor = true; | |
this.enableLoggingButton.CheckedChanged += new System.EventHandler(this.enableLoggingButton_CheckedChanged); | |
// | |
// flowLayoutPanel1 | |
// | |
this.flowLayoutPanel1.Controls.Add(this.label6); | |
this.flowLayoutPanel1.Controls.Add(this.requestDeviceInfoLabel); | |
this.flowLayoutPanel1.Controls.Add(this.label7); | |
this.flowLayoutPanel1.Controls.Add(this.getConditionLabel); | |
this.flowLayoutPanel1.Controls.Add(this.label8); | |
this.flowLayoutPanel1.Controls.Add(this.dataTransferLabel); | |
this.flowLayoutPanel1.Controls.Add(this.otherDescLabel); | |
this.flowLayoutPanel1.Controls.Add(this.otherLabel); | |
this.flowLayoutPanel1.Dock = System.Windows.Forms.DockStyle.Top; | |
this.flowLayoutPanel1.Location = new System.Drawing.Point(0, 0); | |
this.flowLayoutPanel1.Name = "flowLayoutPanel1"; | |
this.flowLayoutPanel1.Size = new System.Drawing.Size(461, 30); | |
this.flowLayoutPanel1.TabIndex = 14; | |
// | |
// label6 | |
// | |
this.label6.AutoSize = true; | |
this.label6.Location = new System.Drawing.Point(3, 0); | |
this.label6.Name = "label6"; | |
this.label6.Size = new System.Drawing.Size(108, 13); | |
this.label6.TabIndex = 0; | |
this.label6.Text = "Request Device Info:"; | |
// | |
// requestDeviceInfoLabel | |
// | |
this.requestDeviceInfoLabel.AutoSize = true; | |
this.requestDeviceInfoLabel.Location = new System.Drawing.Point(117, 0); | |
this.requestDeviceInfoLabel.Name = "requestDeviceInfoLabel"; | |
this.requestDeviceInfoLabel.Size = new System.Drawing.Size(13, 13); | |
this.requestDeviceInfoLabel.TabIndex = 1; | |
this.requestDeviceInfoLabel.Text = "0"; | |
// | |
// label7 | |
// | |
this.label7.AutoSize = true; | |
this.label7.Location = new System.Drawing.Point(136, 0); | |
this.label7.Name = "label7"; | |
this.label7.Size = new System.Drawing.Size(74, 13); | |
this.label7.TabIndex = 2; | |
this.label7.Text = "Get Condition:"; | |
// | |
// getConditionLabel | |
// | |
this.getConditionLabel.AutoSize = true; | |
this.getConditionLabel.Location = new System.Drawing.Point(216, 0); | |
this.getConditionLabel.Name = "getConditionLabel"; | |
this.getConditionLabel.Size = new System.Drawing.Size(13, 13); | |
this.getConditionLabel.TabIndex = 3; | |
this.getConditionLabel.Text = "0"; | |
// | |
// label8 | |
// | |
this.label8.AutoSize = true; | |
this.label8.Location = new System.Drawing.Point(235, 0); | |
this.label8.Name = "label8"; | |
this.label8.Size = new System.Drawing.Size(75, 13); | |
this.label8.TabIndex = 4; | |
this.label8.Text = "Data Transfer:"; | |
// | |
// dataTransferLabel | |
// | |
this.dataTransferLabel.AutoSize = true; | |
this.dataTransferLabel.Location = new System.Drawing.Point(316, 0); | |
this.dataTransferLabel.Name = "dataTransferLabel"; | |
this.dataTransferLabel.Size = new System.Drawing.Size(13, 13); | |
this.dataTransferLabel.TabIndex = 5; | |
this.dataTransferLabel.Text = "0"; | |
// | |
// otherDescLabel | |
// | |
this.otherDescLabel.AutoSize = true; | |
this.otherDescLabel.Location = new System.Drawing.Point(335, 0); | |
this.otherDescLabel.Name = "otherDescLabel"; | |
this.otherDescLabel.Size = new System.Drawing.Size(36, 13); | |
this.otherDescLabel.TabIndex = 6; | |
this.otherDescLabel.Text = "Other:"; | |
// | |
// otherLabel | |
// | |
this.otherLabel.AutoSize = true; | |
this.otherLabel.Location = new System.Drawing.Point(377, 0); | |
this.otherLabel.Name = "otherLabel"; | |
this.otherLabel.Size = new System.Drawing.Size(13, 13); | |
this.otherLabel.TabIndex = 7; | |
this.otherLabel.Text = "0"; | |
// | |
// Form1 | |
// | |
this.AutoScaleBaseSize = new System.Drawing.Size(5, 13); | |
this.ClientSize = new System.Drawing.Size(812, 442); | |
this.Controls.Add(this.panel2); | |
this.Controls.Add(this.panel1); | |
this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon"))); | |
this.Menu = this.mainMenu; | |
this.MinimumSize = new System.Drawing.Size(615, 420); | |
this.Name = "Form1"; | |
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen; | |
this.Text = "C# Streamer"; | |
this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.Form1_FormClosing); | |
this.groupBox1.ResumeLayout(false); | |
this.CPULoadBox.ResumeLayout(false); | |
this.CPULoadBox.PerformLayout(); | |
this.panel1.ResumeLayout(false); | |
this.panel1.PerformLayout(); | |
this.groupBox2.ResumeLayout(false); | |
this.groupBox2.PerformLayout(); | |
this.panel2.ResumeLayout(false); | |
this.panel2.PerformLayout(); | |
this.flowLayoutPanel1.ResumeLayout(false); | |
this.flowLayoutPanel1.PerformLayout(); | |
this.ResumeLayout(false); | |
} | |
#endregion | |
/*Summary | |
The main entry point for the application. | |
*/ | |
[STAThread] | |
static void Main() | |
{ | |
try | |
{ | |
Application.Run(new Form1()); | |
} | |
catch (Exception e) | |
{ | |
MessageBox.Show(e.StackTrace, "Exception '" + e.Message + "' thrown by " + e.Source); | |
} | |
} | |
/*Summary | |
Executes on clicking Help->about | |
*/ | |
private void AboutItem_Click(object sender, System.EventArgs e) | |
{ | |
string assemblyList = Util.Assemblies; | |
MessageBox.Show(assemblyList, Text); | |
} | |
/*Summary | |
Executes on clicking File->Exit | |
*/ | |
private void ExitItem_Click(object sender, System.EventArgs e) | |
{ | |
Close(); | |
} | |
/*Summary | |
Executes on clicking close button | |
*/ | |
private void Form1_FormClosing(object sender, FormClosingEventArgs e) | |
{ | |
if (usbDevices != null) | |
usbDevices.Dispose(); | |
} | |
/*Summary | |
This is the System event handler. | |
Enforces valid values for PPX(Packet per transfer) | |
*/ | |
private void PpxBox_SelectedIndexChanged(object sender, EventArgs e) | |
{ | |
if (InEndPoint == null) return; | |
int ppx = Convert.ToUInt16(PpxBox.Text); | |
int len = InEndPoint.MaxPktSize * ppx; | |
int maxLen = 0x400000; // 4MBytes | |
if (len > maxLen) | |
{ | |
//ppx = maxLen / (EndPoint.MaxPktSize) / 8 * 8; | |
if (InEndPoint.MaxPktSize ==0) | |
{ | |
MessageBox.Show("Please correct MaxPacketSize in Descriptor", "Invalid MaxPacketSize"); | |
return; | |
} | |
ppx = maxLen / (InEndPoint.MaxPktSize); | |
ppx -= (ppx % 8); | |
MessageBox.Show("Maximum of 4MB per transfer. Packets reduced.", "Invalid Packets per Xfer."); | |
//Update the DropDown list for the packets | |
int iIndex = PpxBox.SelectedIndex; // Get the packet index | |
PpxBox.Items.Remove(PpxBox.Text); // Remove the Existing Packet index | |
PpxBox.Items.Insert(iIndex, ppx.ToString()); // insert the ppx | |
PpxBox.SelectedIndex = iIndex; // update the selected item index | |
} | |
if ((MyDevice.bSuperSpeed || MyDevice.bHighSpeed) && (InEndPoint.Attributes == 1) && (ppx < 8)) | |
{ | |
PpxBox.Text = "8"; | |
MessageBox.Show("Minimum of 8 Packets per Xfer required for HS/SS Isoc.", "Invalid Packets per Xfer."); | |
} | |
if ((MyDevice.bHighSpeed) && (InEndPoint.Attributes == 1)) | |
{ | |
if (ppx > 128) | |
{ | |
PpxBox.Text = "128"; | |
MessageBox.Show("Maximum 128 packets per transfer for High Speed Isoc", "Invalid Packets per Xfer."); | |
} | |
} | |
} | |
/*Summary | |
This is a system event handler, when the selected index changes(end point selection). | |
*/ | |
private void EndPointsComboBox_SelectedIndexChanged(object sender, EventArgs e) | |
{ | |
// Get the Alt setting | |
string sAlt = EndPointsComboBox.Text.Substring(4, 1); | |
byte a = Convert.ToByte(sAlt); | |
MyDevice.AltIntfc = a; | |
// Get the endpoint | |
int aX = EndPointsComboBox.Text.LastIndexOf("0x"); | |
string sAddr = EndPointsComboBox.Text.Substring(aX, 4); | |
byte addr = (byte)Util.HexToInt(sAddr); | |
InEndPoint = MyDevice.EndPointOf(0x86); | |
OutEndPoint = MyDevice.EndPointOf(0x02); | |
// Ensure valid PPX for this endpoint | |
PpxBox_SelectedIndexChanged(sender, null); | |
} | |
DeviceType deviceType; | |
bool EnableLogging = false; | |
int requestDeviceInfoCount; | |
int getConditionCount; | |
int dataTransferCount; | |
int otherCommandCount; | |
/*Summary | |
Executes on Start Button click | |
*/ | |
private void StartBtn_Click(object sender, System.EventArgs e) | |
{ | |
if (MyDevice == null) | |
return; | |
if (QueueBox.Text == "") | |
{ | |
MessageBox.Show("Please Select Xfers to Queue", "Invalid Input"); | |
return; | |
} | |
if (StartBtn.Text.Equals("Start")) | |
{ | |
EndPointsComboBox.Enabled = false; | |
StartBtn.Text = "Stop"; | |
StartBtn.BackColor = Color.Pink; | |
PpxBox.Enabled = false; | |
QueueBox.Enabled = false; | |
pendingPrints = new ConcurrentQueue<string>(); | |
logOutput.Clear(); | |
requestDeviceInfoCount = getConditionCount = dataTransferCount = otherCommandCount = 0; | |
BufSz = InEndPoint.MaxPktSize * Convert.ToUInt16(PpxBox.Text); | |
QueueSz = Convert.ToUInt16(QueueBox.Text); | |
PPX = Convert.ToUInt16(PpxBox.Text); | |
InEndPoint.XferSize = BufSz; | |
if (InEndPoint is CyIsocEndPoint) | |
IsoPktBlockSize = (InEndPoint as CyIsocEndPoint).GetPktBlockSize(BufSz); | |
else | |
IsoPktBlockSize = 0; | |
bRunning = true; | |
deviceType = DeviceType.Passive; | |
if (isControllerButton.Checked) | |
{ | |
deviceType = DeviceType.Controller; | |
globalGamePadState = GamePad.GetState(PlayerIndex.One); | |
globalControllerButtons = DreamcastControllerButtons.FromGamePadState(globalGamePadState); | |
tRead = new Thread(new ThreadStart(updateControllerStateThread)); | |
tRead.IsBackground = true; | |
tRead.Priority = ThreadPriority.AboveNormal; | |
tRead.Start(); | |
} | |
updateTimer.Start(); | |
// Start Maplebus | |
tListen = new Thread(new ThreadStart(XferThread)); | |
tListen.IsBackground = true; | |
tListen.Priority = ThreadPriority.Highest; | |
tListen.Start(); | |
} | |
else | |
{ | |
if (tListen.IsAlive) | |
{ | |
EndPointsComboBox.Enabled = true; | |
PpxBox.Enabled = true; | |
QueueBox.Enabled = true; | |
StartBtn.Text = "Start"; | |
bRunning = false; | |
t2 = DateTime.Now; | |
elapsed = t2 - t1; | |
xferRate = (long)(XferBytes / elapsed.TotalMilliseconds); | |
xferRate = xferRate / (int)100 * (int)100; | |
tListen.Abort(); | |
tListen.Join(); | |
tListen = null; | |
updateTimer.Stop(); | |
StartBtn.BackColor = Color.Aquamarine; | |
} | |
if (tRead != null && tRead.IsAlive) | |
{ | |
tRead.Abort(); | |
tRead.Join(); | |
tRead = null; | |
} | |
} | |
} | |
void updateTimer_Tick(object sender, EventArgs e) | |
{ | |
this.Invoke(updateUI); | |
} | |
GamePadState globalGamePadState; | |
DreamcastControllerButtons globalControllerButtons; | |
public void updateControllerStateThread() | |
{ | |
for (; bRunning; ) | |
{ | |
GamePadState state = GamePad.GetState(PlayerIndex.One); | |
if (state.PacketNumber != globalGamePadState.PacketNumber) | |
{ | |
// The pointer write is atomic so no locking is required | |
globalGamePadState = state; | |
globalControllerButtons = DreamcastControllerButtons.FromGamePadState(globalGamePadState); | |
} | |
Thread.Sleep(8); // About 120FPS | |
} | |
} | |
/*Summary | |
Data Xfer Thread entry point. Starts the thread on Start Button click | |
*/ | |
public unsafe void XferThread() | |
{ | |
// Setup the queue buffers | |
byte[][] cmdBufs = new byte[QueueSz][]; | |
byte[][] xferBufs = new byte[QueueSz][]; | |
byte[][] ovLaps = new byte[QueueSz][]; | |
ISO_PKT_INFO[][] pktsInfo = new ISO_PKT_INFO[QueueSz][]; | |
int xStart = 0; | |
try | |
{ | |
LockNLoad(ref xStart, cmdBufs, xferBufs, ovLaps, pktsInfo); | |
} | |
catch (NullReferenceException e) | |
{ | |
// This exception gets thrown if the device is unplugged | |
// while we're streaming data | |
e.GetBaseException(); | |
this.Invoke(handleException); | |
} | |
} | |
/*Summary | |
This is a recursive routine for pinning all the buffers used in the transfer in memory. | |
It will get recursively called QueueSz times. On the QueueSz_th call, it will call | |
XferData, which will loop, transferring data, until the stop button is clicked. | |
Then, the recursion will unwind. | |
*/ | |
public unsafe void LockNLoad(ref int j, byte[][] cBufs, byte[][] xBufs, byte[][] oLaps, ISO_PKT_INFO[][] pktsInfo) | |
{ | |
// Allocate one set of buffers for the queue, Buffered IO method require user to allocate a buffer as a part of command buffer, | |
// the BeginDataXfer does not allocated it. BeginDataXfer will copy the data from the main buffer to the allocated while initializing the commands. | |
cBufs[j] = new byte[CyConst.SINGLE_XFER_LEN + IsoPktBlockSize + ((InEndPoint.XferMode == XMODE.BUFFERED) ? BufSz : 0)]; | |
xBufs[j] = new byte[BufSz]; | |
//initialize the buffer with initial value 0xA5 | |
for (int iIndex = 0; iIndex < BufSz; iIndex++) | |
xBufs[j][iIndex] = DefaultBufInitValue; | |
oLaps[j] = new byte[20]; | |
pktsInfo[j] = new ISO_PKT_INFO[PPX]; | |
fixed (byte* tL0 = oLaps[j], tc0 = cBufs[j], tb0 = xBufs[j]) // Pin the buffers in memory | |
{ | |
OVERLAPPED* ovLapStatus = (OVERLAPPED*)tL0; | |
ovLapStatus->hEvent = (IntPtr)PInvoke.CreateEvent(0, 0, 0, 0); | |
// Pre-load the queue with a request | |
int len = BufSz; | |
InEndPoint.BeginDataXfer(ref cBufs[j], ref xBufs[j], ref len, ref oLaps[j]); | |
j++; | |
if (j < QueueSz) | |
LockNLoad(ref j, cBufs, xBufs, oLaps, pktsInfo); // Recursive call to pin next buffers in memory | |
else | |
XferData(cBufs, xBufs, oLaps, pktsInfo); // All loaded. Let's go! | |
} | |
} | |
/*Summary | |
Called at the end of recursive method, LockNLoad(). | |
XferData() implements the infinite transfer loop | |
*/ | |
public unsafe void XferData(byte[][] cBufs, byte[][] xBufs, byte[][] oLaps, ISO_PKT_INFO[][] pktsInfo) | |
{ | |
int k = 0; | |
int len = 0; | |
Successes = 0; | |
Failures = 0; | |
XferBytes = 0; | |
t1 = DateTime.Now; | |
for (; bRunning; ) | |
{ | |
// WaitForXfer | |
fixed (byte* tmpOvlap = oLaps[k]) | |
{ | |
OVERLAPPED* ovLapStatus = (OVERLAPPED*)tmpOvlap; | |
if (!InEndPoint.WaitForXfer(ovLapStatus->hEvent, 5000)) | |
{ | |
InEndPoint.Abort(); | |
PInvoke.WaitForSingleObject(ovLapStatus->hEvent, 5000); | |
} | |
} | |
if (InEndPoint.Attributes == 1) | |
{ | |
CyIsocEndPoint isoc = InEndPoint as CyIsocEndPoint; | |
// FinishDataXfer | |
if (isoc.FinishDataXfer(ref cBufs[k], ref xBufs[k], ref len, ref oLaps[k], ref pktsInfo[k])) | |
{ | |
//XferBytes += len; | |
//Successes++; | |
ISO_PKT_INFO[] pkts = pktsInfo[k]; | |
for (int j = 0; j < PPX; j++) | |
{ | |
if (pkts[j].Status == 0) | |
{ | |
XferBytes += pkts[j].Length; | |
Successes++; | |
} | |
else | |
Failures++; | |
pkts[j].Length = 0; | |
} | |
} | |
else | |
Failures++; | |
} | |
else | |
{ | |
// FinishDataXfer | |
if (InEndPoint.FinishDataXfer(ref cBufs[k], ref xBufs[k], ref len, ref oLaps[k])) | |
{ | |
XferBytes += len; | |
Successes++; | |
String analysis = analyzeFrameData(xBufs[k], len); | |
if (EnableLogging) { | |
pendingPrints.Enqueue(analysis); | |
} | |
} | |
else | |
{ | |
Failures++; | |
pendingPrints.Enqueue(String.Format("Error: {0}", InEndPoint.LastError)); | |
} | |
} | |
// Re-submit this buffer into the queue | |
len = BufSz; | |
InEndPoint.BeginDataXfer(ref cBufs[k], ref xBufs[k], ref len, ref oLaps[k]); | |
k++; | |
if (k == QueueSz) // Only update displayed stats once each time through the queue | |
{ | |
k = 0; | |
t2 = DateTime.Now; | |
elapsed = t2 - t1; | |
xferRate = (long)(XferBytes / elapsed.TotalMilliseconds); | |
xferRate = xferRate / (int)100 * (int)100; | |
// Call StatusUpdate() in the main thread | |
// For small QueueSz or PPX, the loop is too tight for UI thread to ever get service. | |
// Without this, app hangs in those scenarios. | |
//Thread.Sleep(1); | |
} | |
} // End infinite loop | |
// Let's recall all the queued buffer and abort the end point. | |
InEndPoint.Abort(); | |
} | |
public String analyzeFrameData(byte[] bytes, int length) | |
{ | |
StringBuilder sb = new StringBuilder(); | |
// Swap endianness | |
if (length >= 5 && (length - 1) % 4 == 0) | |
{ | |
var buffer = swapEndianness(bytes, length - 1); | |
printByteArray(sb, bytes, length); | |
sb.Append(" "); | |
var LRC = computeLRC(bytes, length-1); | |
if (LRC == bytes[length-1]) | |
{ | |
sb.Append("XOR ok"); | |
} | |
else | |
{ | |
sb.AppendFormat("XOR bad (0x{0:x2} => 0x{1:x2})", bytes[length - 1], LRC); | |
} | |
sb.AppendLine(); | |
parseFrame(sb, buffer, length); | |
} | |
else | |
{ | |
if (length == 0) | |
{ | |
sb.Append("Empty Packet"); | |
} | |
else | |
{ | |
sb.Append("Bad packet"); | |
} | |
} | |
return sb.ToString(); | |
} | |
private byte computeLRC(byte[] bytes) | |
{ | |
return computeLRC(bytes, bytes.Length); | |
} | |
private byte computeLRC(byte[] bytes, int length) | |
{ | |
byte LRC = 0x00; | |
for (var i = 0; i < length; ++i) | |
{ | |
LRC ^= bytes[i]; | |
} | |
return LRC; | |
} | |
private void printByteArray(StringBuilder sb, byte[] bytes) | |
{ | |
printByteArray(sb, bytes, bytes.Length); | |
} | |
private void printByteArray(StringBuilder sb, byte[] bytes, int length) | |
{ | |
sb.Append("new byte[] {"); | |
for (int j = 0; j < length; ++j) | |
{ | |
byte b = bytes[j]; | |
sb.AppendFormat("0x{0:x2}", b); | |
if (j + 1 < length) | |
{ | |
sb.Append(", "); | |
} | |
} | |
sb.AppendLine("};"); | |
} | |
public enum Command : sbyte | |
{ | |
RequestDeviceInformation = 1, | |
DeviceInformation = 5, | |
DataTransfer = 8, | |
GetCondition = 9 | |
} | |
enum DeviceType | |
{ | |
Passive, | |
Host, | |
Controller | |
} | |
public void parseFrame(StringBuilder sb, byte[] buffer, int len) { | |
byte command = buffer[0]; | |
byte recipientAddress = buffer[1]; | |
byte senderAddress = buffer[2]; | |
byte additionalWords = buffer[3]; | |
sb.AppendFormat(" Command: {0}", commandToString(command)); | |
sb.AppendLine(); | |
sb.AppendFormat(" Recipient: {0}", addressToString(recipientAddress)); | |
sb.AppendLine(); | |
sb.AppendFormat(" Sender: {0}", addressToString(senderAddress)); | |
sb.AppendLine(); | |
bool packetLengthOk = (buffer.Length - 4) == additionalWords * 4; | |
sb.AppendFormat(" Additional Words: {0} {1}", additionalWords, packetLengthOk ? "OK" : "Invalid Length"); | |
sb.AppendLine(); | |
if (packetLengthOk) | |
{ | |
Command cmd = (Command)command; | |
if (cmd == Command.GetCondition) | |
{ | |
var function = parseGetCondition(sb, buffer); | |
if (deviceType == DeviceType.Controller) | |
{ | |
sendDeviceCondition(sb); | |
} | |
getConditionCount += 1; | |
} | |
else if (cmd == Command.DataTransfer) | |
{ | |
parseDataTransfer(sb, buffer); | |
dataTransferCount += 1; | |
} | |
else if (cmd == Command.DeviceInformation) | |
{ | |
parseDeviceInformation(sb, buffer); | |
otherCommandCount += 1; | |
} | |
else if (cmd == Command.RequestDeviceInformation) | |
{ | |
if (deviceType == DeviceType.Controller) | |
{ | |
sendDeviceInformation(sb); | |
} | |
requestDeviceInfoCount += 1; | |
} | |
else | |
{ | |
sb.AppendLine("Unknown Command!"); | |
otherCommandCount += 1; | |
} | |
} | |
} | |
private void sendDeviceCondition(StringBuilder sb) | |
{ | |
var deviceCondition = new byte[] { 0x03, 0x20, 0x00, 0x08, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x80, 0x80, 0x80, 0x80, 0x00 }; | |
applyControllerState(deviceCondition, globalControllerButtons); | |
deviceCondition[deviceCondition.Length - 1] = computeLRC(deviceCondition, deviceCondition.Length - 1); | |
sb.AppendLine(" -> Sending Device Condition"); | |
parseDataTransfer(sb, swapEndianness(deviceCondition)); | |
int len = deviceCondition.Length; | |
var success = MyDevice.BulkOutEndPt.XferData(ref deviceCondition, ref len); | |
if (success) | |
{ | |
sb.AppendFormat(" -> Device Condition sent successfully: {0}", len); | |
} | |
else | |
{ | |
sb.AppendFormat(" -> Device Condition failed to send : {0}", len); | |
} | |
sb.AppendLine(); | |
} | |
class DreamcastControllerButtons | |
{ | |
public byte LeftTrigger = 0; | |
public byte RightTrigger = 0; | |
public byte LeftThumbX = 128; | |
public byte LeftThumbY = 128; | |
public byte RightThumbX = 128; | |
public byte RightThumbY = 128; | |
public byte Buttons1 = 0xFF; | |
public byte Buttons2 = 0xFF; | |
public static DreamcastControllerButtons FromGamePadState(GamePadState state) | |
{ | |
var controller = new DreamcastControllerButtons(); | |
if (state.IsConnected) | |
{ | |
controller.LeftTrigger = (byte)Math.Ceiling(state.Triggers.Left * 255); | |
controller.RightTrigger = (byte)Math.Ceiling(state.Triggers.Right * 255); | |
controller.LeftThumbX = (byte)Math.Floor(127 * state.ThumbSticks.Left.X + 128); | |
controller.LeftThumbY = (byte)Math.Floor(-127 * state.ThumbSticks.Left.Y + 128); | |
controller.RightThumbX = (byte)Math.Floor(127 * state.ThumbSticks.Right.X + 128); | |
controller.RightThumbY = (byte)Math.Floor(-127 * state.ThumbSticks.Right.Y + 128); | |
if (state.DPad.Right == XInputDotNetPure.ButtonState.Pressed) | |
controller.Buttons1 ^= 0x80; | |
if (state.DPad.Left == XInputDotNetPure.ButtonState.Pressed) | |
controller.Buttons1 ^= 0x40; | |
if (state.DPad.Down == XInputDotNetPure.ButtonState.Pressed) | |
controller.Buttons1 ^= 0x20; | |
if (state.DPad.Up == XInputDotNetPure.ButtonState.Pressed) | |
controller.Buttons1 ^= 0x10; | |
if (state.Buttons.Start == XInputDotNetPure.ButtonState.Pressed) | |
controller.Buttons1 ^= 0x08; | |
if (state.Buttons.A == XInputDotNetPure.ButtonState.Pressed) | |
controller.Buttons1 ^= 0x04; | |
if (state.Buttons.B == XInputDotNetPure.ButtonState.Pressed) | |
controller.Buttons1 ^= 0x02; | |
if (state.Buttons.RightShoulder == XInputDotNetPure.ButtonState.Pressed) | |
controller.Buttons1 ^= 0x01; | |
if (state.Buttons.X == XInputDotNetPure.ButtonState.Pressed) | |
controller.Buttons2 ^= 0x04; | |
if (state.Buttons.Y == XInputDotNetPure.ButtonState.Pressed) | |
controller.Buttons2 ^= 0x02; | |
if (state.Buttons.LeftShoulder == XInputDotNetPure.ButtonState.Pressed) | |
controller.Buttons2 ^= 0x01; | |
} | |
return controller; | |
} | |
} | |
private void applyControllerState(byte[] deviceCondition, DreamcastControllerButtons controller) | |
{ | |
/* | |
* new byte[] { | |
* 0x03, 0x20, 0x00, 0x08, | |
* 0x01, 0x00, 0x00, 0x00, | |
* 0x00, 0x00, 0xff, 0xff, // RIght Trigger, Left Trigger, XYZ, ABC | |
* 0x80, 0x80, 0x80, 0x80, // A2Y, A2X, A1Y, A2X | |
* 0x00 | |
* }; | |
* | |
*/ | |
deviceCondition[8] = controller.LeftTrigger; | |
deviceCondition[9] = controller.RightTrigger; | |
deviceCondition[10] = controller.Buttons2; | |
deviceCondition[11] = controller.Buttons1; | |
deviceCondition[12] = controller.RightThumbY; | |
deviceCondition[13] = controller.RightThumbX; | |
deviceCondition[14] = controller.LeftThumbY; | |
deviceCondition[15] = controller.LeftThumbX; | |
} | |
private void sendDeviceInformation(StringBuilder sb) | |
{ | |
var deviceInfo = new byte[] { 0x1c, 0x20, 0x00, 0x05, 0x01, 0x00, 0x00, 0x00, 0xfe, 0x06, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x72, 0x44, 0x00, 0xff, 0x63, 0x6d, 0x61, 0x65, 0x20, 0x74, 0x73, 0x61, 0x74, 0x6e, 0x6f, 0x43, 0x6c, 0x6c, 0x6f, 0x72, 0x20, 0x20, 0x72, 0x65, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x64, 0x6f, 0x72, 0x50, 0x64, 0x65, 0x63, 0x75, 0x20, 0x79, 0x42, 0x20, 0x55, 0x20, 0x72, 0x6f, 0x72, 0x65, 0x64, 0x6e, 0x63, 0x69, 0x4c, 0x20, 0x65, 0x73, 0x6e, 0x65, 0x6f, 0x72, 0x46, 0x20, 0x45, 0x53, 0x20, 0x6d, 0x45, 0x20, 0x41, 0x47, 0x52, 0x45, 0x54, 0x4e, 0x53, 0x49, 0x52, 0x50, 0x4c, 0x2c, 0x53, 0x45, 0x20, 0x2e, 0x44, 0x54, 0x20, 0x20, 0x20, 0x20, 0x01, 0xf4, 0x01, 0xae, 0x00}; | |
deviceInfo[deviceInfo.Length - 1] = computeLRC(deviceInfo, deviceInfo.Length - 1); | |
sb.AppendLine(" -> Sending Device Info"); | |
int len = deviceInfo.Length; | |
var success = MyDevice.BulkOutEndPt.XferData(ref deviceInfo, ref len); | |
if (success) | |
{ | |
sb.AppendFormat(" -> Device info sent successfully: {0}", len); | |
} | |
else | |
{ | |
sb.AppendFormat(" -> Device info failed to send : {0}", len); | |
} | |
sb.AppendLine(); | |
} | |
private byte[] swapEndianness(byte[] bytes) { | |
return swapEndianness(bytes, bytes.Length); | |
} | |
private byte[] swapEndianness(byte[] bytes, int length) | |
{ | |
// Swap endianness | |
var buffer = new byte[length]; | |
var i = 0; | |
for (i = 0; i + 3 < length; i += 4) | |
{ | |
buffer[i + 0] = bytes[i + 3]; | |
buffer[i + 1] = bytes[i + 2]; | |
buffer[i + 2] = bytes[i + 1]; | |
buffer[i + 3] = bytes[i + 0]; | |
} | |
// For the odd bytes | |
for (; i < length; ++i) | |
{ | |
buffer[i] = bytes[i]; | |
} | |
return buffer; | |
} | |
[Flags] | |
public enum RegionCode : byte | |
{ | |
NorthAmerica = 0x01, | |
Japan = 0x02, | |
Asia = 0x04, | |
Europe = 0x08, | |
Unlocked = 0xFF | |
} | |
private void parseDeviceInformation(StringBuilder sb, byte[] buffer) | |
{ | |
var currentIndex = 4; | |
CommandFunction function = (CommandFunction)BitConverter.ToUInt32(new byte[] { buffer[7], buffer[6], buffer[5], buffer[4]}, 0); | |
currentIndex += 4; | |
sb.AppendFormat(" Function: {0}", Enum.GetName(function.GetType(), function)); | |
sb.AppendLine(); | |
sb.AppendFormat(" Functional Data 0: {0} {1} {2} {3}", buffer[currentIndex++], buffer[currentIndex++], buffer[currentIndex++], buffer[currentIndex++]); | |
sb.AppendLine(); | |
sb.AppendFormat(" Functional Data 1: {0} {1} {2} {3}", buffer[currentIndex++], buffer[currentIndex++], buffer[currentIndex++], buffer[currentIndex++]); | |
sb.AppendLine(); | |
sb.AppendFormat(" Functional Data 2: {0} {1} {2} {3}", buffer[currentIndex++], buffer[currentIndex++], buffer[currentIndex++], buffer[currentIndex++]); | |
sb.AppendLine(); | |
RegionCode regionCode = (RegionCode)buffer[currentIndex++]; | |
sb.AppendFormat(" Region Code: {0}", Enum.GetName(regionCode.GetType(), regionCode)); | |
sb.AppendLine(); | |
currentIndex += 1; // I don't know what this byte is? it's 0 | |
string productName = System.Text.Encoding.UTF8.GetString(buffer, currentIndex, 30); | |
currentIndex += 30; | |
sb.AppendFormat(" Product Name: {0}", productName); | |
sb.AppendLine(); | |
string licence = System.Text.Encoding.UTF8.GetString(buffer, currentIndex, 60); | |
currentIndex += 60; | |
sb.AppendFormat(" Licence: {0}", licence); | |
sb.AppendLine(); | |
ushort standbyCurrent = BitConverter.ToUInt16(new byte[] { buffer[currentIndex + 1], buffer[currentIndex] }, 0); | |
currentIndex += 2; | |
sb.AppendFormat(" Standby Current: {0}", standbyCurrent); | |
sb.AppendLine(); | |
ushort maxCurrent = BitConverter.ToUInt16(new byte[] { buffer[currentIndex + 1], buffer[currentIndex] }, 0); | |
currentIndex += 2; | |
sb.AppendFormat(" Max Current: {0}", standbyCurrent); | |
sb.AppendLine(); | |
if (buffer.Length - 1 != currentIndex) | |
{ | |
sb.AppendLine(" Extra bytes encountered"); | |
} | |
} | |
[Flags] | |
public enum Buttons : ushort | |
{ | |
Right2 = 0x8000, | |
Left2 = 0x4000, | |
Down2 = 0x2000, | |
Up2 = 0x1000, | |
D = 0x0800, | |
X = 0x0400, | |
Y = 0x0200, | |
Z = 0x0100, | |
Right1 = 0x0080, | |
Left1 = 0x0040, | |
Down1 = 0x0020, | |
Up1 = 0x0010, | |
Start = 0x0008, | |
A = 0x0004, | |
B = 0x0002, | |
C = 0x0001 | |
} | |
private void parseDataTransfer(StringBuilder sb, byte[] buffer) | |
{ | |
var length = buffer.Length; | |
length -= 5; | |
var currentIndex = 4; | |
/* | |
* 00 00 00 01 <- I don't know what this means | |
* ff ff 00 00 | |
* 80 80 80 80 | |
*/ | |
if (12 == length) | |
{ | |
currentIndex += 4; // skip the first word | |
Buttons buttons = (Buttons)BitConverter.ToUInt16(buffer, currentIndex); | |
currentIndex += 2; | |
sb.AppendFormat(" DPad1: Up ({0}), Down ({1}), Left ({2}), Right ({3})", | |
(buttons & Buttons.Up1) == 0, | |
(buttons & Buttons.Down1) == 0, | |
(buttons & Buttons.Left1) == 0, | |
(buttons & Buttons.Right1) == 0 | |
); | |
sb.AppendLine(); | |
sb.AppendFormat(" DPad2: Up ({0}), Down ({1}), Left ({2}), Right ({3})", | |
(buttons & Buttons.Up2) == 0, | |
(buttons & Buttons.Down2) == 0, | |
(buttons & Buttons.Left2) == 0, | |
(buttons & Buttons.Right2) == 0 | |
); | |
sb.AppendLine(); | |
sb.AppendFormat(" A ({0}), B ({1}), C ({2}), D ({3})", | |
(buttons & Buttons.A) == 0, | |
(buttons & Buttons.B) == 0, | |
(buttons & Buttons.C) == 0, | |
(buttons & Buttons.D) == 0 | |
); | |
sb.AppendLine(); | |
sb.AppendFormat(" X ({0}), Y ({1}), Z ({2}), Start ({3}))", | |
(buttons & Buttons.X) == 0, | |
(buttons & Buttons.Y) == 0, | |
(buttons & Buttons.Z) == 0, | |
(buttons & Buttons.Start) == 0 | |
); | |
sb.AppendLine(); | |
byte rightTrigger = buffer[currentIndex++], | |
leftTrigger = buffer[currentIndex++]; | |
sb.AppendFormat(" Left Trigger ({0}), Right Trigger ({1}))", | |
leftTrigger, rightTrigger | |
); | |
sb.AppendLine(); | |
byte analogX1 = buffer[currentIndex++], | |
analogY1 = buffer[currentIndex++]; | |
sb.AppendFormat(" Analog 1 ({0}, {1})", | |
analogX1, analogY1 | |
); | |
sb.AppendLine(); | |
byte analogX2 = buffer[currentIndex++], | |
analogY2 = buffer[currentIndex++]; | |
sb.AppendFormat(" Analog 2 ({0}, {1})", | |
analogX2, analogY2 | |
); | |
} | |
else | |
{ | |
sb.AppendFormat(" Invalid payload length {0}, expected 12", length); | |
} | |
sb.AppendLine(); | |
} | |
[Flags] | |
public enum CommandFunction : uint | |
{ | |
None = 0x0000, | |
Controller = 0x01, | |
MemoryCard = 0x02, | |
LCDDisplay = 0x04, | |
Clock = 0x08, | |
Microphone = 0x10, | |
ARGun = 0x20, | |
Keyboard = 0x40, | |
LightGun = 0x80, | |
PuruPuruPack = 0x0100, | |
Mouse = 0x0200 | |
} | |
private CommandFunction parseGetCondition(StringBuilder sb, byte[] buffer) | |
{ | |
CommandFunction function = CommandFunction.None; | |
if (buffer.Length - 4 == 4) { | |
function = (CommandFunction)BitConverter.ToUInt32(buffer, 3); | |
sb.AppendFormat(" Function: {0}", Enum.GetName(function.GetType(), function)); | |
} else { | |
sb.AppendFormat(" Invalid payload length {0}, expected 4", buffer.Length - 5); | |
} | |
sb.AppendLine(); | |
return function; | |
} | |
[Flags] | |
public enum Port : byte | |
{ | |
A = 0x00, | |
B = 0x40, | |
C = 0x80, | |
D = 0xC0 | |
} | |
[Flags] | |
public enum Peripheral : byte | |
{ | |
Dreamcast= 0x00, | |
SubPeripheral1 = 0x01, | |
SubPeripheral2 = 0x02, | |
SubPeripheral3 = 0x04, | |
SubPeripheral4 = 0x08, | |
SubPeripheral5 = 0x10, | |
Main = 0x20 | |
} | |
private string addressToString(byte address) | |
{ | |
Port port = (Port)(address & 0xC0); | |
Peripheral peripheral = (Peripheral)(address & 0x3F); | |
return String.Format("Port {0} {1}", Enum.GetName(port.GetType(), port), Enum.GetName(peripheral.GetType(), peripheral)); | |
} | |
private string commandToString(byte commandByte) | |
{ | |
sbyte command = (sbyte)commandByte; | |
switch (command) | |
{ | |
case 1: | |
return "Request Device Information (1)"; | |
case 2: | |
return "Request extended device information (2)"; | |
case 3: | |
return "Reset device (3)"; | |
case 4: | |
return "Shutdown device (4)"; | |
case 5: | |
return "Device information (response) (5)"; | |
case 6: | |
return "Extended device information (response) (6)"; | |
case 7: | |
return "Command acknowledge (response) (7)"; | |
case 8: | |
return "Data transfer (response) (8)"; | |
case 9: | |
return "Get condition (9)"; | |
case 10: | |
return "Get memory information (10)"; | |
case 11: | |
return "Block read (11)"; | |
case 12: | |
return "Block write (12)"; | |
case 14: | |
return "Set condition (14)"; | |
case -1: | |
return "No response (-1)"; | |
case -2: | |
return "Function code unsupported (response) (-2)"; | |
case -3: | |
return "Unknown command (response) (-3)"; | |
case -4: | |
return "Command needs to be sent again (response) (-4)"; | |
case -5: | |
return "File error (response) (-5)"; | |
default: | |
return "Unknown command"; | |
} | |
} | |
/*Summary | |
The callback routine delegated to updateUI. | |
*/ | |
public void StatusUpdate() | |
{ | |
if (xferRate > ProgressBar.Maximum) | |
ProgressBar.Maximum = (int)(xferRate * 1.25); | |
ProgressBar.Value = (int)xferRate; | |
ThroughputLabel.Text = ProgressBar.Value.ToString(); | |
SuccessBox.Text = Successes.ToString(); | |
FailuresBox.Text = Failures.ToString(); | |
requestDeviceInfoLabel.Text = requestDeviceInfoCount.ToString(); | |
getConditionLabel.Text = getConditionCount.ToString(); | |
dataTransferLabel.Text = dataTransferCount.ToString(); | |
otherLabel.Text = otherCommandCount.ToString(); | |
string message; | |
while (pendingPrints.TryDequeue(out message)) | |
{ | |
logOutput.AppendText(message + Environment.NewLine); | |
} | |
} | |
/*Summary | |
The callback routine delegated to handleException. | |
*/ | |
public void ThreadException() | |
{ | |
StartBtn.Text = "Start"; | |
bRunning = false; | |
t2 = DateTime.Now; | |
elapsed = t2 - t1; | |
xferRate = (long)(XferBytes / elapsed.TotalMilliseconds); | |
xferRate = xferRate / (int)100 * (int)100; | |
tListen = null; | |
StartBtn.BackColor = Color.Aquamarine; | |
} | |
/*Summary | |
Updates the CPU Load meter. | |
*/ | |
private void PerfTimer_Tick(object sender, EventArgs e) | |
{ | |
if (bVista) return; | |
float cpu = CpuCounter.NextValue(); | |
CpuBar.Value = (int)cpu; | |
CpuLabel.Text = string.Format("{0} %", (int)cpu); | |
} | |
private void enableLoggingButton_CheckedChanged(object sender, EventArgs e) | |
{ | |
EnableLogging = enableLoggingButton.Checked; | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#pragma noiv // Do not generate interrupt vectors | |
//----------------------------------------------------------------------------- | |
// File: slave.c | |
// Contents: Hooks required to implement USB peripheral function. | |
// Code written for FX2 REVE 56-pin and above. | |
// This firmware is used to demonstrate FX2 Slave FIFO | |
// operation. | |
// Copyright (c) 2003 Cypress Semiconductor All rights reserved | |
//----------------------------------------------------------------------------- | |
#include "Fx2.h" | |
#include "fx2regs.h" | |
#include "syncdly.h" // SYNCDELAY macro | |
#define LED_ALL (bmBIT0 | bmBIT1 | bmBIT2 | bmBIT3) | |
extern BOOL GotSUD; // Received setup data flag | |
extern BOOL Sleep; | |
extern BOOL Rwuen; | |
extern BOOL Selfpwr; | |
BYTE Configuration; // Current configuration | |
BYTE AlternateSetting; // Alternate settings | |
static WORD __xdata LED_Count = 0; | |
static BYTE __xdata LED_Status = 0; | |
BOOL done_frm_fpga = 0; | |
// EZUSB FX2 PORTA = slave fifo enable(s), when IFCFG[1:0]=11 | |
// sbit PA0 = IOA ^ 0; // alt. func., INT0# | |
// sbit PA1 = IOA ^ 1; // alt. func., INT1# | |
// sbit PA2 = IOA ^ 2; // is SLOE | |
// sbit PA3 = IOA ^ 3; // alt. func., WU2 | |
// sbit PA4 = IOA ^ 4; // is FIFOADR0 | |
// sbit PA5 = IOA ^ 5; // is FIFOADR1 | |
// sbit PA6 = IOA ^ 6; // is PKTEND | |
// sbit PA7 = IOA ^ 7; // is FLAGD | |
// EZUSB FX2 PORTC i/o... port NA for 56-pin FX2 | |
// sbit PC0 = IOC ^ 0; | |
// sbit PC1 = IOC ^ 1; | |
// sbit PC2 = IOC ^ 2; | |
// sbit PC3 = IOC ^ 3; | |
// sbit PC4 = IOC ^ 4; | |
// sbit PC5 = IOC ^ 5; | |
// sbit PC6 = IOC ^ 6; | |
// sbit PC7 = IOC ^ 7; | |
// EZUSB FX2 PORTB = FD[7:0], when IFCFG[1:0]=11 | |
// sbit PB0 = IOB ^ 0; | |
// sbit PB1 = IOB ^ 1; | |
// sbit PB2 = IOB ^ 2; | |
// sbit PB3 = IOB ^ 3; | |
// sbit PB4 = IOB ^ 4; | |
// sbit PB5 = IOB ^ 5; | |
// sbit PB6 = IOB ^ 6; | |
// sbit PB7 = IOB ^ 7; | |
// EZUSB FX2 PORTD = FD[15:8], when IFCFG[1:0]=11 and WORDWIDE=1 | |
//sbit PD0 = IOD ^ 0; | |
//sbit PD1 = IOD ^ 1; | |
//sbit PD2 = IOD ^ 2; | |
//sbit PD3 = IOD ^ 3; | |
//sbit PD4 = IOD ^ 4; | |
//sbit PD5 = IOD ^ 5; | |
//sbit PD6 = IOD ^ 6; | |
//sbit PD7 = IOD ^ 7; | |
// EZUSB FX2 PORTE is not bit-addressable... | |
//----------------------------------------------------------------------------- | |
// Task Dispatcher hooks | |
// The following hooks are called by the task dispatcher. | |
//----------------------------------------------------------------------------- | |
//void LED_Off (BYTE LED_Mask); | |
//void LED_On (BYTE LED_Mask); | |
//----------------------------------------------------------------------------- | |
// Task Dispatcher hooks | |
// The following hooks are called by the task dispatcher. | |
//----------------------------------------------------------------------------- | |
void TD_Init( void ) | |
{ // Called once at startup | |
/* | |
CPUCS[4:3] CLKSPD[1:0] 00 = 12MHz, 01 = 24MHz, 10 = 48MHz | |
CPUCS.2 CLKINV 0 = CLKOUT signal not inverted, 1 = CLKOUT signal inverted. | |
CPUCS.1 CLKOE 0 = CLKOUT pin floats, 1 = CLKOUT pin driven. | |
CPUCS.0 8051RES CPU RESET (read only) | |
*/ | |
CPUCS = 0x10; // (00010000) | |
// FIFOPINPOLAR |= 0x03; | |
PINFLAGSAB = 0x08; // FLAGB => Indexed FF, FLAGA => EP2EF (0b00001000) | |
SYNCDELAY; | |
PINFLAGSCD = 0xE0; // FLAGD - EP6FF, FLAGC => Indexed EF (0b11100000) | |
SYNCDELAY; | |
/* | |
PORTACFG.7 FLAGD If IFCFG[1:0] = 11, setting this bit to '1' configures the PA7 pin as FLAGD, a programmable FIFO flag. | |
PORTACFG.6 SLCS If IFCFG[1:0] = 11, setting this bit to '1' configures the PA7 pin as SLCS, the slave FIFO chip select. | |
PORTACFG[1:0] INT[1:0] Setting these bits to '1' configures these PORTA pins as the INT1 or INT0 pins. | |
*/ | |
PORTACFG |= 0x80; // (0b10000000) | |
SYNCDELAY; | |
/* | |
IFCONFIG.7 selects between internal and external sources: 0 = external, 1 = internal. | |
IFCONFIG.6 selects between the 30- and 48-MHz internal clock: 0 = 30 MHz, 1 = 48 MHz | |
IFCONFIG.5 is the output enable for the internal clock source: 0 = disable, 1 = enable. This bit must not be set to 1 when IFCONFIG.7 = 0. | |
IFCONFIG.4 inverts the polarity of the interface clock (either internal or external): 0 = normal, 1 = inverted. | |
IFCONFIG.3 0 = sync, 1 = async | |
IFCONFIG[1:0] enables slave FIFO when set to 11 | |
*/ | |
IFCONFIG = 0x07; // (11000111) | |
SYNCDELAY; | |
// IFCLKSRC=1 , FIFOs executes on internal clk source | |
// xMHz=1 , 48MHz operation | |
// IFCLKOE=1 ,Drive IFCLK pin signal at 48MHz | |
// IFCLKPOL=0 , Don't invert IFCLK pin signal from internal clk | |
// ASYNC=0 , master samples synchronous | |
// GSTATE=0 , Don't drive GPIF states out on PORTE[2:0], debug WF | |
// IFCFG[1:0]=11, FX2 in slave FIFO mode | |
// Registers which require a synchronization delay, see section 15.14 | |
// FIFORESET FIFOPINPOLAR | |
// INPKTEND OUTPKTEND | |
// EPxBCH:L REVCTL | |
// GPIFTCB3 GPIFTCB2 | |
// GPIFTCB1 GPIFTCB0 | |
// EPxFIFOPFH:L EPxAUTOINLENH:L | |
// EPxFIFOCFG EPxGPIFFLGSEL | |
// PINFLAGSxx EPxFIFOIRQ | |
// EPxFIFOIE GPIFIRQ | |
// GPIFIE GPIFADRH:L | |
// UDMACRCH:L EPxGPIFTRIG | |
// GPIFTRIG | |
// Note: The pre-REVE EPxGPIFTCH/L register are affected, as well... | |
// ...these have been replaced by GPIFTC[B3:B0] registers | |
/* | |
EPxCFG.7 VALID 1 = Activate an Endpoint. 0 = Deactivate an endpoint. An endpoint whose VALID bit is 0 does not respond to any USB traffic. | |
EPxCFG.6 DIR Sets Endpoint Direction. 0 = OUT, 1 = IN | |
EPxCGF[5:4] TYPE[1:0] Defines the Endpoint Type. The TYPE bits apply to all of the large-endpoint configuration registers. | |
00 Invalid | |
01 Isochronous | |
10 Bulk (default) | |
11 Interrupt | |
EPxCFG.3 SIZE Sets Size of Endpoint Buffer. Endpoints 4 and 8 can only be 512 bytes. Endpoints 2 and 6 are selectable. | |
0 512 bytes | |
1 1024 bytes | |
EPxCFG[1:0] BUF[1:0] Buffering Type/Amount. | |
00 Quad | |
01 Invalid | |
10 Double | |
11 Triple | |
*/ | |
// EP4 and EP8 are not used in this implementation... | |
EP2CFG = 0xA0; // (0b10100000) out 512 bytes, 4x, bulk | |
SYNCDELAY; | |
EP6CFG = 0xF0; // (0b11110000) in 512 bytes, 4x, interrupt | |
SYNCDELAY; | |
EP4CFG = 0x02; // (0b00000010) clear valid bit | |
SYNCDELAY; | |
EP8CFG = 0x02; // (0b00000010) clear valid bit | |
SYNCDELAY; | |
SYNCDELAY; | |
FIFORESET = 0x80; // activate NAK-ALL to avoid race conditions | |
SYNCDELAY; // see TRM section 15.14 | |
FIFORESET = 0x02; // reset, FIFO 2 | |
SYNCDELAY; // | |
FIFORESET = 0x04; // reset, FIFO 4 | |
SYNCDELAY; // | |
FIFORESET = 0x06; // reset, FIFO 6 | |
SYNCDELAY; // | |
FIFORESET = 0x08; // reset, FIFO 8 | |
SYNCDELAY; // | |
FIFORESET = 0x00; // deactivate NAK-ALL | |
SYNCDELAY; | |
// handle the case where we were already in AUTO mode... | |
// ...for example: back to back firmware downloads... | |
/* | |
EPxFIFOCFG.6 INFM1 In Full Minus One | |
EPxFIFOCFG.5 OEP1 Out Empty Plus One | |
EPxFIFOCFG.4 AUTOOUT 1 = Auto Commit, 0 = Manually Commit | |
EPxFIFOCFG.3 AUTOIN 1 = Auto Commit, 0 = Manually Commit | |
EPxFIFOCFG.2 ZEROLENIN 1 = Zero length packet is sent when there is no data in the buffer, 0 = Zero length packets are sent on PKTEND. | |
EPxFIFOCFG.0 WORDWIDE 0 = byte, 1 = word | |
*/ | |
EP2FIFOCFG = 0x00; // AUTOOUT=0, WORDWIDE=0 | |
SYNCDELAY; | |
// core needs to see AUTOOUT=0 to AUTOOUT=1 switch to arm endp's | |
EP2FIFOCFG = 0x10; // (00010001) AUTOOUT=1, WORDWIDE=0 | |
SYNCDELAY; | |
EP6FIFOCFG = 0x0C; // (00001101) AUTOIN=1, ZEROLENIN=1, WORDWIDE=0 | |
SYNCDELAY; | |
} | |
void TD_Poll( void ) | |
{ | |
} | |
BOOL TD_Suspend( void ) | |
{ // Called before the device goes into suspend mode | |
return( TRUE ); | |
} | |
BOOL TD_Resume( void ) | |
{ // Called after the device resumes | |
return( TRUE ); | |
} | |
//----------------------------------------------------------------------------- | |
// Device Request hooks | |
// The following hooks are called by the end point 0 device request parser. | |
//----------------------------------------------------------------------------- | |
BOOL DR_GetDescriptor( void ) | |
{ | |
return( TRUE ); | |
} | |
BOOL DR_SetConfiguration( void ) | |
{ // Called when a Set Configuration command is received | |
if( EZUSB_HIGHSPEED( ) ) | |
{ // ...FX2 in high speed mode | |
EP6AUTOINLENH = 0x02; | |
SYNCDELAY; | |
EP8AUTOINLENH = 0x02; // set core AUTO commit len = 512 bytes | |
SYNCDELAY; | |
EP6AUTOINLENL = 0x00; | |
SYNCDELAY; | |
EP8AUTOINLENL = 0x00; | |
} | |
else | |
{ // ...FX2 in full speed mode | |
EP6AUTOINLENH = 0x00; | |
SYNCDELAY; | |
EP8AUTOINLENH = 0x00; // set core AUTO commit len = 64 bytes | |
SYNCDELAY; | |
EP6AUTOINLENL = 0x40; | |
SYNCDELAY; | |
EP8AUTOINLENL = 0x40; | |
} | |
Configuration = SETUPDAT[ 2 ]; | |
return( TRUE ); // Handled by user code | |
} | |
BOOL DR_GetConfiguration( void ) | |
{ // Called when a Get Configuration command is received | |
EP0BUF[ 0 ] = Configuration; | |
EP0BCH = 0; | |
EP0BCL = 1; | |
return(TRUE); // Handled by user code | |
} | |
BOOL DR_SetInterface( void ) | |
{ // Called when a Set Interface command is received | |
AlternateSetting = SETUPDAT[ 2 ]; | |
return( TRUE ); // Handled by user code | |
} | |
BOOL DR_GetInterface( void ) | |
{ // Called when a Set Interface command is received | |
EP0BUF[ 0 ] = AlternateSetting; | |
EP0BCH = 0; | |
EP0BCL = 1; | |
return( TRUE ); // Handled by user code | |
} | |
BOOL DR_GetStatus( void ) | |
{ | |
return( TRUE ); | |
} | |
BOOL DR_ClearFeature( void ) | |
{ | |
return( TRUE ); | |
} | |
BOOL DR_SetFeature( void ) | |
{ | |
return( TRUE ); | |
} | |
BOOL DR_VendorCmnd( void ) | |
{ | |
return( TRUE ); | |
} | |
//----------------------------------------------------------------------------- | |
// USB Interrupt Handlers | |
// The following functions are called by the USB interrupt jump table. | |
//----------------------------------------------------------------------------- | |
// Setup Data Available Interrupt Handler | |
void ISR_Sudav( void ) __interrupt 0 | |
{ | |
GotSUD = TRUE; // Set flag | |
EZUSB_IRQ_CLEAR( ); | |
USBIRQ = bmSUDAV; // Clear SUDAV IRQ | |
} | |
// Setup Token Interrupt Handler | |
void ISR_Sutok( void ) __interrupt 0 | |
{ | |
EZUSB_IRQ_CLEAR( ); | |
USBIRQ = bmSUTOK; // Clear SUTOK IRQ | |
} | |
void ISR_Sof( void ) __interrupt 0 | |
{ | |
EZUSB_IRQ_CLEAR( ); | |
USBIRQ = bmSOF; // Clear SOF IRQ | |
} | |
void ISR_Ures( void ) __interrupt 0 | |
{ | |
if ( EZUSB_HIGHSPEED( ) ) | |
{ | |
pConfigDscr = pHighSpeedConfigDscr; | |
pOtherConfigDscr = pFullSpeedConfigDscr; | |
} | |
else | |
{ | |
pConfigDscr = pFullSpeedConfigDscr; | |
pOtherConfigDscr = pHighSpeedConfigDscr; | |
} | |
EZUSB_IRQ_CLEAR( ); | |
USBIRQ = bmURES; // Clear URES IRQ | |
} | |
void ISR_Susp( void ) __interrupt 0 | |
{ | |
Sleep = TRUE; | |
EZUSB_IRQ_CLEAR( ); | |
USBIRQ = bmSUSP; | |
} | |
void ISR_Highspeed( void ) __interrupt 0 | |
{ | |
if ( EZUSB_HIGHSPEED( ) ) | |
{ | |
pConfigDscr = pHighSpeedConfigDscr; | |
pOtherConfigDscr = pFullSpeedConfigDscr; | |
} | |
else | |
{ | |
pConfigDscr = pFullSpeedConfigDscr; | |
pOtherConfigDscr = pHighSpeedConfigDscr; | |
} | |
EZUSB_IRQ_CLEAR( ); | |
USBIRQ = bmHSGRANT; | |
} | |
void ISR_Ep0ack( void ) __interrupt 0 | |
{ | |
} | |
void ISR_Stub( void ) __interrupt 0 | |
{ | |
} | |
void ISR_Ep0in( void ) __interrupt 0 | |
{ | |
} | |
void ISR_Ep0out( void ) __interrupt 0 | |
{ | |
} | |
void ISR_Ep1in( void ) __interrupt 0 | |
{ | |
} | |
void ISR_Ep1out( void ) __interrupt 0 | |
{ | |
} | |
void ISR_Ep2inout( void ) __interrupt 0 | |
{ | |
} | |
void ISR_Ep4inout( void ) __interrupt 0 | |
{ | |
} | |
void ISR_Ep6inout( void ) __interrupt 0 | |
{ | |
} | |
void ISR_Ep8inout( void ) __interrupt 0 | |
{ | |
} | |
void ISR_Ibn( void ) __interrupt 0 | |
{ | |
} | |
void ISR_Ep0pingnak( void ) __interrupt 0 | |
{ | |
} | |
void ISR_Ep1pingnak( void ) __interrupt 0 | |
{ | |
} | |
void ISR_Ep2pingnak( void ) __interrupt 0 | |
{ | |
} | |
void ISR_Ep4pingnak( void ) __interrupt 0 | |
{ | |
} | |
void ISR_Ep6pingnak( void ) __interrupt 0 | |
{ | |
} | |
void ISR_Ep8pingnak( void ) __interrupt 0 | |
{ | |
} | |
void ISR_Errorlimit( void ) __interrupt 0 | |
{ | |
} | |
void ISR_Ep2piderror( void ) __interrupt 0 | |
{ | |
} | |
void ISR_Ep4piderror( void ) __interrupt 0 | |
{ | |
} | |
void ISR_Ep6piderror( void ) __interrupt 0 | |
{ | |
} | |
void ISR_Ep8piderror( void ) __interrupt 0 | |
{ | |
} | |
void ISR_Ep2pflag( void ) __interrupt 0 | |
{ | |
} | |
void ISR_Ep4pflag( void ) __interrupt 0 | |
{ | |
} | |
void ISR_Ep6pflag( void ) __interrupt 0 | |
{ | |
} | |
void ISR_Ep8pflag( void ) __interrupt 0 | |
{ | |
} | |
void ISR_Ep2eflag( void ) __interrupt 0 | |
{ | |
} | |
void ISR_Ep4eflag( void ) __interrupt 0 | |
{ | |
} | |
void ISR_Ep6eflag( void ) __interrupt 0 | |
{ | |
} | |
void ISR_Ep8eflag( void ) __interrupt 0 | |
{ | |
} | |
void ISR_Ep2fflag( void ) __interrupt 0 | |
{ | |
} | |
void ISR_Ep4fflag( void ) __interrupt 0 | |
{ | |
} | |
void ISR_Ep6fflag( void ) __interrupt 0 | |
{ | |
} | |
void ISR_Ep8fflag( void ) __interrupt 0 | |
{ | |
} | |
void ISR_GpifComplete( void ) __interrupt 0 | |
{ | |
} | |
void ISR_GpifWaveform( void ) __interrupt 0 | |
{ | |
} | |
// ...debug LEDs: accessed via movx reads only ( through CPLD ) | |
// it may be worth noting here that the default monitor loads at 0xC000 | |
__xdata __at 0x8000 volatile const BYTE LED0_ON ; | |
__xdata __at 0x8100 volatile const BYTE LED0_OFF ; | |
__xdata __at 0x9000 volatile const BYTE LED1_ON ; | |
__xdata __at 0x9100 volatile const BYTE LED1_OFF ; | |
__xdata __at 0xA000 volatile const BYTE LED2_ON ; | |
__xdata __at 0xA100 volatile const BYTE LED2_OFF ; | |
__xdata __at 0xB000 volatile const BYTE LED3_ON ; | |
__xdata __at 0xB100 volatile const BYTE LED3_OFF ; | |
// use this global variable when (de)asserting debug LEDs... | |
BYTE __xdata ledX_rdvar = 0x00; | |
BYTE __xdata LED_State = 0; | |
void LED_Off (BYTE LED_Mask) | |
{ | |
if (LED_Mask & bmBIT0) | |
{ | |
ledX_rdvar = LED0_OFF; | |
LED_State &= ~bmBIT0; | |
} | |
if (LED_Mask & bmBIT1) | |
{ | |
ledX_rdvar = LED1_OFF; | |
LED_State &= ~bmBIT1; | |
} | |
if (LED_Mask & bmBIT2) | |
{ | |
ledX_rdvar = LED2_OFF; | |
LED_State &= ~bmBIT2; | |
} | |
if (LED_Mask & bmBIT3) | |
{ | |
ledX_rdvar = LED3_OFF; | |
LED_State &= ~bmBIT3; | |
} | |
} | |
void LED_On (BYTE LED_Mask) | |
{ | |
if (LED_Mask & bmBIT0) | |
{ | |
ledX_rdvar = LED0_ON; | |
LED_State |= bmBIT0; | |
} | |
if (LED_Mask & bmBIT1) | |
{ | |
ledX_rdvar = LED1_ON; | |
LED_State |= bmBIT1; | |
} | |
if (LED_Mask & bmBIT2) | |
{ | |
ledX_rdvar = LED2_ON; | |
LED_State |= bmBIT2; | |
} | |
if (LED_Mask & bmBIT3) | |
{ | |
ledX_rdvar = LED3_ON; | |
LED_State |= bmBIT3; | |
} | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment