src/app/host-serial/libftdi/ftdi.c
static int ftdi_to_clkbits_AM(int baudrate, unsigned long *encoded_divisor)

{
    static const char frac_code[8] = {0, 3, 2, 4, 1, 5, 6, 7};
    static const char am_adjust_up[8] = {0, 0, 0, 1, 0, 3, 2, 1};
    static const char am_adjust_dn[8] = {0, 0, 0, 1, 0, 1, 2, 3};
    int divisor, best_divisor, best_baud, best_baud_diff;
    int i;
    divisor = 24000000 / baudrate;

    // Round down to supported fraction (AM only)
    divisor -= am_adjust_dn[divisor & 7];

    // Try this divisor and the one above it (because division rounds down)
    best_divisor = 0;
    best_baud = 0;
    best_baud_diff = 0;
    for (i = 0; i < 2; i++)
    {
        int try_divisor = divisor + i;
        int baud_estimate;
        int baud_diff;

        // Round up to supported divisor value
        if (try_divisor <= 8)
        {
            // Round up to minimum supported divisor
            try_divisor = 8;
        }
        else if (divisor < 16)
        {
            // AM doesn't support divisors 9 through 15 inclusive
            try_divisor = 16;
        }
        else
        {
            // Round up to supported fraction (AM only)
            try_divisor += am_adjust_up[try_divisor & 7];
            if (try_divisor > 0x1FFF8)
            {
                // Round down to maximum supported divisor value (for AM)
                try_divisor = 0x1FFF8;
            }
        }
        // Get estimated baud rate (to nearest integer)
        baud_estimate = (24000000 + (try_divisor / 2)) / try_divisor;
        // Get absolute difference from requested baud rate
        if (baud_estimate < baudrate)
        {
            baud_diff = baudrate - baud_estimate;
        }
        else
        {
            baud_diff = baud_estimate - baudrate;
        }
        if (i == 0 || baud_diff < best_baud_diff)
        {
            // Closest to requested baud rate so far
            best_divisor = try_divisor;
            best_baud = baud_estimate;
            best_baud_diff = baud_diff;
            if (baud_diff == 0)
            {
                // Spot on! No point trying
                break;
            }
        }
    }
    // Encode the best divisor value
    *encoded_divisor = (best_divisor >> 3) | (frac_code[best_divisor & 7] << 14);
    // Deal with special cases for encoded value
    if (*encoded_divisor == 1)
    {
        *encoded_divisor = 0;    // 3000000 baud
    }
    else if (*encoded_divisor == 0x4001)
    {
        *encoded_divisor = 1;    // 2000000 baud (BM only)
    }
    return best_baud;
}
/*  ftdi_to_clkbits_AM For the AM device, convert a requested baudrate
                    to encoded divisor and the achievable baudrate
    Function is only used internally
    \internal

    See AN120
   clk/1   -> 0
   clk/1.5 -> 1
   clk/2   -> 2
   From /2, 0.125/ 0.25 and 0.5 steps may be taken
   The fractional part has frac_code encoding
*/
ftdi_to_clkbits_AM For the AM device, convert a requested baudrate
to encoded divisor and the achievable baudrate
Function is only used internally
\internal


ftdi_to_clkbits_AM For the AM device convert a requested baudrate to encoded divisor and the achievable baudrate Function is only used internally \ internal
static int ftdi_to_clkbits_AM(int baudrate, unsigned long *encoded_divisor)
{
    static const char frac_code[8] = {0, 3, 2, 4, 1, 5, 6, 7};
    static const char am_adjust_up[8] = {0, 0, 0, 1, 0, 3, 2, 1};
    static const char am_adjust_dn[8] = {0, 0, 0, 1, 0, 1, 2, 3};
    int divisor, best_divisor, best_baud, best_baud_diff;
    int i;
    divisor = 24000000 / baudrate;
    divisor -= am_adjust_dn[divisor & 7];
    best_divisor = 0;
    best_baud = 0;
    best_baud_diff = 0;
    for (i = 0; i < 2; i++)
    {
        int try_divisor = divisor + i;
        int baud_estimate;
        int baud_diff;
        if (try_divisor <= 8)
        {
            try_divisor = 8;
        }
        else if (divisor < 16)
        {
            try_divisor = 16;
        }
        else
        {
            try_divisor += am_adjust_up[try_divisor & 7];
            if (try_divisor > 0x1FFF8)
            {
                try_divisor = 0x1FFF8;
            }
        }
        baud_estimate = (24000000 + (try_divisor / 2)) / try_divisor;
        if (baud_estimate < baudrate)
        {
            baud_diff = baudrate - baud_estimate;
        }
        else
        {
            baud_diff = baud_estimate - baudrate;
        }
        if (i == 0 || baud_diff < best_baud_diff)
        {
            best_divisor = try_divisor;
            best_baud = baud_estimate;
            best_baud_diff = baud_diff;
            if (baud_diff == 0)
            {
                break;
            }
        }
    }
    *encoded_divisor = (best_divisor >> 3) | (frac_code[best_divisor & 7] << 14);
    if (*encoded_divisor == 1)
    {
        *encoded_divisor = 0;    
    }
    else if (*encoded_divisor == 0x4001)
    {
        *encoded_divisor = 1;    
    }
    return best_baud;
}
static int ftdi_to_clkbits_AM ( int baudrate , unsigned long * encoded_divisor ) { static const char frac_code [ 8 ] = { 0 , 3 , 2 , 4 , 1 , 5 , 6 , 7 } ; static const char am_adjust_up [ 8 ] = { 0 , 0 , 0 , 1 , 0 , 3 , 2 , 1 } ; static const char am_adjust_dn [ 8 ] = { 0 , 0 , 0 , 1 , 0 , 1 , 2 , 3 } ; int divisor , best_divisor , best_baud , best_baud_diff ; int i ; divisor = 24000000 / baudrate ; divisor -= am_adjust_dn [ divisor & 7 ] ; best_divisor = 0 ; best_baud = 0 ; best_baud_diff = 0 ; for ( i = 0 ; i < 2 ; i ++ ) { int try_divisor = divisor + i ; int baud_estimate ; int baud_diff ; if ( try_divisor <= 8 ) { try_divisor = 8 ; } else if ( divisor < 16 ) { try_divisor = 16 ; } else { try_divisor += am_adjust_up [ try_divisor & 7 ] ; if ( try_divisor > 0x1FFF8 ) { try_divisor = 0x1FFF8 ; } } baud_estimate = ( 24000000 + ( try_divisor / 2 ) ) / try_divisor ; if ( baud_estimate < baudrate ) { baud_diff = baudrate - baud_estimate ; } else { baud_diff = baud_estimate - baudrate ; } if ( i == 0 || baud_diff < best_baud_diff ) { best_divisor = try_divisor ; best_baud = baud_estimate ; best_baud_diff = baud_diff ; if ( baud_diff == 0 ) { break ; } } } * encoded_divisor = ( best_divisor >> 3 ) | ( frac_code [ best_divisor & 7 ] << 14 ) ; if ( * encoded_divisor == 1 ) { * encoded_divisor = 0 ; } else if ( * encoded_divisor == 0x4001 ) { * encoded_divisor = 1 ; } return best_baud ; }
ftdi_to_clkbits_AM For the AM device, convert a requested baudrate
to encoded divisor and the achievable baudrate
Function is only used internally
\internal
ftdi_to_clkbits_AM For the AM device convert a requested baudrate to encoded divisor and the achievable baudrate Function is only used internally \ internal
// Round down to supported fraction (AM only) // Try this divisor and the one above it (because division rounds down) // Round up to supported divisor value // Round up to minimum supported divisor // AM doesn't support divisors 9 through 15 inclusive // Round up to supported fraction (AM only) // Round down to maximum supported divisor value (for AM) // Get estimated baud rate (to nearest integer) // Get absolute difference from requested baud rate // Closest to requested baud rate so far // Spot on! No point trying // Encode the best divisor value // Deal with special cases for encoded value // 3000000 baud // 2000000 baud (BM only)