FT4232H Android开发 5 - USB转SPI

6 篇文章 1 订阅

目录

1.  基本原理

2. 设置频率

3. CS电平控制

4. SPI写的实现

 5. SPI读的实现

 6. 验证


当FT4232H作为MPSSE设备时,DBUS0固定为CLK输出,DBUSD1固定为DO,DBUSD2固定为DI。其他DBUS口都可以作为SPI的CS脚控制,所以理论上FT4232H可以一路通道控制5个SPI设备。验证的电路如下:

基于USB转GPIO的工程修改

1.  基本原理

与USB转GPIO类似,通过特殊的命令字写入FTx232H,FTx232H在DO上根据命令字的不同在CLK的上升沿或者下降沿将数据送出,在DI上将数据读入。

这里只实现SPI Mode 0。其基本属性是:

CPOL = 0,CPHA = 0 --- 即SPI_CLK空闲试为低电平,SPI在SPI_CLK的第一个边沿开始采样。 

MSB first --- 高位在前

在上升沿捕获数据,在下降沿时输出数据

参考类mpsse_gpio增加一个新类mpsse_spi。

public class mpsse_spi {
    public FT_Device ftDevice;
    mpsse_gpio gpio;
    public mpsse_spi(mpsse_gpio spiGPIO)
    {
        gpio = spiGPIO;
        ftDevice = dev;
    }
}

2. 设置频率

通过命令设置SPI的频率。通过命令0x8a和0x8b开启关闭5分配设置最大频率,通过0x86设置SPI的频率。

0x8a: 关闭5分频,即MaxFreq = 60MHz。

0x8b: 开启5分频,MaxFreq = 12MHz。

0x86, 0xValueH, 0xValueL: SPI_CLK的最大频率计算公式为MaxFreq / (( 1 +[ (0xValueH * 256) OR 0xValueL] ) * 2)

注:0x8a、0x8b只有FT232H,FT2232H,FT4232H支持。

    public void setFreq(int freq)
    {
        int byteWritten = 0;
        int maxFreq = 60 * 1000 * 1000;
        int value = 0;
        byte[] buf = new byte[3];
        if(freq < 500)
        {
            buf[0] = (byte)0x8b;
            maxFreq = 12 * 1000 * 1000;
        }
        else
        {
            buf[0] = (byte)0x8a;
        }
        ftDevice.write(buf, 1);
        if (freq > 30 * 1000 * 1000)
            value = 0;
        else if (freq < 92)
            value = 0xffff;
        else
            value = (int)((maxFreq - freq * 2) / (freq * 2));
        buf[0] = (byte)0x86;
        buf[1] = (byte)(value & 0xff);
        buf[2] = (byte)((value >> 8) & 0xff);
        ftDevice.write(buf, 3);
    }

3. CS电平控制

SPI的CS控制通过GPIO的方式控制.

     /*
     * io:  3-7 low byte io, xDBUS3 - xDBUS7
     *      8-15 high byte io, xCBUS0 - xCBUS7
     *      x - A or B
     * sel:   true - select flash
     *        false = deselect flash
     */
    public void cs(byte io, boolean sel)
    {
        if(sel == true)
        {
            gpio.output((byte)io, mpsse_gpio.eLevel.Low);
        }
        else
        {
            gpio.output((byte)io, mpsse_gpio.eLevel.High);
        }
    }

4. SPI写的实现

利用MPSSE的命令0x11实现,一次最多64K字节。

    public void writeBytes(byte[] wrBuf, int len)
    {
        if (len == 0 || wrBuf == null)
            return;
        int offset = 0;
        while (len > 0)
        {
            int count = (len > 0x10000) ? 0x10000 : len;

            byte[] tmpWrBuf = new byte[count + 3];
            int byteWritten = 0;

            tmpWrBuf[0] = 0x11;
            tmpWrBuf[1] = (byte)((count - 1) & 0xff);
            tmpWrBuf[2] = (byte)(((count - 1) >> 8) & 0xff);
            for (int i = 0; i < count; i++)
            {
                tmpWrBuf[3 + i] = wrBuf[i + offset];
            }
            ftDevice.write(tmpWrBuf, count + 3);
            len -= count;
            offset += count;
        }
    }

 5. SPI读的实现

利用MPSSE的命令0x20实现

    public void readBytes(byte[] rdBuf, int len) throws InterruptedException {
        if (len == 0 || rdBuf == null)
            return;
        int offset = 0;
        //Clear read buffer from device first.
        int gpioData = 0;
        int dly = 0;
        gpioData = ftDevice.getQueueStatus();
        if (gpioData > 0)
        {
            byte[] tmpbuf = new byte[gpioData];
            ftDevice.read(tmpbuf, gpioData);
        }
        while (len > 0)
        {
            int count = (len > 0x10000) ? 0x10000 : len;
            byte[] tmpWrBuf = new byte[3];
            byte[] tmpRdBuf = new byte[count];

            tmpWrBuf[0] = 0x20;
            tmpWrBuf[1] = (byte)((count - 1) & 0xff);
            tmpWrBuf[2] = (byte)(((count - 1) >> 8) & 0xff);
            ftDevice.write(tmpWrBuf, 3);

            while (true)
            {
                gpioData = ftDevice.getQueueStatus();
                dly++;
                if (dly > 0xfffffff)
                {
                    //Console.Write("spi transfer data time out\n");
                    return;
                }
                if (gpioData >= count)
                    break;
                Thread.sleep(1);
            }
            if (gpioData > 0)
            {
                ftDevice.read(tmpRdBuf, count);
                System.arraycopy(tmpRdBuf, 0, rdBuf, (int)offset, (int)count);
            }
            len -= count;
            offset += count;
        }
    }

 6. 验证

FT4232H的通道A上接一颗SPI接口的Nor Flash,CS脚接ADBUS3,通过读取Flash的ID确认SPI是否通讯正确。

    TextView tvSpiFlashID;
    void getFlashID() throws InterruptedException {
        if(mpsseDev == null)
            return;

        byte[] cmdBuf = {(byte)0x9F};
        byte[] rdBuf = {(byte)0xff, (byte)0xff, (byte)0xff};
        mpsseDev.spi.cs((byte)3, true);
        mpsseDev.spi.writeBytes(cmdBuf, cmdBuf.length);
        mpsseDev.spi.readBytes(rdBuf, 3);
        mpsseDev.spi.cs((byte)3, false);
        int id = ((int)rdBuf[0] << 16) | (int)(rdBuf[1] << 8) | (int)(rdBuf[2]);
        String strID = "Flash ID:0x" +
                Integer.toHexString(id).toUpperCase();
        tvSpiFlashID.setText(strID);
    }

初始化ADBUS0~3,其中0为SCK脚,输出,1为MOSI,输出,2为MISO,输入,3为CS,输出。

mpsseDev.gpio.init((byte)0xfb, (byte)0xfe, (byte)0xff, (byte)0xff);
try {
    getFlashID();
} catch (InterruptedException e) {
    e.printStackTrace();
}

测试结果:

 

  • 0
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
FT-4232可以配置为SPI设备。当FT4232H作为MPSSE设备时,DBUS0固定为CLK输出,DBUSD1固定为DO,DBUSD2固定为DI。其他DBUS口可以作为SPI的CS脚控制,因此理论上FT4232H可以一路通道控制5个SPI设备。\[1\] 要配置FT-4232为SPI设备,可以使用FTDI提供的驱动程序。FTDI提供了免费的Virtual Com Port (VCP)和Direct (D2XX)驱动程序,这些驱动程序可以消除对额外驱动程序的需求。\[2\] SPI的CS控制可以通过GPIO的方式进行。可以使用以下代码实现SPI的CS控制: ```java /* * io: 3-7 low byte io, xDBUS3 - xDBUS7 * 8-15 high byte io, xCBUS0 - xCBUS7 * x - A or B * sel: true - select flash * false = deselect flash */ public void cs(byte io, boolean sel) { if(sel == true) { gpio.output((byte)io, mpsse_gpio.eLevel.Low); } else { gpio.output((byte)io, mpsse_gpio.eLevel.High); } } ``` 这段代码可以实现SPI的CS控制,通过设置GPIO口的输出电平来选择或取消选择SPI设备。\[3\] 因此,要配置FT-4232为SPI设备,可以使用FTDI提供的驱动程序,并使用GPIO控制SPI的CS脚。 #### 引用[.reference_title] - *1* *3* [FT4232H Android开发 5 - USBSPI](https://blog.csdn.net/pq113_6/article/details/120863108)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* [linux中FT4232H设备驱动添加,USB4串口芯片FT4232HL,FT4232HQ](https://blog.csdn.net/weixin_32330765/article/details/116815360)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值