PaulStoffregen / USBHost_t36

USB Host Library for Teensy 3.6 and 4.0
170 stars 87 forks source link

FTDI Baudrate calculation issue #45

Open ziv2013 opened 3 years ago

ziv2013 commented 3 years ago

Hi,

When I tried to use USB Host on a FTDI dongle, I found 9600 baudrate can't work.

And after I modified code as below, it can work

    // set baud rate
    if (pending_control & 2) {
        pending_control &= ~2;
        uint32_t baudval = 3000000 / baudrate;
        //Zoologsit mk_setup(setup, 0x40, 3, baudval, 0, 0);
                    baudval=0x4138; //Zoologsit 
                    mk_setup(setup, 0x40, 3, baudval, 0, 0);
        queue_Control_Transfer(device, &setup, NULL, this);
        control_queued = true;
        return;
    }

The value "0x4138" is calculated with below code(copied from USB Host Library)

uint8_t FTDI::SetBaudRate(uint32_t baud) { uint16_t baud_value, baud_index = 0; uint32_t divisor3; divisor3 = 48000000 / 2 / baud; // divisor shifted 3 bits to the left

    if(wFTDIType == FT232AM) {
            if((divisor3 & 0x7) == 7)
                    divisor3++; // round x.7/8 up to x+1

            baud_value = divisor3 >> 3;
            divisor3 &= 0x7;

            if(divisor3 == 1) baud_value |= 0xc000;
            else // 0.125
                    if(divisor3 >= 4) baud_value |= 0x4000;
            else // 0.5
                    if(divisor3 != 0) baud_value |= 0x8000; // 0.25
            if(baud_value == 1) baud_value = 0; /* special case for maximum baud rate */
    } else {
            static const uint8_t divfrac [8] = {0, 3, 2, 0, 1, 1, 2, 3};
            static const uint8_t divindex[8] = {0, 0, 0, 1, 0, 1, 1, 1};

            baud_value = divisor3 >> 3;
            baud_value |= divfrac [divisor3 & 0x7] << 14;
            baud_index = divindex[divisor3 & 0x7];

            /* Deal with special cases for highest baud rates. */
            if(baud_value == 1) baud_value = 0;
            else // 1.0
                    if(baud_value == 0x4001) baud_value = 1; // 1.5
    }
    USBTRACE2("baud_value:", baud_value);
    USBTRACE2("baud_index:", baud_index);
    uint8_t rv = pUsb->ctrlReq(bAddress, 0, bmREQ_FTDI_OUT, FTDI_SIO_SET_BAUD_RATE, baud_value & 0xff, baud_value >> 8, baud_index, 0, 0, NULL, NULL);
    if(rv && rv != hrNAK) {
            Release();
    }
    return rv;

}

So could you fix the way you calculate the value for setting baud rate?

Thanks,

Zoologist