FT2232H的MCU Host Bus Emulation 模式

使用FTDI公司的2DXX 驱动方式。

新建一个空的C++工程,然后将ftd2xx.lib和ftd2xx.h文件拷到工程目录下。

在连接的时候,要注意IORDY(BD4)接到GND端。这样可以保证在读周期的时候,t5阶段的时间不为0。

(详见datasheet Page32 table 4.5)

编码的过程:

(一)设置MCU Host Bus Emulation 模式

打开编号为0的设备,获得一个句柄。

FT_HANDLE handle;
status
= FT_Open(0,&handle);

重置设备

status = FT_ResetDevice(handle);

设置FT2232H的工作模式(最关键

//先设置为无模式
status = FT_SetBitMode(handle,0x00,0x00);
//然后设置为我们需要的MCU Host Bus Emulation模式,模式编码为0x08
status = FT_SetBitMode(handle,0x00,0x08);

设置读写的等待时间

status = FT_SetTimeouts(handle,500,500);

设置Div By 5

当Div By 5设为on状态时,一个读周期将返回两个byte,为off状态时,一个读周期返回一个byte,详见FT2232H的datasheet的32页

BYTE disableDivBy5 = 0x8c;//enable 0x8c, disable 0x8a

(二)读写数据

The MPSSE Command Processor unit is controlled using a SETUP command【1】. Various commands are used to clock data out of and into the chip, as well as controlling the other I/O lines. If disabled the MPSSE is held in reset and will not have any effect on the rest of the chip. When enabled, it will take its commands and data from the OUT data written to the OUT pipe in the chip. This is done by simply using the normal WRITE command, as if data were being written to a COM port. Any data read will be passed back in the normal IN pipe. This is done using the normal READ command, as if data were being read from a COM port. 【2】

【1】里面提到的SETUP command就是指上面设置mode时候使用到的FT_SetBitMode指令。

【2】只要将编程指南中的指令字,如0x93、0x87等,用FT_Write指令写入FT2232H即可完成相应的功能。详见下面的示例。

(1)写数据

往扩展后的地址写数据(即16位地址)

//往双口ram写数据
BYTE writeToLowAddr[4] = {0x93,0x46,0x00,0xa5};
status = FT_Write(handle,writeToLowAddr,4,&lpByteToWrite);

其中,0x93为写扩展地址的指令

详见文档Command Processor for MPSSE and MCU Host Bus Emulation Modes的Instructions for CPU mode部分

0x46为低8位地址,0x00为高8位地址。

0xa5为要写入的数据。

文档中的描述如下:

CPUMode Write Extended Address

0x93,
0xAddrHigh,
0xAddrLow,
0xData

This will write
1 byte from the target device.

往一般的短地址写数据:

CPUMode Write Short Address

0x92,
0xAddrLow,
0xData

This will write
1 byte from the target device.

(2)读数据

读扩展地址的数据(即从16位地址线的存储单元读数据)

//从双口RAM读数据
BYTE readFromHighAddr[4] = {0x91,0x46,0x00,0x87};
status = FT_Write(handle,readFromHighAddr,4,&lpByteToRead);

相关文档中的描述为:

读8位地址的存储单元

CPUMode Read Short Address

0x90,
0xAddrLow 

This will read
1 byte from the target device.

读16位地址的存储单元

CPUMode Read Extended Address

0x91,
0xAddrHigh
0xAddrLow

This will read
1 byte from the target device.

另外,指令中的0x87是指:

Send Immediate

0x87,

This will make the chip flush its buffer back to the PC.

---------------------------------------------------------------------------

完整代码如下(使用扩展地址):

#include <Windows.h>
#include
<stdlib.h>
#include
<stdio.h>
#include
<iostream>
#include
<string>
#pragma comment(lib,"FTD2XX.lib")
#include
"ftd2xx.h"

bool showStatus(FT_STATUS status,std::string str1, std::string str2){
if (status == FT_OK)
{
std::cout
<< str1 << std::endl;
return true;
}
else{
std::cout
<< str2 << std::endl;
return false;
}

}
int main(){

FT_STATUS status,status2;
FT_HANDLE handle;

status
= FT_Open(0,&handle);
if (!showStatus(status,"open device0 success","open device 0 failed"))
{
return 0;
}

status
= FT_ResetDevice(handle);
if (!showStatus(status,"reset device0 success","reset device 0 failed"))
{
return 0;
}


ULONG baudRate
= 9600;
status
= FT_SetBaudRate(handle,baudRate);
if (!showStatus(status,"set device0 baudRate success","set device0 baudRate failed") )//|| !showStatus(status2,"成功set设备1 baudRate","set设备1失败 baudRate")
{
return 0;
}

status
= FT_SetBitMode(handle,0x00,0x00);

status
= FT_SetBitMode(handle,0x00,0x08);
if (!showStatus(status,"set device0 mode 8 success","set device0 mode 8 failed"))
{
return 0;
}

status
= FT_SetTimeouts(handle,500,500);
if (!showStatus(status,"set times out success","set times out 8 failed"))
{
return 0;
}
DWORD lpByteToWrite;

DWORD RxBytes;

DWORD backlp;
BYTE disableDivBy5
= 0x8c;//enable 0x8c, disable 0x8a
FT_Write(handle,&disableDivBy5,1,&backlp);
if (!showStatus(status,"disable div by 5 success","disable div by 5 failed"))
{
return 0;
}

DWORD lpSendImme
= 0;
std::cout
<< "inputs 1 to stop the loop" << std::endl;
int control = 0;
while(control != 1){
//往双口ram写数据
BYTE writeToLowAddr[4] = {0x93,0x46,0x00,0xa5}; //[4] = {0x93,0x46,0x00,0x13}
status = FT_Write(handle,writeToLowAddr,4,&lpByteToWrite);//4
if (!showStatus(status,"write success","write failed"))
{
return 0;
}

//从双口RAM读数据
BYTE readFromHighAddr[4] = {0x91,0x46,0x00,0x87};//[4] = {0x91,0x55,0x55,0x87};
status = FT_Write(handle,readFromHighAddr,4,&lpByteToRead);
if (!showStatus(status,"read command send success","read command send failed"))
{
return 0;
}

////将读到的数据返回给pc
//BYTE sendImmediate = 0x87;
//FT_Write(handle,&sendImmediate,1,&lpSendImme);
//if (!showStatus(status,"send immediate success","send immediate failed"))
//{
// return 0;
//}

//读缓存
FT_GetQueueStatus(handle,&RxBytes);
if (RxBytes != 0)
{
std::cout
<< "RxByte: " << RxBytes << std::endl;
DWORD readByteLp;
BYTE b[
32] = {0x00};
status
= FT_Read(handle,&b,RxBytes,&readByteLp);
if (!showStatus(status,"read success","read failed"))
{
return 0;
}
for (int i = 0; i < RxBytes; i++)
{
std::cout
<< "byte" << i << ": " << std::hex << b[i] << std::endl;
}

}
else{
std::cout
<< "RxByte: " << RxBytes << std::endl;
}
std::cin
>> control;
}
status
= FT_Close(handle);
if (!showStatus(status,"close device0 success","close device0 failed"))
{
return 0;
}

std::cin.
get();
return 1;

}

-----------------------------------------------------------

相关文档:

FT2232H datasheet

Command Processor for MPSSE and MCU Host Bus Emulation Modes

原文地址:https://www.cnblogs.com/elaron/p/2035438.html