FTDI MPSSE 串行引擎编程教程:基础知识和 GUI 示例

发布时间:2024年01月19日

前言:

FTDI MPSSE 串行引擎编程教程:基础知识和 GUI 示例 - Atadiat

许多MCU没有物理层来支持USB的直接连接,而大多数MCU都具有串行接口,这就是为什么需要通过USB进行有线通信的设备常用方法是使用桥接芯片。USB 串行桥最常见的品牌是 FTDI。

芯片进行一种类型转换

知名产品和开发板使用FTDI的FT232R作为USB到UART转换器。然而,FT232R在其他可用的串行接口中只转换UART,而不需要进行配置或编程,它提供了一个虚拟COM(VCOM)来与你的USB端口进行通信。这意味着如果要将SPI转换为USB .i.e:FT220X,或I2C转换为USB .i.e:FT201X,则需要使用不同的芯片。等。

一个芯片可以做多种类型的转换!

FTDI在下一代芯片中引入了通用串行转换引擎。因此,客户可以使用同一芯片将USB转换为UART或SPI或其他串行协议。

“Multi-Protocol Synchronous Serial Engine”或MPSSE是FTDI新一代芯片内部的模块名称,旨在提供USB到各种串行协议转换的灵活性。该引擎驱动芯片引脚以执行所需的串行协议。

MPSSE 在 FT232H 框图中突出显示 –?数据表

这种灵活性使MPSSE可用于不同的应用,包括不同类型的USB到串行转换,其中一个著名的例子是使用OpenOCD,即带有MPSSE芯片的JTAG/SWD调试器。要了解有关 OpenOCD 的更多信息,请参阅此入门指南

在本文中,我们将了解MPSSE的基础知识,如何配置,并编写一个小程序来驱动包含MPSSE引擎的FT2232H芯片。

本教程中将使用的分线板来自全球速卖通的中国提供商。但是,FTDI有一个官方模块,也可以使用,称为FT2232H迷你模块。

“设备管理器”眼中的MPSSE

MPSSE 模块可以在新一代 FTDI 芯片中找到,即:FT232H、FT2232H、FT4232H 和 FT2232D。为了配置MPSSE,使用了一个名为D2XX的软件USB接口,该接口是专门用于FTDI设备的专有接口,并且可以使用“FTD2XX.DLL”库使用其功能。但是,通常的虚拟 COM 端口 (VCP) 接口也可用。因此,当您将芯片连接到PC时,您会看到2个不同的接口,并且实际上属于同一硬件。

Windows 组合驱动程序模型 (CDM) 驱动程序体系结构 –?D2XX 程序员指南

您可以通过在连接FT2232H后在 Windows 中打开“设备管理器”来查看这一点。由于上述原因,您将在两个地方看到FTDI芯片:在“端口(COM和LPT)”和“通用串行总线控制器”下。

从每个人的驱动程序详细信息中,我们可以看到差异:

Mr. MPSSE 引脚

根据您使用的芯片,您可能有一个通道(FT232H)、双通道(FT2232D和FT2232H)或四通道(FT4232H)。

每个通道都有固定的引脚来进行串行通信(如果需要,可以进行数据输出、数据输入、时钟和片选),如下表所示:

来源:应用笔记?AN 135,标题为“MPSSE_Basics”

下表说明了如何将协议信号分配给 MPSSE 中串行通信的 4 个主要固定引脚:

来源:应用笔记?AN 135,标题为“MPSSE_Basics”

与 MPSSE 对话:命令

从程序中驱动任何带有MPSSE引擎的FTDI芯片的第一步是了解MPSSE命令以及如何使用“FTD2XX.DLL“库。

稍后你会发现 MPSSE 完全由命令驱动,这就是它被称为命令处理器的原因。您需要从 MPSSE 执行的每个功能或操作都由命令驱动。这包括:将数据放在行上,将 gpio 拉高,读取 gpio 状态,......等。

与 MPSSE 对话:图书馆

要在程序和MPSEE之间进行所需的通信,这将通过“FTD2XX.DLL“库。但是,如果您不想直接理解和使用 MPSSE 命令,则可以在 FTDI 的其他库中使用更高级别的抽象。FTDI 提供 SPI、I2C 和 JTAG 库;分别为 FTCSPI.DLL、FTCI2C.DLL 和 FTJTAG.DLL。

您可以从 FTCSPI.DLL、FTCI2C.DLL 或 FTJTAG.DLL 开始,但我发现至少做一个简单的示例很重要,使用 FTD2XX.DLL 和裸机 MPSSE 命令来理解 MPSSE 的实际工作原理,这就是我们将在以下示例中执行的操作。FTDI芯片将使用MPSSE直接驱动GPIO。

示例:包含库

在此示例中,我将使用 QT C++ 框架,您可以使用您觉得舒服的任何其他环境,例如 Visual Studio,并且步骤应该类似。
首先,我们首先从下载页面下载DLL文件,然后将您的DLL文件包含在您的程序中。这是在 QT 中通过在 QT 项目的“.pro”文件中添加以下行来完成的:

INCLUDEPATH += “LIBs”
LIBS += -L$$_PRO_FILE_PWD_/LIBs -lftd2xx

库文件 FTD2XX.DLL 位于下载并解压缩的“CDM v2.12.28 WHQL 认证”文件夹中。将“amd64”或“i386”目录的内容复制到项目目录。为此,我制作了一个名为 LIBs 的文件夹。

稍后,在使用 D2XX API 的位置包含“ftd2xx.h”标头。

示例:开始使用 API

FTDI 在其?D2XX 程序员指南中提供了 D2XX?API 的完整文档。

我们首先使用以下 API 通过 USB 扫描连接的设备:

FT_CreateDeviceInfoList&numDevs);

FT_CreateDeviceInfoList&numDevs);

其中?numDevs?将包含检测到的 FT 设备数

然后,要使用此功能获取这些设备的详细列表:

FT_GetDeviceInfoListdevInfo, &numDevs);

其中?devInfo?是指向?FT_DEVICE_LIST_INFO_NODE?元素数组的指针。FT_DEVICE_LIST_INFO_NODE包含以下成员:

稍后使用 FT_Open 打开与目标设备的连接

FT_Opendevice_num, &ftHandle);

其中?device_num?是要连接的设备的编号。设备编号类似于存储在设备列表“devInfo”中的顺序。

ftHandle?是指向 FT_HANDLE 类型的变量的指针,该变量将存储句柄。此句柄必须用于访问程序中的设备。

建立连接后,MPSSE 已准备好执行 get 命令,每个命令都由一个操作代码组成,后跟任何必要的参数或数据。

示例:发送 MPSSE 命令

在发送任何命令之前,需要 2 个步骤:

1- 为 MPSSE <-> USB 连接设置一些配置,例如:IN 和 OUT 传输大小、设备的读写超时和延迟。

ftStatus |= FT_SetUSBParametersftHandle, 6553565535; 设置USB请求传输大小
ftStatus |= FT_SetCharsftHandlefalse, 0, false 0; 禁用事件和错误字符
ftStatus |= FT_SetTimeoutsftHandle, 30003000; 设置FT2232H的读写超时时间(以 3 秒为单位
ftStatus |= FT_SetLatencyTimerftHandle, 1; //设置延迟计时器

2- 确保您的应用程序和 MPSSE 正确同步。为此,MPSSE 有一个名为“bad command”的特殊命令,当检测到它时,MPSSE 返回 0xFA 的值,后跟导致错误命令的字节。

关于该过程的文档是这样描述的:“使用错误命令检测是确定 MPSSE 是否与应用程序同步的推荐方法。通过故意发送错误命令并查找0xFA,应用程序可以确定是否可以与 MPSSE 进行通信”。

要通过 USB 在应用程序和 MPSSE 之间发送命令,您需要使用“FT_Write”api 发送数据。

然后,当使用?FT_GetQueueStatus?检查状态时,使用?FT_Read?读取输入,返回要读取的非零字节数。

发送“错误命令”0xAA或0xAB的代码如下所示:

dwNumBytesToSend = 0;
输出缓冲区[dwNumBytesToSend++] = '\xAA'; 添加 BAD 命令 & xAA*
ftStatus = FT_Write(ftHandle, OutputBuffer, dwNumBytesToSend, &dwNumBytesSent); 发送 BAD 命令
dwNumBytesToSend = 0; 清除输出缓冲区

做 {
ftStatus = FT_GetQueueStatus(ftHandle, &dwNumInputBuffer); 获取设备输入缓冲区中的字节数
} while ((dwNumInputBuffer == 0) && (ftStatus == FT_OK)); //或超时

bool bCommandEchod = 假;
ftStatus = FT_Read(ftHandle, InputBuffer, dwNumInputBuffer, &dwNumBytesRead); 从输入缓冲区读出数据
for (dwCount = 0; dwCount < (dwNumBytesRead - 1); dwCount++ ) //检查是否收到错误命令和回显命令
{
if ((InputBuffer[dwCount] == BYTE('\xFA')) && (InputBuffer[dwCount + 1] == BYTE('\xAA')))
{
bCommandEchod = 真;
破;
}
}

示例:小部件

下面的小组件扫描发现的设备并将其添加到表中,然后用户选择要连接的所需设备。

FT2232H有 2 个通道,每个通道都被视为一个独立设备。

注意:这是一个 QT 项目,我将通过本文和下一部分添加更多组件。

此阶段的文件(扫描和连接)可在此提交中找到。

示例:驱动 GPIO

现在,让我们通过设置 GPIO 来实际使用 MPSSE。

虽然 MPSSE 是串行引擎,但需要 GPIO 功能。例如,在SPI中,我们可以使用一个额外的引脚作为芯片选择。

GPIO示例中使用的命令包括:

0x80 <值> <方向>

这将设置前 8 行的方向,并在设置为输出的位上强制一个值。Direction 字节中的 1 将使该位成为输出。

0x82 <值> <方向>

这将设置高 8 行的方向,并在设置为输出的位上强制一个值。Direction 字节中的 1 将使该位成为输出。

0x81

这将读取前 8 个引脚的当前状态并发回 1 个字节。

0x83

这将读取高 8 引脚的当前状态并发回 1 个字节。

例:

将 TCK/SK、TDI/D0、TMS/CS 设置为输出,将 TDO/DI、GPIOL0-> GPIOL3 设置为低电平状态的输入。我们发送以下命令:

0x80 0x00 0x0B

知道 Direction 字节中的 1 将使该位成为输出

我没有遇到对GPIO命令参数的位字段表的引用。我必须在实践中弄清楚这一点。在下图中,演示了高低GPIO端口的位顺序。

过去的小组件已更新,以控制通道中可用的 GPIO。此阶段的文件,扫描和连接以及 GPIO 控制 ,可在此提交中找到。

以下是使用更新的 Widget 对输出功能的测试。FT2232H发送信号,“Analog Discovery 2”及其波中的静态 I/O 功能检查状态。

后来,Widget 也进行了更新,以支持输入功能。

下面是如何从 MPSSE 读取的示例

输出缓冲区[dwNumBytesToSend++] = '\x81';
ftStatus = FT_WriteftHandle、OutputBuffer、dwNumBytesToSend、&dwNumBytesSent);
dwNumBytesToSend = 0; 清除输出缓冲区
睡眠10);
{
ftStatus = FT_GetQueueStatusftHandle, &dwNumInputBuffer);
} while ((dwNumInputBuffer == 0&& ftStatus == FT_OK; //或超时
ftStatus = FT_ReadftHandle, InputBuffer, dwNumInputBuffer, &dwNumBytesRead; 从输入缓冲区读出数据

这是对 MPSSE 输入读数的测试。测试是使用 Digilent 的?Analog Discovery 2?波中的静态 I/O 功能完成的。有关Analog Discovery 2的更多信息,请参阅我们之前在Atadait上的介绍

阅读有关Analog Discovery 2的更多信息:

下一步是什么

到目前为止,我们已经熟悉了MPSSE的基础知识,它的工作原理,以及如何编写一个基本的应用程序来扫描和连接到FT设备,然后使用MPSSE命令控制GPIO。在下一部分中,我们将了解如何使用 SPI 器件和 FT2232H 进行串行通信。

参考资料和 阅读更多

文章来源:https://blog.csdn.net/a15236617777/article/details/135703183
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。