加载中…
个人资料
  • 博客等级:
  • 博客积分:
  • 博客访问:
  • 关注人气:
  • 获赠金笔:0支
  • 赠出金笔:0支
  • 荣誉徽章:
正文 字体大小:

(针对USB2.0 芯片CY7C68013A,基于CyAPI.lib与Bulkloo

(2012-12-05 16:16:33)
标签:

杂谈

分类: USB

引用于 http://blog.csdn.net/chenyujing1234 

http://blog.csdn.net/chenyujing1234/article/details/7622901

 

欢迎大家提出意见,一起讨论!

需要源码的可以与我联系.

 

在我的一篇文章    Window XP驱动开发(十二) 驱动应用程序端 (原理分析)

中讲到了驱动应用程序端的开发原理。

这里针对CY7C68013A供应商提供的 .sys .inf及提供的.lib文件进行应用程序端的开发。

 先看一下界面效果:

http://my.csdn.net/uploads/201207/04/1341394373_5805.jpg芯片CY7C68013A,基于CyAPI.lib与Bulkloo" />

一、环境

http://www.cypress.com/?rID=34870 下载 CY7C68013的组件开发安装程序。

下载后得到 http://my.csdn.net/uploads/201206/01/1338522968_7504.jpg芯片CY7C68013A,基于CyAPI.lib与Bulkloo" />

 

安装后得到驱动安装文件与应用程序开发库:

图一:

http://my.csdn.net/uploads/201206/01/1338523021_1166.jpg芯片CY7C68013A,基于CyAPI.lib与Bulkloo" />

 

http://my.csdn.net/uploads/201206/01/1338523073_2873.jpg芯片CY7C68013A,基于CyAPI.lib与Bulkloo" />

 

http://my.csdn.net/uploads/201206/01/1338523544_3056.jpg芯片CY7C68013A,基于CyAPI.lib与Bulkloo" />

 

二、应用程序开发

现在我们就基于CyAPI.lib进行三次开发。

1、首先将 CyAPI.lib 与 CyAPI.lib加入到我们工程的链接中。(相对简单,不介绍了)

2、代码实现:

2、1  创建CCyUSBDevice接口

           USBDevice = new CCyUSBDevice(m_hWnd);   // Create an instance of CCyUSBDevice

2、2  获得设备列表,并找开设备。用:

         UCHAR                 DeviceCount(void);

         bool                  Open(UCHAR dev);

          获得端点列表,用:

         UCHAR                 EndPointCount(void);

         

  1. void CBulkLoopDlg::OnRefreshBtn()   
  2.  
  3.     int i;  
  4.   
  5.     // if we are currently running loopback, stop   
  6.     if (XferThread)  
  7.      
  8.         bLooping false 
  9.   
  10.         InEndpt->Abort();  
  11.         InEndpt->Reset();  
  12.   
  13.         OutEndpt->Abort();  
  14.         OutEndpt->Reset();  
  15.   
  16.         m_StartBtn.SetWindowText("Start");  
  17.      
  18.   
  19.     // clear the combo boxes   
  20.     m_DeviceListComBox.ResetContent();  
  21.     m_InEndptComBox.ResetContent();    
  22.     m_OutEndptComBox.ResetContent();  
  23.   
  24.     // make sure there is at lesat one device out there   
  25.     if (USBDevice->DeviceCount())  
  26.      
  27.         // search for all connected devices, and add them to the device   
  28.         // combo box   
  29.         for (i 0; USBDevice->DeviceCount(); i++)  
  30.          
  31.             USBDevice->Open(i);  
  32.   
  33.             m_DeviceListComBox.AddString(USBDevice->DeviceName);  
  34.          
  35.   
  36.   
  37.         m_DeviceListComBox.SetCurSel(0);  
  38.         OnSelchangeDeviceListCombox();      // This will set the device index and load the ep lists   
  39.   
  40.         
  41.  
void CBulkLoopDlg::OnRefreshBtn() 
{
    int i;

    // if we are currently running loopback, stop
    if (XferThread)
    {
        bLooping = false;

        InEndpt->Abort();
        InEndpt->Reset();

        OutEndpt->Abort();
        OutEndpt->Reset();

        m_StartBtn.SetWindowText("Start");
    }

    // clear the combo boxes
    m_DeviceListComBox.ResetContent();
        m_InEndptComBox.ResetContent();  
        m_OutEndptComBox.ResetContent();

    // make sure there is at lesat one device out there
    if (USBDevice->DeviceCount())
    {
        // search for all connected devices, and add them to the device
        // combo box
        for (i = 0; i < USBDevice->DeviceCount(); i++)
        {
            USBDevice->Open(i);

            m_DeviceListComBox.AddString(USBDevice->DeviceName);
        }


        m_DeviceListComBox.SetCurSel(0);
        OnSelchangeDeviceListCombox();          // This will set the device index and load the ep lists

    }   
}


 

  1. void CBulkLoopDlg::OnSelchangeDeviceListCombox()   
  2.  
  3.     int i;  
  4.     char s[12];  
  5.   
  6.     DeviceIndex m_DeviceListComBox.GetCurSel();  
  7.   
  8.     USBDevice->Open(DeviceIndex);  
  9.   
  10.     // 获得端点数目   
  11.     int epts USBDevice->EndPointCount();  
  12.     CCyUSBEndPoint *endpt;  
  13.   
  14.     // Load the endpoint combo boxes   
  15.     // 跳过端点0,因为我们知道它是控制端点   
  16.     for (i=1; i
  17.          
  18.         endpt USBDevice->EndPoints[i];  
  19.   
  20.         if (endpt->Attributes == 2)      // Bulk   
  21.          
  22.             sprintf(s, "0xX"endpt->Address);  
  23.   
  24.               
  25.             if (endpt->Address 0x80)   // In 端点   
  26.              
  27.                 m_InEndptComBox.AddString(s);  
  28.                 m_InEndptComBox.SetItemData(m_InEndptComBox.GetCount()-1,i);  
  29.              
  30.             else                        // Out端点   
  31.              
  32.                 m_OutEndptComBox.AddString(s);  
  33.                 m_OutEndptComBox.SetItemData(m_OutEndptComBox.GetCount()-1,i);  
  34.              
  35.          
  36.      
  37.   
  38.     m_InEndptComBox.SetCurSel(0);  
  39.     m_OutEndptComBox.SetCurSel(0);  
  40.   
  41.     OnSelchangeInCombox();      // Set the InEndpt member   
  42.     OnSelchangeOutCombox();     // Set the OutEndpt member   
  43.   
  44.  
void CBulkLoopDlg::OnSelchangeDeviceListCombox() 
{
    int i;
    char s[12];

    DeviceIndex = m_DeviceListComBox.GetCurSel();

    USBDevice->Open(DeviceIndex);

        // 获得端点数目
    int epts = USBDevice->EndPointCount();
    CCyUSBEndPoint *endpt;

        // Load the endpoint combo boxes
    // 跳过端点0,因为我们知道它是控制端点
        for (i=1; iEndPoints[i];

        if (endpt->Attributes == 2)             // Bulk
        {
            sprintf(s, "0xX", endpt->Address);

                        
            if (endpt->Address & 0x80)  // In 端点
            {
                m_InEndptComBox.AddString(s);
                m_InEndptComBox.SetItemData(m_InEndptComBox.GetCount()-1,i);
            }
            else                                                // Out端点
            {
                m_OutEndptComBox.AddString(s);
                m_OutEndptComBox.SetItemData(m_OutEndptComBox.GetCount()-1,i);
            }
        }
    }

    m_InEndptComBox.SetCurSel(0);
        m_OutEndptComBox.SetCurSel(0);

    OnSelchangeInCombox();              // Set the InEndpt member
        OnSelchangeOutCombox();         // Set the OutEndpt member

}


2、3  根据选定的In端点与Out 端点进行数据传输.

          Loop线程函数是 XferLoop,用到的函数有

        PUCHAR BeginDataXfer(PUCHAR buf, LONG len, OVERLAPPED *ov);

        bool    WaitForXfer(OVERLAPPED *ov, ULONG tOut); 

        bool FinishDataXfer(PUCHAR buf, LONG &len, OVERLAPPED *ov, PUCHAR pXmitBuf, CCyIsoPktInfo* pktInfos = NULL);

 

  1. void CBulkLoopDlg::OnStartBtn()   
  2.  
  3.     if (XferThread)  
  4.         bLooping false 
  5.   
  6. //      InEndpt->Abort();   
  7. //      InEndpt->Reset();   
  8.   
  9. //      OutEndpt->Abort();   
  10. //      OutEndpt->Reset();   
  11.   
  12.         m_StartBtn.SetWindowText("Start");  
  13.     else  
  14.   
  15.         char s[12];  
  16.         ZeroMemory(s,12);  
  17.         m_XferSize.GetLine(0,s,8);  
  18.         LONG xfer atol(s);  
  19.         if (xfer 2048)  
  20.             xfer 2048;  
  21.             m_XferSize.SetWindowText("2048");  
  22.          
  23.   
  24.         USBDevice->Open(DeviceIndex);  
  25.         OutEndpt USBDevice->EndPoints[m_OutEndptComBox.GetItemData(m_OutEndptComBox.GetCurSel())];  
  26.         InEndpt USBDevice->EndPoints[m_InEndptComBox.GetItemData(m_InEndptComBox.GetCurSel())];  
  27.   
  28.         // Launch the looping thread  (Calls XferLoop() function, above.)   
  29.         if (xfer && USBDevice->IsOpen())  
  30.             bLooping true 
  31.             XferThread AfxBeginThread(XferLoop, this);  
  32.          
  33.   
  34.         m_StartBtn.SetWindowText("Stop");  
  35.      
  36.       
  37.  
void CBulkLoopDlg::OnStartBtn() 
{
        if (XferThread) {
                bLooping = false;

//              InEndpt->Abort();
//              InEndpt->Reset();

//              OutEndpt->Abort();
//              OutEndpt->Reset();

                m_StartBtn.SetWindowText("Start");
        } else {

                char s[12];
                ZeroMemory(s,12);
                m_XferSize.GetLine(0,s,8);
                LONG xfer = atol(s);
                if (xfer > 2048) {
                        xfer = 2048;
                        m_XferSize.SetWindowText("2048");
                }

        USBDevice->Open(DeviceIndex);
        OutEndpt = USBDevice->EndPoints[m_OutEndptComBox.GetItemData(m_OutEndptComBox.GetCurSel())];
        InEndpt = USBDevice->EndPoints[m_InEndptComBox.GetItemData(m_InEndptComBox.GetCurSel())];

                // Launch the looping thread  (Calls XferLoop() function, above.)
                if (xfer && USBDevice->IsOpen()) {
                        bLooping = true;
                        XferThread = AfxBeginThread(XferLoop, this);
                }

                m_StartBtn.SetWindowText("Stop");
        }
        
}


 

  1. UINT XferLoop( LPVOID params  
  2.   
  3.     OVERLAPPED outOvLap, inOvLap;   
  4.   
  5.     CBulkLoopDlg *dlg (CBulkLoopDlg *) params;  
  6.     char s[24];                     ZeroMemory(s, 24);  
  7.       
  8.     dlg->m_XferSize.GetLine(0,s,8);  
  9.     LONG xfer atol(s);  
  10.     PUCHAR data new UCHAR[xfer];  ZeroMemory(data,xfer);  
  11.     PUCHAR inData new UCHAR[xfer];    ZeroMemory(inData,xfer);  
  12.   
  13.     outOvLap.hEvent  CreateEvent(NULL, falsefalse"CYUSB_OUT");   
  14.     inOvLap.hEvent   CreateEvent(NULL, falsefalse"CYUSB_IN");   
  15.   
  16.     dlg->m_SeedValue.GetLine(0,s,8);  
  17.     LONG seed atol(s);  
  18.   
  19.     int stopOnError dlg->m_StopOnErrorChkBox.GetCheck();  
  20.   
  21.     stuffBuff(data,xfer,seed,dlg->m_FillPatternComBox.GetCurSel());  
  22.   
  23.     dlg->m_StatusLabel.SetWindowText(STATUS: Transferring data .");  
  24.     dlg->m_SuccessCount.SetWindowText("0");  
  25.     dlg->m_FailureCount.SetWindowText("0");  
  26.   
  27.     bool success;  
  28.     LONG nSuccess 0;  
  29.     LONG nFailure 0;  
  30.   
  31.     if (dlg->m_DisableTimeoutChkBox.GetCheck())  
  32.      
  33.         dlg->OutEndpt->TimeOut 0;  
  34.         dlg->InEndpt->TimeOut 0;  
  35.      
  36.     else  
  37.      
  38.         dlg->OutEndpt->TimeOut 2000;  
  39.         dlg->InEndpt->TimeOut 2000;  
  40.      
  41.   
  42.     for (;dlg->bLooping;)  
  43.         LONG outlen,inlen,len;  
  44.   
  45.         outlen inlen len xfer;     // Use temp var because XferData can change the value of len   
  46.   
  47.         // 发送数据给USB设备   
  48.         UCHAR  *outContext dlg->OutEndpt->BeginDataXfer(data,outlen,&outOvLap);  
  49.         // 从USB设备中读到数据   
  50.         UCHAR  *inContext dlg->InEndpt->BeginDataXfer(inData,inlen,&inOvLap);  
  51.   
  52.         // 等待   
  53.         dlg->OutEndpt->WaitForXfer(&outOvLap,2000);   
  54.         dlg->InEndpt->WaitForXfer(&inOvLap,2000);   
  55.   
  56.         // 完成数据传输   
  57.         success dlg->OutEndpt->FinishDataXfer(data, outlen, &outOvLap,outContext);   
  58.         success dlg->InEndpt->FinishDataXfer(inData,inlen, &inOvLap,inContext);   
  59.   
  60.   
  61.         if (success)  
  62.             bool pass (memcmp(data,inData,len) == 0);  
  63.             if (pass)  
  64.                 nSuccess++;  
  65.             else  
  66.                 nFailure++;  
  67.         else   
  68.             nFailure++;  
  69.   
  70.         sprintf(s,"%d",nSuccess);  
  71.         dlg->m_SuccessCount.SetWindowText(s);  
  72.         sprintf(s,"%d",nFailure);  
  73.         dlg->m_FailureCount.SetWindowText(s);  
  74.   
  75.         if ((!success) && stopOnError) dlg->bLooping false 
  76.       
  77.   
  78.     CloseHandle(outOvLap.hEvent);   
  79.     CloseHandle(inOvLap.hEvent);   
  80.   
  81.     delete [] data;  
  82.     delete [] inData;  
  83.   
  84.     dlg->m_StatusLabel.SetWindowText(STATUS: Stopped");  
  85.   
  86.     dlg->XferThread NULL;  
  87.   
  88.     dlg->USBDevice->Close();  
  89.   
  90.     return true 
  91.  
UINT XferLoop( LPVOID params ) {

    OVERLAPPED outOvLap, inOvLap; 

    CBulkLoopDlg *dlg = (CBulkLoopDlg *) params;
        char s[24];                                             ZeroMemory(s, 24);
        
        dlg->m_XferSize.GetLine(0,s,8);
        LONG xfer = atol(s);
        PUCHAR data = new UCHAR[xfer];  ZeroMemory(data,xfer);
        PUCHAR inData = new UCHAR[xfer];        ZeroMemory(inData,xfer);

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

        dlg->m_SeedValue.GetLine(0,s,8);
        LONG seed = atol(s);

        int stopOnError = dlg->m_StopOnErrorChkBox.GetCheck();

        stuffBuff(data,xfer,seed,dlg->m_FillPatternComBox.GetCurSel());

        dlg->m_StatusLabel.SetWindowText(" STATUS: Transferring data . . .");
        dlg->m_SuccessCount.SetWindowText("0");
        dlg->m_FailureCount.SetWindowText("0");

        bool success;
        LONG nSuccess = 0;
        LONG nFailure = 0;

    if (dlg->m_DisableTimeoutChkBox.GetCheck())
    {
        dlg->OutEndpt->TimeOut = 0;
            dlg->InEndpt->TimeOut = 0;
    }
    else
    {
        dlg->OutEndpt->TimeOut = 2000;
            dlg->InEndpt->TimeOut = 2000;
    }

        for (;dlg->bLooping;) {
        LONG outlen,inlen,len;

        outlen = inlen = len = xfer;     // Use temp var because XferData can change the value of len

                // 发送数据给USB设备
            UCHAR  *outContext = dlg->OutEndpt->BeginDataXfer(data,outlen,&outOvLap);
                // 从USB设备中读到数据
            UCHAR  *inContext = dlg->InEndpt->BeginDataXfer(inData,inlen,&inOvLap);

                // 等待
        dlg->OutEndpt->WaitForXfer(&outOvLap,2000); 
        dlg->InEndpt->WaitForXfer(&inOvLap,2000); 

                // 完成数据传输
        success = dlg->OutEndpt->FinishDataXfer(data, outlen, &outOvLap,outContext); 
        success = dlg->InEndpt->FinishDataXfer(inData,inlen, &inOvLap,inContext); 


                if (success) {
                        bool pass = (memcmp(data,inData,len) == 0);
                        if (pass)
                                nSuccess++;
                        else
                                nFailure++;
                } else 
                        nFailure++;

                sprintf(s,"%d",nSuccess);
                dlg->m_SuccessCount.SetWindowText(s);
                sprintf(s,"%d",nFailure);
                dlg->m_FailureCount.SetWindowText(s);

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

    CloseHandle(outOvLap.hEvent); 
    CloseHandle(inOvLap.hEvent); 

        delete [] data;
        delete [] inData;

        dlg->m_StatusLabel.SetWindowText(" STATUS: Stopped");

        dlg->XferThread = NULL;

    dlg->USBDevice->Close();

        return true;
}


 

三、测试方法

1、加载此应用程序对应的CY7C68013固件

固件源码在CYPRESS提供的安装包下:

http://my.csdn.net/uploads/201207/04/1341394646_4339.jpg芯片CY7C68013A,基于CyAPI.lib与Bulkloo" />

设计方法请看我的另一篇文章:<<>>

这里我们得把得到的bulkloop.hex单片机文件写入的CY7C里。

我们采用的工具是CYPRESS提供的工具: CyConsole.exe

http://my.csdn.net/uploads/201207/04/1341394830_6689.jpg芯片CY7C68013A,基于CyAPI.lib与Bulkloo" />

(1)在运行界面下打开EZ-USB Interface选项界面

http://my.csdn.net/uploads/201207/04/1341394992_6860.jpg芯片CY7C68013A,基于CyAPI.lib与Bulkloo" />

 

http://my.csdn.net/uploads/201207/04/1341395029_3670.jpg芯片CY7C68013A,基于CyAPI.lib与Bulkloo" />

(2)选择Download按钮,将选择bulkloop.hex

http://my.csdn.net/uploads/201207/04/1341395114_9738.jpg芯片CY7C68013A,基于CyAPI.lib与Bulkloo" />

 

(3)写入bulkloop.hex文件后,我们在设备管理器中发现此设备变化无法识别了。

这是因为我们之前的驱动是建立的VID:04B4      PID:8613 基础上的。

而现在我们的VID与PID变了,所以找不到驱动:

http://my.csdn.net/uploads/201207/04/1341395270_5690.jpg芯片CY7C68013A,基于CyAPI.lib与Bulkloo" />

为什么PID发生了变化?这是因为bulkloop.hex改变了PID。请看我的文章:

<<http://blog.csdn.net/chenyujing1234/article/details/7722669>>

 

接下来我们修改CyUsb.inf文件。

 

2、修改CyUsb.Inf(请将以下的8613改为我们实际的PID,eg: 1004)
http://my.csdn.net/uploads/201206/01/1338533222_7263.jpg芯片CY7C68013A,基于CyAPI.lib与Bulkloo" />

中的CyUSB.chm里有讲到怎么对CyUSB.INF进行修改,使之在具体的应该中使用.

1、1  增加设备的标识符到驱动中

把 图一中的CyUSB.inf中的

;%VID_XXXX&PID_XXXX.DeviceDesc%=CyUsb, USB\VID_XXXX&PID_XXXX

改为:

%VID_04B4&PID_8613.DeviceDesc%=CyUsb, USB\VID_04B4&PID_8613

 

1、2 替换Cypress 串,使之与自己的公司描述更确切。

CYUSB_Provider    = "Cypress"
CYUSB_Company     = "Cypress Semiconductor Corporation"
CYUSB_Description = "Cypress Generic USB Driver"
CYUSB_DisplayName = "Cypress USB Generic"

1、3  执行一个通用的GUID

   应用程序软件通过驱动的的GUID访问驱动,每一个Window系统的驱动都应该有一个唯一的GUID

因为可能会有不同的硬件供应商,这样就会有很多CYUSB.SYS的实例。我们可以通过GUIDGEN.exe来产生我们

自己的GUID。并把此GUI写在CyUSB.inf中

CYUSB.GUID="{AE18AA60-7F6A-11d4-97DD-00010229B959}"

 

1、4  在启动时执行一个脚本

  CYUSB.sys驱动在启动时能被配置到默认的控制端点(端点0)。

为了配置设备使之能表现控制传输,我们用CyConsole.exe来创建一个脚本文件。

我们保存此脚本文件为MyDevice.SPT,把此文件放到.INF文件下。

目的是让此脚夫本文件把固件镜像下载到设备中。

1、4、1  在CyUSB.inf中的 [CYUSB.AddReg.Guid]下添加

HKR,,DriverEXECSCRIPT,,%CYUSB.EXECSCRIPT%

1、4、2  在[Strings]下添加

 CYUSB.EXECSCRIPT="\systemroot\system32\MyDevice\MyDevice.spt"

 

2、强制系统用CYUSB.sys驱动

由于cyusb.inf文件中没有提供DefaultInstall 默认安装节点,但我们可以通过EzDriverInstaller安装(请参见:http://blog.csdn.net/chenyujing1234/article/details/7676812

安装完后,我们的应用程序才有意义,接下来开始测试应用程序了。

0

阅读 收藏 喜欢 打印举报/Report
  

新浪BLOG意见反馈留言板 欢迎批评指正

新浪简介 | About Sina | 广告服务 | 联系我们 | 招聘信息 | 网站律师 | SINA English | 产品答疑

新浪公司 版权所有