using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; using AIOWDMNet; // the namespace exposes the AIOWDM Class interface namespace PCIDA { public partial class Form1 : Form { UInt32 Status = 0; const UInt32 MAX_CARDS = 10; public Int32 NumCards = 1; // We can handle multiple cards but will only handle one card at a time // This is the basic data that we will be using to interface with the selected card: public Int32 CardNum = 0; // The index of the one card we will be using public UInt32 Channels = 8; // The number of channels on this card public UInt32 Offset, EPROMAddress; // These are the addresses of the card selected public bool TimerEnabled = false; // DAC data and flag; bool RunFlag; uint XValue; uint Value; // This will hold the data for each individual card installed in the system and detected: public struct TCardData { public bool IsValid; public bool IsSelected; public UInt32 DeviceID; public UInt32 Base; // This the result of findcards and the base address of the card public UInt32 EPROMBase; // This the result of QueryBARBase and the EPROM base address of the card public UInt32 numChan; }; public TCardData CardData; // only set up for one card here public UInt32[] PortOffsets = new UInt32[5] { 0, 4, 8, 12, 16 }; // offsets for 5 max ports // Interval Timer fou GUI update: // Note: Consider using other timers and threading to run faster. // Note: A Windows Forms timer designed for single threaded environments not a System Timer 55 ms min res static System.Windows.Forms.Timer myTimer = new System.Windows.Forms.Timer(); public Form1() { InitializeComponent(); // Initialize default values: // Ping the driver AIOWDM.SYS first: // This is the one place we actual might use all 16 bits returned for an error code AA55 // otherwise we only use an 8 bit byte of data per read and write: if (AIOWDM.InPortB(0x61) == 0xAA55) //Driver Call this is an absolute address no relative address function { MessageBox.Show(" AIOWDM.SYS not detected.\r\n Please copy AIOWDM.SYS into [Windows]/system32/drivers and re-run this sample.\r\n Ensure that a board is installed properly.", "Warning"); } // Check device info: Int32 iNumCards = AIOWDM.GetNumCards(); FindCardsWDM(); // This will get all the card info textBoxStatus.AppendText("\r\nThis sample outputs a simple sine wave pattern on the DAC channel selected.\r\n"); if (RunFlag) { comboBoxPort.SelectedIndex = 0; // default to first card found if any comboBoxNumChan.SelectedIndex = 0; // default to 8 channels } // Add the event and the event handler for the method that will // process the timer event to the timer: myTimer.Tick += new EventHandler(TimerEventProcessor); // Set the timer interval in miliseconds and start 55ms min resolution: myTimer.Interval = 60; } private void Form1_Load(object sender, EventArgs e) { } private void FindCardsWDM() { bool found = false; char[] AddStr = new char[256]; // Vars for QueryCardInfo() : UInt32 DeviceID, Base, EPROMBase; UInt32 NameSize = 256; UInt16[] Name = new UInt16[256]; String strname; // Init: RunFlag = true; NumCards = 0; int DataIndex = 0; // Set CardData to 0 as needed max 10 cards: CardData.IsValid = false; CardData.IsSelected = false; CardData.DeviceID = 0; CardData.Base = 0; CardData.EPROMBase = 0; CardData.numChan = 8; // Get the total number of cards installed: NumCards = AIOWDM.GetNumCards(); if (NumCards == 0) // no cards present { textBoxStatus.Text = "No cards were found!\r\n"; textBoxStatus.AppendText(" This may mean the card is not installed.\r\n"); textBoxStatus.AppendText(" Check Device Manager for a card and its status.\r\n"); textBoxStatus.AppendText(" You may consider rebooting your system.\r\n"); comboBoxPort.Enabled = false; RunFlag = false; } else { // Loop through the cards ,validate, flag and store card data: for (CardNum = 0; CardNum != NumCards; CardNum++) { NameSize = 256; // This is where we get the basic card info we need: Status = AIOWDM.QueryCardInfo((Int32)CardNum, out DeviceID, out Base, out NameSize, out strname); AIOWDM.QueryBARBase((Int32)CardNum, (UInt32)3, out EPROMBase); // Populate list box with addresses etc found and set flags: switch (DeviceID) { case 0x6CA8: String strLabel = String.Format("Card: {0,0:00}, Name: PCI-DA12-8, Address: {1,4:X}, {2,4:X}", DataIndex, (Base & 0xFFF8), (EPROMBase & 0xFFF8) ); //correct EEPROM comboBoxPort.Items.Add(strLabel); CardData.IsValid = true; CardData.DeviceID = DeviceID; CardData.Base = Base & 0xFFF8; CardData.EPROMBase = EPROMBase & 0xFFF8; CardData.numChan = 8; found = true; break; default: break; } }// end loop on validate present cards }//end else card present // If card(s) are present but no valid cards were found: if ((NumCards != 0) && (found == false) ) { textBoxStatus.Text = "No valid card was found!\r\n"; textBoxStatus.AppendText(" This may mean the card is not installed.\r\n"); textBoxStatus.AppendText(" Check Device Manager for a card and its status.\r\n"); textBoxStatus.AppendText(" You may consider rebooting your system.\r\n"); comboBoxPort.Enabled = false; RunFlag = false; } if (RunFlag) { // This is the result setting the active addresses to be used etc: comboBoxPort.SelectedIndex = 0; CardNum = comboBoxPort.SelectedIndex; //Offset = CardData.Base; //default to first valid base (Port 0) Offset = PortOffsets[0]; //default to first valid base (Port 0) EPROMAddress = CardData.EPROMBase; //default to first valid EEPROM found CardData.IsSelected = true; } } private void comboBoxPort_SelectedIndexChanged(object sender, EventArgs e) { // Update the GUI with new selection: String SelStr, strAddress; SelStr = comboBoxPort.Items[comboBoxPort.SelectedIndex].ToString(); strAddress = SelStr.Substring(SelStr.Length - 4); Offset = (uint)Convert.ToInt32(strAddress, 16); textBoxStatus.AppendText("\r\n New Port Selected: "); textBoxStatus.AppendText(SelStr); // Reset the adresses used to ones that are selected: CardData.IsSelected = false; //reset CardNum = comboBoxPort.SelectedIndex; //Offset = CardData.Base; EPROMAddress = CardData.EPROMBase; CardData.IsSelected = true; //Set new Offset from Array of correct offsets Offset = PortOffsets[comboBoxPort.SelectedIndex]; } private void TimerEventProcessor(Object myObject, EventArgs myEventArgs) { // This is the method that runs when the timer event is raised: myTimer.Stop(); //if() // may need to test UpdateGUIState(); myTimer.Enabled = true; } private void UpdateGUIState() { double RValue = Math.Sin(++Value / 50.0); double OutValue = RValue * 2048.0 + 2048.0; int Chan = comboBoxNumChan.SelectedIndex; if (RunFlag) AIOWDM.OutPort((uint)(CardData.Base + Chan * 2), Cal((ushort)OutValue, Chan)); //AIOWDM.RelOutPort(CardNum, (uint)(Offset + Chan * 2), Cal((ushort)OutValue, Chan)); } private void btnPerformIO_Click(object sender, EventArgs e) { if (TimerEnabled) { TimerEnabled = false; myTimer.Stop(); btnPerformIO.Text = "Perform I/O"; } else { TimerEnabled = true; myTimer.Enabled = true; btnPerformIO.Text = "Stop I/O"; } //Setup DAC: AIOWDM.InPortB(CardData.Base + 0xF); AIOWDM.InPortB(CardData.Base + 0x2); //AIOWDM.RelInPortB(CardNum, Offset + 0xF); //AIOWDM.RelInPortB(CardNum, Offset + 0x2); XValue = Value = 0; } private ushort Cal(ushort InValue, int Ch) { // Please note: InPortB is quite slow in Windows; consider building an // array of "a" and "b" per channel during init-phase -- the code would run 100x faster, or more, // on a modern computer. uint EBase = EPROMAddress; uint temp = (uint) (EBase + ((Ch * 2) + (AIOWDM.InPortB((uint)(EBase + 240 + Ch)) * 32)) + 1); //uint temp = (uint)(EBase + ((Ch * 2) + (AIOWDM.RelInPortB(CardNum, (uint)(EBase + 240 + Ch)) * 32)) + 1); ushort a = AIOWDM.InPortB(temp); //ushort a = AIOWDM.RelInPortB(CardNum, temp); temp = (uint) (EBase + ((Ch * 2) + (AIOWDM.InPortB((uint)(EBase + 240 + Ch)) * 32))); //temp = (uint)(EBase + ((Ch * 2) + (AIOWDM.RelInPortB(CardNum, (uint)(EBase + 240 + Ch)) * 32))); ushort b = AIOWDM.InPortB(temp); //ushort b = AIOWDM.RelInPortB(CardNum, temp); ushort OutValue = (ushort) ( ((4095.0 - a - b) / 4095.0) * InValue + b ); return OutValue; } private void btnExit_Click(object sender, EventArgs e) { // Right now this is only called on button click not window close ALtF4 etc: // Kill the timer: myTimer.Stop(); myTimer.Enabled = false; myTimer.Dispose(); // Close the form and Application: this.Close(); } } }