Skip to content

Commit ee58278

Browse files
committed
add code to calculate divisor from baudrate for ftdi
1 parent 8214f0f commit ee58278

File tree

1 file changed

+29
-6
lines changed

1 file changed

+29
-6
lines changed

src/class/cdc/cdc_host.c

Lines changed: 29 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -847,13 +847,36 @@ static bool ftdi_sio_set_modem_ctrl(cdch_interface_t* p_cdc, uint16_t line_state
847847
return true;
848848
}
849849

850-
static bool ftdi_sio_set_baudrate(cdch_interface_t* p_cdc, uint32_t baudrate, tuh_xfer_cb_t complete_cb, uintptr_t user_data)
850+
static uint32_t ftdi_232bm_baud_base_to_divisor(uint32_t baud, uint32_t base)
851+
{
852+
const uint8_t divfrac[8] = { 0, 3, 2, 4, 1, 5, 6, 7 };
853+
uint32_t divisor;
854+
855+
/* divisor shifted 3 bits to the left */
856+
uint32_t divisor3 = base / (2 * baud);
857+
divisor = (divisor3 >> 3);
858+
divisor |= (uint32_t) divfrac[divisor3 & 0x7] << 14;
859+
860+
/* Deal with special cases for highest baud rates. */
861+
if (divisor == 1) { /* 1.0 */
862+
divisor = 0;
863+
}
864+
else if (divisor == 0x4001) { /* 1.5 */
865+
divisor = 1;
866+
}
867+
868+
return divisor;
869+
}
870+
871+
static uint32_t ftdi_232bm_baud_to_divisor(uint32_t baud)
851872
{
852-
// TODO baudrate to baud divisor
853-
(void) baudrate;
854-
uint16_t divisor = 0x4138; // FIXME hardcoded to 9600 baud
873+
return ftdi_232bm_baud_base_to_divisor(baud, 48000000u);
874+
}
855875

856-
TU_LOG_CDCH("CDC FTDI Set BaudRate = %u, divisor = %u\n", baudrate, divisor);
876+
static bool ftdi_sio_set_baudrate(cdch_interface_t* p_cdc, uint32_t baudrate, tuh_xfer_cb_t complete_cb, uintptr_t user_data)
877+
{
878+
uint16_t const divisor = (uint16_t) ftdi_232bm_baud_to_divisor(baudrate);
879+
TU_LOG_CDCH("CDC FTDI Set BaudRate = %lu, divisor = 0x%04x\n", baudrate, divisor);
857880

858881
p_cdc->user_control_cb = complete_cb;
859882
TU_ASSERT(ftdi_sio_set_request(p_cdc, FTDI_SIO_SET_BAUD_RATE, divisor, cdch_internal_control_complete, user_data));
@@ -985,7 +1008,7 @@ static bool cp210x_ifc_enable(cdch_interface_t* p_cdc, uint16_t enabled, tuh_xfe
9851008
}
9861009

9871010
static bool cp210x_set_baudrate(cdch_interface_t* p_cdc, uint32_t baudrate, tuh_xfer_cb_t complete_cb, uintptr_t user_data) {
988-
TU_LOG_CDCH("CDC CP210x Set BaudRate = %u\n", baudrate);
1011+
TU_LOG_CDCH("CDC CP210x Set BaudRate = %lu\n", baudrate);
9891012
baudrate = tu_htole32(baudrate);
9901013
return cp210x_set_request(p_cdc, CP210X_SET_BAUDRATE, 0, (uint8_t *) &baudrate, 4, complete_cb, user_data);
9911014
}

0 commit comments

Comments
 (0)