drivers: uart_nrf5: Use MDK baudrate divisor constants
The baudrate calculation present in set_baudrate() is causing the UART to emit inital bytes incorrectly, for a reason currently unknown, but directly related to the fact that __aeabi_uldivmod is being invoked. Since the nRF5x Product Specifications do not provide a standard formula to calculate baudrates and instead list a predefined set of divisor values, we opt here to use the official values and remove the attempt at calculating them manually. Change-Id: Ic3ff42ea6d065e9a1d26a5350ce5bf5ad661160a Signed-off-by: Carles Cufi <carles.cufi@nordicsemi.no>
This commit is contained in:
parent
3daf30c912
commit
33d17497d2
2 changed files with 87 additions and 13 deletions
|
@ -71,4 +71,28 @@
|
|||
#define NRF52_IRQ_I2S_IRQn 37
|
||||
#define NRF52_IRQ_FPU_IRQn 38
|
||||
|
||||
/**
|
||||
* @file UART baudrate divisors for NRF51/NRF52 family processors.
|
||||
*
|
||||
* Based on Nordic MDK included header file: nrf52_bitfields.h
|
||||
* Uses the UARTE_BAUDRATE macros since they are more precise.
|
||||
*/
|
||||
|
||||
#define NRF5_UART_BAUDRATE_1200 0x0004f000
|
||||
#define NRF5_UART_BAUDRATE_2400 0x0009d000
|
||||
#define NRF5_UART_BAUDRATE_4800 0x0013b000
|
||||
#define NRF5_UART_BAUDRATE_9600 0x00275000
|
||||
#define NRF5_UART_BAUDRATE_14400 0x003af000
|
||||
#define NRF5_UART_BAUDRATE_19200 0x004ea000
|
||||
#define NRF5_UART_BAUDRATE_28800 0x0075c000
|
||||
#define NRF5_UART_BAUDRATE_38400 0x009d0000
|
||||
#define NRF5_UART_BAUDRATE_57600 0x00eb0000
|
||||
#define NRF5_UART_BAUDRATE_76800 0x013a9000
|
||||
#define NRF5_UART_BAUDRATE_115200 0x01d60000
|
||||
#define NRF5_UART_BAUDRATE_230400 0x03b00000
|
||||
#define NRF5_UART_BAUDRATE_250000 0x04000000
|
||||
#define NRF5_UART_BAUDRATE_460800 0x07400000
|
||||
#define NRF5_UART_BAUDRATE_921600 0x0f000000
|
||||
#define NRF5_UART_BAUDRATE_1000000 0x10000000
|
||||
|
||||
#endif /* _NRF5_SOC_COMMON_H_ */
|
||||
|
|
|
@ -106,24 +106,70 @@ static struct uart_driver_api uart_nrf5_driver_api;
|
|||
* @return N/A
|
||||
*/
|
||||
|
||||
static void baudrate_set(struct device *dev,
|
||||
static int baudrate_set(struct device *dev,
|
||||
uint32_t baudrate, uint32_t sys_clk_freq_hz)
|
||||
{
|
||||
volatile struct _uart *uart = UART_STRUCT(dev);
|
||||
|
||||
uint32_t set_baudrate; /* baud rate divisor */
|
||||
uint32_t divisor; /* baud rate divisor */
|
||||
|
||||
if ((baudrate != 0) && (sys_clk_freq_hz != 0)) {
|
||||
set_baudrate = (uint32_t) (
|
||||
(uint64_t)baudrate *
|
||||
(uint64_t)UINT32_MAX /
|
||||
(uint64_t)sys_clk_freq_hz
|
||||
);
|
||||
|
||||
/* Round the value */
|
||||
set_baudrate = (set_baudrate + 0x800) & 0xFFFFF000;
|
||||
uart->BAUDRATE = set_baudrate << UART_BAUDRATE_BAUDRATE_Pos;
|
||||
/* Use the common nRF5 macros */
|
||||
switch (baudrate) {
|
||||
case 1200:
|
||||
divisor = NRF5_UART_BAUDRATE_1200;
|
||||
break;
|
||||
case 2400:
|
||||
divisor = NRF5_UART_BAUDRATE_2400;
|
||||
break;
|
||||
case 4800:
|
||||
divisor = NRF5_UART_BAUDRATE_4800;
|
||||
break;
|
||||
case 9600:
|
||||
divisor = NRF5_UART_BAUDRATE_9600;
|
||||
break;
|
||||
case 14400:
|
||||
divisor = NRF5_UART_BAUDRATE_14400;
|
||||
break;
|
||||
case 19200:
|
||||
divisor = NRF5_UART_BAUDRATE_19200;
|
||||
break;
|
||||
case 28800:
|
||||
divisor = NRF5_UART_BAUDRATE_28800;
|
||||
break;
|
||||
case 38400:
|
||||
divisor = NRF5_UART_BAUDRATE_38400;
|
||||
break;
|
||||
case 57600:
|
||||
divisor = NRF5_UART_BAUDRATE_57600;
|
||||
break;
|
||||
case 76800:
|
||||
divisor = NRF5_UART_BAUDRATE_76800;
|
||||
break;
|
||||
case 115200:
|
||||
divisor = NRF5_UART_BAUDRATE_115200;
|
||||
break;
|
||||
case 230400:
|
||||
divisor = NRF5_UART_BAUDRATE_230400;
|
||||
break;
|
||||
case 250000:
|
||||
divisor = NRF5_UART_BAUDRATE_250000;
|
||||
break;
|
||||
case 460800:
|
||||
divisor = NRF5_UART_BAUDRATE_460800;
|
||||
break;
|
||||
case 921600:
|
||||
divisor = NRF5_UART_BAUDRATE_921600;
|
||||
break;
|
||||
case 1000000:
|
||||
divisor = NRF5_UART_BAUDRATE_1000000;
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
uart->BAUDRATE = divisor << UART_BAUDRATE_BAUDRATE_Pos;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -140,6 +186,7 @@ static int uart_nrf5_init(struct device *dev)
|
|||
{
|
||||
volatile struct _uart *uart = UART_STRUCT(dev);
|
||||
struct device *gpio_dev;
|
||||
int err;
|
||||
|
||||
gpio_dev = device_get_binding(CONFIG_GPIO_NRF5_P0_DEV_NAME);
|
||||
(void) gpio_pin_configure(gpio_dev,
|
||||
|
@ -170,8 +217,11 @@ static int uart_nrf5_init(struct device *dev)
|
|||
DEV_DATA(dev)->baud_rate = CONFIG_UART_NRF5_BAUD_RATE;
|
||||
|
||||
/* Set baud rate */
|
||||
baudrate_set(dev, DEV_DATA(dev)->baud_rate,
|
||||
err = baudrate_set(dev, DEV_DATA(dev)->baud_rate,
|
||||
DEV_CFG(dev)->sys_clk_freq);
|
||||
if (err) {
|
||||
return err;
|
||||
}
|
||||
|
||||
/* Enable receiver and transmitter */
|
||||
uart->ENABLE = (UART_ENABLE_ENABLE_Enabled << UART_ENABLE_ENABLE_Pos);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue