FT4222H学习笔记6 - SPI Slave

FT4222H的SPI从模式只支持SPI,不支持DSPI,QSPI接口,并且只支持Mode0、Mode3两种模式,另外,从模式也不支持Android系统(指的是J2XX驱动)。

注意因为USB的数据传输特性,也许SPI Master通过SPI读数据时USB接口并没有将数据准备好,所以如果要保证可靠的通信,建议使用协议的方式交互数据。

目前的library在每次写操作(Slave->Master)时会在有效数据前自动添加一个字节0x00,在Master端需要移除掉这个字节。如果不需要这个机制,可以直接调用D2XX的FT_Write写数据。

【初始化为SPI(从)接口】

当FT4222H打开后可以得到一个handle值,将该值赋值给变量spiSHandle

对应的API函数是FT4222_SPISlave_InitFT4222_SPISlave_InitEx

[DllImport("LibFT4222.dll", CallingConvention = CallingConvention.Cdecl)]

public static extern eFT4222Status FT4222_SPISlave_Init(IntPtr ftHandle);

[DllImport("LibFT4222.dll", CallingConvention = CallingConvention.Cdecl)]

public static extern eFT4222Status FT4222_SPISlave_InitEx(IntPtr ftHandle, eSPISlaveProtocol protocolOpt);

区别在于FT4222_SPISlave_InitEx可以指定是否采用协议的方式通信,而FT4222_SPISlave_Init则是默认采用SPI_SLAVE_WITH_PROTOCOL。

当使用协议方式时, Master端需要处理对应的数据结构,使之符合协议的格式,其协议的格式如下:

Sync word固定为0x5ACommand的定义如下:

SN表示包的序列号,用于packets的识别;2个字节的size表示,大端模式,高位在前;Checksum是所有数据(从Sync Word开始到Data的最后一个字节)相加后取低2字节,大端模式。

比如Master要发送1个字节0x55的数据给FT4222H,数据流如下:

FT4222H是自动处理协议的,对于用户来说就是得到实际数据0x55FT4222_SPISlave_Read读到的数据,并不会读到其他协议的数据),后面的ACK也是自动回复给Master的(会自动插入一个0x00)。

如果Master需要读一个字节回来时,因为SPI是全双工通信,实际Master可以在发送数据的同时接收数据,数据流如下(第一个字节是FT4222H库函数自动增加的一个字节0x00):

如果是FT4222H主动发送数据时,FT4222H同样是发送和Master发送一样格式的数据,不过对于调用API FT4222_SPISlave_Write函数来说,只需要发送原始数据即可,API FT4222_SPISlave_Write函数会自动将数据转成协议的格式。

【设置模式】

SPI模式只支持Mode0Mode3,默认Mode0

[DllImport("LibFT4222.dll", CallingConvention = CallingConvention.Cdecl)]

public static extern eFT4222Status FT4222_SPISlave_SetMode(

     IntPtr ftHandle, eSPICPOL  cpol, eSPICPHA  cpha);

【获取接收队列中数据的长度】

[DllImport("LibFT4222.dll", CallingConvention = CallingConvention.Cdecl)]

public static extern eFT4222Status FT4222_SPISlave_GetRxStatus(

     IntPtr ftHandle, ref UInt16 pRxSize);

参数pRxSize是接收队列(即Master发送过来的数据)中的数据长度。

【读函数】

[DllImport("LibFT4222.dll", CallingConvention = CallingConvention.Cdecl)]

public static extern eFT4222Status FT4222_SPISlave_Read(

     IntPtr ftHandle, byte[] buffer, UInt16 bufferSize, ref UInt16 sizeOfRead);

参数buffer是读入的数据;参数bufferSize是需要读入的数据个数;参数sizeOfRead是实际读入的数据个数。

【写函数】

[DllImport("LibFT4222.dll", CallingConvention = CallingConvention.Cdecl)]

public static extern eFT4222Status FT4222_SPISlave_Write(

     IntPtr ftHandle, byte[] buffer, UInt16 bufferSize, ref UInt16 sizeTransferred);

参数buffer是写入的数据,注意实际写出去的数据第一个字节会插入一个0x00;参数bufferSize是写入的数据个数;参数sizeTransferred是实际写的数据个数。

 

用STM32F030平台作为Master验证FT4222H的SPI Slave功能,在STM32F030端接收发送数据,并把读到的数据打印到串口。

uint8_t head[] = {0x5A, 0x80, 0x00, 0x00, 0x00};

head[3] = (uint8_t)((length >> 8) & 0xff);

head[4] = (uint8_t)(length & 0xff);

SpiMasterCSEn();

dat = spiTransferByte(0xff); //Skip 0x00

for(i = 0; i < 5; i++)

{

         dat = spiTransferByte(head[i]);

         checkSum += head[i];

         Printf("%x ", dat);

}

Printf("\nValid Data:");

for(i = 0; i < length; i++)

{

         dat = spiTransferByte(0x55 & 0xff);

         checkSum += 0x55;

         if((i % 16) == 0)

                   Printf("\n");

         Printf("%x ", dat);

}

Printf("\nCheckSum:\n");

{

         uint16_t sum = 0;

         dat = spiTransferByte((uint8_t)((checkSum >> 8) & 0xff));

         Printf("%x ", dat);

         sum = dat;

         dat = spiTransferByte((uint8_t)(checkSum & 0xff));

         Printf("%x ", dat);

         sum = (sum << 8) | dat;

}

Printf("\nACK data:");

for(i = 0; i < 8; i++)//FT4222H auto add 0x00 at first byte.

{

         dat = spiTransferByte(0xff);

         if((i % 16) == 0)

                   Printf("\n");

         Printf("%x ", dat);

}

而FT4222H端如果要发送数据到STM32F030则需要先写入到buffer,等Master启动SPI通信时才真正的传输数据。

wrBuf[0] = 0xAA;

sendHexLen = 1;

status = FT4222H.FT4222_SPISlave_Write(spiSHandle, wrBuf, (UInt16)sendHexLen, ref lpBytesWritten);

然后在一个BackgroundWorker里面不停的检测接收队列,有数据就读回数据。

while(true)

{

    UInt16 rxSize = 0;

    status = FT4222H.FT4222_SPISlave_GetRxStatus(spiSHandle, ref rxSize);

    if (status == FT4222H.eFT4222Status.FT4222_OK)

    {

        if (rxSize > 0)

        {

            Console.WriteLine("SPIS rd len:" + rxSize);

            byte[] rdBuf = new byte[rxSize];

            UInt16 sizeTransferred = 0;

            status = FT4222H.FT4222_SPISlave_Read(spiSHandle, rdBuf, (UInt16)rxSize, ref sizeTransferred);

            if (status != FT4222H.eFT4222Status.FT4222_OK)

                Console.Write("SPI Slave read fail:" + status);

    

            for (int i = 0; i < rxSize; i++)

            {

                spiSRevQueue.Enqueue(rdBuf[i]);

            }

            bgWorkerSpiS.ReportProgress(0);

        }

    }

}

串口的打印数据:

SPI SLAVE With Protocol Read Data 1

5a 81 2 0 1

Valid Data:

aa

CheckSum:

1 88

ACK data:

0 5a 84 0 0 0 0 de

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值