FTDI MPSSE 串行引擎编程教程:基础知识和 GUI 示例 - Atadiat
知名产品和开发板使用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 模块可以在新一代 FTDI 芯片中找到,即:FT232H、FT2232H、FT4232H 和 FT2232D。为了配置MPSSE,使用了一个名为D2XX的软件USB接口,该接口是专门用于FTDI设备的专有接口,并且可以使用“FTD2XX.DLL”库使用其功能。但是,通常的虚拟 COM 端口 (VCP) 接口也可用。因此,当您将芯片连接到PC时,您会看到2个不同的接口,并且实际上属于同一硬件。
Windows 组合驱动程序模型 (CDM) 驱动程序体系结构 –?D2XX 程序员指南
您可以通过在连接FT2232H后在 Windows 中打开“设备管理器”来查看这一点。由于上述原因,您将在两个地方看到FTDI芯片:在“端口(COM和LPT)”和“通用串行总线控制器”下。
从每个人的驱动程序详细信息中,我们可以看到差异:
根据您使用的芯片,您可能有一个通道(FT232H)、双通道(FT2232D和FT2232H)或四通道(FT4232H)。
每个通道都有固定的引脚来进行串行通信(如果需要,可以进行数据输出、数据输入、时钟和片选),如下表所示:
来源:应用笔记?AN 135,标题为“MPSSE_Basics”
下表说明了如何将协议信号分配给 MPSSE 中串行通信的 4 个主要固定引脚:
来源:应用笔记?AN 135,标题为“MPSSE_Basics”
从程序中驱动任何带有MPSSE引擎的FTDI芯片的第一步是了解MPSSE命令以及如何使用“FTD2XX.DLL“库。
稍后你会发现 MPSSE 完全由命令驱动,这就是它被称为命令处理器的原因。您需要从 MPSSE 执行的每个功能或操作都由命令驱动。这包括:将数据放在行上,将 gpio 拉高,读取 gpio 状态,......等。
要在程序和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”标头。
FTDI 在其?D2XX 程序员指南中提供了 D2XX?API 的完整文档。
我们首先使用以下 API 通过 USB 扫描连接的设备:
FT_CreateDeviceInfoList(&numDevs);
其中?numDevs?将包含检测到的 FT 设备数
然后,要使用此功能获取这些设备的详细列表:
其中?devInfo?是指向?FT_DEVICE_LIST_INFO_NODE?元素数组的指针。FT_DEVICE_LIST_INFO_NODE包含以下成员:
稍后使用 FT_Open 打开与目标设备的连接,
FT_Open(device_num, &ftHandle);
其中?device_num?是要连接的设备的编号。设备编号类似于存储在设备列表“devInfo”中的顺序。
ftHandle?是指向 FT_HANDLE 类型的变量的指针,该变量将存储句柄。此句柄必须用于访问程序中的设备。
建立连接后,MPSSE 已准备好执行 get 命令,每个命令都由一个操作代码组成,后跟任何必要的参数或数据。
在发送任何命令之前,需要 2 个步骤:
1- 为 MPSSE <-> USB 连接设置一些配置,例如:IN 和 OUT 传输大小、设备的读写超时和延迟。
ftStatus |= FT_SetUSBParameters(ftHandle, 65535, 65535); 设置USB请求传输大小ftStatus |= FT_SetChars(ftHandle, false, 0, false, 0); 禁用事件和错误字符ftStatus |= FT_SetTimeouts(ftHandle, 3000, 3000); 设置FT2232H的读写超时时间(以 3 秒为单位)ftStatus |= FT_SetLatencyTimer(ftHandle, 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 = 真;
破;
}
}
下面的小组件扫描发现的设备并将其添加到表中,然后用户选择要连接的所需设备。
注意:这是一个 QT 项目,我将通过本文和下一部分添加更多组件。
现在,让我们通过设置 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 读取的示例
这是对 MPSSE 输入读数的测试。测试是使用 Digilent 的?Analog Discovery 2?波形中的静态 I/O 功能完成的。有关Analog Discovery 2的更多信息,请参阅我们之前在Atadait上的介绍。
阅读有关Analog Discovery 2的更多信息:
到目前为止,我们已经熟悉了MPSSE的基础知识,它的工作原理,以及如何编写一个基本的应用程序来扫描和连接到FT设备,然后使用MPSSE命令控制GPIO。在下一部分中,我们将了解如何使用 SPI 器件和 FT2232H 进行串行通信。