精华内容
下载资源
问答
  • FT2232H是一个USB 2.0高速(480Mb/s)到UART/FIFO IC,它有能力配置在各种工业标准串行或并行接口。 FT2232H唯一通道A可以配置为FT245风格的同步FIFO接口。在这种模式下配置时,所使用的引脚和信号的描述见表3.6。要...
  • 参考官方文档:AN_135_MPSSE_Basics.pdf,AN_113_FTDI_Hi_Speed_USB_To_I2C_Example.pdf 有疑问的部分,色标已经标出。具体的执行时序流程,参考上一篇。 // Set initial states of the MPSSE interface // - low ...

    参考官方文档:AN_135_MPSSE_Basics.pdf, AN_113_FTDI_Hi_Speed_USB_To_I2C_Example.pdf

    有疑问的部分,色标已经标出。具体的执行时序流程,参考上一篇。

    // Set initial states of the MPSSE interface
    // - low byte, both pin directions and output values
    // Pin name   Signal      Direction   Config    Initial State     Config
    // ADBUS0   TCK/SK    output       1                 high             1       -------------------->SCL(BIT0)
    // ADBUS1   TDI/DO     output       1                 low              1       ---------------------->output SDA(BIT1)
    // ADBUS2   TDO/DI     input         0                                     0       ----------------------->input SDA
    // ADBUS3   TMS/CS    output      0                 high              0
    // ADBUS4   GPIOL0     output      1                  low              0
    // ADBUS5   GPIOL1     output      0                  low              0
    // ADBUS6   GPIOL2     output      0                  high             0
    // ADBUS7   GPIOL3     output      0                  high             0

    //---------------------I2C--------------------------------------------------------------------------------------------------
    void FT2232I2cByteWrOneTime(unsigned char DeviceAddr,unsigned char RegAddr,unsigned char RegVal)
    {
        DWORD dwCount;
        FT_STATUS ftStatus = FT_OK;
        //-------------I2cStart-------------------------
        for(dwCount=0; dwCount < 4; dwCount++) // Repeat commands to ensure the minimum period of the stop setup time ie 600ns is achieved
        {

          Set initial states of the MPSSE interface
            OutputBuffer[dwNumBytesToSend++] = 0x80; Configure data bits low-byte of MPSSE port, Command to set directions of lower 8 pins and force value on bits set as output
            OutputBuffer[dwNumBytesToSend++] = 0x03; Initial state config above, Set SDA, SCL high, WP disabled by SK, DO at bit „1‟, GPIOL0 at bit „0‟ 
            OutputBuffer[dwNumBytesToSend++] = 0x13; Direction config above, Set SK,DO,GPIOL0 pins as output with bit „1‟, other pins as input with bit „0‟
        }

        for(dwCount=0; dwCount < 20; dwCount++) 
        {
            OutputBuffer[dwNumBytesToSend++] = 0x80; //Command to set directions of lower 8 pins and force value on bits set as output
            OutputBuffer[dwNumBytesToSend++] = 0x01; //Set SDA low, SCL high, WP disabled by SK at bit 1, DO, GPIOL0 at bit 0
            OutputBuffer[dwNumBytesToSend++] = 0x13; //Set SK,DO,GPIOL0 pins as output with bit 1, other pins as input with bit 0
        }
        for(dwCount=0; dwCount < 20; dwCount++) 
        {
        OutputBuffer[dwNumBytesToSend++] = 0x80; //Command to set directions of lower 8 pins and force value on bits set as output
        OutputBuffer[dwNumBytesToSend++] = 0x00; 
        OutputBuffer[dwNumBytesToSend++] = 0x13; //Set SK,DO,GPIOL0 pins as output with bit 1, other pins as input with bit 0
        }

        //Sleep(10);        //Delay for a while

        //-------------I2cSendByteAndNotCheckACK_DeviceAddr-------------------------
        
        OutputBuffer[dwNumBytesToSend++] = MSB_FALLING_EDGE_CLOCK_BYTE_OUT; //Clock data byte out on -ve Clock Edge MSB first
        OutputBuffer[dwNumBytesToSend++] = '\x00';
        OutputBuffer[dwNumBytesToSend++] = '\x00'; //Data length of 0x0000 means 1 byte data to clock out(8 bit)
        OutputBuffer[dwNumBytesToSend++] = DeviceAddr;

        //Get slave's ack
        for(dwCount=0; dwCount<4; dwCount++) // Repeat commands to ensure the minimum period of the stop setup time ie 800ns is achieved
        {
            OutputBuffer[dwNumBytesToSend++] = 0x80; //Command to set directions of lower 8 pins and force value on bits set as output
            OutputBuffer[dwNumBytesToSend++] = 0x02; 
            OutputBuffer[dwNumBytesToSend++] = 0x13; //Set SK,DO,GPIOL0 pins as output with bit 1, other pins as input with bit 0
        }
        for(dwCount=0; dwCount<10; dwCount++) // Repeat commands to ensure the minimum period of the stop setup time ie 800ns is achieved
        {
            OutputBuffer[dwNumBytesToSend++] = 0x80; //Command to set directions of lower 8 pins and force value on bits set as output
            OutputBuffer[dwNumBytesToSend++] = 0x03; 
            OutputBuffer[dwNumBytesToSend++] = 0x13; //Set SK,DO,GPIOL0 pins as output with bit 1, other pins as input with bit 0
        }
        for(dwCount=0; dwCount<40; dwCount++) // Repeat commands to ensure the minimum period of the stop setup time ie 800ns is achieved
        {
            OutputBuffer[dwNumBytesToSend++] = 0x80; //Command to set directions of lower 8 pins and force value on bits set as output
            OutputBuffer[dwNumBytesToSend++] = 0x02; 
            OutputBuffer[dwNumBytesToSend++] = 0x13; //Set SK,DO,GPIOL0 pins as output with bit 1, other pins as input with bit 0
        }
        //Sleep(10);        //Delay for a while

        //-------------I2cSendByteAndNotCheckACK_RegAddr-------------------------
        OutputBuffer[dwNumBytesToSend++] = MSB_FALLING_EDGE_CLOCK_BYTE_OUT; //Clock data byte out on -ve Clock Edge MSB first
        OutputBuffer[dwNumBytesToSend++] = '\x00';
        OutputBuffer[dwNumBytesToSend++] = '\x00'; //Data length of 0x0000 means 1 byte data to clock out(8 bit)
        OutputBuffer[dwNumBytesToSend++] = RegAddr;
        //Get slave's ack
        for(dwCount=0; dwCount<4; dwCount++) // Repeat commands to ensure the minimum period of the stop setup time ie 800ns is achieved
        {
            OutputBuffer[dwNumBytesToSend++] = 0x80; //Command to set directions of lower 8 pins and force value on bits set as output
            OutputBuffer[dwNumBytesToSend++] = 0x02; 
            OutputBuffer[dwNumBytesToSend++] = 0x13; //Set SK,DO,GPIOL0 pins as output with bit 1, other pins as input with bit 0
        }
        for(dwCount=0; dwCount<10; dwCount++) // Repeat commands to ensure the minimum period of the stop setup time ie 800ns is achieved
        {
            OutputBuffer[dwNumBytesToSend++] = 0x80; //Command to set directions of lower 8 pins and force value on bits set as output
            OutputBuffer[dwNumBytesToSend++] = 0x03; 
            OutputBuffer[dwNumBytesToSend++] = 0x13; //Set SK,DO,GPIOL0 pins as output with bit 1, other pins as input with bit 0
        }
        for(dwCount=0; dwCount<40; dwCount++) // Repeat commands to ensure the minimum period of the stop setup time ie 800ns is achieved
        {
            OutputBuffer[dwNumBytesToSend++] = 0x80; //Command to set directions of lower 8 pins and force value on bits set as output
            OutputBuffer[dwNumBytesToSend++] = 0x02; 
            OutputBuffer[dwNumBytesToSend++] = 0x13; //Set SK,DO,GPIOL0 pins as output with bit 1, other pins as input with bit 0
        }
        //Sleep(10);        //Delay for a while

        //-------------I2cSendByteAndNotCheckACK_RegVal-------------------------
        OutputBuffer[dwNumBytesToSend++] = MSB_FALLING_EDGE_CLOCK_BYTE_OUT; //Clock data byte out on -ve Clock Edge MSB first
        OutputBuffer[dwNumBytesToSend++] = '\x00';
        OutputBuffer[dwNumBytesToSend++] = '\x00'; //Data length of 0x0000 means 1 byte data to clock out(8 bit)
        OutputBuffer[dwNumBytesToSend++] = RegVal;
        //Get slave's ack
        for(dwCount=0; dwCount<4; dwCount++) // Repeat commands to ensure the minimum period of the stop setup time ie 800ns is achieved
        {
            OutputBuffer[dwNumBytesToSend++] = 0x80; //Command to set directions of lower 8 pins and force value on bits set as output
            OutputBuffer[dwNumBytesToSend++] = 0x02; 
            OutputBuffer[dwNumBytesToSend++] = 0x13; //Set SK,DO,GPIOL0 pins as output with bit 1, other pins as input with bit 0
        }
        for(dwCount=0; dwCount<10; dwCount++) // Repeat commands to ensure the minimum period of the stop setup time ie 800ns is achieved
        {
            OutputBuffer[dwNumBytesToSend++] = 0x80; //Command to set directions of lower 8 pins and force value on bits set as output
            OutputBuffer[dwNumBytesToSend++] = 0x03; 
            OutputBuffer[dwNumBytesToSend++] = 0x13; //Set SK,DO,GPIOL0 pins as output with bit 1, other pins as input with bit 0
        }
        for(dwCount=0; dwCount<40; dwCount++) // Repeat commands to ensure the minimum period of the stop setup time ie 800ns is achieved
        {
            OutputBuffer[dwNumBytesToSend++] = 0x80; //Command to set directions of lower 8 pins and force value on bits set as output
            OutputBuffer[dwNumBytesToSend++] = 0x02; 
            OutputBuffer[dwNumBytesToSend++] = 0x13; //Set SK,DO,GPIOL0 pins as output with bit 1, other pins as input with bit 0
        }

        //Sleep(100);        //Delay for a while

        //------------I2cStop-----------------
        for(dwCount=0; dwCount<10; dwCount++) // Repeat commands to ensure the minimum period of the stop setup time ie 800ns is achieved
        {
            OutputBuffer[dwNumBytesToSend++] = 0x80; //Command to set directions of lower 8 pins and force value on bits set as output
            OutputBuffer[dwNumBytesToSend++] = 0x00; //Set SDA low, SCL high, WP disabled by SK at bit 1, DO, GPIOL0 at bit 0
            OutputBuffer[dwNumBytesToSend++] = 0x13; //Set SK,DO,GPIOL0 pins as output with bit 1, other pins as input with bit 0
        }

        for(dwCount=0; dwCount<20; dwCount++) // Repeat commands to ensure the minimum period of the stop setup time ie 800ns is achieved
        {
            OutputBuffer[dwNumBytesToSend++] = 0x80; //Command to set directions of lower 8 pins and force value on bits set as output
            OutputBuffer[dwNumBytesToSend++] = 0x01; //Set SDA low, SCL high, WP disabled by SK at bit 1, DO, GPIOL0 at bit 0
            OutputBuffer[dwNumBytesToSend++] = 0x13; //Set SK,DO,GPIOL0 pins as output with bit 1, other pins as input with bit 0
        }

        for(dwCount=0; dwCount<20; dwCount++) // Repeat commands to ensure the minimum period of the stop hold time ie 800ns is achieved
        {
            OutputBuffer[dwNumBytesToSend++] = 0x80; //Command to set directions of lower 8 pins and force value on bits set as output
            OutputBuffer[dwNumBytesToSend++] = 0x03; //Set SDA, SCL high, WP disabled by SK, DO at bit 1, GPIOL0 at bit 0
            OutputBuffer[dwNumBytesToSend++] = 0x13; //Set SK,DO,GPIOL0 pins as output with bit 1, other pins as input with bit 0
        }
        //Tristate the SCL, SDA pins
        OutputBuffer[dwNumBytesToSend++] = 0x80; //Command to set directions of lower 8 pins and force value on bits set as output
        OutputBuffer[dwNumBytesToSend++] = 0x03; //Set SCL low, WP disabled by SK, DO, GPIOL0 at bit 0
        OutputBuffer[dwNumBytesToSend++] = 0x10; //Set GPIOL0 pins as output with bit 1, SK, DO and other pins as input with bit 0
        //Sleep(1);        //Delay for a while
        //-------------Send off all commands--------------
        ftStatus = FT_Write(ftHandle, OutputBuffer, dwNumBytesToSend, &dwNumBytesSent);
        dwNumBytesToSend = 0; //Clear output buffer
        //Sleep(1);    

    }


    int FT2232I2cByteRdOneTime(unsigned char DeviceAddr,unsigned char RegAddr)
    {
        DWORD dwCount;
        FT_STATUS ftStatus = FT_OK;

        unsigned char Value;
        BOOL bSucceed = TRUE;
        char DataLen=4;
        UCHAR* pDataB = new UCHAR[DataLen];
        memset(pDataB,0,DataLen);
        //Purge USB receive buffer first before read operation
        ftStatus = FT_GetQueueStatus(ftHandle, &dwNumInputBuffer); // Get the number of bytes in the device receive buffer
        if ((ftStatus == FT_OK) && (dwNumInputBuffer > 0))
        FT_Read(ftHandle, &InputBuffer, dwNumInputBuffer, &dwNumBytesRead); //Read out all the data from receive buffer

        //-------------I2cStart-------------------------
        for(dwCount=0; dwCount < 4; dwCount++) // 
        {
            OutputBuffer[dwNumBytesToSend++] = 0x80; //Command to set directions of lower 8 pins and force value on bits set as output
            OutputBuffer[dwNumBytesToSend++] = 0x03; //Set SDA, SCL high, WP disabled by SK, DO at bit 1, GPIOL0 at bit 0
            OutputBuffer[dwNumBytesToSend++] = 0x13; //Set SK,DO,GPIOL0 pins as output with bit 1, other pins as input with bit 0
        }

        for(dwCount=0; dwCount < 20; dwCount++) // 
        {
            OutputBuffer[dwNumBytesToSend++] = 0x80; //Command to set directions of lower 8 pins and force value on bits set as output
            OutputBuffer[dwNumBytesToSend++] = 0x01; //Set SDA low, SCL high, WP disabled by SK at bit 1, DO, GPIOL0 at bit 0
            OutputBuffer[dwNumBytesToSend++] = 0x13; //Set SK,DO,GPIOL0 pins as output with bit 1, other pins as input with bit 0
        }

        OutputBuffer[dwNumBytesToSend++] = 0x80; //Command to set directions of lower 8 pins and force value on bits set as output
        OutputBuffer[dwNumBytesToSend++] = 0x00; 
        OutputBuffer[dwNumBytesToSend++] = 0x13; //Set SK,DO,GPIOL0 pins as output with bit 1, other pins as input with bit 0
        //Sleep(10);        //Delay for a while
        //-------------I2cSendByteAndNotCheckACK_DeviceAddr-------------------------
        
        OutputBuffer[dwNumBytesToSend++] = MSB_FALLING_EDGE_CLOCK_BYTE_OUT; //Clock data byte out on -ve Clock Edge MSB first
        OutputBuffer[dwNumBytesToSend++] = '\x00';
        OutputBuffer[dwNumBytesToSend++] = '\x00'; //Data length of 0x0000 means 1 byte data to clock out(8 bit)
        OutputBuffer[dwNumBytesToSend++] = DeviceAddr;

        //Get slave's ack
        for(dwCount=0; dwCount<4; dwCount++) // Repeat commands to ensure the minimum period of the stop setup time ie 800ns is achieved
        {
            OutputBuffer[dwNumBytesToSend++] = 0x80; //Command to set directions of lower 8 pins and force value on bits set as output
            OutputBuffer[dwNumBytesToSend++] = 0x02; 
            OutputBuffer[dwNumBytesToSend++] = 0x13; //Set SK,DO,GPIOL0 pins as output with bit 1, other pins as input with bit 0
        }
        for(dwCount=0; dwCount<10; dwCount++) // Repeat commands to ensure the minimum period of the stop setup time ie 800ns is achieved
        {
            OutputBuffer[dwNumBytesToSend++] = 0x80; //Command to set directions of lower 8 pins and force value on bits set as output
            OutputBuffer[dwNumBytesToSend++] = 0x03; 
            OutputBuffer[dwNumBytesToSend++] = 0x13; //Set SK,DO,GPIOL0 pins as output with bit 1, other pins as input with bit 0
        }
        for(dwCount=0; dwCount<40; dwCount++) // Repeat commands to ensure the minimum period of the stop setup time ie 800ns is achieved
        {
            OutputBuffer[dwNumBytesToSend++] = 0x80; //Command to set directions of lower 8 pins and force value on bits set as output
            OutputBuffer[dwNumBytesToSend++] = 0x02; 
            OutputBuffer[dwNumBytesToSend++] = 0x13; //Set SK,DO,GPIOL0 pins as output with bit 1, other pins as input with bit 0
        }
        //Sleep(10);        //Delay for a while

        //-------------I2cSendByteAndNotCheckACK_RegAddr-------------------------
        OutputBuffer[dwNumBytesToSend++] = MSB_FALLING_EDGE_CLOCK_BYTE_OUT; //Clock data byte out on -ve Clock Edge MSB first
        OutputBuffer[dwNumBytesToSend++] = '\x00';
        OutputBuffer[dwNumBytesToSend++] = '\x00'; //Data length of 0x0000 means 1 byte data to clock out(8 bit)
        OutputBuffer[dwNumBytesToSend++] = RegAddr;

        //Get slave's ack
        for(dwCount=0; dwCount<4; dwCount++) // Repeat commands to ensure the minimum period of the stop setup time ie 800ns is achieved
        {
            OutputBuffer[dwNumBytesToSend++] = 0x80; //Command to set directions of lower 8 pins and force value on bits set as output
            OutputBuffer[dwNumBytesToSend++] = 0x02; 
            OutputBuffer[dwNumBytesToSend++] = 0x13; //Set SK,DO,GPIOL0 pins as output with bit 1, other pins as input with bit 0
        }
        for(dwCount=0; dwCount<10; dwCount++) // Repeat commands to ensure the minimum period of the stop setup time ie 800ns is achieved
        {
            OutputBuffer[dwNumBytesToSend++] = 0x80; //Command to set directions of lower 8 pins and force value on bits set as output
            OutputBuffer[dwNumBytesToSend++] = 0x03; 
            OutputBuffer[dwNumBytesToSend++] = 0x13; //Set SK,DO,GPIOL0 pins as output with bit 1, other pins as input with bit 0
        }
        for(dwCount=0; dwCount<40; dwCount++) // Repeat commands to ensure the minimum period of the stop setup time ie 800ns is achieved
        {
            OutputBuffer[dwNumBytesToSend++] = 0x80; //Command to set directions of lower 8 pins and force value on bits set as output
            OutputBuffer[dwNumBytesToSend++] = 0x02; 
            OutputBuffer[dwNumBytesToSend++] = 0x13; //Set SK,DO,GPIOL0 pins as output with bit 1, other pins as input with bit 0
        }
        //Sleep(10);        //Delay for a while

        //-------------I2cReStart-------------------------
        for(dwCount=0; dwCount<4; dwCount++) // Repeat commands to ensure the minimum period of the stop setup time ie 800ns is achieved
        {
            OutputBuffer[dwNumBytesToSend++] = 0x80; //Command to set directions of lower 8 pins and force value on bits set as output
            OutputBuffer[dwNumBytesToSend++] = 0x00; //Set SDA low, SCL high, WP disabled by SK at bit 1, DO, GPIOL0 at bit 0
            OutputBuffer[dwNumBytesToSend++] = 0x13; //Set SK,DO,GPIOL0 pins as output with bit 1, other pins as input with bit 0
        }

        for(dwCount=0; dwCount<20; dwCount++) // Repeat commands to ensure the minimum period of the stop setup time ie 800ns is achieved
        {
            OutputBuffer[dwNumBytesToSend++] = 0x80; //Command to set directions of lower 8 pins and force value on bits set as output
            OutputBuffer[dwNumBytesToSend++] = 0x01; //Set SDA low, SCL high, WP disabled by SK at bit 1, DO, GPIOL0 at bit 0
            OutputBuffer[dwNumBytesToSend++] = 0x13; //Set SK,DO,GPIOL0 pins as output with bit 1, other pins as input with bit 0
        }

        for(dwCount=0; dwCount<20; dwCount++) 
        {
            OutputBuffer[dwNumBytesToSend++] = 0x80; //Command to set directions of lower 8 pins and force value on bits set as output
            OutputBuffer[dwNumBytesToSend++] = 0x03; //Set SDA, SCL high, WP disabled by SK, DO at bit 1, GPIOL0 at bit 0
            OutputBuffer[dwNumBytesToSend++] = 0x13; //Set SK,DO,GPIOL0 pins as output with bit 1, other pins as input with bit 0
        }


        for(dwCount=0; dwCount < 40; dwCount++) 
        {
            OutputBuffer[dwNumBytesToSend++] = 0x80; //Command to set directions of lower 8 pins and force value on bits set as output
            OutputBuffer[dwNumBytesToSend++] = 0x01; //Set SDA low, SCL high, WP disabled by SK at bit 1, DO, GPIOL0 at bit 0
            OutputBuffer[dwNumBytesToSend++] = 0x13; //Set SK,DO,GPIOL0 pins as output with bit 1, other pins as input with bit 0
        }

        for(dwCount=0; dwCount < 20; dwCount++) 
        {
            OutputBuffer[dwNumBytesToSend++] = 0x80; //Command to set directions of lower 8 pins and force value on bits set as output
            OutputBuffer[dwNumBytesToSend++] = 0x00;
            OutputBuffer[dwNumBytesToSend++] = 0x13; //Set SK,DO,GPIOL0 pins as output with bit 1, other pins as input with bit 0
        }
        //Sleep(10);        //Delay for a while

        //-------------I2cSendByteAndNotCheckACK_DeviceAddr+1-------------------------
        OutputBuffer[dwNumBytesToSend++] = MSB_FALLING_EDGE_CLOCK_BYTE_OUT; //Clock data byte out on -ve Clock Edge MSB first
        OutputBuffer[dwNumBytesToSend++] = '\x00';
        OutputBuffer[dwNumBytesToSend++] = '\x00'; //Data length of 0x0000 means 1 byte data to clock out(8 bit)
        OutputBuffer[dwNumBytesToSend++] = DeviceAddr+1;

        //Get slave's ack
        for(dwCount=0; dwCount<4; dwCount++) // Repeat commands to ensure the minimum period of the stop setup time ie 800ns is achieved
        {
            OutputBuffer[dwNumBytesToSend++] = 0x80; //Command to set directions of lower 8 pins and force value on bits set as output
            OutputBuffer[dwNumBytesToSend++] = 0x02; 
            OutputBuffer[dwNumBytesToSend++] = 0x13; //Set SK,DO,GPIOL0 pins as output with bit 1, other pins as input with bit 0
        }
        for(dwCount=0; dwCount<10; dwCount++) // Repeat commands to ensure the minimum period of the stop setup time ie 800ns is achieved
        {
            OutputBuffer[dwNumBytesToSend++] = 0x80; //Command to set directions of lower 8 pins and force value on bits set as output
            OutputBuffer[dwNumBytesToSend++] = 0x03; 
            OutputBuffer[dwNumBytesToSend++] = 0x13; //Set SK,DO,GPIOL0 pins as output with bit 1, other pins as input with bit 0
        }
        for(dwCount=0; dwCount<40; dwCount++) // 
        {
            OutputBuffer[dwNumBytesToSend++] = 0x80; //Command to set directions of lower 8 pins and force value on bits set as output
            OutputBuffer[dwNumBytesToSend++] = 0x02; 
            OutputBuffer[dwNumBytesToSend++] = 0x13; //Set SK,DO,GPIOL0 pins as output with bit 1, other pins as input with bit 0
        }
        //Sleep(140);        //Delay for a while

        //-------------I2cReceiveByte-------------------------
        OutputBuffer[dwNumBytesToSend++] = '\x20'; //0x20:  rising edge latch data
        OutputBuffer[dwNumBytesToSend++] = '\x00';
        OutputBuffer[dwNumBytesToSend++] = '\x00'; //Data length of 0x0000 means 1 byte data to clock in
        OutputBuffer[dwNumBytesToSend++] = '\x87'; //Send answer back immediate command
        //pDataB[0] = FT2232I2cReceiveByte(); // Read value back

        //------------I2cSendNAck--------------------
        for(dwCount=0; dwCount<4; dwCount++) // Repeat commands to ensure the minimum period of the stop hold time ie 2.5us is achieved
        {
            OutputBuffer[dwNumBytesToSend++] = 0x80; //Command to set directions of lower 8 pins and force value on bits set as output
            OutputBuffer[dwNumBytesToSend++] = 0x02; //Set SDA high, SCL low(20180720), WP disabled by SK at bit 0, DO, GPIOL0 at bit 1
            OutputBuffer[dwNumBytesToSend++] = 0x13; //Set SK,DO,GPIOL0 pins as output with bit 1, other pins as input with bit 0
        }

        for(dwCount=0; dwCount<10; dwCount++) // Repeat commands to ensure the minimum period of the stop hold time ie 2.5us is achieved
        {
            OutputBuffer[dwNumBytesToSend++] = 0x80; //Command to set directions of lower 8 pins and force value on bits set as output
            OutputBuffer[dwNumBytesToSend++] = 0x03; //Set SDA high, SCL high(20180720), WP disabled by SK at bit 0, DO, GPIOL0 at bit 1
            OutputBuffer[dwNumBytesToSend++] = 0x13; //Set SK,DO,GPIOL0 pins as output with bit 1, other pins as input with bit 0
        }

        for(dwCount=0; dwCount<40; dwCount++) // Repeat commands to ensure the minimum period of the stop setup time ie 2.5us is achieved
        {
            OutputBuffer[dwNumBytesToSend++] = 0x80; //Command to set directions of lower 8 pins and force value on bits set as output
            OutputBuffer[dwNumBytesToSend++] = 0x02; //Set SDA high, SCL low(20180720), WP disabled by SK at bit 1, DO, GPIOL0 at bit 0
            OutputBuffer[dwNumBytesToSend++] = 0x13; //Set SK,DO,GPIOL0 pins as output with bit 1, other pins as input with bit 0
        }

        //for(dwCount=0; dwCount<12; dwCount++) // Repeat commands to ensure the minimum period of the stop setup time ie 2.5us is achieved
        {
            OutputBuffer[dwNumBytesToSend++] = 0x80; //Command to set directions of lower 8 pins and force value on bits set as output
            OutputBuffer[dwNumBytesToSend++] = 0x00; //Set SDA low, SCL low(20180720), WP disabled by SK at bit 1, DO, GPIOL0 at bit 0
            OutputBuffer[dwNumBytesToSend++] = 0x13; //Set SK,DO,GPIOL0 pins as output with bit 1, other pins as input with bit 0
        }
        //Sleep(100);        //Delay for a while
        //------------I2cStop-----------------
        for(dwCount=0; dwCount<6; dwCount++) // Repeat commands to ensure the minimum period of the stop setup time ie 800ns is achieved
        {
            OutputBuffer[dwNumBytesToSend++] = 0x80; //Command to set directions of lower 8 pins and force value on bits set as output
            OutputBuffer[dwNumBytesToSend++] = 0x00; //Set SDA low, SCL high, WP disabled by SK at bit 1, DO, GPIOL0 at bit 0
            OutputBuffer[dwNumBytesToSend++] = 0x13; //Set SK,DO,GPIOL0 pins as output with bit 1, other pins as input with bit 0
        }

        for(dwCount=0; dwCount<20; dwCount++) 
        {
            OutputBuffer[dwNumBytesToSend++] = 0x80; //Command to set directions of lower 8 pins and force value on bits set as output
            OutputBuffer[dwNumBytesToSend++] = 0x01; //Set SDA low, SCL high, WP disabled by SK at bit 1, DO, GPIOL0 at bit 0
            OutputBuffer[dwNumBytesToSend++] = 0x13; //Set SK,DO,GPIOL0 pins as output with bit 1, other pins as input with bit 0
        }

        for(dwCount=0; dwCount<10; dwCount++) 
        {
            OutputBuffer[dwNumBytesToSend++] = 0x80; //Command to set directions of lower 8 pins and force value on bits set as output
            OutputBuffer[dwNumBytesToSend++] = 0x03; //Set SDA, SCL high, WP disabled by SK, DO at bit 1, GPIOL0 at bit 0
            OutputBuffer[dwNumBytesToSend++] = 0x13; //Set SK,DO,GPIOL0 pins as output with bit 1, other pins as input with bit 0
        }
        //Tristate the SCL, SDA pins
        OutputBuffer[dwNumBytesToSend++] = 0x80; //Command to set directions of lower 8 pins and force value on bits set as output
        OutputBuffer[dwNumBytesToSend++] = 0x03; //Set SCL low, WP disabled by SK, DO, GPIOL0 at bit 0
        OutputBuffer[dwNumBytesToSend++] = 0x10; //Set GPIOL0 pins as output with bit 1, SK, DO and other pins as input with bit 0

        //-------------Send off all commands--------------
        ftStatus = FT_Write(ftHandle, OutputBuffer, dwNumBytesToSend, &dwNumBytesSent); //Send off the commands
        dwNumBytesToSend = 0; //Clear output buffer
        //Sleep(0.1);        //Delay for a while
        ftStatus = FT_Read(ftHandle, InputBuffer, 1, &dwNumBytesRead);
        if ((ftStatus != FT_OK) || (dwNumBytesRead == 0))
        { 
                return 0; /*Error*/ 
        }
        //Value = InputBuffer[0];
        return InputBuffer[0];
    }

    展开全文
  • USB转串行通信芯片FT2232

    千次阅读 2020-03-22 09:59:19
    USB转串行通信芯片FT2232

    1 FT2232主要特性
    1)2232表示支持2个RS232。
    2)FT2232D最高支持full-speed,所以时钟是12MHz;而FT2232H最高支持high-speed,所以时钟是60MHz。
    3)FT2232的Port A和Port B会在Windows设备管理器的“通用串行总线控制器”下产生2个设备。绝大部分的MCU JTAG工具都是基于FT2232制作的,FT2232的其中一个Port作为JTAG,另一个Port作为UART用来打印调试log。
    4)Port A和Port B的初始配置放置在一个SOP8 EEPROM中。
    5)FT2232缺少对一些特殊接口控制信号的支持,可以使用FPGA扩展,FPGA的固件通过FT2232下载,保存在SPI NOR Flash中。
    6)PC驱动架构
    Figure 1-1 Windows CDM Driver Architecture

    2 Bit-Bang
    2.1 基本概念
    1)Use software to control serial communication at general-purpose I/O pins。
    2)对接传统的很多基于PC LPT并口模拟的外设。
    3)用GPIO模拟I2C和SPI都称为Bit-Bang。
    4)FT_SetBitMode()的参数ucMask对应bit为0表示input,反之则为output。

    2.2 Bit-Bang分类
    1)异步Bit-Bang - 0x01
    2)同步Bit-Bang - 0x04
    3)CBUS Bit-Bang - 0x20
    Figure 2-1 ucMode Table

    Figure 2-2 CBUS Bit-Bang ucMask

    2.3 GPIO读写控制传输
    DBUS FTDI_SIO_SET_BITMODE
    ucMask对应bit为0表示input,反之则为output
    bmRequestType:0x40
    bRequest:0x0B
    wValue:ucMode << 8 | ucMask
    wIndex:bInterfaceNumber + 1
    wLength:0

    CBUS FTDI_SIO_SET_BITMODE
    ucMask的高4位表示方向,低4位表示数值
    bmRequestType:0x40
    bRequest:0x0B
    wValue:0x20 << 8 | ucMask
    wIndex:bInterfaceNumber + 1
    wLength:0

    FTDI_SIO_READ_PINS
    bmRequestType:0xC0
    bRequest:0x0C
    wValue:0
    wIndex:bInterfaceNumber + 1
    wLength:1
    返回一字节buffer

    2.4 EEPROM读写控制传输
    FTDI_SIO_READ_EEPROM
    bmRequestType:0xC0
    bRequest:0x90
    wValue:0
    wIndex:eeprom_addr,u16地址
    wLength:2
    每次只能返回2字节buffer

    FTDI_SIO_WRITE_EEPROM
    bmRequestType:0x40
    bRequest:0x91
    wValue:2字节的EEPROM值,每次只能写2字节
    wIndex:eeprom_addr,u16地址
    wLength:0

    3 MPSSE
    3.1 基本概念
    FT2232不需要固件程序,因为所有功能都由芯片硬件实现,the FT2232D, FT232H, FT2232H and FT4232H incorporate a command processor called the Multi-Protocol Synchronous Serial Engine (MPSSE)。

    The MPSSE Command Processor unit is controlled using a SETUP command。Various commands are used to clock data out of and into the chip,as well as controlling the other I/O lines。

    USB SETUP command参考文档"API Definitions for FTDI FT232 and FT245 USB Interface Chips"。

    USB SETUP command的状态阶段的状态包是个ZLP。

    3.2 Port A包括2组pin
    ADBUS - Port A Data Bus
    ACBUS - Port A Control Bus

    3.3 Port B包括2组pin
    BDBUS - Port B Data Bus
    BCBUS - Port B Control Bus

    3.4 使能MPSSE控制传输
    FTDI_SIO_SET_BITMODE
    bmRequestType:0x40
    bRequest:0x0B
    wValue:0x02 << 8 | 0x0
    wIndex:bInterfaceNumber + 1
    wLength:0

    3.5 Data Shifting Command
    Figure 3-1 Data Shifting Command

    1)+VE、-VE:Valid Edge,分别表示上升沿和下降沿有效。
    2)图中说明:MPSSE串行命令的bit7为0,MPSSE其它命令的bit7为1。

    4 FTDI编程
    4.1 FTDI FT_Prog
    该工具主要用来读写EEPROM,修改完毕,选择[DEVICES][Program]写入EEPROM即可。

    4.2 Python ftd2xx for Windows
    1)安装
    Programming FTDI devices in Python: Part 1
    https://iosoft.blog/2018/12/02/ftdi-python-part-1

    ftd2xx is a simple python wrapper around the FTDI D2XX DLL.
    pip install ftd2xx

    2)示例
    import sys, ftd2xx as ftd
    d = ftd.open(0)
    print(d.getDeviceInfo())

    4.3 libFTDI for Windows
    1)
    USB Resources for Microchip Microcontrollers, libusb and libftdi
    https://sourceforge.net/projects/picusb/files/
    2)拷贝lib64\site_packages下所有文件到python的Lib\site_packages下
    3)拷贝bin64\Python3.6\Lib\site_packages下所有文件到python的Lib\site_packages下

    5 Abbreviations
    .cat文件:category表示Windows的驱动签名安全目录
    CH341:winchiphead
    D2XX:D表示FTD,2表示USB2.0
    Falcon:FAst Logic CONtroller。NVIDIA私有的RISC MCU,主要用在桌面GPU(Falcon中的寄存器一般映射到PCI BAR0)或者Tegra xHCI控制器中。NVIDIA正在把私有的Falcon MCU架构换成RISC-V
    FTDI:Future Technology Devices International
    MM232R:Miniature Development Module
    MISO:mi s əu
    MOSI:m əu si
    QUP:高通平台的SPI总线和I2C共用core和引脚,称为QUP(QCOM Universal Peripheral);而UART和QUP又共用引脚,并且称为BLSP

    展开全文
  • FT2232H编程流程分析

    千次阅读 2020-04-11 19:09:34
    FT2232H编程流程分析前言正菜获取当前连接的FTDI设备获取指定设备的详细信息擦桌子 前言 如何熟练操作FT2232H设备呢?这是一个问题。下面我们以Visual Studio环境下C++例程代码为例来逐步进行解析。 正菜 获取当前...

    前言

    如何熟练操作FT2232H设备呢?这是一个问题。下面我们以Visual Studio环境下C++例程代码为例来逐步进行解析。

    正菜

    获取当前连接的FTDI设备

    ftStatus = FT_CreateDeviceInfoList(&dwNumDevs);		// Get the number of FTDI devices
    
    if (ftStatus != FT_OK)			// Did the command execute OK?
    {
    	printf("Error in getting the number of devices\n");
    	return 1;					// Exit with error
    }
    
    if (dwNumDevs < 1)				// Exit if we don't see any
    {
    	printf("There are no FTDI devices installed\n");
    	return 1;					// Exist with error
    }
    
    printf("%d FTDI devices found - the count includes individual ports on a single chip\n", dwNumDevs);
    

    上述代码获取当前系统下的FTDI设备数,如果设备是FT232H,那么dwNumDevs等于1;如果设备是FT2232H,那么dwNumDevs等于2.

    获取指定设备的详细信息

    FT_HANDLE ftHandleTemp; 
    DWORD numDevs; 
    DWORD Flags;
    DWORD ID; 
    DWORD Type; 
    DWORD LocId; 
    char SerialNumber[16]; 
    char Description[64];
    
    ftStatus = FT_GetDeviceInfoDetail(1, &Flags, &Type, &ID, &LocId, SerialNumber, Description, &ftHandleTemp);
    if (ftStatus != FT_OK)
    {
    	printf("Open Failed with error %d\n", ftStatus);
    	return 1;					// Exit with error
    }
    printf("TYPE:%x\n", Type);
    printf("ID:%x\n", ID);
    printf("Flags:%x\n", Flags);
    printf("SN:%x\n", SerialNumber);
    printf("Description:%x\n", Description);
    

    确认设备信息后,打开指定设备

    ftStatus = FT_Open(1, &ftHandle);
    if (ftStatus != FT_OK)
    {
    	printf("Open Failed with error %d\n", ftStatus);
    	return 1;					// Exit with error
    }	
    

    上面代码中1表示设备号。

    复位设备

    ftStatus |= FT_ResetDevice(ftHandle); 	//Reset USB device
    

    清空缓存

    ftStatus |= FT_GetQueueStatus(ftHandle, &dwNumBytesToRead);   // Get the number of bytes in the FT2232H receive buffer
    if ((ftStatus == FT_OK) && (dwNumBytesToRead > 0))
    	FT_Read(ftHandle, &byInputBuffer, dwNumBytesToRead, &dwNumBytesRead);  	//Read out the data from FT2232H receive buffer
    

    清空接收缓存和发送缓存.

    配置设备

    ftStatus |= FT_SetUSBParameters(ftHandle, 65536, 65535); 	//Set USB request transfer sizes to 64K
    ftStatus |= FT_SetChars(ftHandle, false, 0, false, 0); 		//Disable event and error characters
    ftStatus |= FT_SetTimeouts(ftHandle, 0, 5000); 	     		//Sets the read and write timeouts in milliseconds 
    ftStatus |= FT_SetLatencyTimer(ftHandle, 16);   			//Set the latency timer (default is 16mS)
    ftStatus |= FT_SetBitMode(ftHandle, 0x0, 0x00); 			//Reset controller
    ftStatus |= FT_SetBitMode(ftHandle, 0x0, 0x02); 			//Enable MPSSE mode
    if (ftStatus != FT_OK)
    {
    	printf("Error in initializing the MPSSE %d\n", ftStatus);
    	FT_Close(ftHandle);
    	return 1;					// Exit with error
    }	
    Sleep(50); // Wait for all the USB stuff to complete and work
    

    主要配置:

    • 设置USB传输块大小
    • 禁止事件和错误字符
    • 按照毫秒单位设定读写timeout
    • 设置延迟定时器
    • 复位控制器
    • 使能MPSSE模式

    同步MPSSE

    /* 
    // -----------------------------------------------------------
    // Synchronize the MPSSE by sending a bogus opcode (0xAA), 
    //		The MPSSE will respond with "Bad Command" (0xFA) followed by
    //		the bogus opcode itself.
    // -----------------------------------------------------------
    */
    byOutputBuffer[dwNumBytesToSend++] = 0xAA;//'\xAA'; 	//Add bogus command 憍AA?to the queue
    ftStatus = FT_Write(ftHandle, byOutputBuffer, dwNumBytesToSend, &dwNumBytesSent);   // Send off the BAD commands
    dwNumBytesToSend = 0;			// Reset output buffer pointer
    do
    {
    	ftStatus = FT_GetQueueStatus(ftHandle, &dwNumBytesToRead); 	// Get the number of bytes in the device input buffer
    } while ((dwNumBytesToRead == 0) && (ftStatus == FT_OK)); 	//or Timeout
    
    bool bCommandEchod = false;
    ftStatus = FT_Read(ftHandle, &byInputBuffer, dwNumBytesToRead, &dwNumBytesRead); 	//Read out the data from input buffer
    for (dwCount = 0; dwCount < dwNumBytesRead - 1; dwCount++)  	//Check if Bad command and echo command received
    {
    	if ((byInputBuffer[dwCount] == 0xFA) && (byInputBuffer[dwCount+1] == 0xAA))
    	{
    		bCommandEchod = true;
    		break;
    	}
    }
    if (bCommandEchod == false)
    {
    	printf("Error in synchronizing the MPSSE\n");
    	FT_Close(ftHandle);
    	return 1;					// Exit with error
    }	
    

    点灯测试代码

    while (1) {
    	//注释掉的代码是MPSSE I2C User Mannual中提到的GPIO操作函数
    	/*FT_WriteGPIO(ftHandle, 0xff, 0xFF);
    	Sleep(50);
    	FT_WriteGPIO(ftHandle, 0xff, 0x00);
    	Sleep(50);*/
    	dwNumBytesToSend = 0;			// Start with a fresh index
    	
    	// Set up the Hi-Speed specific commands for the FTx232H
    	byOutputBuffer[dwNumBytesToSend++] = 0x82;	// Use 60MHz master clock (disable divide by 5)
    	byOutputBuffer[dwNumBytesToSend++] = 0xFF;	// Turn off adaptive clocking (may be needed for ARM)
    	byOutputBuffer[dwNumBytesToSend++] = 0xFF;	// Disable three-phase clocking
    	ftStatus = FT_Write(ftHandle, byOutputBuffer, dwNumBytesToSend, &dwNumBytesSent);
    	dwNumBytesToSend = 0;
    	Sleep(50);
    	byOutputBuffer[dwNumBytesToSend++] = 0x82;	// Use 60MHz master clock (disable divide by 5)
    	byOutputBuffer[dwNumBytesToSend++] = 0x00;	// Turn off adaptive clocking (may be needed for ARM)
    	byOutputBuffer[dwNumBytesToSend++] = 0xFF;	// Disable three-phase clocking
    	ftStatus = FT_Write(ftHandle, byOutputBuffer, dwNumBytesToSend, &dwNumBytesSent);
    	dwNumBytesToSend = 0;
    	Sleep(50);
    }
    

    配置MPSSE JTAG

    /* 
    // -----------------------------------------------------------
    // Configure the MPSSE settings for JTAG
    //		Multple commands can be sent to the MPSSE with one FT_Write
    // -----------------------------------------------------------
    */
    dwNumBytesToSend = 0;			// Start with a fresh index
    
    // Set up the Hi-Speed specific commands for the FTx232H
    byOutputBuffer[dwNumBytesToSend++] = 0x8A;		// Use 60MHz master clock (disable divide by 5)
    byOutputBuffer[dwNumBytesToSend++] = 0x97;  	// Turn off adaptive clocking (may be needed for ARM)
    byOutputBuffer[dwNumBytesToSend++] = 0x8D;		// Disable three-phase clocking
    ftStatus = FT_Write(ftHandle, byOutputBuffer, dwNumBytesToSend, &dwNumBytesSent); 
    									// Send off the HS-specific commands
    dwNumBytesToSend = 0;			// Reset output buffer pointer
    // Set initial states of the MPSSE interface - low byte, both pin directions and output values
    //		Pin name	Signal	Direction	Config	Initial State	Config
    //		ADBUS0		TCK		output		1		low				0
    //		ADBUS1		TDI		output		1		low				0
    //		ADBUS2		TDO		input		0						0
    //		ADBUS3		TMS		output		1		high			1
    //		ADBUS4		GPIOL0	input		0						0
    //		ADBUS5		GPIOL1	input		0						0
    //		ADBUS6		GPIOL2	input		0						0
    //		ADBUS7		GPIOL3	input		0						0
    		
    byOutputBuffer[dwNumBytesToSend++] = 0x80;  // Set data bits low-byte of MPSSE port
    byOutputBuffer[dwNumBytesToSend++] = 0x08;	// Initial state config above
    byOutputBuffer[dwNumBytesToSend++] = 0x0B;	// Direction config above
    ftStatus = FT_Write(ftHandle, byOutputBuffer, dwNumBytesToSend, &dwNumBytesSent);  // Send off the low GPIO config commands
    dwNumBytesToSend = 0;			// Reset output buffer pointer
    

    配置GPIO

    dwNumBytesToSend = 0;			// Start with a fresh index
    // Set initial states of the MPSSE interface - high byte, both pin directions and output values
    //		Pin name	Signal	Direction	Config	Initial State	Config
    //		ACBUS0		GPIOH0	input		0						0
    //		ACBUS1		GPIOH1	input		0						0
    //		ACBUS2		GPIOH2	input		0						0
    //		ACBUS3		GPIOH3	input		0						0
    //		ACBUS4		GPIOH4	input		0						0
    //		ACBUS5		GPIOH5	input		0						0
    //		ACBUS6		GPIOH6	input		0						0
    //		ACBUS7		GPIOH7	input		0						0
    
    byOutputBuffer[dwNumBytesToSend++] = 0x82;	// Set data bits low-byte of MPSSE port
    byOutputBuffer[dwNumBytesToSend++] = 0x00;	// Initial state config above
    byOutputBuffer[dwNumBytesToSend++] = 0x00;	// Direction config above
    
    ftStatus = FT_Write(ftHandle, byOutputBuffer, dwNumBytesToSend, &dwNumBytesSent);  // Send off the high GPIO config commands
    
    dwNumBytesToSend = 0;			// Reset output buffer pointer
    

    设置TCK时钟

    // Set TCK frequency 
    // TCK = 60MHz /((1 + [(1 +0xValueH*256) OR 0xValueL])*2)
    byOutputBuffer[dwNumBytesToSend++] = '\x86'; //Command to set clock divisor
    byOutputBuffer[dwNumBytesToSend++] = dwClockDivisor & 0xFF; 	//Set 0xValueL of clock divisor
    byOutputBuffer[dwNumBytesToSend++] = (dwClockDivisor >> 8) & 0xFF; 	//Set 0xValueH of clock divisor
    ftStatus = FT_Write(ftHandle, byOutputBuffer, dwNumBytesToSend, &dwNumBytesSent); // Send off the clock divisor commands
    dwNumBytesToSend = 0;			// Reset output buffer pointer
    

    0xValueH表示高8位,0xValueL表示低8位. dwClockDivisor设定为0x05DB(即1499),TCK时钟频率设定为20KHz。

    禁用Loopback

    dwNumBytesToSend = 0;			// Reset output buffer pointer
    // Disable internal loop-back
    byOutputBuffer[dwNumBytesToSend++] = 0x85;	// Disable loopback
    ftStatus = FT_Write(ftHandle, byOutputBuffer, dwNumBytesToSend, &dwNumBytesSent);  // Send off the loopback command
    dwNumBytesToSend = 0;	// Reset output buffer pointer
    

    JTAG状态转换(Test-Logic-Reset -> Run-Test-Idle -> Select-DR-Scan -> Select-IR-Scan->Capture IR->Shift IR

    // Navigage TMS through Test-Logic-Reset -> Run-Test-Idle -> Select-DR-Scan -> Select-IR-Scan
    // TMS=1   TMS=0   TMS=1     TMS=1
    byOutputBuffer[dwNumBytesToSend++] = 0x4B;	// Don't read data in Test-Logic-Reset, Run-Test-Idle, Select-DR-Scan, Select-IR-Scan
    byOutputBuffer[dwNumBytesToSend++] = 0x05;	// Number of clock pulses = Length + 1 (6 clocks here)
    byOutputBuffer[dwNumBytesToSend++] = 0x0D;	// Data is shifted LSB first, so the TMS pattern is 101100
    ftStatus = FT_Write(ftHandle, byOutputBuffer, dwNumBytesToSend, &dwNumBytesSent); 	// Send off the TMS command
    dwNumBytesToSend = 0;			// Reset output buffer pointer
    

    JTAG状态机转换(Shift-IR

    // TMS is currently low.  State machine is in Shift-IR, so now use the TDI/TDO command to shift 1's out TDI/DO while reading TDO/DI
    // Although 8 bits need shifted in, only 7 are clocked here.  The 8th will be in conjunciton with a TMS command, coming next
    
    byOutputBuffer[dwNumBytesToSend++] = 0x3B;		// Clock data out throuth states Capture-IR, Shift-IR and Exit-IR, read back result
    byOutputBuffer[dwNumBytesToSend++] = 0x06;		// Number of clock pulses = Length + 1 (7 clocks here)
    byOutputBuffer[dwNumBytesToSend++] = 0xFF;		// Shift out 1111111 (ignore last bit)
    ftStatus = FT_Write(ftHandle, byOutputBuffer, dwNumBytesToSend, &dwNumBytesSent); 				// Send off the TMS command
    dwNumBytesToSend = 0;			// Reset output buffer pointer
    

    JTAG状态机转换(Exit 1-IR

    // Here is the TMS command for one clock.  Data is also shifted in.
    byOutputBuffer[dwNumBytesToSend++] = 0x6B;			// Clock out TMS, Read one bit.
    byOutputBuffer[dwNumBytesToSend++] = 0x00;			// Number of clock pulses = Length + 0 (1 clock here)
    byOutputBuffer[dwNumBytesToSend++] = 0x83;			// Data is shifted LSB first, so TMS becomes 1.  Also, bit 7 is shifted into TDI/DO, also a 1
    	                						        // The 1 in bit 1 will leave TMS high for the next commands.
    ftStatus = FT_Write(ftHandle, byOutputBuffer, dwNumBytesToSend, &dwNumBytesSent); 	// Send off the TMS command
    dwNumBytesToSend = 0;			// Reset output buffer pointer
    

    JTAG状态机转换(Update-IR->Select-DR-Scan->Capture DR->Shift-DR

    // Navigage TMS from Exit-IR through Update-IR -> Select-DR-Scan -> Capture-DR
    //					                 TMS=1        TMS=1             TMS=0
    
    byOutputBuffer[dwNumBytesToSend++] = 0x4B;	// Don't read data in Update-IR -> Select-DR-Scan -> Capture-DR
    byOutputBuffer[dwNumBytesToSend++] = 0x03;	// Number of clock pulses = Length + 1 (4 clocks here)
    byOutputBuffer[dwNumBytesToSend++] = 0x83;	// Data is shifted LSB first, so the TMS pattern is 110
    ftStatus = FT_Write(ftHandle, byOutputBuffer, dwNumBytesToSend, &dwNumBytesSent);  // Send off the TMS command
    dwNumBytesToSend = 0;	// Reset output buffer pointer
    

    JTAG状态机转换(Shift-DR

    // TMS is currently low.  State machine is in Shift-DR, so now use the TDI/TDO command to shift 101 out TDI/DO while reading TDO/DI
    // Although 3 bits need shifted in, only 2 are clocked here.  The 3rd will be in conjunciton with a TMS command, coming next
    byOutputBuffer[dwNumBytesToSend++] = 0x3B;	// Clock data out throuth states Shift-DR and Exit-DR.
    byOutputBuffer[dwNumBytesToSend++] = 0x01;	// Number of clock pulses = Length + 1 (2 clocks here)
    byOutputBuffer[dwNumBytesToSend++] = 0x01;	// Shift out 101 (ignore last bit)
    ftStatus = FT_Write(ftHandle, byOutputBuffer, dwNumBytesToSend, &dwNumBytesSent); 	// Send off the TMS command
    dwNumBytesToSend = 0;			// Reset output buffer pointer
    

    JTAG状态机转换(Exit 1-DR

    // Here is the TMS command for one clock.  Data is also shifted in.
    byOutputBuffer[dwNumBytesToSend++] = 0x6B;	// Clock out TMS, Read one bit.
    byOutputBuffer[dwNumBytesToSend++] = 0x00;	// Number of clock pulses = Length + 0 (1 clock here)
    byOutputBuffer[dwNumBytesToSend++] = 0x83;		// Data is shifted LSB first, so TMS becomes 1.  Also, bit 7 is shifted into TDI/DO, also a 1
    									            // The 1 in bit 1 will leave TMS high for the next commands.
    ftStatus = FT_Write(ftHandle, byOutputBuffer, dwNumBytesToSend, &dwNumBytesSent); 	// Send off the TMS command
    dwNumBytesToSend = 0;			// Reset output buffer pointer
    

    JTAG状态机转换(Exit 1-DR->Update-DR->Select-DR-Scan -> Select-IR-Scan -> Test Logic Reset

    // Navigage TMS through Update-DR -> Select-DR-Scan -> Select-IR-Scan -> Test Logic Reset
    // TMS=1        TMS=1             TMS=1             TMS=1
    
    byOutputBuffer[dwNumBytesToSend++] = 0x4B;		// Don't read data in Update-DR -> Select-DR-Scan -> Select-IR-Scan -> Test Logic Reset
    byOutputBuffer[dwNumBytesToSend++] = 0x03;  	// Number of clock pulses = Length + 1 (4 clocks here)
    byOutputBuffer[dwNumBytesToSend++] = 0xFF;		// Data is shifted LSB first, so the TMS pattern is 101100
    ftStatus = FT_Write(ftHandle, byOutputBuffer, dwNumBytesToSend, &dwNumBytesSent); 	// Send off the TMS command
    dwNumBytesToSend = 0;			// Reset output buffer pointer
    

    直至JTAG的状态机转换基本就结束了,大家可以将代码片段有序组合,按照要求嵌入到GUI应用程序。

    洗锅刷碗

    关于FT2232H的Visual Studio环境下C++编程基本就是看完了,大家可以在FTDI官网下载到AN-129的应用笔记以及HS_JTAG_MPSEE_Source的工程源代码。建议亲自实操测试,最好可以使用Demo板卡和示波器亲自调试。

    展开全文
  • SC2232数据手册_V1.4.pdf

    2020-05-29 13:39:26
    思特威sc2232h数据手册 ,海思SDK下自带驱动,
  • FT2232H MPSSE JTAG例程代码分析

    千次阅读 2020-04-10 12:29:13
    FT2232H MPSSE JTAG例程代码分析 /* AN_129_HS_JTAG_with_MPSSE.cpp : Defines the entry point for the console application. */ /* @Desc:包含必要的头文件 */ #include "stdafx.h" #include <windows.h>...

    FT2232H MPSSE JTAG例程代码分析

    /* 
    AN_129_HS_JTAG_with_MPSSE.cpp : Defines the entry point for the console application.
    */
    
    /*
    @Desc:包含必要的头文件
    */
    #include "stdafx.h"
    #include <windows.h>
    #include <stdio.h>
    #include "ftd2xx.h"
    
    /*
    @Desc:Main Function
    */
    int _tmain(int argc, _TCHAR* argv[])
    {
    	FT_HANDLE ftHandle;				// Handle of the FTDI device
    	FT_STATUS ftStatus;				// Result of each D2XX call
    	
    	DWORD dwNumDevs;				// The number of devices
    	unsigned int uiDevIndex = 0xF;	// The device in the list that we'll use
    
    	BYTE byOutputBuffer[1024];		// Buffer to hold MPSSE commands and data to be sent to the FT2232H
    	BYTE byInputBuffer[1024];		// Buffer to hold data read from the FT2232H
    
    	DWORD dwCount = 0;				// General loop index
    	DWORD dwNumBytesToSend = 0;		// Index to the output buffer
    	DWORD dwNumBytesSent = 0;		// Count of actual bytes sent - used with FT_Write
    	DWORD dwNumBytesToRead = 0;		// Number of bytes available to read in the driver's input buffer
    	DWORD dwNumBytesRead = 0;		// Count of actual bytes read - used with FT_Read
    
    	DWORD dwClockDivisor = 0x05DB;	// Value of clock divisor, SCL Frequency = 60/((1+0x05DB)*2) (MHz) = 20khz
    
    	// Does an FTDI device exist?
    
    	printf("Checking for FTDI devices...\n");
    	
    	ftStatus = FT_CreateDeviceInfoList(&dwNumDevs);
    									// Get the number of FTDI devices
    	if (ftStatus != FT_OK)			// Did the command execute OK?
    	{
    		printf("Error in getting the number of devices\n");
    		return 1;					// Exit with error
    	}
    
    	if (dwNumDevs < 1)				// Exit if we don't see any
    	{
    		printf("There are no FTDI devices installed\n");
    		return 1;					// Exist with error
    	}
    /*
    	printf("%d FTDI devices found - the count includes individual ports on a single chip\n", dwNumDevs);
    
    	FT_HANDLE ftHandleTemp; 
    	DWORD numDevs; 
    	DWORD Flags;
    	DWORD ID; 
    	DWORD Type; 
    	DWORD LocId; 
    	char SerialNumber[16]; 
    	char Description[64];
    
    	ftStatus = FT_GetDeviceInfoDetail(3, &Flags, &Type, &ID, &LocId, SerialNumber, Description, &ftHandleTemp);
    
    */
    
    
    	// Open the port - For this application note, we'll assume the first device is a FT2232H or FT4232H
    	// Further checks can be made against the device descriptions, locations, serial numbers, etc. 
    	// before opening the port.
    
    	printf("\nAssume first device has the MPSSE and open it...\n");
    
    	ftStatus = FT_Open(0, &ftHandle);
    	if (ftStatus != FT_OK)
    	{
    		printf("Open Failed with error %d\n", ftStatus);
    		return 1;					// Exit with error
    	}	
    	
    	// Configure port parameters
    	
    	printf("\nConfiguring port for MPSSE use...\n");
    
    	ftStatus |= FT_ResetDevice(ftHandle); 
    									//Reset USB device
    	
    	//Purge USB receive buffer first by reading out all old data from FT2232H receive buffer
    	ftStatus |= FT_GetQueueStatus(ftHandle, &dwNumBytesToRead); 
    									// Get the number of bytes in the FT2232H receive buffer
    	if ((ftStatus == FT_OK) && (dwNumBytesToRead > 0))
    		FT_Read(ftHandle, &byInputBuffer, dwNumBytesToRead, &dwNumBytesRead); 
    									//Read out the data from FT2232H receive buffer
    	ftStatus |= FT_SetUSBParameters(ftHandle, 65536, 65535); 
    									//Set USB request transfer sizes to 64K
    	ftStatus |= FT_SetChars(ftHandle, false, 0, false, 0); 
    									//Disable event and error characters
    	ftStatus |= FT_SetTimeouts(ftHandle, 0, 5000); 
    									//Sets the read and write timeouts in milliseconds 
    	ftStatus |= FT_SetLatencyTimer(ftHandle, 16); 
    									//Set the latency timer (default is 16mS)
    	ftStatus |= FT_SetBitMode(ftHandle, 0x0, 0x00); 
    									//Reset controller
    	ftStatus |= FT_SetBitMode(ftHandle, 0x0, 0x02); 
    									//Enable MPSSE mode
    	if (ftStatus != FT_OK)
    	{
    		printf("Error in initializing the MPSSE %d\n", ftStatus);
    		FT_Close(ftHandle);
    		return 1;					// Exit with error
    	}	
    
    	Sleep(50); // Wait for all the USB stuff to complete and work		
    
    	/* 
    	// -----------------------------------------------------------
    	// At this point, the MPSSE is ready for commands
    	// -----------------------------------------------------------
    	*/
    
    	/* 
    	// -----------------------------------------------------------
    	// Synchronize the MPSSE by sending a bogus opcode (0xAA), 
    	//		The MPSSE will respond with "Bad Command" (0xFA) followed by
    	//		the bogus opcode itself.
    	// -----------------------------------------------------------
    	*/
    	byOutputBuffer[dwNumBytesToSend++] = 0xAA;//'\xAA';
    									//Add bogus command 憍AA?to the queue
    	ftStatus = FT_Write(ftHandle, byOutputBuffer, dwNumBytesToSend, &dwNumBytesSent); 
    									// Send off the BAD commands
    	dwNumBytesToSend = 0;			// Reset output buffer pointer
    	do
    	{
    		ftStatus = FT_GetQueueStatus(ftHandle, &dwNumBytesToRead); 
    									// Get the number of bytes in the device input buffer
    	} while ((dwNumBytesToRead == 0) && (ftStatus == FT_OK)); 
    									//or Timeout
    
    	bool bCommandEchod = false;
    	
    	ftStatus = FT_Read(ftHandle, &byInputBuffer, dwNumBytesToRead, &dwNumBytesRead); 
    									//Read out the data from input buffer
    	for (dwCount = 0; dwCount < dwNumBytesRead - 1; dwCount++) 
    									//Check if Bad command and echo command received
    	{
    		if ((byInputBuffer[dwCount] == 0xFA) && (byInputBuffer[dwCount+1] == 0xAA))
    		{
    			bCommandEchod = true;
    			break;
    		}
    	}
    	if (bCommandEchod == false)
    	{
    		printf("Error in synchronizing the MPSSE\n");
    		FT_Close(ftHandle);
    		return 1;					// Exit with error
    	}	
    
    	/* 
    	// -----------------------------------------------------------
    	// Configure the MPSSE settings for JTAG
    	//		Multple commands can be sent to the MPSSE with one FT_Write
    	// -----------------------------------------------------------
    	*/
    	dwNumBytesToSend = 0;			// Start with a fresh index
    	
    
    	// Set up the Hi-Speed specific commands for the FTx232H
    
    	byOutputBuffer[dwNumBytesToSend++] = 0x8A;
    									// Use 60MHz master clock (disable divide by 5)
    	byOutputBuffer[dwNumBytesToSend++] = 0x97;
    									// Turn off adaptive clocking (may be needed for ARM)
    	byOutputBuffer[dwNumBytesToSend++] = 0x8D;
    									// Disable three-phase clocking
    	ftStatus = FT_Write(ftHandle, byOutputBuffer, dwNumBytesToSend, &dwNumBytesSent); 
    									// Send off the HS-specific commands
    	
    	dwNumBytesToSend = 0;			// Reset output buffer pointer
    	
    	// Set initial states of the MPSSE interface - low byte, both pin directions and output values
    	//		Pin name	Signal	Direction	Config	Initial State	Config
    	//		ADBUS0		TCK		output		1		low				0
    	//		ADBUS1		TDI		output		1		low				0
    	//		ADBUS2		TDO		input		0						0
    	//		ADBUS3		TMS		output		1		high			1
    	//		ADBUS4		GPIOL0	input		0						0
    	//		ADBUS5		GPIOL1	input		0						0
    	//		ADBUS6		GPIOL2	input		0						0
    	//		ADBUS7		GPIOL3	input		0						0
    			
    	byOutputBuffer[dwNumBytesToSend++] = 0x80;
    									// Set data bits low-byte of MPSSE port
    	byOutputBuffer[dwNumBytesToSend++] = 0x08;
    									// Initial state config above
    	byOutputBuffer[dwNumBytesToSend++] = 0x0B;
    									// Direction config above
    	
    	ftStatus = FT_Write(ftHandle, byOutputBuffer, dwNumBytesToSend, &dwNumBytesSent); 
    									// Send off the low GPIO config commands
    
    	dwNumBytesToSend = 0;			// Reset output buffer pointer
    
    
    	// Set initial states of the MPSSE interface - high byte, both pin directions and output values
    	//		Pin name	Signal	Direction	Config	Initial State	Config
    	//		ACBUS0		GPIOH0	input		0						0
    	//		ACBUS1		GPIOH1	input		0						0
    	//		ACBUS2		GPIOH2	input		0						0
    	//		ACBUS3		GPIOH3	input		0						0
    	//		ACBUS4		GPIOH4	input		0						0
    	//		ACBUS5		GPIOH5	input		0						0
    	//		ACBUS6		GPIOH6	input		0						0
    	//		ACBUS7		GPIOH7	input		0						0
    
    	byOutputBuffer[dwNumBytesToSend++] = 0x82;
    									// Set data bits low-byte of MPSSE port
    	byOutputBuffer[dwNumBytesToSend++] = 0x00;
    									// Initial state config above
    	byOutputBuffer[dwNumBytesToSend++] = 0x00;
    									// Direction config above
    
    	ftStatus = FT_Write(ftHandle, byOutputBuffer, dwNumBytesToSend, &dwNumBytesSent); 
    									// Send off the high GPIO config commands
    
    	dwNumBytesToSend = 0;			// Reset output buffer pointer
    	
    	// Set TCK frequency 
    	// TCK = 60MHz /((1 + [(1 +0xValueH*256) OR 0xValueL])*2)
    
    	byOutputBuffer[dwNumBytesToSend++] = '\x86'; 
    									//Command to set clock divisor
    	byOutputBuffer[dwNumBytesToSend++] = dwClockDivisor & 0xFF; 
    									//Set 0xValueL of clock divisor
    	byOutputBuffer[dwNumBytesToSend++] = (dwClockDivisor >> 8) & 0xFF; 
    									//Set 0xValueH of clock divisor
    	ftStatus = FT_Write(ftHandle, byOutputBuffer, dwNumBytesToSend, &dwNumBytesSent); 
    									// Send off the clock divisor commands
    
    	dwNumBytesToSend = 0;			// Reset output buffer pointer
    
    
    	// Disable internal loop-back
    
    	byOutputBuffer[dwNumBytesToSend++] = 0x85;
    									// Disable loopback
    
    	ftStatus = FT_Write(ftHandle, byOutputBuffer, dwNumBytesToSend, &dwNumBytesSent); 
    									// Send off the loopback command
    
    	dwNumBytesToSend = 0;			// Reset output buffer pointer
    
    	
    	// Navigage TMS through Test-Logic-Reset -> Run-Test-Idle -> Select-DR-Scan -> Select-IR-Scan
    	//                      TMS=1               TMS=0            TMS=1             TMS=1
    
    	byOutputBuffer[dwNumBytesToSend++] = 0x4B;
    									// Don't read data in Test-Logic-Reset, Run-Test-Idle, Select-DR-Scan, Select-IR-Scan
    	byOutputBuffer[dwNumBytesToSend++] = 0x05;
    									// Number of clock pulses = Length + 1 (6 clocks here)
    	byOutputBuffer[dwNumBytesToSend++] = 0x0D;
    									// Data is shifted LSB first, so the TMS pattern is 101100
    	ftStatus = FT_Write(ftHandle, byOutputBuffer, dwNumBytesToSend, &dwNumBytesSent); 
    									// Send off the TMS command
    	dwNumBytesToSend = 0;			// Reset output buffer pointer
    
    	// TMS is currently low.  State machine is in Shift-IR, so now use the TDI/TDO command to shift 1's out TDI/DO while reading TDO/DI
    	// Although 8 bits need shifted in, only 7 are clocked here.  The 8th will be in conjunciton with a TMS command, coming next
    
    	byOutputBuffer[dwNumBytesToSend++] = 0x3B;
    									// Clock data out throuth states Capture-IR, Shift-IR and Exit-IR, read back result
    	byOutputBuffer[dwNumBytesToSend++] = 0x06;
    									// Number of clock pulses = Length + 1 (7 clocks here)
    	byOutputBuffer[dwNumBytesToSend++] = 0xFF;
    									// Shift out 1111111 (ignore last bit)
    	ftStatus = FT_Write(ftHandle, byOutputBuffer, dwNumBytesToSend, &dwNumBytesSent); 
    									// Send off the TMS command
    	dwNumBytesToSend = 0;			// Reset output buffer pointer
    
    
    	// Here is the TMS command for one clock.  Data is also shifted in.
    
    	byOutputBuffer[dwNumBytesToSend++] = 0x6B;
    									// Clock out TMS, Read one bit.
    	byOutputBuffer[dwNumBytesToSend++] = 0x00;
    									// Number of clock pulses = Length + 0 (1 clock here)
    	byOutputBuffer[dwNumBytesToSend++] = 0x83;
    									// Data is shifted LSB first, so TMS becomes 1.  Also, bit 7 is shifted into TDI/DO, also a 1
    									// The 1 in bit 1 will leave TMS high for the next commands.
    	ftStatus = FT_Write(ftHandle, byOutputBuffer, dwNumBytesToSend, &dwNumBytesSent); 
    									// Send off the TMS command
    	dwNumBytesToSend = 0;			// Reset output buffer pointer
    
    
    	// Navigage TMS from Exit-IR through Update-IR -> Select-DR-Scan -> Capture-DR
    	//					                 TMS=1        TMS=1             TMS=0
    
    	byOutputBuffer[dwNumBytesToSend++] = 0x4B;
    									// Don't read data in Update-IR -> Select-DR-Scan -> Capture-DR
    	byOutputBuffer[dwNumBytesToSend++] = 0x03;
    									// Number of clock pulses = Length + 1 (4 clocks here)
    	byOutputBuffer[dwNumBytesToSend++] = 0x83;
    									// Data is shifted LSB first, so the TMS pattern is 110
    	ftStatus = FT_Write(ftHandle, byOutputBuffer, dwNumBytesToSend, &dwNumBytesSent); 
    									// Send off the TMS command
    	dwNumBytesToSend = 0;			// Reset output buffer pointer
    
    	// TMS is currently low.  State machine is in Shift-DR, so now use the TDI/TDO command to shift 101 out TDI/DO while reading TDO/DI
    	// Although 3 bits need shifted in, only 2 are clocked here.  The 3rd will be in conjunciton with a TMS command, coming next
    
    	byOutputBuffer[dwNumBytesToSend++] = 0x3B;
    									// Clock data out throuth states Shift-DR and Exit-DR.
    	byOutputBuffer[dwNumBytesToSend++] = 0x01;
    									// Number of clock pulses = Length + 1 (2 clocks here)
    	byOutputBuffer[dwNumBytesToSend++] = 0x01;
    									// Shift out 101 (ignore last bit)
    	ftStatus = FT_Write(ftHandle, byOutputBuffer, dwNumBytesToSend, &dwNumBytesSent); 
    									// Send off the TMS command
    	dwNumBytesToSend = 0;			// Reset output buffer pointer
    
    	// Here is the TMS command for one clock.  Data is also shifted in.
    
    	byOutputBuffer[dwNumBytesToSend++] = 0x6B;
    									// Clock out TMS, Read one bit.
    	byOutputBuffer[dwNumBytesToSend++] = 0x00;
    									// Number of clock pulses = Length + 0 (1 clock here)
    	byOutputBuffer[dwNumBytesToSend++] = 0x83;
    									// Data is shifted LSB first, so TMS becomes 1.  Also, bit 7 is shifted into TDI/DO, also a 1
    									// The 1 in bit 1 will leave TMS high for the next commands.
    	ftStatus = FT_Write(ftHandle, byOutputBuffer, dwNumBytesToSend, &dwNumBytesSent); 
    									// Send off the TMS command
    	dwNumBytesToSend = 0;			// Reset output buffer pointer
    
    		
    	// Navigage TMS through Update-DR -> Select-DR-Scan -> Select-IR-Scan -> Test Logic Reset
    	//                      TMS=1        TMS=1             TMS=1             TMS=1
    
    	byOutputBuffer[dwNumBytesToSend++] = 0x4B;
    									// Don't read data in Update-DR -> Select-DR-Scan -> Select-IR-Scan -> Test Logic Reset
    	byOutputBuffer[dwNumBytesToSend++] = 0x03;
    									// Number of clock pulses = Length + 1 (4 clocks here)
    	byOutputBuffer[dwNumBytesToSend++] = 0xFF;
    									// Data is shifted LSB first, so the TMS pattern is 101100
    	ftStatus = FT_Write(ftHandle, byOutputBuffer, dwNumBytesToSend, &dwNumBytesSent); 
    									// Send off the TMS command
    	dwNumBytesToSend = 0;			// Reset output buffer pointer
    
    	do
    	{
    		ftStatus = FT_GetQueueStatus(ftHandle, &dwNumBytesToRead); 
    									// Get the number of bytes in the device input buffer
    	} while ((dwNumBytesToRead == 0) && (ftStatus == FT_OK)); 
    									//or Timeout
    
    	ftStatus = FT_Read(ftHandle, &byInputBuffer, dwNumBytesToRead, &dwNumBytesRead); 
    									//Read out the data from input buffer
    
    	printf("\n");
    	printf("TI SN74BCT8244A IR default value is 0x81\n");
    	printf("The value scanned by the FT2232H is 0x%x\n", byInputBuffer[dwNumBytesRead - 3]);
    	printf("\n");
    	printf("TI SN74BCT8244A DR bypass expected data is 00000010 = 0x2\n");
    	printf("                   The value scanned by the FT2232H = 0x%x\n", (byInputBuffer[dwNumBytesRead-1] >> 5));
    
    	// Generate a clock while in Test-Logic-Reset
    	// This will not do anything with the TAP in the Test-Logic-Reset state, 
    	//		but will demonstrate generation of clocks without any data transfer
    
    	byOutputBuffer[dwNumBytesToSend++] = 0x8F;
    									// Generate clock pulses
    	byOutputBuffer[dwNumBytesToSend++] = 0x02;
    									// (0x0002 + 1) * 8 = 24 clocks
    	byOutputBuffer[dwNumBytesToSend++] = 0x00;
    									// 
    
    	ftStatus = FT_Write(ftHandle, byOutputBuffer, dwNumBytesToSend, &dwNumBytesSent); 
    									// Send off the clock commands
    
    	dwNumBytesToSend = 0;			// Reset output buffer pointer
    
    
    
    	/* 
    	// -----------------------------------------------------------
    	// Start closing everything down
    	// -----------------------------------------------------------
    	*/
    
    	printf("\nJTAG program executed successfully.\n");
    	printf("Press <Enter> to continue\n");
    	getchar();						// wait for a carriage return
    
    	FT_Close(ftHandle);				// Close the port
    
    	return 0;						// Exit with success
    }
    
    
    展开全文
  • USB转串口双向转换芯片FT2232H

    万次阅读 2012-08-05 23:08:13
    FT2232H是USB/RS232双向转换器,支持480 Mb/s的USB 2.0高速规范,提供2个支持USB 2.0高速规范且可配置的并行/串行接口,并且内部集成有USB协议,无须编写USB固件程序。
  • hdu2232 机器人的舞蹈

    千次阅读 2011-03-22 21:20:00
    <br />机器人的舞蹈 Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 69 Accepted Submission(s): 39 <br />Problem...
  • 题目 给出两个数a,ba,ba,b,求出[a,b][a,b][a,b]中各位数字之和能整除原数的数的个数。 ...设f[i][s][m][0/1]为前i位,和为s,这个数modsum=m,0表示没卡上界,1表示...设f[i][s][m][0/1]为前i位,和为s,这个数\m...
  • Song Jiang's rank listTime Limit: 2000/1000 MS (Java/Others) Memory Limit: 512000/512000 K (Java/Others)Total Submission(s): 2232 Accepted Submission(s): 1231Problem Description《Shui Hu Zhuan》,a....
  • FT2232 驱动程序版本

    千次阅读 2010-06-13 15:04:00
    FT Dual USB UART/FIFO. 用了两个星期的 2.06.00 (October 22, 2009) 版本,在winxp和windows7电脑上每天都会死机一到三次。...On making a new release the files will be posted on FTDI’s web site h...
  • FTDI FT2232H在嵌入式教学中的应用

    千次阅读 2018-03-14 14:30:27
    作为第五代USB协议转串行总线通信协议的芯片,完全符合USB2.0规范(480Mb/s)并且可以依靠编程的方式配置成为串行或者并行的其他总线接口规范。这对于在进行嵌入式教学是的传感器总线仿真是非常方便的,甚至可以作为...
  • Time Limit: 1000/1000 MS (Java/Others)Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 292Accepted Submission(s): 154 Problem Description 一天四个不同的机器人a、b、c和d在一张跳舞毯上...
  • 全新FT2232H USB2.0 数据采集方案 ...核心板主芯片为FT2232H , USB2.0 接口芯片,经过我们测试,速度可达40MBYTE/S。 核心板将所有的芯片管脚全部引出,非常方便大家二次开发使用。 ...
  • FZU 2232 炉石传说(二分图最大匹配)
  • 表示对手的n个随从,ci表示随从生命,di表示随从攻击力。 Output 每组数据,根据GG是否能完成他的目标,输出一行”Yes”或”No”。 Sample Input 2 3 4 4 5 5 6 6 1 1 2 2 3 3 3 ...
  • FT232H FT2232H FT4232H

    2015-09-17 21:39:00
    The FT232H is the single channel version, the FT2232H is the dual-channel, and there is also anFT4232Hquad channel part. While these are all logically the same, with different numbers of UART cha...
  • 石头剪刀布,每个人出什么已知,你可以决定他们游戏的顺序,有多少人有可能赢 分情况:1:对于石头剪刀布都有的情况,这个值是n ... 1 program pku2232(input,output); 2 var 3 n,i :longint; ...
  • N个小朋友围成一圈。,S代表石头,F代表剪刀,C代表布,小朋友A起立与逆时针与其它小朋友比较,输的出圈,直到只剩下一人为赢家。求可能的赢家数。
  • FT2232C型USB UARTFIFO电路的特征

    千次阅读 2007-06-03 16:45:00
    一: FT2232C介绍1.1 电路概览FT2232C是一款USB到UART/FIFO的转换电路,是FTDI公司继第二代FT232BM、FT245BM之后的第三代产品,集成了两片BM...一个USB下游端口转换成两个I/O通道,每个I/O通道相当一个FT232BM或FT245
  • ov_ftdi 这是(基于FTDI的)OpenVizsla 3.x USB协议跟踪程序的主要存储库。...如果在复制udev规则之前已插入板子,请拔下它,然后再插回去,或者运行sudo udevadm trigger -s usb -c add 。 要捕获USB流量,您需
  • 题目链接:http://poj.org/problem?id=2232 题目描述: 一些人围成一圈,输入他们此时的手势(石头、剪刀、布),每次选择一个人A,那个人与他逆时针B比较手势,输得淘汰,若一样,B淘汰,每次A的选择是随机的,...
  • HDOJ-2232 误打误撞..构造矩阵..

    千次阅读 2012-04-03 02:58:03
    后来发现了2232和2238的描述几乎一模一样..就往2232交..结果就AC了..很蛋疼啊...不清楚机器人相同和机器人不同到底有何区别...  回到这题..关键就是构造矩阵...这里实际上就是要构造各个状之间态经过一次转移能...
  • 题目链接:http://acm.fzu.edu.cn/problem.php?pid=2232 Description GG学长虽然并不打炉石传说,但是由于题面需要他便学会了打炉石传说。但是传统的炉石传说对于刚入门的GG学长来说有点复杂,所以他决定...
  • 提交:2232 解决:547 题目描述:输入一个递增排序的数组和一个数字S,在数组中查找两个数,是的他们的和正好是S,如果有多对数字的和等于S,输出两个数的乘积最小的。 输入: 每个测试案例包括两行:...
  • JLink的调试功能、烧写Flash的功能都很强大,但是对于S3C2410、S3C2440的Flash操作有些麻烦:烧写Nor Flash时需要设置SDRAM,否则速率很慢;烧写Nand Flash只是从理论上能够达到,但是还没有人直接实现这点。 本文...
  • http://acm.fzu.edu.cn/problem.php?pid=2232 #include #include #include #pragma warning (disable: 4996) using namespace std; const int maxn = 1005; const int maxm = 10005; struct edge...
  • Problem 2232 炉石传说 Accept: 19 Submit: 49 Time Limit: 1000 mSec Memory Limit : 32768 KB  Problem Description GG学长虽然并不打炉石传说,但是由于题面需要他便学

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 3,460
精华内容 1,384
关键字:

s2232i