Skip to content

Instantly share code, notes, and snippets.

@ismell
Last active August 29, 2015 13:57
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ismell/9390416 to your computer and use it in GitHub Desktop.
Save ismell/9390416 to your computer and use it in GitHub Desktop.
CyAPI Corruption Issue
;;-----------------------------------------------------------------------------
;; 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
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;
}
}
}
#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