FT2232H - SPI模式下的不规则时钟

时间:2018-03-15 17:45:29

标签: spi ftdi

我在Linux 64b上使用带有libftdi1的FT2232H。

我在MPSSE位模式下使用INTERFACE_B,并通过SPI传输大缓冲区(1024B)(D2XX命令0x11)。当我用逻辑分析仪查看生成的信号时,似乎在一个字节的传输过程中时钟频率是一致的,但在两个连续的字节之间存在某种“毛刺”,如下面的屏幕截图所示(第二条曲线) ):

enter image description here

以下是设置代码

marksList

发送代码:

static void init_ftdi_context(struct ftdi_context *ctx, unsigned long sample_rate)
{
    ftdi_init(ctx);
    ftdi_set_interface(ctx, INTERFACE_B);

    if (ftdi_usb_open(ctx, 0x0403, 0x6010) != 0){
        die("Cannot open FTDI USB device");
    }

    if (ftdi_usb_reset(ctx) != 0){
        die("Cannot reset FTDI USB");
    }

    if (ftdi_usb_purge_buffers(ctx) != 0){
        die("Cannot flush FTDI buffers");
    }

    if (ftdi_set_latency_timer(ctx, 1) < 0){
        die("Cannot set latency timer (%s)", ftdi_get_error_string(ctx));
    }

    if (ftdi_set_bitmode(ctx, 0xff, BITMODE_MPSSE) < 0) {
        die("Failed to set BITMODE_MPSSE on iCE FTDI USB device.\n");
    }

    /* Clock settings:
     * FT2232H has a 60MHz clock. The clock can have a 1/5 prescaler, reducing
     * the base clock to 12MHz, the clock divider is defined as:
     *         base_clock
     * Freq = -----------
     *        2 * (1+div)
     */
    unsigned long divider = (FT2232H_CLOCK_FREQ - 2*sample_rate) / (2*sample_rate);
    unsigned long true_sample_rate = FT2232H_CLOCK_FREQ / (2 * (1+divider));
    if (true_sample_rate != sample_rate){
        fprintf(stderr, "WARNING: Sample rate not precise (%luHz instead of %luHz)\n",
                        true_sample_rate, sample_rate);
    }

    if (divider > 0xffff){
        die("Sample rate too low (divider cannot exceed 65535)");
    }

    uint8_t divider_lsb = divider & 0xff;
    uint8_t divider_msb = (divider >> 8) & 0xff;
    const uint8_t clk_cmd[] = {
        0x97, // Disable adaptive clock
        0x8d, // Disable 3-phase clock
        0x85, // Disable loopback
        0x8a, // Disable prescaler mode
        0x86, divider_lsb, divider_msb
    };
    if (ftdi_write_data(ctx, clk_cmd, sizeof(clk_cmd)) != sizeof(clk_cmd)){
        die("Cannot configure clock");
    }

    const uint8_t gpio_cmd[] = {0x80, 0x91, 0x93};
    if (ftdi_write_data(ctx, gpio_cmd, sizeof(gpio_cmd)) != sizeof(gpio_cmd)){
        die("Cannot configure GPIO");
    }
    usleep(100000);
}

是否可以选择指定在传输的两个连续字节之间应用的延迟?

1 个答案:

答案 0 :(得分:0)

确保初始化MPSSE端口引脚的初始状态(命令0x80)。具体来说,对于命令0x11,SPI时钟应从低电平开始。如果SPI时钟从高电平开始,则使用命令0x10。如果你没有以正确的状态启动,你会看到时钟故障。