FT93x D2XX学习笔记 - 5. USB转UART

72 篇文章 39 订阅

FT93x最多可以支持4路硬件UART(FT930支持4路,FT931、FT932、FT933支持2路),注意由于管脚有共用,如果需要支持全功能串口则不能支持4路或2路。

这里仅考虑只使用RXD和TXD的情况,官方例程是D2XX Example UART Bridge。

USB转UART可以使用VCP驱动(非D2XX驱动),使用普通的串口工具,一个串口打开另外一个USB转串口,接FT930的UART0的RXD和TXD,一个串口工具打开FT930的USB转串口,测试结果如下:

可以修改程序将uart_configuration中UART0的波特率改为1M,同样测试会发现丢数据,如下图:

1. 目前的例程中FT930的USB转串口波特率设置并不起作用,所以左边的设定为19200或者任意值都可以正常工作,毕竟走的是USB协议,而例程中并没有通道可以通过工具设置FT930的UART波特率

2. FT930串口打印数据应该没有问题,但是从PC发送数据出去会没有打印,而从UART发送数据到PC会掉数据

基于D2XX Example 1参考UART Example 4的例程(使用UART的FIFO接收数据)修改为USB转串口程序:

1. 初始化UART0的IO口,以UART0为例

    #if defined(__FT930__)
    gpio_function(23, pad_uart0_txd); /* UART0 TXD */
    gpio_function(22, pad_uart0_rxd); /* UART0 RXD */
    #else
    gpio_function(48, pad_uart0_txd); /* UART0 TXD */
    gpio_function(49, pad_uart0_rxd); /* UART0 RXD */
    #endif

2. 打开UART,其中参数idx表示第几个UART

    ft900_uart_regs_t* const uart[] =
    {
        UART0, UART1,
    #if defined(__FT930__)
        UART2, UART3,
    #endif
    };

    uint8_t const sys_device_uart[] =
    {
        sys_device_uart0, sys_device_uart1,
        #if defined(__FT930__)
        sys_device_uart2, sys_device_uart3
        #endif
    };

    sys_enable(sys_device_uart[idx]);
    // Open the UART using the coding required.
    uart_open(uart[idx],                       /* Device */
            1,                            /* Prescaler = 1 */
            UART_DIVIDER_1000000_BAUD,  /* Divider = 1302 */
            uart_data_bits_8,             /* No. buffer Bits */
            uart_parity_none,             /* Parity */
            uart_stop_bits_1);            /* No. Stop Bits */

波特率设置为1M,可以根据实际需求修改。

3. 设置UART的模式和trigger方式

    /*Enable mode*/
    uart_mode(uart[idx], UART_MODE);
    /*Set trigger levels and flow controls*/
    uart_set_trigger_level(uart[idx], UART_MODE, RX_TRIGGER_LEVEL, TX_TRIGGER_LEVEL, FCH, FCL);
    /*Enable flow control*/
    //uart_set_flow_control(UART0, uart_flow_rts_cts, XON, XOFF);

其中各个参数参考例程中的定义

#define UART_FIFO_SIZE         128
#define UART_BUF_SIZE         (UART_FIFO_SIZE * 2)
#define UART_MODE             uart_mode_16950
#define RX_LEVEL            (127)
#define TX_LEVEL            (0)
/*Receiver interrupt trigger level*/
#define RX_TRIGGER_LEVEL    RX_LEVEL
/*Transmitter interrupt trigger level*/
#define TX_TRIGGER_LEVEL    TX_LEVEL
#define FCH                    112
#define FCL                    64
/*XON and XOFF bytes for flow control*/
#define XON                    0x11
#define XOFF                0x13

4. 初始化中断,中断函数采用每个UART一个中断函数,减少中断函数处理的时间,并且只处理接收中断,关掉发送中断。

    /* Attach the interrupt so it can be called... */
    interrupt_attach(interrupt_uart[idx], (uint8_t) interrupt_uart[idx], uart_ISR[idx]);
    /* Enable the UART to fire interrupts when receiving data... */
    uart_enable_interrupt(uart[idx], uart_interrupt_rx);
    /* Enable the UART to fire interrupts when transmitting data... */
    uart_disable_interrupt(uart[idx], uart_interrupt_tx);
    /* Enable interrupts to be fired... */
    uart_enable_interrupts_globally(uart[idx]);

参数:

    void(*uart_ISR[])(void) =
    {
            uart0ISR, uart1ISR,
            #if defined(__FT930__)
            uart2ISR, uart3ISR
            #endif
    };

    uint8_t const interrupt_uart[] =
    {
        interrupt_uart0, interrupt_uart1,
        #if defined(__FT930__)
        interrupt_uart2, interrupt_uart3
        #endif
    };

中断函数:

void uart0ISR(void)
{
    uartISR(0);
}

void uart1ISR(void)
{
    uartISR(1);
}

void uart2ISR(void)
{
    uartISR(2);
}

void uart3ISR(void)
{
    uartISR(3);
}

5. 中断处理函数uartISR,采用Ring Buffer的方式接收数据,在主循环中处理该数据。

//RX buffer
#define UART_BUF_SIZE         (UART_FIFO_SIZE * 2)
uint8_t uartRxBuf[USB2UART_NUM][UART_BUF_SIZE] = {0};
volatile uint16_t uartRxWrIdx[USB2UART_NUM] = {0};
volatile uint16_t uartRxRdIdx[USB2UART_NUM] = {0};

void uartISR(uint8_t idx)
{
    uint8_t count = 0, i = 0;
    uint8_t buf[UART_FIFO_SIZE];

    /* Receive interrupt... */
    if (uart_is_interrupted(uart[idx], uart_interrupt_rx)
            || uart_is_interrupted(uart[idx], uart_interrupt_rx_time_out))
    {
        count = uart_get_rx_fifo_level(uart[idx]);
        __asm__("streamin.b %0,%1,%2"::"r"(&buf[0]), "r"(&(uart[idx]->RHR_THR_DLL)), "r"(count));
        for(i = 0; i < count; i++)
        {
            uartRxBuf[idx][uartRxWrIdx[idx]++] = buf[i];
            uartRxWrIdx[idx] %= UART_BUF_SIZE;
        }
    }
}

6. 主循环中处理函数,从USB读到数据直接通过uart_write把数据发送到UART上,然后将接收Ring buffer中的数据发送给USB。

void usb2uartHandle(uint8_t idx)
{
    int32_t count = 0;
    uint8_t buf[USB2UART_BUF_MAX];
    count = D2XX_Read(idx + 1, buf, USB2UART_BUF_MAX);
    if(count > 0)
    {
        uint16_t i;
        for(i = 0; i < count; i++)
        {
            uart_write(uart[idx], buf[i]);
        }
    }
    if(uartRxRdIdx[idx] != uartRxWrIdx[idx])
    {
        uint16_t i;
        if(uartRxWrIdx[idx] > uartRxRdIdx[idx])
        {
            count = uartRxWrIdx[idx] - uartRxRdIdx[idx];

        }
        else
        {
            count = UART_BUF_SIZE + uartRxWrIdx[idx] - uartRxRdIdx[idx];
        }
        for(i = 0; i < count; i++)
        {
            buf[i] = uartRxBuf[idx][uartRxRdIdx[idx]++];
            uartRxRdIdx[idx] %= UART_BUF_SIZE;
        }
        count = D2XX_Write(idx + 1, buf, count);
    }
}

7.测试方式:

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值