K8061 driver in c# help

Hi, I’m trying to translate the driver into c#. My problem is that I have to open 1 card at a time. Multiple applications need to open there own K8061 card. So after some digging the web, I arrived at this point, but now I’m stuck.
var numberOfCards = MPUSB.GetDeviceCount(vid_pid_norm);
numberOfCards is always 0. Anybody any Idea (I’m on a Win7 64Bit, so put your project in x86 mode) and copy the mpusbapi.dll to your bin/debug folder

MPUSB.cs

[code]using System;
using System.Runtime.InteropServices;
using DWORD = System.UInt32;
using HANDLE = System.UInt32;

public class MPUSB
{
public const HANDLE INVALID_HANDLE_VALUE = 0xFFFFFFFF;
public const DWORD SUCCESS = 1;
public const DWORD FAIL = 0;

public enum PipeDir : uint
{
    Write = 0,
    Read = 1
}

public const int maxDevs = 127;

[DllImport("mpusbapi.dll", EntryPoint = "_MPUSBGetDLLVersion", CallingConvention = CallingConvention.Cdecl)]
public static extern DWORD MPUSBGetDLLVersion();
//, EntryPoint = "_MPUSBGetDeviceCount", CallingConvention = CallingConvention.Cdecl)]
[DllImport("mpusbapi.dll", EntryPoint = "_MPUSBGetDeviceCount")] 
public static extern DWORD GetDeviceCount([MarshalAs(UnmanagedType.LPStr)] string pVID_PID);

[DllImport("mpusbapi.dll", EntryPoint = "_MPUSBOpen", SetLastError = true, CallingConvention = CallingConvention.Cdecl)]
public static extern DWORD Open(DWORD instance,
   [MarshalAs(UnmanagedType.LPStr)] string pVID_PID,
   [MarshalAs(UnmanagedType.LPStr)] string pEP,
      [MarshalAs(UnmanagedType.U4)] PipeDir dwDir,
                                    DWORD dwReserved);

[DllImport("mpusbapi.dll", EntryPoint = "_MPUSBRead", SetLastError = true, CallingConvention = CallingConvention.Cdecl)]
public static extern DWORD Read(HANDLE handle,
 [MarshalAs(UnmanagedType.LPArray)] byte[] pData,
                                    DWORD dwLen,
                                out DWORD pLength,
                                    DWORD dwMilliseconds);

[DllImport("mpusbapi.dll", EntryPoint = "_MPUSBWrite", SetLastError = true, CallingConvention = CallingConvention.Cdecl)]
public static extern DWORD Write(HANDLE handle,
 [MarshalAs(UnmanagedType.LPArray)] byte[] pData,
                                    DWORD dwLen,
                                out DWORD pLength,
                                    DWORD dwMilliseconds);

[DllImport("mpusbapi.dll", EntryPoint = "_MPUSBReadInt", CallingConvention = CallingConvention.Cdecl)]
public static extern DWORD ReadInt(HANDLE handle,
 [MarshalAs(UnmanagedType.LPArray)] byte[] pData,
                                    DWORD dwLen,
                                out DWORD pLength,
                                    DWORD dwMilliseconds);

[DllImport("mpusbapi.dll", EntryPoint = "_MPUSBClose", CallingConvention = CallingConvention.Cdecl)]
public static extern bool Close(HANDLE handle);

public static DWORD DLLVersion { get { return MPUSBGetDLLVersion(); } }
public static void GetDLLVersion(out ushort major, out ushort minor)
{
    DWORD ver = DLLVersion;
    major = (ushort)(DLLVersion >> 16);
    minor = (ushort)(DLLVersion & 0x0000FFFF);
}

}[/code]

Program.cs

[code]using System;
using DWORD = System.UInt32;

namespace K8061DriverCSharp
{
class Program
{

    static void Main(string[] args)
    {
        try
        {
            var prgr = new K8061Connector(1);
            prgr.Dispose();
        }
        catch (Exception ex)
        {
            Console.WriteLine(ex.Message);
        }
        Console.ReadLine();
    }
}
public class K8061Connector : IDisposable
{
    public const string vid_pid_norm = "vid_10cf&pid_8061";
    const string out_pipe = @"\MCHP_EP1";
    const string in_pipe = @"\MCHP_EP1";
    internal static readonly IntPtr INVALID_HANDLE_VALUE = new IntPtr(-1);
    private uint myOutPipe;
    private uint myInPipe;
    public int CardNumber { get; set; }
    public bool IsOpen { get; set; }
    public int NumberOfCards { get; set; }

    public K8061Connector(int cardNumber)
    {
        CardNumber = cardNumber;
        Open();
        SetDigitalChannel(0, true);
    }

    private bool Open()
    {
        //ushort a = 0;
        //ushort b = 0;
        //MPUSB.GetDLLVersion(out a,out b);
        if (IsOpen) return true;
        IsOpen = false;
        var numberOfCards = MPUSB.GetDeviceCount(vid_pid_norm);
        NumberOfCards = Convert.ToInt32(numberOfCards);
        //if (NumberOfCards==0) throw new Exception("No cards found!");
        DWORD selection = 0;// (DWORD)CardNumber; // Selects the device to connect to, in this example it is assumed you will only have one device per vid_pid connected.
        myOutPipe = MPUSB.Open(selection, vid_pid_norm, out_pipe, MPUSB.PipeDir.Write, 0);
        myInPipe = MPUSB.Open(selection, vid_pid_norm, in_pipe, MPUSB.PipeDir.Read, 0);
      
        if (myInPipe == 0 || myOutPipe == 0) return false;
        var send_buf = new byte[1];
        var receive_buf = new byte[2];

        send_buf[0] = 12;  //JUMPERS
        uint bytesWritten;
        uint bytesRead;
        var h1 = MPUSB.Write(myOutPipe, send_buf, (uint)send_buf.Length, out bytesWritten, 1000);
        var h2 = MPUSB.Write(myInPipe, receive_buf, (uint)receive_buf.Length, out bytesRead, 1000);
        var tmp = receive_buf[1];
        var count = MPUSB.GetDeviceCount(vid_pid_norm);
        SetAllDigital();
        IsOpen = true;
        return IsOpen;
    }





    #region Analog
    public int ReadAnalogChannel(int channel)
    {
        if (channel > 8) channel = 8;
        if (channel < 1) channel = 1;
        var send_buf = new byte[2];
        var receive_buf = new byte[4];
        send_buf[0] = 0; //READ_ANALOG_CH
        send_buf[1] = Convert.ToByte((channel - 1));
        OutIn(send_buf, receive_buf);
        int result = receive_buf[2] + 256 * receive_buf[3];
        return result;
    }
    public int ReadAllAnalog()
    {
        var send_buf = new byte[1];
        send_buf[0] = 1; // READ_ALL_ANALOG
        var receive_buf = new byte[17];
        OutIn(send_buf, receive_buf);
        for (int i = 0; i < 8; i++)
        {
            var n = receive_buf[i * 2 + 1] + 256 * receive_buf[i * 2 + 2];
            //           n:=receive_buf[i*2+1]+256*receive_buf[i*2+2];
            //p^:=n;
            //inc(p);
        }
        return 1;
    }

    public void OutputAnalogChannel(int channel, byte value)
    {
        if (channel > 8) channel = 8;
        if (channel < 1) channel = 1;
        var send_buf = new byte[3];
        var receive_buf = new byte[4];
        send_buf[0] = 2; // OUT_ANALOG_CH
        send_buf[1] = Convert.ToByte((channel - 1));
        send_buf[2] = value;
        OutIn(send_buf, receive_buf);
    }
    public void OutputAnalogChannel(int channel, byte[] values)
    {
        if (channel > 8) channel = 8;
        if (channel < 1) channel = 1;
        if (values.Length == 0 || values.Length > 8) throw new Exception("Invalid values length");
        var send_buf = new byte[9];
        var receive_buf = new byte[2];
        send_buf[0] = 3;    // OUT_ALL_ANALOG
        send_buf[1] = Convert.ToByte((channel - 1));
        for (int i = 0; i < values.Length; i++)
        {
            send_buf[i + 1] = values[i];
        }
        OutIn(send_buf, receive_buf);
    }
    public void ClearAnalogChannel(int channel)
    {
        if (channel > 8) channel = 8;
        if (channel < 1) channel = 1;
        var send_buf = new byte[3];
        var receive_buf = new byte[4];
        send_buf[0] = 2;  // OUT_ANALOG_CH
        send_buf[1] = Convert.ToByte((channel - 1));
        send_buf[2] = 0;
        OutIn(send_buf, receive_buf);
    }
    public void ClearAllAnalog()
    {
        var send_buf = new byte[9];
        var receive_buf = new byte[2];
        send_buf[0] = 3;    // OUT_ALL_ANALOG
        OutIn(send_buf, receive_buf);
    }
    public void SetAnalogChannel(int channel)
    {
        if (channel > 8) channel = 8;
        if (channel < 1) channel = 1;
        var send_buf = new byte[3];
        var receive_buf = new byte[4];
        send_buf[0] = 2; // OUT_ANALOG_CH
        send_buf[1] = Convert.ToByte((channel - 1));
        send_buf[2] = 255;
        OutIn(send_buf, receive_buf);
    }

    public byte[] ReadBackAnalogOut()
    {
        var send_buf = new byte[1];
        var receive_buf = new byte[9];
        send_buf[0] = 15;  // READ_ANALOG_OUT
        OutIn(send_buf, receive_buf);
        var returnData = new byte[8];
        for (int i = 8; i < 9; i++)
        {
            returnData[i] = receive_buf[i];
        }
        return returnData;
    }

  
    #endregion

    #region PWM
    public void OutputPWM(int value)
    {
        var send_buf = new byte[3];
        var receive_buf = new byte[4];
        send_buf[0] = 4; //OUT_PWM
        byte lo = 0; // todo:
        byte hi = 0; // todo:
        send_buf[1] = lo;
        send_buf[2] = hi;
        OutIn(send_buf, receive_buf);
    }
    public int ReadBackPWMOut()
    {
        var send_buf = new byte[1];
        var receive_buf = new byte[3];
        send_buf[0] = 16;  // READ_PWM_OUT
        OutIn(send_buf, receive_buf);
        var result = receive_buf[1] + 4 * receive_buf[2];
        return result;
    } 
    #endregion

    #region Digital
    public byte ReadAllDigital()
    {
        var send_buf = new byte[1];
        var receive_buf = new byte[2];
        send_buf[0] = 5; //READ_DIGITAL_BYTE
        OutIn(send_buf, receive_buf);
        var result = receive_buf[1];
        return result;
    }
    public byte OutputAllDigital(byte value)
    {
        var send_buf = new byte[2];
        var receive_buf = new byte[3];
        send_buf[0] = 6; //OUT_DIGITAL_BYTE
        send_buf[1] = value;
        OutIn(send_buf, receive_buf);
        var result = receive_buf[1];
        return result;
    }
    public byte ReadDigitalChannel(int channel)
    {
        if (channel > 8) channel = 8;
        if (channel < 1) channel = 1;
        var send_buf = new byte[1];
        var receive_buf = new byte[2];
        send_buf[0] = 5;  //READ_DIGITAL_BYTE
        OutIn(send_buf, receive_buf);
        var result = receive_buf[1];
        return result;
    }
    public void ClearDigitalChannel(int channel)
    {
        if (channel > 8) channel = 8;
        if (channel < 1) channel = 1;
        var send_buf = new byte[2];
        var receive_buf = new byte[3];
        var k = 255 - Math.Round(Math.Exp((channel - 1) * Math.Log(2)));
        send_buf[0] = 7; // Clear Digital Channel
        send_buf[1] = Convert.ToByte(k);
        OutIn(send_buf, receive_buf);
    }
    public void ClearAllDigital()
    {
        var send_buf = new byte[2];
        var receive_buf = new byte[3];
        send_buf[0] = 6;  //OUT_DIGITAL_BYTE
        send_buf[1] = 0;
        OutIn(send_buf, receive_buf);
    }


    public void SetDigitalChannel(int channel, bool isOn)
    {
        if (channel > 8) channel = 8;
        if (channel < 1) channel = 1;
        double k = 0;
        var send_buf = new byte[2];
        var receive_buf = new byte[3];
        if (isOn)
        {
            k = Math.Round(Math.Exp((channel - 1) * Math.Log(2)));
            send_buf[0] = 8; // Set Digital Channel
            send_buf[1] = Convert.ToByte(k);
        }
        else
        {
            k = 255 - Math.Round(Math.Exp((channel - 1) * Math.Log(2)));
            send_buf[0] = 7; // Clear Digital Channel
            send_buf[1] = Convert.ToByte(k);
        }

        OutIn(send_buf, receive_buf);
    }
    public void SetAllDigital()
    {
        var send_buf = new byte[2];
        var receive_buf = new byte[3];
        send_buf[0] = 6;  //OUT_DIGITAL_BYTE
        send_buf[1] = 255;
        OutIn(send_buf, receive_buf);
    }
    public byte ReadBackDigitalOut()
    {
        var send_buf = new byte[1];
        var receive_buf = new byte[2];
        send_buf[0] = 14;  //READ_DIGITAL_OUT
        OutIn(send_buf, receive_buf);
        var result = receive_buf[1];
        return result;
    }
    
    #endregion


    public bool PowerGood()
    {
        var send_buf = new byte[1];
        var receive_buf = new byte[2];
        send_buf[0] = 13;  // POWER_STATUS
        OutIn(send_buf, receive_buf);
        var result = Convert.ToBoolean(receive_buf[1]);
        return result;
    }

    public string ReadVersion()
    {
        var send_buf = new byte[1];
        var receive_buf = new byte[49];
        send_buf[0] = 11;  // READ_VERSION
        OutIn(send_buf, receive_buf);
        var data1 = "";
        for (int i = 1; i < 25; i++)
        {
            data1 += receive_buf[i].ToString();
        }
        var data2 = "";
        for (int i = 25; i < 49; i++)
        {
            data2 += receive_buf[i].ToString();
        }
        return data1 + " " + data2;
    }



    private void OutIn(byte[] sendBuffer, byte[] receiveBuffer)
    {
        uint bytesWritten;
        uint bytesRead;
        uint h;
        if (!IsOpen) return;
        h = MPUSB.Write(myOutPipe, sendBuffer, (uint)sendBuffer.Length, out bytesWritten, 1000);
        if (h == 0)
        {
            CheckInvalidHandle();
            return;
        }
        h = MPUSB.Read(myInPipe, receiveBuffer, (uint)receiveBuffer.Length, out bytesRead, 1000);
        if (h == 0)
        {
            CheckInvalidHandle();
            return;
        }
    }
    private void CheckInvalidHandle()
    {
        // Most likely cause of the error is the board was disconnected.
        Close();
    }





    public void Close()
    {
        IsOpen = false;
        if (myInPipe != 0)
        {
            MPUSB.Close(myInPipe);
            myInPipe = 0;
        }
        if (myOutPipe != 0)
        {
            MPUSB.Close(myOutPipe);
            myOutPipe = 0;
        }
    }

    public void Dispose()
    {
        IsOpen = false;
        if (myInPipe != 0) MPUSB.Close(myInPipe);
        if (myOutPipe != 0) MPUSB.Close(myOutPipe);
    }
}

}
[/code]

I made a simple test program to test the function GetDeviceCount.

[DllImport("mpusbapi.dll", EntryPoint = "_MPUSBGetDeviceCount", CallingConvention = CallingConvention.Cdecl)] public static extern DWORD GetDeviceCount([MarshalAs(UnmanagedType.LPStr)] string pVID_PID);
Then I tested the function operation by using this code:

[code] public const string vid_pid_norm = “vid_10cf&pid_8061”;

    private void button1_Click(object sender, EventArgs e)
    {
        DWORD NumberOfCards;
        NumberOfCards = GetDeviceCount(vid_pid_norm);
        label1.Text = NumberOfCards.ToString();
    }[/code]

Works fine.

Using some snippets from your code I expanded the test program to use the SetAllDigital() and ClearAllDigital() as test functions.
Here is the complete code:

[code]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 System.Runtime.InteropServices;
using DWORD = System.UInt32;
using HANDLE = System.UInt32;

namespace K8061_CSharp_GetDeviceCount
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}

    public enum PipeDir : uint
    {
        Write = 0,
        Read = 1
    }

    public const string vid_pid_norm = "vid_10cf&pid_8061";
    const string out_pipe = @"\MCHP_EP1";
    const string in_pipe = @"\MCHP_EP1";
    private uint myOutPipe;
    private uint myInPipe;


    [DllImport("mpusbapi.dll", EntryPoint = "_MPUSBGetDeviceCount", CallingConvention = CallingConvention.Cdecl)]
    public static extern DWORD GetDeviceCount([MarshalAs(UnmanagedType.LPStr)] string pVID_PID);

    [DllImport("mpusbapi.dll", EntryPoint = "_MPUSBOpen", SetLastError = true, CallingConvention = CallingConvention.Cdecl)]
    public static extern DWORD Open(DWORD instance,
       [MarshalAs(UnmanagedType.LPStr)] string pVID_PID,
       [MarshalAs(UnmanagedType.LPStr)] string pEP,
          [MarshalAs(UnmanagedType.U4)] PipeDir dwDir,
                                        DWORD dwReserved);
    [DllImport("mpusbapi.dll", EntryPoint = "_MPUSBRead", SetLastError = true, CallingConvention = CallingConvention.Cdecl)]
    public static extern DWORD Read(HANDLE handle,
     [MarshalAs(UnmanagedType.LPArray)] byte[] pData,
                                        DWORD dwLen,
                                    out DWORD pLength,
                                        DWORD dwMilliseconds);

    [DllImport("mpusbapi.dll", EntryPoint = "_MPUSBWrite", SetLastError = true, CallingConvention = CallingConvention.Cdecl)]
    public static extern DWORD Write(HANDLE handle,
     [MarshalAs(UnmanagedType.LPArray)] byte[] pData,
                                        DWORD dwLen,
                                    out DWORD pLength,
                                        DWORD dwMilliseconds);



    private void button1_Click(object sender, EventArgs e)
    {
        DWORD NumberOfCards;
        NumberOfCards = GetDeviceCount(vid_pid_norm);
        label1.Text = NumberOfCards.ToString();
    }

    private void button2_Click(object sender, EventArgs e)
    {
        DWORD selection = 0;// Selects the device to connect to, in this example it is assumed you will only have one device per vid_pid connected.
        myOutPipe = Open(selection, vid_pid_norm, out_pipe, PipeDir.Write, 0);
        myInPipe = Open(selection, vid_pid_norm, in_pipe, PipeDir.Read, 0);

        if (myInPipe == 0 || myOutPipe == 0)
            label2.Text = "Fail";
        else
            label2.Text = "Card Opened";
    }

    private void button3_Click(object sender, EventArgs e)
    {
        SetAllDigital();
    }

    private void button4_Click(object sender, EventArgs e)
    {
        ClearAllDigital();
    }

    public void SetAllDigital()
    {
        var send_buf = new byte[2];
        var receive_buf = new byte[3];
        send_buf[0] = 6;  //OUT_DIGITAL_BYTE
        send_buf[1] = 255;
        OutIn(send_buf, receive_buf);
    }

    public void ClearAllDigital()
    {
        var send_buf = new byte[2];
        var receive_buf = new byte[3];
        send_buf[0] = 6;  //OUT_DIGITAL_BYTE
        send_buf[1] = 0;
        OutIn(send_buf, receive_buf);
    }

    private void OutIn(byte[] sendBuffer, byte[] receiveBuffer)
    {
        uint bytesWritten;
        uint bytesRead;
        uint h;
        h = Write(myOutPipe, sendBuffer, (uint)sendBuffer.Length, out bytesWritten, 1000);
        h = Read(myInPipe, receiveBuffer, (uint)receiveBuffer.Length, out bytesRead, 1000);
    }

}

}[/code]This works fine too.

Strange, I tried your form but still nothing. Cards-count = 0
I had to copy the mpusbapi.dll to the bin/debug folder. Perhaps he has to be in the GAC?

Maybe you have installed the Vistapack driver. It is not compatible with the MPUSBAPI.DLL.

You may try to use a new driver and new K8061.DLL:
Here is a link to download the package containing the new DLL, new driver, documentation and demo software: box.net/shared/p8hszo58sh
The driver version is 1.0.0.6 and it must be installed to use the new K8061.DLL version 3.0.0.1.
The driver is located in subfolder K8061_Driver64 of the package.

There is also a demo software included to the package to test the operation of this new driver and new K8061.DLL.

The file MPUSBAPI.DLL must be copied to the same folder with the K8061.DLL.
The best place to copy these two files is the Windows’ subfolder System32 or SysWOW64 in 64-bit environment.
These two files can be copied to your application (.exe) folder too.

The file mpusbapi.dll is a regular DLL not a .NET assembly, so putting it in the GAC won’t be possible. It has to be in the search path though if you want to use it

I found a solution by using the WinUSBNet library. Just find it strange that I couldn’t get it working with MPUSBAPI.DLL. But ok, now its working great.
Thanks

Manu

Nice, + WinUSBNet has some extra goodies!