FT232H读写驱动设计

本节中,笔者将介绍FT232H的读写驱动设计,芯片采用FTDI的FT232H,其支持SPI,JTAG,UART,FIFO等各类接口,无需关心USB2.0协议,即可实现USB数据的传输,简单易行,并且官方提供固件下载工具,供用户进行各类驱动接口的配置,本项目中,使用FT232H的FT245同步FIFO模式,进行PC,FT232H,FPGA三者之间的数据交互。
下图所示,是FT245 Synchronous FIFO Interface Mode的时序图
在这里插入图片描述
在任何一个时钟周期内,都只允许读操作或是写操作
首先对USB的读时序做解读。
首先FT232H拉低RXF#信号,表示FT232H中的FIFO有数据等待读出,当FPGA接收到这个信号时,将OE#信号拉低,使能FT232H的输出,观察时序可知,在OE#拉低的t6时间后,总线开始输出有效数据,这时拉低RD#,即可读取有效数据,注意手册中明确指出OE#拉低压迫至少比RD#拉低提早一个时钟周期,故在程序设计中,将RD#拉低晚于OE#一个时钟周期即可。关于
FT245 Synchronous FIFO Interface下各个接口的介绍,在手册中给到了表格介绍
在这里插入图片描述
在这里插入图片描述
对USB的写时序做解读
当FT232H的TXE#信号为低时,表示其内部FIFO没有被写满,可以接收数据。若此时FPGA侧的FIFO同样有数据进行发送,则拉低WR#,进行数据输出即好,保证WR#与DATA的同步即可,避免数据丢失。
以下是相关代码

/*The transceiver logic of USB data is realized. The data written is from the upper FIFO, 
and the data read is stored in the upper FIFO. The two are not the same FIFO*/
module usb_rw(
    input               i_usb_clk               ,
    input               i_usb_rst               ,
    /*FT232H Signals*/
    input               i_usb_rxf_n             ,
    input               i_usb_txe_n             ,
    output              o_usb_oe_n              ,
    output              o_usb_rd_n              ,
    output              o_usb_wr_n              ,
    inout   [7 :0]      io_usb_data             ,
    /*FIFO Signals*/
    input               i_usb_wr_fifo_empty     ,
    input   [7 :0]      i_usb_wr_fifo_rd_data   ,
    output              o_usb_wr_fifo_rd_en     ,
    output              o_usb_rd_fifo_wr_en     ,
    output  [7 :0]      o_usb_rd_fifo_wr_data
    );

localparam      P_ST_IDLE = 0   ,
                P_ST_READ = 1   ,
                P_ST_WRITE= 2   ;

reg     [2 :0]  r_state         ;
reg             ro_usb_oe_n     ;
reg             ro_usb_oe_n_1d  ;

assign  o_usb_rd_n              = (ro_usb_oe_n == 'b0 && ro_usb_oe_n_1d == 'b0) ? 1'b0 : 1'b1;
assign  o_usb_rd_fifo_wr_data   = r_state == P_ST_READ ? io_usb_data : 8'hzz;
assign  o_usb_rd_fifo_wr_en     = (ro_usb_oe_n_1d == 'b0 && i_usb_rxf_n == 'b0) ? 1'b1 : 1'b0;

assign  o_usb_wr_n              = ((r_state == P_ST_WRITE) && (i_usb_txe_n == 0) && (i_usb_wr_fifo_empty == 0)) ? 1'b0 : 1'b1;
assign  o_usb_wr_fifo_rd_en     = ((r_state == P_ST_WRITE) && (i_usb_txe_n == 0) && (i_usb_wr_fifo_empty == 0)) ? 1'b1 : 1'b0;
assign  io_usb_data             = r_state == P_ST_WRITE ? i_usb_wr_fifo_rd_data : 8'hzz;


always@(posedge i_usb_clk,posedge i_usb_rst)
begin
    if(i_usb_rst)
        ro_usb_oe_n <= 'b1;
    else if(i_usb_rxf_n == 'b0)
        ro_usb_oe_n <= 'b0;
    else if(i_usb_rxf_n)
        ro_usb_oe_n <= 'b1;
end

always@(posedge i_usb_clk,posedge i_usb_rst)
begin
    if(i_usb_rst)
        ro_usb_oe_n_1d <= 'b1;
    else
        ro_usb_oe_n_1d <= ro_usb_oe_n;
end

always@(posedge i_usb_clk,posedge i_usb_rst)
begin
    if(i_usb_rst)
        r_state <= P_ST_IDLE;
    else
        case(r_state)
            P_ST_IDLE : begin
                if(i_usb_rxf_n == 1'b0)
                    r_state <= P_ST_READ;
                else if(i_usb_txe_n == 'b0 && i_usb_wr_fifo_empty == 'b0)
                    r_state <= P_ST_WRITE;
            end
            P_ST_READ : begin
                if(i_usb_rxf_n == 1'b1)
                    r_state <= P_ST_IDLE;
            end
            P_ST_WRITE : begin
                if(i_usb_txe_n == 'b1 || i_usb_wr_fifo_empty == 1'b1)
                    r_state <= P_ST_IDLE;
            end
        endcase
end

endmodule

可以看到关于FPGA内部的FIFO信号是由两组的,其中usb_wr_fifo表示的含义为FPGA向FT232H写数据的存储FIFO,也即前文提到的ADC原始数据以及ADC频谱
usb_rd_fifo表示FPGA从FT232H中读到的数据存入的FIFO。主要是一些指令信息,用于PC与FPGA的交互。

本节主要介绍了FT232H的驱动编写,本节代码可以私信博主免费领取。
在下一章节中,笔者将对ADC数据,ADC数据频谱的处理代码,进行统一梳理。

Logo

DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。

更多推荐