Cyapi使用心得

Cyapi使用心得(1)--USB连接2009-11-07 19:23 

    用Cyapi也有一阵了,这个确实比EZusb的api好用,简单说下Cyapi的使用心得,在编程中应该注意的一些问题,毕竟,说起来,那个CYapi的说明文档讲的实在太简单了点,好多东西都讲得不明白,只能在使用中自己慢慢积累了。

    首先说下前提,固件架构是EZ-USB FX2/FX2LP(CY7C68013),编译环境VC++ 6.0,驱动是Cyusb.sys

上位机简单说下,建立一个MFC 单文档/对话框 应用程序;在路径项目中包含头文件cyapi.h和cyapi.lib所在的路径,最好移到最上面。然后手动导入cyapi.lib,注意是CV6_7的lib,不要导入BCB的。

下面讲得是按照USB一般工作流程来讲得。

(1)USB连接

1.首先要建立一个USB设备对象,文档里有说的了,copy一下

       CCyUSBDevice *USBDevice = new   CCyUSBDev(Handle);

括号中的Handle是USB所关联对象的句柄,一般在MFC中直接就是m_hwnd。

2.然后就该是打开USB设备了,可以用到两个函数open();isopen()

这两个都可以用来打开USB设备,isopen()还可以判断能否获得USB设备句柄

    一般来说,如果只有一个USB设备连接,可以这样打开:

               USBDevice->open(0)    //打开0号USB设备

如果要判断,可以:

            if(! USBDevice->open(0)) //打开失败

               {messagebox("USB未连接");}

或者        if(!USBDevice->Isopen())

                     ..........

    如果连接有多个USB设备,那么可以枚举所有的USB,用到DeviceCount()函数;具体的可以参考cybulk的例子,执行USBDevice->DeviceCount()后,返回所连接的USB设备个数:

       if (USBDevice->DeviceCount())   //保证至少有一个USB设备连接

    {

        for (i = 0; i < USBDevice->DeviceCount(); i++)    //枚举所有USB设备

        {

           USBDevice->Open(i);                   //打开第i号USB设备

           m_DeviceListComBox.AddString(USBDevice->DeviceName);//所选择的当前设备名

        }

    }

    好了,今天说到这里,有空接着写~

 

Cyapi使用心得(2)--端点使用及其他USB属性获取2009-11-13 22:52    

◆  在cybulk的例子中介绍了如何枚举固件中使用的所有端点,也就是使用多个端点的情况:

       CCyUSBDevice *USBDevice =new CCyUSBDevice(m_hWnd); //USB设备

       USBDevice->Open(0);    //打开0号USB设备

【1】首先获取所用的端点数目

       int epts = USBDevice->EndPointCount();

EndPointCount();函数返回当前所用的端点数+1,也就是包含了控制端点例如在固件接口描述符Interface Descriptor中设置Number of end points项(第5项)的值为4,则epts的值为4+1=5。

【2】定义端点指针

      CCyUSBEndPoint *endpt;  

CCyUSBEndPoint 建立一个端点对象,可建立所有的端点类型,控制端点,bulk端点,ISO端点等;

【3】开始枚举端点,并获得其属性:端点号,传输方向

       for (i=1; i

    {   

       endpt = USBDevice->EndPoints[i];    //EndPoints-端点列表,最大16.EndPoints[0]

                                       //指向控制端点( CCyControlEndPoint)

                                       //未使用的端点设置为NULL

        if (endpt->Attributes == 2)    // Bulk Attributes--判断传输类型bulk,control,等

        {

            sprintf(s, "0xX", endpt->Address);

            if (endpt->Address & 0x80)   //Address--判断传输方向in or out  

                                     //0x8_-in;0x0_-out

            {

                m_InEndptComBox.AddString(s); //最高位为8,in端点,添加到in组合框

                m_InEndptComBox.SetItemData(m_InEndptComBox.GetCount()-1,i);

            }

            else

            {

                m_OutEndptComBox.AddString(s); //否则,最高位为0,out端点,

                                             //添加到out组合框

                m_OutEndptComBox.SetItemData(m_OutEndptComBox.GetCount()-1,i);

            }

        }

    }

◆ 这样,就完成了某个具体端点的选择。从上面的代码来看,非常烦琐,如果只需要使用一个端点的画,那上面的代码无疑就显得冗长不够简洁了。仅使用一个端点,可以使用EndPointOf()函数,该函数直接使用指定的端点,返回其指针例如,要使用端点2,in传输,那么,可以这样:

            CCyUSBDevice *USBDevice =new CCyUSBDevice(m_hWnd); //USB设备 

            USBDevice->Open(0); //打开0号设备,

           CCyUSBEndPoint *endpt = USBDevice->EndPointOf(0X82); //使用端点2,in传输

可以看到,上面的只需要3行代码,比枚举简洁方便多了。

◆ 至于获取USB其他属性,这里列出经常使用的几个,具体的可参考cyapi的文档,在CCyUSBDevice和CCyUSBEndPoint这两个类里可查询到。

       USBDevice->DeviceCount()     //返回连接到电脑的USB设备个数,

                                   //从0,1,2.。开始命名

        USBDevice->DeviceName()     //返回USB设备名称,也就是固件中

                                    //StringDscr2: 字段字符串  

       USBDevice->VendorID           //返回USB设备VID

       USBDevice->ProductID           //返回USB设备PID

 

Cyapi使用心得(3)--控制传输2009-11-17 21:04        

今天写写控制传输吧--

可以说,写USB上位机,控制传输肯定第一个要做的例子和试验了;因为固件不用很多代码,VC也不用很多代码就测试你写的USB上位机的正确与否,这里简单介绍下cyapi写控制传输的一些方法。

    基本上,要对固件进行自定义命令(vendor)传输,通常都是用控制传输进行的。使用控制传输in或者out方式都可以实现对固件的自定义命令。

【1】out控制传输发送vendor命令

    我想采用out方式应该比较符合大家的思维,因为是从上位机发命令到下位机,怎么看都应该是out而不是in。

    例如你在固件里设置了out的接收buf:

      BOOL DR_VendorCmnd(void)

{

   switch (SETUPDAT[1])

{

   case 0xDD:

   { temp=EP0BUF[0];

    EP0BCH=0;

    EP0BCL=1;

    EP0CS |=bmHSNAK;

    break;

   }

   default:

    return(TRUE);

   }

   return(FALSE);

}

      VC中:

           CCyControlEndPoint* CtlEndpoint;   //定义一个控制端点  

          CtlEndpoint->Target    = TGT_DEVICE;       //不必关注,固定

          CtlEndpoint->ReqType   = REQ_VENDOR;  //请求类型:自定义请求(标准请求等)

          CtlEndpoint->Direction = DIR_TO_DEVICE;    //传输方向:主机->usb设备(out)

          CtlEndpoint->ReqCode   = 0XDD;      //自定义请求码  

          CtlEndpoint->Value     = 0;     //这里的设定值将传给setupdat的【2:3】位

           CtlEndpoint->Index     = 0;    //这里的设定值将传给setupdat的【4:5】位

          PUCHAR buf=new UCHAR[1];

         ZeroMemory(buf,1);             //用0填充buf区,填充大小(1字节)

          long buflen=1;        //传输的其他字节数:cy控制台console中length的值

           CtlEndpoint->XferData(buf,buflen);

当然,没有规定说一定必须传给下位机至少一个字节的数据;你也可以不传;不过最好下位机同样设置接收字节为0,否则小心有莫名奇妙的错误(XX内存不能为只读等等)。

将temp=EP0BUF[0];去掉,上位机:

          PUCHAR buf=new UCHAR;   //用0填充buf区,填充大小(1字节)

          long buflen=0;

           CtlEndpoint->XferData(buf,buflen);

也是可以的,友情提示:控制传输请尽量用同步的xferdata()而不是异步的begindataxfer()。

【2】in控制传输发送vendor命令

     基本上,跟out区别不大。固件中:

       BOOL DR_VendorCmnd(void)

{

   switch (SETUPDAT[1])

{

   case 0xDD:

   {

    *EP0BUF=0XDD;

    EP0BCH=0;

    EP0BCL=1;

    EP0CS |=bmHSNAK;

    break;

   }

   default:

    return(TRUE);

   }

   return(FALSE);

}

      VC中:

          CCyControlEndPoint* CtlEndpoint;   //定义一个控制端点  

          CtlEndpoint->Target    = TGT_DEVICE;  //不必关注,固定

          CtlEndpoint->ReqType   = REQ_VENDOR; //请求类型:自定义请求(标准请求等)

          CtlEndpoint->Direction = DIR_FROM_DEVICE;    //传输方向:usb设备->主机(in)

          CtlEndpoint->ReqCode   = 0XDD;      //自定义请求码  

          CtlEndpoint->Value     = 0;     //这里的设定值将传给setupdat的【2:3】位

           CtlEndpoint->Index     = 0;    //这里的设定值将传给setupdat的【4:5】位

          PUCHAR buf=new UCHAR[1];

         ZeroMemory(buf,1);           //用0填充buf区,填充大小(1字节)

          long buflen=1;          //传输的其他字节数:cy控制台console中length的值

           CtlEndpoint->XferData(buf,buflen);

这里的话,推荐尽量设置接收缓冲,不要将buflen设置为0.同样,友情提示:控制传输请尽量用同步的xferdata()而不是异步的begindataxfer()。

【3】另外,还有两个简化版本的函数Write(out传输)和Read(in传输)也可以进行控制传输,作用同XferData()是一样的,因为已经明确表示了是in还是out,所以Direction 项的值就省略了。只是看起来代码更加简洁,输入效率更高而已。基本上,大多数时候,我都是使用Write和Read。

          CCyControlEndPoint* CtlEndpoint;   //定义一个控制端点  

          CtlEndpoint->Target    = TGT_DEVICE;   //不必关注,固定

          CtlEndpoint->ReqType   = REQ_VENDOR; //请求类型:自定义请求(标准请求等)

          CtlEndpoint->ReqCode   = 0XDD;      //自定义请求码  

          CtlEndpoint->Value     = 0;     //这里的设定值将传给setupdat的【2:3】位

           CtlEndpoint->Index     = 0;    //这里的设定值将传给setupdat的【4:5】位

          PUCHAR buf=new UCHAR[1];

         ZeroMemory(buf,1);        //用0填充buf区,填充大小(1字节)

          long buflen=1;       //传输的其他字节数:cy控制台console中length的值

           CtlEndpoint->Write(buf,buflen);  

      Read的话同理。

 

Cyapi使用心得(4)--bulk传输2009-12-01 19:50           

今天有空写以下bulk传输。bulk的话,cy开发包里有个例子cybulk写的很好,不过说实话,那个太烦琐了,基本上我们自己只用到其中的一部分,另外,就是局限性很大,例如它只是512字节的倍数,对于任意数目的字节貌似是不支持的,数据会不同步。

    为了提高传输速度与效率,一般要把数据采集放在另外一个线程,单独开启一个bulk线程。恩,前面的还是稍微提一下,在打开USB,设定端点后,紧接着开启线程,进行bulk采集:

         if (USBDevice->IsOpen()) {   //如果USB设备已经打开

           bLooping = true;      //线程循环标志为真

          XferThread = AfxBeginThread(XferLoop, this); //启动线程

           }

然后是线程中的处理,在这里上位机用异步接收,创建异步事件:

     OVERLAPPED inOvLap;

     CVC_SimpleCyapiDlg *dlg = (CVC_SimpleCyapiDlg *) params;   //使该线程可访问

                                                //CBulkLoopDlg类的所 有公有成员

     inOvLap.hEvent   = CreateEvent(NULL, false, false, "CYUSB_IN");

线程循环:

    bool success;

    dlg->InEndpt->TimeOut = 120;

for (;dlg->bLooping;) {       //线程循环,直到循环标志blooping为假

   LONG inlen ;

   inlen = 512;

   UCHAR *inContext = dlg->InEndpt->BeginDataXfer(inData,inlen,&inOvLap);

        dlg->InEndpt->WaitForXfer(&inOvLap,TimeOut);

        success = dlg->InEndpt->FinishDataXfer(inData,inlen, &inOvLap,inContext);

     if (!success) dlg->bLooping = false;

}

    主要是三步,调用三个函数BeginDataXfer,WaitForXfer,FinishDataXfer。按照手册上说的,BeginDataXfer发起异步传输,并且立即返回。也就是说,发起此次的inlen后,并不会等inlen传输完,而是立即开始下一次inlen字节传输;WaitForXfer,异步传输最大等待时间;FinishDataXfer,到这里才开始真正的写内存,将读到的数写到缓冲区indata中。

      最后,完了别忘记释放对象:

     CloseHandle(inOvLap.hEvent);

     delete [] inData;

     另外,如果要传输非512字节整数倍的数据,而且不是一次传输完的话,最好在线程中用SetXferSize()重新设置传输大小,否则会导致数据不同步。

    

 


  • 4
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
CyAPI原版资料, CyAPI.lib provides a simple, powerful C++ programming interface to USB devices. More specifically, it is a C++ class library that provides a high-level programming interface to the CyUsb3.sys device driver. The library is only able to communicate with USB devices that are served by (i.e. bound to) this driver. Rather than communicate with the driver via Windows API calls such as SetupDiXxxx and DeviceIoControl, applications can call simpler CyAPI methods such as Open, Close, and XferData to communicate with these USB devices. To use the library, you need to include the header file, CyAPI.h, in files that access the CCyUSBDevice class. In addition, the statically linked CyAPI.lib file must be linked to your project. Versions of the .lib files are available for use with Microsoft Visual Studio 2008. The library employs a Device and EndPoints use model. To use the library you must create an instance of the CCyUSBDevice class using the new keyword. A CCyUSBDevice object knows how many USB devices are attached to the CyUsb3.sys driver and can be made to abstract any one of those devices at a time by using the Open method. An instance of CCyUSBDevice exposes several methods and data members that are device-specific, such as DeviceName, DevClass, VendorID, ProductID, and SetAltIntfc. When a CCyUSBDevice object is open to an attached USB device, its endpoint members provide an interface for performing data transfers to and from the device's endpoints. Endpoint-specific data members and methods such as MaxPktSize, TimeOut, bIn, Reset and XferData are only accessible through endpoint members of a CCyUSBDevice object. In addition to its simplicity, the class library facilitates creation of sophisticated applications as well. The CCyUSBDevice constructor automatically registers the application for Windows USB Plug and Play event notification. This allows your application to support "hot plugging" of devices. Also, the asynchronous BeginDataXfer/

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值