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_I2S_IRQn 37
|
||||||
#define NRF52_IRQ_FPU_IRQn 38
|
#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_ */
|
#endif /* _NRF5_SOC_COMMON_H_ */
|
||||||
|
|
|
@ -106,24 +106,70 @@ static struct uart_driver_api uart_nrf5_driver_api;
|
||||||
* @return N/A
|
* @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)
|
uint32_t baudrate, uint32_t sys_clk_freq_hz)
|
||||||
{
|
{
|
||||||
volatile struct _uart *uart = UART_STRUCT(dev);
|
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)) {
|
/* Use the common nRF5 macros */
|
||||||
set_baudrate = (uint32_t) (
|
switch (baudrate) {
|
||||||
(uint64_t)baudrate *
|
case 1200:
|
||||||
(uint64_t)UINT32_MAX /
|
divisor = NRF5_UART_BAUDRATE_1200;
|
||||||
(uint64_t)sys_clk_freq_hz
|
break;
|
||||||
);
|
case 2400:
|
||||||
|
divisor = NRF5_UART_BAUDRATE_2400;
|
||||||
/* Round the value */
|
break;
|
||||||
set_baudrate = (set_baudrate + 0x800) & 0xFFFFF000;
|
case 4800:
|
||||||
uart->BAUDRATE = set_baudrate << UART_BAUDRATE_BAUDRATE_Pos;
|
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);
|
volatile struct _uart *uart = UART_STRUCT(dev);
|
||||||
struct device *gpio_dev;
|
struct device *gpio_dev;
|
||||||
|
int err;
|
||||||
|
|
||||||
gpio_dev = device_get_binding(CONFIG_GPIO_NRF5_P0_DEV_NAME);
|
gpio_dev = device_get_binding(CONFIG_GPIO_NRF5_P0_DEV_NAME);
|
||||||
(void) gpio_pin_configure(gpio_dev,
|
(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;
|
DEV_DATA(dev)->baud_rate = CONFIG_UART_NRF5_BAUD_RATE;
|
||||||
|
|
||||||
/* Set 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);
|
DEV_CFG(dev)->sys_clk_freq);
|
||||||
|
if (err) {
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
/* Enable receiver and transmitter */
|
/* Enable receiver and transmitter */
|
||||||
uart->ENABLE = (UART_ENABLE_ENABLE_Enabled << UART_ENABLE_ENABLE_Pos);
|
uart->ENABLE = (UART_ENABLE_ENABLE_Enabled << UART_ENABLE_ENABLE_Pos);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue