FT4232H Android development 6 - USB to IIC

catalogue

  1. Create a new class mpsse_iic

2. Modify mpsse_gpio

3. iic initialization

4. Start of IIC

5. Stop of IIC

6. Read one byte of IIC

7. Send one byte of IIC

8. IIC read operation

9. IIC write operation

10. Verification

IIC is implemented by GPIO simulation. In GPIO mode, any IO can be used as the pin of IIC. Here, in order to simplify the program, only the PortD port is used as the IO of IIC.

In order to maintain compatibility, xDBUS0 is selected as SCL of IIC, xDBUS1 and xDBUS2 are shorted together as SDA, xDBUS1 is used as output of SDA, and xDBUS2 is used as input of SDA. Actually, only xDBUS1 is used as the input and output of SDA port.

  1. Create a new class mpsse_iic

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

1.1 add a variable to indicate the corresponding IO port position

private byte SCL = 0;
private byte SDAO = 1;
private byte SDAI = 2;

  1.2 add variable to save IO control sequence

private ArrayList ftCommand = new ArrayList();

  When controlling GPIO, instead of writing the state of the IO port every time, write a group of IO states. For example, write 8bit data at a time. You can write the 8bit data into the USB Buffer at a time. In this way, these command sequences can be saved in the ftCommand variable and written out for the last time.

1.3 add variables to determine the frequency of IO

private int mCLK = 0;

2. Modify mpsse_gpio

In order not to affect the state of other IO ports when operating IIC, some methods are added.

Will variable

private byte PortDDir;
private byte PortDLevel;
private byte PortCDir;
private byte PortCLevel;

Change to Class so that these four variables can be obtained.

    public static class classPort
    {
        public byte PortDDir;
        public byte PortDLevel;
        public byte PortCDir;
        public byte PortCLevel;
    }
    classPort mPort = new classPort();

    public classPort getPortState()
    {
        return mPort;
    }

    public void setPortState(classPort port)
    {
        mPort = port;
    }

3. iic initialization

In class mpsse_ Add init and clk to IIC to indicate the frequency of gpio, which is generally 1 (800KHz) or 2(400KHz). Note that this rate is approximate and not very accurate.

    /*
     * clk: normally 1 or 2.
     * ioSCL/ioSDA:  0-7 low byte io, xDBUS0 - xDBUS7
     */
    public void init(int clk, byte ioSCL, byte ioSDA)
    {
        mCLK = clk;
        SCL = ioSCL;
        SDAO = ioSDA;

        gpio.setDir(SCL, (byte)0); //SCL is output
        gpio.setDir(SDAO, (byte)0); //SDA(AD1) is output
        gpio.setDir(SDAI, (byte)1); //SDA(AD2) is input
        gpio.output(SCL, mpsse_gpio.eLevel.High);
        gpio.output(SDAO, mpsse_gpio.eLevel.High);
    }

4. Start of IIC

Here, only the command sequence of Start is written into ftCommand, and the 0x80 command of MPSSE is used to control GPIO.

The Start timing of IIC is that SDA and SCL Start to output high level, and then SDA generates a falling edge.  

    private void start()
    {
        mpsse_gpio.classPort port;
        Log.i("IIC", "Start");
        port = gpio.getPortState();
        port.PortDLevel |= (byte)1 << SCL | (byte)1 << SDAO; //SCL outputs high, SDA outputs high
        for (int i = 0; i < mCLK; i++)
        {
            ftCommand.add((byte)0x80);
            ftCommand.add(port.PortDLevel);
            ftCommand.add(port.PortDDir);
        }
        port.PortDLevel &= (byte)(~((byte)1 << SDAO));       //SDA outputs low
        for (int i = 0; i < mCLK * 2; i++) //Wait a moment
        {
            ftCommand.add((byte)0x80);
            ftCommand.add(port.PortDLevel);
            ftCommand.add(port.PortDDir);
        }
        gpio.setPortState(port);
    }

For example, when SCL=4, SDAO=5, mCLK = 2, the contents in ftCommand are:

80 fe 3b 80 fe 3b 80 de 3b 80 de 3b 80 de 3b 80 de 3b

Every 3 bytes is an IO control, and mCLK is 2, which means to repeat it, that is, operate the same io for 2 consecutive times, and the frequency is equivalent to the highest frequency / 2.

Fe - > de, that is, SDA (bit 5) changes from high to low.

5. Stop of IIC

The Stop timing of IC is SCL output high, and then SDA generates a rising edge.

    private void stop()
    {
        mpsse_gpio.classPort port;
        Log.i("IIC", "Stop");
        port = gpio.getPortState();

        port.PortDLevel &= (byte)(~((byte)1 << SDAO));    //SDA outpus low
        for (int i = 0; i < mCLK; i++)
        {
            ftCommand.add((byte)0x80);
            ftCommand.add(port.PortDLevel);
            ftCommand.add(port.PortDDir);
        }
        port.PortDLevel |= (byte)1 << SCL;                //SCL outputs high
        for (int i = 0; i < mCLK; i++)
        {
            ftCommand.add((byte)0x80);
            ftCommand.add(port.PortDLevel);
            ftCommand.add(port.PortDDir);
        }
        port.PortDLevel |= (byte)1 << SDAO;               //SDA outputs high
        for (int i = 0; i < mCLK; i++)
        {
            ftCommand.add((byte)0x80);
            ftCommand.add(port.PortDLevel);
            ftCommand.add(port.PortDDir);
        }
        gpio.setPortState(port);
    }

6. Read one byte of IIC

After the SCL of IIC generates a rising edge, read the level of SDA, cycle 8 times to read 1 byte of data, and then set SDA according to whether to ack. If you want ACK, SDA outputs 0, otherwise outputs 1, and finally set SCL output low.

    private void receiveByte(boolean ack)
    {
        mpsse_gpio.classPort port;
        Log.i("IIC", "receiveByte");
        port = gpio.getPortState();

        port.PortDLevel &= (byte)(~(byte)1 << SCL | (byte)1 << SDAO); //SCL outputs low, SDA outputs low
        port.PortDDir &= (byte)(~((byte)1 << SDAO));         //Set SDA as input
        ftCommand.add((byte)0x80);
        ftCommand.add(port.PortDLevel);
        ftCommand.add(port.PortDDir);

        if(ioCtrlMode == true)
        {
            byte loop = 8;
            while (loop-- > 0)
            {
                port.PortDLevel &= (byte)(~((byte)1 << SCL)); //SCL output low
                for (int i = 0; i < mCLK; i++)
                {
                    ftCommand.add((byte)0x80);
                    ftCommand.add(port.PortDLevel);
                    ftCommand.add(port.PortDDir);
                }
                port.PortDLevel |= (byte)(1 << SCL); //SCL output high
                for (int i = 0; i < mCLK; i++)
                {
                    ftCommand.add((byte)0x80);
                    ftCommand.add(port.PortDLevel);
                    ftCommand.add(port.PortDDir);
                }
                ftCommand.add((byte)0x81); //Rd SDA
            }
        }
        else
        {
            ftCommand.add((byte)0x22);
            ftCommand.add((byte)7);
        }

        port.PortDLevel &= (byte)(~(byte)1 << SCL | (byte)1 << SDAO); //SCL outputs low, SDA outputs low
        port.PortDDir |= ((byte)1 << SDAO);     //Set SDA as output
        ftCommand.add((byte)0x80);
        ftCommand.add(port.PortDLevel);
        ftCommand.add(port.PortDDir);

        if (ioCtrlMode == true)
        {
            if (ack == true)
                port.PortDLevel &= (byte)(~((byte)1 << SDAO));
            else
                port.PortDLevel |= ((byte)1 << SDAO);
            for (int i = 0; i < mCLK; i++)
            {
                ftCommand.add((byte)0x80);
                ftCommand.add(port.PortDLevel);
                ftCommand.add(port.PortDDir);
            }
            port.PortDLevel |= (byte)((byte)1 << SCL);
            for (int i = 0; i < mCLK; i++)
            {
                ftCommand.add((byte)0x80);
                ftCommand.add(port.PortDLevel);
                ftCommand.add(port.PortDDir);
            }
        }
        else
        {
            ftCommand.add((byte)0x13); //Clock Data Bits Out on clock raise edge MSB first
            ftCommand.add((byte)0x0);               // 1bit
            if (ack == true)
                ftCommand.add((byte)0x00);          // SDA outputs low means ack
            else
                ftCommand.add((byte)0x80);          // SDA outputs high means nack, only use bit7.
        }
        ftCommand.add((byte)0x87);

        port.PortDLevel &= (byte)(~((byte)1 << SCL)); //SCL outputs low
        ftCommand.add((byte)0x80);
        ftCommand.add(port.PortDLevel);
        ftCommand.add(port.PortDDir);

        gpio.setPortState(port);
    }

The SDA level status read here will be in the cache of FT4232H. The purpose of writing 0x87 command is to tell FT4232H to send the data in the cache to the host immediately.

7. Send one byte of IIC

Set the SCL to low and the SDA to set the corresponding data bit, then pull the SCL high, repeat 8 times to send a byte of data, and then read the SDA level to judge whether the slave is ACK. Finally, the SCL output is low and the SDA output is high.

    private void sendByte(byte dat)
    {
        mpsse_gpio.classPort port;
        Log.i("IIC", "sendByte");
        port = gpio.getPortState();

        if (ioCtrlMode == true)
        {
            for(byte j = 0; j < 8; j++)
            {
                port.PortDLevel &= (byte)(~((byte)1 << SCL));  //SCL outputs low
                //for (int i = 0; i < mCLK; i++)
                {
                    ftCommand.add((byte)0x80);
                    ftCommand.add(port.PortDLevel);
                    ftCommand.add(port.PortDDir);
                }
                if ((dat & 0x80) == 0x80)
                    port.PortDLevel |= (byte)(1 << SDAO);           //SDA Output High
                else
                    port.PortDLevel &= (byte)(~((byte)1 << SDAO));  //SDA Output Low
                dat <<= 1;
                port.PortDDir |= (byte)(1 << SDAO);                 //Set SDA as output
                //for (int i = 0; i < mCLK; i++)
                {
                    ftCommand.add((byte)0x80);
                    ftCommand.add(port.PortDLevel);
                    ftCommand.add(port.PortDDir);
                }
                port.PortDLevel |= (byte)(1 << SCL);            //set SCL to high
                for (int i = 0; i < mCLK * 1; i++)
                {
                    ftCommand.add((byte)0x80);
                    ftCommand.add(port.PortDLevel);
                    ftCommand.add(port.PortDDir);
                }
            }
        }
        else
        {
            port.PortDLevel &= (byte)(~((byte)1 << SCL));     //SCL outputs low
            port.PortDLevel |= (byte)(1 << SDAO);             //SDA outputs high
            port.PortDDir |= (byte)(1 << SDAO);               //Set SDA as output
            for (int i = 0; i < mCLK; i++)
            {
                ftCommand.add((byte)0x80);
                ftCommand.add(port.PortDLevel);
                ftCommand.add(port.PortDDir);
            }
            ftCommand.add((byte)0x13); //Clock Data Bits Out on clock raise edge MSB first
            ftCommand.add((byte)7);
            ftCommand.add(dat);
        }

        port.PortDLevel &= (byte)(~((byte)1 << SCL) | (byte)1 << SDAO); //SCL and SDA output low
        port.PortDDir &= (byte)(~((byte)1 << SDAO));                    //Set SDA as input
        for (int i = 0; i < mCLK; i++)
        {
            ftCommand.add((byte)0x80);
            ftCommand.add(port.PortDLevel);
            ftCommand.add(port.PortDDir);
        }

        if (ioCtrlMode == true)
        {
            port.PortDLevel &= (byte)(~((byte)1 << SCL)); //SCL output low
            for (int i = 0; i < mCLK; i++)
            {
                ftCommand.add((byte)0x80);
                ftCommand.add(port.PortDLevel);
                ftCommand.add(port.PortDDir);
            }

            port.PortDLevel |= (byte)1 << SCL;          //set SCL to high
            for (int i = 0; i < mCLK * 10; i++)
            {
                ftCommand.add((byte)0x80);
                ftCommand.add(port.PortDLevel);
                ftCommand.add(port.PortDDir);
            }
            ftCommand.add((byte)0x81); //Rd SDA

            port.PortDLevel |= (byte)1 << SDAO;          //SDA outputs high
            port.PortDDir |= (byte)1 << SDAO;            //Set SDA as output
            for (int i = 0; i < mCLK; i++)
            {
                ftCommand.add((byte)0x80);
                ftCommand.add(port.PortDLevel);
                ftCommand.add(port.PortDDir);
            }
        }
        else
        {
            ftCommand.add((byte)0x26); //Clock Data Bits In on clock falling edge MSB first
            ftCommand.add((byte)0);    // 1bit
            ftCommand.add((byte)0x87);
        }


        port.PortDLevel &= (byte)(~((byte)1 << SCL));      //SCL outputs low
        // port.PortDLevel |= (byte)0x02;                  //SDA outputs high
        port.PortDDir |= (byte)1 << SDAO;                  //Set SDA as output
        for (int i = 0; i < mCLK; i++)
        {
            ftCommand.add((byte)0x80);
            ftCommand.add(port.PortDLevel);
            ftCommand.add(port.PortDDir);
        }
        /*
        port.PortDLevel |= (byte)1 << SDAO;                    //SDA outputs high
        port.PortDDir |= (byte)1 << SDAO;                      //Set SDA as output
        ftCommand.add((byte)0x80);
        ftCommand.add(port.PortDLevel);
        ftCommand.add(port.PortDDir);
        */
        gpio.setPortState(port);
    }

8. IIC read operation

The parameter slaveAddr indicates the IIC address of the IIC slave device; addrbit indicates the width of the internal address of the IIC device, and the valid values are 0, 8, 16; addr indicates the internal address of the device; dat is the read in data cache; len indicates how many bytes of data need to be read in. Because the maximum number of bytes for a USB communication is 64KB, and more command bytes will be used for GPIO operation, it is recommended that the data read in at one time should not exceed 1KB.

    public boolean read(byte slaveAddr, byte addrbit, int addr, byte[] dat, int len)
    {
        if (len == 0)
            return false;

        int rdDatLen = len;
        if (ioCtrlMode == true)
            rdDatLen = len * 8;
        int rdLen = (int)(addrbit / 8 + 2 + rdDatLen);
        if(addrbit == 0)
            rdLen = (int)(addrbit / 8 + 1 + rdDatLen);
        int byteWritten = 0, byteRead = 0, dly = 0;
        //Read USB buffer first to clear the buffer.
        byteRead  = ftDevice.getQueueStatus();
        if (byteRead > 0)
        {
            byte[] tmpbuf = new byte[byteRead];
            ftDevice.read(tmpbuf, byteRead);
        }

        //Create command list
        ftCommand.clear();
        start();
        if(addrbit > 0)
            sendByte(slaveAddr);
        if (addrbit == 16)
            sendByte((byte)(addr >> 8));
        if(addrbit > 0) {
            sendByte((byte) (addr >> 0));
            start();
        }
        sendByte((byte)(slaveAddr | 0x01));
        while (--len > 0)
        {
            receiveByte(true);
        }
        receiveByte(false);
        ftCommand.add((byte)0x87);
        stop();

        byte[] cmdBuf = new byte[ftCommand.size()];
        for (int i = 0; i < ftCommand.size(); i++)
            cmdBuf[i] = (byte)ftCommand.get(i);
        ftDevice.write(cmdBuf, cmdBuf.length);

        byte[] rdBuf = new byte[rdLen];
        int offset = 0;
        while (true)
        {
            byteRead  = ftDevice.getQueueStatus();
            dly++;
            if (dly > 0xffff)
            {
                Log.e("iic read", "read data time out");
                return false;
            }
            if(byteRead == 0)
                continue;

            byte[] tmpBuf = new byte[byteRead];
            ftDevice.read(tmpBuf, byteRead);
            for (int i = 0; i < tmpBuf.length; i++ )
            {
                rdBuf[offset++] = tmpBuf[i];
            }

            if (offset >= rdLen)
                break;

            try {
                Thread.sleep(1);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }

                for (int i = 0; i < rdBuf.length - rdDatLen; i++)
        {
            if (ioCtrlMode == true)
            {
                if ((rdBuf[i] & ((byte)(1 << SDAO))) == (byte)(1 << SDAO)) //Check ACK
                {
                    Log.e("iic read", "return nack:" +
                            Integer.toHexString((rdBuf[i] & 0x000000FF) | 0xFFFFFF00).substring(6));
                    return false;
                }
            }
            else
            {
                if ((byte)(rdBuf[i] & 0x01) == (byte)0x01)
                {
                    Log.e("iic read", "return nack:" +
                            Integer.toHexString((rdBuf[i] & 0x000000FF) | 0xFFFFFF00).substring(6));
                    return false;
                }
            }
        }

        for (int i = (int)(rdBuf.length - rdDatLen); i < rdBuf.length; i++)
        {
            if(ioCtrlMode == true)
            {
                int max = i + 8;
                byte tmp = 0;
                for(; i < max; i++)
                {
                    tmp <<= 1;
                    if ((rdBuf[i] & ((byte)(1 << SDAO))) == (byte)(1 << SDAO))
                    {
                        tmp |= 0x01;
                    }
                }
                dat[(i - (rdBuf.length - rdDatLen)) / 8 - 1] = tmp;
                i--;
            }
            else
                dat[i - (rdBuf.length - rdDatLen)] = rdBuf[i];
        }
        return true;
    }

After sending the command data to FT4232H at one time, the read data will be in the buffer of FT4232H and read back to rdBuf. These data include IO level and ACK information.

8.1 check whether the ACK of the sending address is correct

When sending slaveAddr and addr, you will get (rdBuf.length - rdDatLen) ACK information, so you will traverse whether these acks are low level. Namely

for (int i = 0; i < rdBuf.length - rdDatLen; i++)
{
    if (ioCtrlMode == true)
    {
        if ((rdBuf[i] & ((byte)(1 << SDAO))) == (byte)(1 << SDAO)) //Check ACK
        {
            Log.e("iic read", "return nack:" +
                    Integer.toHexString((rdBuf[i] & 0x000000FF) | 0xFFFFFF00).substring(6));
            return false;
        }
    }
    else
    {
        if ((byte)(rdBuf[i] & 0x01) == (byte)0x01)
        {
            Log.e("iic read", "return nack:" +
                    Integer.toHexString((rdBuf[i] & 0x000000FF) | 0xFFFFFF00).substring(6));
            return false;
        }
    }
}

8.2 receiving data

The next data is the real SDA data. Note that the level of the whole PortD is read, so the corresponding bits need to be combined into bytes. Namely

for (int i = (int)(rdBuf.length - rdDatLen); i < rdBuf.length; i++)
{
    if(ioCtrlMode == true)
    {
        int max = i + 8;
        byte tmp = 0;
        for(; i < max; i++)
        {
            tmp <<= 1;
            if ((rdBuf[i] & ((byte)(1 << SDAO))) == (byte)(1 << SDAO))
            {
                tmp |= 0x01;
            }
        }
        dat[(i - (rdBuf.length - rdDatLen)) / 8 - 1] = tmp;
        i--;
    }
    else
        dat[i - (rdBuf.length - rdDatLen)] = rdBuf[i];
}

9. IIC write operation

IIC write operation is similar to read operation. The data read back is relatively simple and all are ACK information.

    public boolean write(byte slaveAddr, byte addrbit, int addr, byte[] dat, int len)
    {
        if (len == 0)
            return false;
        int rdLen = (int)(addrbit / 8 + 1 + len);
        ftCommand.clear();
        start();
        sendByte(slaveAddr);
        if (addrbit == 16)
            sendByte((byte)(addr >> 8));
        if(addrbit > 0)
            sendByte((byte)(addr >> 0));
        int n = 0;
        while (len-- > 0)
        {
            sendByte(dat[n++]);
        }
        stop();
        ftCommand.add((byte)0x87);
        byte[] cmdBuf = new byte[ftCommand.size()];
        Log.i("iic write", "Command Length:" + ftCommand.size());
        for (int i = 0; i < ftCommand.size(); i++) {
            cmdBuf[i] = (byte) ftCommand.get(i);
            /*if((i + 1) % 16 == 0)
            {
                Log.i("iic write", "cmd[" + (i - 15) + "] - cmd[" + i + "]=" +
                        Integer.toHexString((cmdBuf[i - 15] & 0x000000FF) | 0xFFFFFF00).substring(6) + " " +
                        Integer.toHexString((cmdBuf[i - 14] & 0x000000FF) | 0xFFFFFF00).substring(6) + " " +
                        Integer.toHexString((cmdBuf[i - 13] & 0x000000FF) | 0xFFFFFF00).substring(6) + " " +
                        Integer.toHexString((cmdBuf[i - 12] & 0x000000FF) | 0xFFFFFF00).substring(6) + " " +
                        Integer.toHexString((cmdBuf[i - 11] & 0x000000FF) | 0xFFFFFF00).substring(6) + " " +
                        Integer.toHexString((cmdBuf[i - 10] & 0x000000FF) | 0xFFFFFF00).substring(6) + " " +
                        Integer.toHexString((cmdBuf[i - 9] & 0x000000FF) | 0xFFFFFF00).substring(6) + " " +
                        Integer.toHexString((cmdBuf[i - 8] & 0x000000FF) | 0xFFFFFF00).substring(6) + " " +
                        Integer.toHexString((cmdBuf[i - 7] & 0x000000FF) | 0xFFFFFF00).substring(6) + " " +
                        Integer.toHexString((cmdBuf[i - 6] & 0x000000FF) | 0xFFFFFF00).substring(6) + " " +
                        Integer.toHexString((cmdBuf[i - 5] & 0x000000FF) | 0xFFFFFF00).substring(6) + " " +
                        Integer.toHexString((cmdBuf[i - 4] & 0x000000FF) | 0xFFFFFF00).substring(6) + " " +
                        Integer.toHexString((cmdBuf[i - 3] & 0x000000FF) | 0xFFFFFF00).substring(6) + " " +
                        Integer.toHexString((cmdBuf[i - 2] & 0x000000FF) | 0xFFFFFF00).substring(6) + " " +
                        Integer.toHexString((cmdBuf[i - 1] & 0x000000FF) | 0xFFFFFF00).substring(6) + " " +
                        Integer.toHexString((cmdBuf[i - 0] & 0x000000FF) | 0xFFFFFF00).substring(6) + " "
                );
            }*/
        }

        int byteRead = 0, dly = 0;
        Log.i("iic write", "write command buffer");
        ftDevice.write(cmdBuf, cmdBuf.length);
        Log.i("iic write", "read response data");
        while (true)
        {
            byteRead  = ftDevice.getQueueStatus();
            dly++;
            if (dly > 0xffff)
            {
                Log.e("iic write", "time out");
                return false;
            }
            if (byteRead >= rdLen)
                break;
            try {
                Thread.sleep(1);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        byte[] rdBuf = new byte[byteRead];
        ftDevice.read(rdBuf, byteRead);
        Log.i("iic write", "read buffer len:" + rdBuf.length);
        for (int i = 0; i < rdBuf.length; i++)
        {
            if (ioCtrlMode == true)
            {
                if ((rdBuf[i] & ((byte)(1 << SDAO))) == (byte)(1 << SDAO)) //Check ACK
                {
                    Log.e("iic write", "return nack" + i + ":"+
                            Integer.toHexString((rdBuf[i] & 0x000000FF) | 0xFFFFFF00).substring(6));
                    //return false;
                }
            }
            else
            {
                if ((byte)(rdBuf[i] & 0x01) == (byte)0x01)
                {
                    Log.e("iic write", "return nack" + i + ":"+
                            Integer.toHexString((rdBuf[i] & 0x000000FF) | 0xFFFFFF00).substring(6));
                    return false;
                }
            }

        }
        Log.i("iic write", "return ok");
        return true;
    }

10. Verification

ADBUS4 as SCL and ADBUS5 as SDA are connected to an EEPROM chip with IIC interface. Verification Code:

    TextView tvERomWr;
    TextView tvERomRd;
    void ERomTest()
    {
        if(mpsseDev == null)
            return;
        byte[] wrBuf = new byte[10];
        byte[] rdBuf = new byte[10];
        tvERomWr.setText("");
        for(int i = 0; i < wrBuf.length; i++)
        {
            wrBuf[i] = (byte)(Math.random() * 256);
            tvERomWr.append(Integer.toHexString((wrBuf[i] & 0x000000FF) | 0xFFFFFF00).substring(6) + " ");
        }
        mpsseDev.iic.write((byte)0xA0, (byte)16, 0, wrBuf, wrBuf.length);
        mpsseDev.iic.read((byte)0xA0, (byte)16, 0, rdBuf, rdBuf.length);

        tvERomRd.setText("");
        for(int i = 0; i < rdBuf.length; i++)
        {
            tvERomRd.append(Integer.toHexString((rdBuf[i] & 0x000000FF) | 0xFFFFFF00).substring(6) + " ");
        }
    }

Initialize IIC

mpsseDev.iic.init((byte)2, (byte)4, (byte)5);

Test results:

 

Tags: Android USB

Posted on Mon, 25 Oct 2021 05:52:31 -0400 by mds1256