查看: 1322|回复: 0
打印 上一主题 下一主题

[讨论]FPGA2USB (68013)传输数据时出现的一些现象

[复制链接]
跳转到指定楼层
沙发
发表于 2016-5-8 23:52:40 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
小弟在做一个FPAG to USB(68013)数据传输的项目,Xilinx的sptan3系列FPGA和56管脚的68013;
采用的方案:上位机程序用VC++编写,由于传输文件数据大概在几十M到几百兆之间,所以采用多线程,单独开个线程来发数据,这样可以避免数据堵塞。68013固件是采用slavefifo模式,4缓冲配置。
FPGA固件是一个USB接收模块,将数据接收后放在一个ip核的ram中,待ram满后在一次发给主板的SDRAM中。
调试现象:点击上位机程序的开始发送后,用USBHOUND观察数据,发现没有,然后关掉上位机程序,发现任务管理器中程序的进程还在运行,强行杀也杀不掉,接着我断开主板与电脑USB连接,发现任务管理器的程序进程没了,同时USBHOUND中有了我发的数据,通过核对,发现数据是正确的。这次希望你通过请教和讨论,帮我排除点干扰找出原因,下附代码:
上位机的发数据线程函数:UINT StartThread(void * pParam)
{
CThreadParam* ThreadParam;
CPrint4Dlg* TestDlg;

HANDLE hOutDevice = NULL;
PUCHAR outBuffer = NULL;
ULONG CurrentTransferSize;
ULONG OutPipeNum;
ULONG  i;
BULK_TRANSFER_CONTROL outBulkControl;
THREAD_CONTROL outThreadControl;
//得到线程参数
ThreadParam=(CThreadParam *)pParam;
TestDlg=ThreadParam->testDlg;
//打开设备
if(bOpenDriver(&hOutDevice,strDevname.GetBuffer(strDevname.GetLength()))!= TRUE)
{
        TestDlg->m_strOutput+="打开设备失败,测试线程结束\r\n";
        ThreadParam->bUpdate=TRUE;
        return 0;
}
//进行数据传输
OutPipeNum=0;
CurrentTransferSize = 8192;
outBuffer = (unsigned char *)malloc(CurrentTransferSize);
Ripdata_buf =(BYTE*)HeapAlloc(GetProcessHeap(),0,CurrentTransferSize);
TestDlg->file.Seek(438560,CFile::begin);
TestDlg->file.Read(Ripdata_buf,CurrentTransferSize);


while(!gStopPrint)//全局变量来决定是否退出测试线程
{
for (i=0;i<CurrentTransferSize;i++)
        outBuffer = Ripdata_buf;

outBulkControl.pipeNum = OutPipeNum;
outThreadControl.hDevice = hOutDevice;

outThreadControl.Ioctl = IOCTL_EZUSB_BULK_WRITE;
outThreadControl.InBuffer = (PVOID)&outBulkControl;
outThreadControl.InBufferSize = sizeof(BULK_TRANSFER_CONTROL);
outThreadControl.OutBuffer = outBuffer;
outThreadControl.OutBufferSize = CurrentTransferSize;

outThreadControl.status = FALSE;
outThreadControl.BytesReturned = 0;

outThreadControl.status= DeviceIoControl(outThreadControl.hDevice,
                                                                                  outThreadControl.Ioctl,
                                                                                  outThreadControl.InBuffer,
                                                                                  outThreadControl.InBufferSize,
                                                                                  outThreadControl.OutBuffer,
                                                                                  outThreadControl.OutBufferSize,
                                                                                  &outThreadControl.BytesReturned,
                                                                                  NULL
                                                                                        );
//如果发生错误,停止数据传输
if ((!outThreadControl.status)||(outThreadControl.BytesReturned != CurrentTransferSize))
                   {
                          TestDlg->m_strOutput+= "Error: Write failed\r\n";
                          Errors++;
                          gStopPrint = TRUE;
                   }
                        SetEvent(hEvent);         
                        ThreadParam->bUpdate=TRUE;
      
        }
   
    free(outBuffer);
    CloseHandle(hOutDevice);
    ThreadParam->bUpdate=TRUE;
        return 0;
}
68013固件一些配置:               CPUCS = 0x12;  //48MHZ CLKOUT ENALBE
        IFCONFIG =0x43;//使用外部时钟,IFCLK输入不反向
        
        SYNCDELAY;
        EP2CFG=0xA0; //需要设定为四缓冲,每个缓冲区大小为512字节
        SYNCDELAY;
        EP4CFG=0x00;
        SYNCDELAY;
        EP6CFG=0xE0;
        SYNCDELAY;
        EP8CFG=0x00;
        
        SYNCDELAY;
        FIFORESET = 0x80;             // activate NAK-ALL to avoid race conditions
        SYNCDELAY;                    // see TRM section 15.14
        FIFORESET = 0x02;             // reset, FIFO 2
        SYNCDELAY;                    //
        FIFORESET = 0x06;             // reset, FIFO 6
        SYNCDELAY;                    //
        FIFORESET = 0x00;             // deactivate NAK-ALL
        
        SYNCDELAY;
        PINFLAGSAB = 0xE6;          // FLAGA - fixed EP6PF, FLAGB - fixed EP6FF
        SYNCDELAY;
        PINFLAGSCD = 0xf8;          // FLAGC - fixed EP2EF, FLAGD - reserved
        SYNCDELAY;
        PORTACFG |=  0x00;  //0x40;             // SLCS, set alt. func. of PA7 pin
        SYNCDELAY;
        FIFOPINPOLAR = 0x00;          // all signals active low,
        SYNCDELAY;

         OEA|=0x0F;
    //小于64字节有效
    //EP6FIFOPFH=0x00; //DEIS PKSTAT  PK2 PK1 PK0 0 PFC9 PFC8
    //EP6FIFOPFL=0x40; //PFC7 PFC6 PFC5 PFC4 PFC3 PFC2 PFC1 PFC0
        
        // handle the case where we were already in AUTO mode...
        EP2FIFOCFG = 0x01;            // AUTOOUT=0, WORDWIDE=1
        SYNCDELAY;
        
        EP2FIFOCFG = 0x11;            // AUTOOUT=1, WORDWIDE=1
        SYNCDELAY;
        
        
        EP6FIFOCFG = 0x09;            // AUTOIN=1, ZEROLENIN=0, WORDWIDE=1
        SYNCDELAY;

        //IO设置
        PORTCCFG=0x00;
        PORTECFG=0x00;
        OEC=0x00;
        OEE=0xff;
        //串口初始化

//        PA3=0;
        PA0=1;

        enum_high_speed=FALSE;
FPGA接收模块状态机:case(STATE)
        IDLE:
                begin
                //添加RESET状态        
                data_wr<='h0;//写数据初始化
                u_slwr<='b1;
                u_slrd<='b1;
                u_sloe<='b1;
                u_addr0<='b1;
                u_addr1<='b1;
                oe<='b0;
        
           ena<='b0;
                enb<='b0;
           addra<=13'h1fff;
           addrb<=13'h1fff;
                dina_i<='h0;
                wr_flag<='b0;
                flag <= 'b0;
                STATE<=READ_EVENT;
                end
        READ_EVENT:
                begin
                //enb<='b0;
                wr_flag<='b1;
                u_addr0<='b0;
                u_addr1<='b0;
                STATE<=POINT_TO_OUT_FIFO;
                end
        POINT_TO_OUT_FIFO:
                begin
                if(u_flagc)
                        begin
                        u_sloe<='b0;
                        u_slrd<='b1;
                        STATE<=DATA_READY;
                        end
                else
                        begin
                        u_sloe<='b1;
                        u_slrd<='b1;
                        STATE<=POINT_TO_OUT_FIFO;
                        end
                end
        DATA_READY:
                begin
                if((u_flagc&&data=='h0100&&!flag)||(u_flagc&&flag))
                        begin
                        flag<=1'b1;
                        u_slrd<='b0;
                        addra<=addra+1;
                        dina_i<=data;////////////////////data_src
                        ena<='b1;
                        enb<='b0;
                        STATE<=READ;
                        end
                else
                        begin
                        u_slrd<='b1;
                        u_sloe<='b1;
                        STATE<=POINT_TO_OUT_FIFO;
                        end
                end
        READ:
                begin
                u_slrd<='b1;
                ena  <='b0;
               
                if(addra!=ADDR_FULL)
                        STATE<=DATA_READY;
                else
                        STATE<=READ_END;
                end
        READ_END:
                begin
                u_slrd<='b1;
                u_sloe<='b1;
                u_addr0<='b0;
                u_addr1<='b0;
                addra<='h1fff;
                STATE<=WRITE_EVENT;
                end
        WRITE_EVENT:
                begin
                wr_flag<='b0;
                sd_flag<='b0;
;                enb<='b0;
                STATE<=POINT_TO_IN_FIFO;
                end
        POINT_TO_IN_FIFO:
                begin
                addrb<=addrb+1;
                ena<='b0;
                enb<='b1;
                STATE<=WRITE;
                end
        WRITE:
                begin
                  if(addrb!=ADDR_FULL)
                        begin
                         addrb<=addrb+1;
                         sd_data<=doutb;
                    ena<='b0;
                    enb<='b1;
                         sd_flag<=1;
                        STATE<=WRITE;
                        end
                else
                        begin
                        addrb<='h1fff;
                         ena<='b0;
                    enb<='b0;
                        STATE<=WRITE_END;
                        end
                end
        WRITE_END:
                begin
                sd_flag<='b0;
                wr_flag<='b0;
                addrb<='h1fff;//add by lww
                u_addr0<='b1;
                u_addr1<='b1;
                STATE<=IDLE;
                end
        default:
                STATE<=IDLE;
        endcase
        end
end

回复

使用道具 举报

您需要登录后才可以回帖 登录 | 加入因仑

本版积分规则

快速回复 返回顶部 返回列表