MiS603开发板 第十二章 SLAVE FIFO流传输

作者:MiS603开发团队

日期:20150911

公司:南京米联电子科技有限公司

论坛:www.osrc.cn

网址:www.milinker.com

网店:http://osrc.taobao.com

EAT博客:http://blog.chinaaet.com/whilebreak

博客园:http://www.cnblogs.com/milinker/

MiS603开发板 第十二章 SLAVE FIFO流传输

15.1 USB 固件源码分析

SLAVE FIFOUSB 固件源码仍然采用上一章节源码。

15.2 FPGA固件源码分析

module USB_FPGA(

input  ifclk_i,

inout [7:0] fdata_b,

output reg [1:0] faddr_o,

output reg slrd_o ,

output reg slwr_o,

output reg sloe_o,

input  flagd_i,

input  flaga_i

    );

//CY7C68013A EP2和EP6端口切换

assign fdata_b = (faddr_o == 2‘b00) ? 8‘hzz : 8‘haa;

//读写控制逻辑

always @(*)begin

if(flaga_i) begin //USB FIFO 非空就读

slwr_o = 1‘b1;

slrd_o = 1‘b0;

sloe_o = 1‘b0;

faddr_o = 2‘b00;

end

else if(flagd_i)begin//USB FIFO 非满就写

slwr_o = 1‘b0;

slrd_o = 1‘b1;

sloe_o = 1‘b0;

faddr_o = 2‘b10;

end

else begin // 否则不读也不写

slwr_o = 1‘b1;

slrd_o = 1‘b1;

sloe_o = 1‘b0;

faddr_o = 2‘b00;

end

end

wire sys_clk;

assign sys_clk=~ifclk_i;

//888888888888888888888888888888888888888888888888888888888888888888

//内部延迟复位

reg [9:0] cnt=0;

always @(posedge sys_clk)begin

if(!cnt[9])cnt<=cnt+1;

end

wire rst;

assign rst =!cnt[9];

endmodule

比起上一章节,本章节的FPGA程序更为简单,设计的关键就是只要USB的Slave fifo读标志非空FPGA就可以读,当USB的Slave fifo写标志非满就可以写

15.3 FPGA上位机源码分析

BOOL CMTestPorjectDlg::OnInitDialog() 函数

BOOL CMTestPorjectDlg::OnInitDialog()

{

CDialog::OnInitDialog();

// 将“关于...”菜单项添加到系统菜单中。

// IDM_ABOUTBOX 必须在系统命令范围内。

ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);

ASSERT(IDM_ABOUTBOX < 0xF000);

CMenu* pSysMenu = GetSystemMenu(FALSE);

if (pSysMenu != NULL)

{

CString strAboutMenu;

strAboutMenu.LoadString(IDS_ABOUTBOX);

if (!strAboutMenu.IsEmpty())

{

pSysMenu->AppendMenu(MF_SEPARATOR);

pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);

}

}

// 设置此对话框的图标。当应用程序主窗口不是对话框时,框架将自动

//  执行此操作

SetIcon(m_hIcon, TRUE); // 设置大图标

SetIcon(m_hIcon, FALSE); // 设置小图标

// TODO: 在此添加额外的初始化代码

pUSBDevice = new CCyUSBDevice(m_hWnd);;//创建一个设备句柄

DisplayDevices();

m_Rate.SetRange(0,60);

m_Rate.SetPos(0);

return TRUE;  // 除非将焦点设置到控件,否则返回TRUE

}

pUSBDevice是定义一个CCyUSBDevice类指针,定义完成后会在内存中开辟一段地址空间,用来保存相关的数据。

void CMTestPorjectDlg::DisplayDevices(void)函数:

void CMTestPorjectDlg::DisplayDevices(void)

{

CString str = _T("米联电子--USB测试工程 没有找到设备");

UCHAR nCount,n;

Sleep(10);

m_Semaphore.Lock();

nCount=pUSBDevice->DeviceCount();

for(n=0;n < nCount;n++)

{

if(pUSBDevice->Open(n))

{

str = pUSBDevice->DeviceName;

if(str==_T("MIS603-X25"))

{

str = _T("米联电子--USB测试      ");

str+=pUSBDevice->DeviceName;

pInEndpt  = pUSBDevice->EndPointOf(0x86);

pOutEndpt = pUSBDevice->EndPointOf(0x02);

if(!pInEndpt || !pOutEndpt) str +=  _T("错误!    设备端点不可用");

break;

}

}

pInEndpt  = NULL;

pOutEndpt = NULL;

}

m_Semaphore.Unlock();

SetWindowText(str);

}

此函数首先通过pUSBDevice->DeviceCount();获得PC机上连接的设备数量,然后通过查找方式,找到设备描述符相对应的设备,然后设置USB设备的IN端点为端点6,OUT端点为端点2。

void CMTestPorjectDlg::OnBnClickedX86() 启动接收数据测试:

void CMTestPorjectDlg::OnBnClickedX86()

{

if(pInEndpt==NULL) return;

m_x86.EnableWindow(false);

m_x02.EnableWindow(false);

m_bXfer=!m_bXfer;

if(m_bXfer)

{

pXferInThread = AfxBeginThread(XferIn, this);//启动线程

if(pXferInThread)

{

m_x86.SetWindowText(_T("停止"));

m_x86.EnableWindow(true);

}

}

}

以上函数是单击端点86接收数据流测试后工作,主要是负责启动接收数据线程工作。

void CMTestPorjectDlg::OnBnClickedX02() 启动发送数据线程工作:

void CMTestPorjectDlg::OnBnClickedX02()

{

if(pOutEndpt==NULL) return;

m_x86.EnableWindow(false);

m_x02.EnableWindow(false);

m_bXfer=!m_bXfer;

if(m_bXfer)

{

pXferOutThread = AfxBeginThread(XferOut, this);//启动发送线程

if(pXferOutThread)

{

m_x02.SetWindowText(_T("停止"));

m_x02.EnableWindow(true);

}

}

}

UINT XferIn( LPVOID params ) 接收线程函数:

UINT XferIn( LPVOID params ) {

    CMTestPorjectDlg *pDlg= (CMTestPorjectDlg*) params;

LARGE_INTEGER BegainTime;

LARGE_INTEGER EndTime;

LARGE_INTEGER Frequency;

QueryPerformanceFrequency(&Frequency);//设置计数器对象

    OVERLAPPED InOvLap[16];

UCHAR  *pInContext[16];

ULONG nSucCount = 0;

ULONG nErrCount = 0;

LONG nLen = 10240;

UCHAR data[10240]; ZeroMemory(data,nLen);

CString s[16];

int n=0;

  pDlg->m_Semaphore.Lock();

//16级缓冲

for(n=0;n<16;n++)

{

if(pDlg->pInEndpt==NULL) break;

nLen = 10240;

s[n].Format(_T("USB_IN%d"),n);

InOvLap[n].hEvent   = CreateEvent(NULL,false,false, s[n]);

pInContext[n] = pDlg->pInEndpt->BeginDataXfer(data,nLen,&InOvLap[n]);

}

pDlg->m_Semaphore.Unlock();

while (1)

{

bool b=pDlg->m_bXfer;

if(pDlg->pInEndpt==NULL) break;

pDlg->m_Semaphore.Lock();//独占模式

pDlg->pInEndpt->TimeOut = 0;

QueryPerformanceFrequency(&Frequency);//设置计数器对象

QueryPerformanceCounter(&BegainTime);//获取初值

for(n=0;n<16;n++)

{

if(!pDlg->pInEndpt->WaitForXfer(&InOvLap[n],2000))

{

pDlg->pInEndpt->Abort();

WaitForSingleObject(InOvLap[n].hEvent, 2000);

}

nLen = 10240;

bool success = pDlg->pInEndpt->FinishDataXfer(data,nLen, &InOvLap[n],pInContext[n]);

if (success)nSucCount++;

else nErrCount++;

nLen = 10240;

if(b) pInContext[n] = pDlg->pInEndpt->BeginDataXfer(data,nLen,&InOvLap[n]);

}

QueryPerformanceCounter(&EndTime);

double t=(double)( EndTime.QuadPart - BegainTime.QuadPart )/Frequency.QuadPart;//计算速度

pDlg->m_Semaphore.Unlock();

pDlg->TestRate(t,nSucCount, nErrCount);

if(!b) break;

}

for(n=0;n<16;n++)

{

CloseHandle(InOvLap[n].hEvent);

}

pDlg->EndOutThread(2);

return true;

}

次函开启16级BUFEER的IN传输,然后通过QueryPerformanceCounter()函数获取时间计数器,计算速度。

UINT XferOut( LPVOID params ) 发送线程函数:

UINT XferOut( LPVOID params ) {

    CMTestPorjectDlg *pDlg= (CMTestPorjectDlg*) params;

LARGE_INTEGER BegainTime;

LARGE_INTEGER EndTime;

LARGE_INTEGER Frequency;

QueryPerformanceFrequency(&Frequency);

    OVERLAPPED OutOvLap[16];

UCHAR  *pOutContext[16];

ULONG nSucCount = 0;

ULONG nErrCount = 0;

LONG nLen = 10240;

UCHAR data[10240]; ZeroMemory(data,nLen);

CString s[16];

int n=0;

  pDlg->m_Semaphore.Lock();

//16级缓冲

for(n=0;n<16;n++)

{

if(pDlg->pOutEndpt==NULL) break;

nLen = 10240;

s[n].Format(_T("USB_OUT%d"),n);

OutOvLap[n].hEvent   = CreateEvent(NULL,false,false, s[n]);

pOutContext[n] = pDlg->pOutEndpt->BeginDataXfer(data,nLen,&OutOvLap[n]);

}

pDlg->m_Semaphore.Unlock();

while (1)

{

bool b=pDlg->m_bXfer;

if(pDlg->pOutEndpt==NULL) break;

pDlg->m_Semaphore.Lock();

pDlg->pOutEndpt->TimeOut = 0;

QueryPerformanceFrequency(&Frequency);

QueryPerformanceCounter(&BegainTime);

for(n=0;n<16;n++)

{

if(!pDlg->pOutEndpt->WaitForXfer(&OutOvLap[n],2000))

{

pDlg->pOutEndpt->Abort();

WaitForSingleObject(OutOvLap[n].hEvent, 2000);

}

nLen = 10240;

bool success = pDlg->pOutEndpt->FinishDataXfer(data,nLen, &OutOvLap[n],pOutContext[n]);

if (success)nSucCount++;

else nErrCount++;

nLen = 10240;

if(b) pOutContext[n] = pDlg->pOutEndpt->BeginDataXfer(data,nLen,&OutOvLap[n]);

}

QueryPerformanceCounter(&EndTime);

pDlg->m_Semaphore.Unlock();

double t=(double)( EndTime.QuadPart - BegainTime.QuadPart )/Frequency.QuadPart;//计算速度

pDlg->TestRate(t,nSucCount, nErrCount);

if(!b) break;

}

for(n=0;n<16;n++)

{

CloseHandle(OutOvLap[n].hEvent);

}

// pDlg->pXferOutThread = NULL;

pDlg->EndOutThread(3);

return true;

}

此发送线程工作原理和接收线程工作原理一样,开启16级发送缓冲,然后通过 QueryPerformanceCounter()函数获取系统计数器值,计算速度。

15.4 测试结果

数据接收:

数据发送:

15.5 小结

本节详细讲述了USB流传输的FPGA硬件代码,以及上位机软件关键代码,并且给出了测试速度。可以看出CY7C68013A在USB2.0高速接口的传输速度还是非常快和稳定的。

第七章、第八章详细讲解了USB2.0控制器CY7C68013A的软件和硬件开发基础,并且给出了SLAVE FIFO块传输的方案,通过实战的例子,和对关键代码的详细剖析,带领读者快速掌握好CY7C68013A的基于FPGA的应用方案。

当然USB2.0传输还有很多内容,本章没有详细讲解,比如控制传输,中断传输、同步传输、块传输,USB描述符,USB应答机制等。读者如果感兴趣可以到我们官方论坛:www.osrc.cn发帖咨询,或者查阅相关书籍。

时间: 2024-10-31 04:06:49

MiS603开发板 第十二章 SLAVE FIFO流传输的相关文章

MiS603开发板 第十四章 UDP协议网络传输

作者:MiS603开发团队 日期:20150911 公司:南京米联电子科技有限公司 论坛:www.osrc.cn 网址:www.milinker.com 网店:http://osrc.taobao.com EAT博客:http://blog.chinaaet.com/whilebreak 博客园:http://www.cnblogs.com/milinker/ MiS603开发板 第十四章 UDP协议网络传输 本实验将实现FPGA 芯片和PC 之间进行千兆以太网数据通信, 通信协议采用Ether

MiS603开发板 第十五章 MCB DDR3内存测试

作者:MiS603开发团队 日期:20150911 公司:南京米联电子科技有限公司 论坛:www.osrc.cn 网址:www.milinker.com 网店:http://osrc.taobao.com EAT博客:http://blog.chinaaet.com/whilebreak 博客园:http://www.cnblogs.com/milinker/ MiS603开发板 第十五章 MCB DDR3内存测试 15.1 DDR3存储器模块及其测试 图像算法硬件最关键的一部分就是内存,内存保

MiS603开发板 第十六章 图像之VGA接口测试

作者:MiS603开发团队 日期:20150911 公司:南京米联电子科技有限公司 论坛:www.osrc.cn 网址:www.milinker.com 网店:http://osrc.taobao.com EAT博客:http://blog.chinaaet.com/whilebreak 博客园:http://www.cnblogs.com/milinker/ MiS603开发板 第十六章 图像之VGA接口测试 第十六章图像之VGA接口测试 在本章开始介绍视频图像处理开发平台的硬件结构,主要包括

MiS603开发板 第十八章 模拟视频输入及测试

作者:MiS603开发团队 日期:20150911 公司:南京米联电子科技有限公司 论坛:www.osrc.cn 网址:www.milinker.com 网店:http://osrc.taobao.com EAT博客:http://blog.chinaaet.com/whilebreak 博客园:http://www.cnblogs.com/milinker/ MiS603开发板 第十八章 模拟视频输入及测试 18.1模拟视频概述 大自然的信号都是模拟的,视频信号也不例外.视频信号是指电视信号.

MiS603开发板 第十一章 CY7C68013A Slave FIFO回传输

作者:MiS603开发团队 日期:20150911 公司:南京米联电子科技有限公司 论坛:www.osrc.cn 网址:www.milinker.com 网店:http://osrc.taobao.com EAT博客:http://blog.chinaaet.com/whilebreak 博客园:http://www.cnblogs.com/milinker/ MiS603开发板 第十一章 CY7C68013A Slave FIFO回传输 CY7C68013A提供了强大和灵活的外部接口通信方式,

MiS603开发板 第十三章 千兆网RGMII PHY测试

作者:MiS603开发团队 日期:20150911 公司:南京米联电子科技有限公司 论坛:www.osrc.cn 网址:www.milinker.com 网店:http://osrc.taobao.com EAT博客:http://blog.chinaaet.com/whilebreak 博客园:http://www.cnblogs.com/milinker/ MiS603开发板 第十三章 千兆网RGMII PHY测试 13.1 RGMII 简介 RGMII(Reduced Gigabit Me

MiS603开发板 第十七章 图像之HDMI接口测试输入日志标题

作者:MiS603开发团队 日期:20150911 公司:南京米联电子科技有限公司 论坛:www.osrc.cn 网址:www.milinker.com 网店:http://osrc.taobao.com EAT博客:http://blog.chinaaet.com/whilebreak 博客园:http://www.cnblogs.com/milinker/ MiS603开发板 第十七章 图像之HDMI接口测试 17.1 HDMI概述 HDMI是High Definition Multimed

MiS603开发板 第三章 多路分频器设计

作者:MiS603开发团队 日期:20150911 公司:南京米联电子科技有限公司 论坛:www.osrc.cn 网址:www.milinker.com 网店:http://osrc.taobao.com EAT博客:http://blog.chinaaet.com/whilebreak 博客园:http://www.cnblogs.com/milinker/ MiS603开发板 第三章 多路分频器设计 设计思想:利用FPGA内部的逻辑单元对FPGA输入的50MHZ高频时钟信号进行计数分频,得到

MiS603开发板 第四章 流水灯实验

作者:MiS603开发团队 日期:20150911 公司:南京米联电子科技有限公司 论坛:www.osrc.cn 网址:www.milinker.com 网店:http://osrc.taobao.com EAT博客:http://blog.chinaaet.com/whilebreak 博客园:http://www.cnblogs.com/milinker/ MiS603开发板 第四章 流水灯实验 关于流水灯,网上有太多的例子了.其实只要掌握上面分频计数的技巧,设计流水灯是件极其简单的事情.从