stmhal: For UART, check that baudrate is within 5% of desired value.

Also includes documentation about minimum baudrate.

Addresses issue #1090.
This commit is contained in:
Damien George 2015-02-22 00:26:49 +00:00
parent e06cf89f04
commit 77fc276c08
2 changed files with 29 additions and 0 deletions

View File

@ -75,6 +75,13 @@ Methods
- ``timeout_char`` is the timeout in milliseconds to wait between characters.
- ``read_buf_len`` is the character length of the read buffer (0 to disable).
This method will raise an exception if the baudrate could not be set within
5% of the desired value. The minimum baudrate is dictated by the frequency
of the bus that the UART is on; UART(1) and UART(6) are APB2, the rest are on
APB1. The default bus frequencies give a minimum baudrate of 1300 for
UART(1) and UART(6) and 650 for the others. Use :func:`pyb.freq <pyb.freq>`
to reduce the bus frequencies to get lower baudrates.
*Note:* with parity=None, only 8 and 9 bits are supported. With parity enabled,
only 7 and 8 bits are supported.

View File

@ -457,6 +457,28 @@ STATIC mp_obj_t pyb_uart_init_helper(pyb_uart_obj_t *self, mp_uint_t n_args, con
HAL_NVIC_EnableIRQ(self->irqn);
}
// compute actual baudrate that was configured
// (this formula assumes UART_OVERSAMPLING_16)
uint32_t actual_baudrate;
if (self->uart.Instance == USART1 || self->uart.Instance == USART6) {
actual_baudrate = HAL_RCC_GetPCLK2Freq();
} else {
actual_baudrate = HAL_RCC_GetPCLK1Freq();
}
actual_baudrate /= self->uart.Instance->BRR;
// check we could set the baudrate within 5%
uint32_t baudrate_diff;
if (actual_baudrate > init->BaudRate) {
baudrate_diff = actual_baudrate - init->BaudRate;
} else {
baudrate_diff = init->BaudRate - actual_baudrate;
}
init->BaudRate = actual_baudrate; // remember actual baudrate for printing
if (20 * baudrate_diff > init->BaudRate) {
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, "set baudrate %d is not within 5%% of desired value", actual_baudrate));
}
return mp_const_none;
}