コード例 #1
0
ファイル: uart_k20.c プロジェクト: CurieBSP/zephyr
/**
 * @brief Check if Rx IRQ has been raised
 *
 * @param dev UART device struct
 *
 * @return 1 if an IRQ is ready, 0 otherwise
 */
static int uart_k20_irq_rx_ready(struct device *dev)
{
	volatile struct K20_UART *uart = UART_STRUCT(dev);

	return (uart->c2.field.rx_full_int_dma_tx_en == 0) ?
			0 : uart->s1.field.rx_data_full;
}
コード例 #2
0
ファイル: uart_stm32.c プロジェクト: sunkaizhu/zephyr
/**
 * @brief Initialize UART channel
 *
 * This routine is called to reset the chip in a quiescent state.
 * It is assumed that this function is called only once per UART.
 *
 * @param dev UART device struct
 *
 * @return 0
 */
static int uart_stm32_init(struct device *dev)
{
	const struct uart_stm32_config *config = DEV_CFG(dev);
	struct uart_stm32_data *data = DEV_DATA(dev);
	UART_HandleTypeDef *UartHandle = &data->huart;

	__uart_stm32_get_clock(dev);
	/* enable clock */
#if defined(CONFIG_SOC_SERIES_STM32F1X) || defined(CONFIG_SOC_SERIES_STM32L4X)
	clock_control_on(data->clock, config->clock_subsys);
#elif defined(CONFIG_SOC_SERIES_STM32F4X)
	clock_control_on(data->clock,
			(clock_control_subsys_t *)&config->pclken);
#endif

	UartHandle->Instance = UART_STRUCT(dev);
	UartHandle->Init.WordLength = UART_WORDLENGTH_8B;
	UartHandle->Init.StopBits = UART_STOPBITS_1;
	UartHandle->Init.Parity = UART_PARITY_NONE;
	UartHandle->Init.HwFlowCtl = UART_HWCONTROL_NONE;
	UartHandle->Init.Mode = UART_MODE_TX_RX;
	UartHandle->Init.OverSampling = UART_OVERSAMPLING_16;

	HAL_UART_Init(UartHandle);

#ifdef CONFIG_UART_INTERRUPT_DRIVEN
	config->uconf.irq_config_func(dev);
#endif
	return 0;
}
コード例 #3
0
ファイル: uart_k20.c プロジェクト: CurieBSP/zephyr
/**
 * @brief Initialize UART channel
 *
 * This routine is called to reset the chip in a quiescent state.
 * It is assumed that this function is called only once per UART.
 *
 * @param dev UART device struct
 *
 * @return DEV_OK
 */
static int uart_k20_init(struct device *dev)
{
	int old_level; /* old interrupt lock level */
	union C1 c1;				   /* UART C1 register value */
	union C2 c2;				   /* UART C2 register value */

	volatile struct K20_UART *uart = UART_STRUCT(dev);
	struct uart_device_config * const dev_cfg = DEV_CFG(dev);
	struct uart_k20_dev_data_t * const dev_data = DEV_DATA(dev);

	/* disable interrupts */
	old_level = irq_lock();

	_uart_k20_baud_rate_set(uart, dev_cfg->sys_clk_freq,
				dev_data->baud_rate);

	/* 1 start bit, 8 data bits, no parity, 1 stop bit */
	c1.value = 0;

	uart->c1 = c1;

	/* enable Rx and Tx with interrupts disabled */
	c2.value = 0;
	c2.field.rx_enable = 1;
	c2.field.tx_enable = 1;

	uart->c2 = c2;

	/* restore interrupt state */
	irq_unlock(old_level);

	dev->driver_api = &uart_k20_driver_api;

	return DEV_OK;
}
コード例 #4
0
ファイル: uart_cmsdk_apb.c プロジェクト: bboozzoo/zephyr
/**
 * @brief Initialize UART channel
 *
 * This routine is called to reset the chip in a quiescent state.
 * It is assumed that this function is called only once per UART.
 *
 * @param dev UART device struct
 *
 * @return 0
 */
static int uart_cmsdk_apb_init(struct device *dev)
{
	volatile struct uart_cmsdk_apb *uart = UART_STRUCT(dev);
#ifdef CONFIG_UART_INTERRUPT_DRIVEN
	const struct uart_device_config * const dev_cfg = DEV_CFG(dev);
#endif

#ifdef CONFIG_CLOCK_CONTROL
	/* Enable clock for subsystem */
	struct device *clk =
		device_get_binding(CONFIG_ARM_CLOCK_CONTROL_DEV_NAME);

	struct uart_cmsdk_apb_dev_data * const data = DEV_DATA(dev);

#ifdef CONFIG_SOC_SERIES_BEETLE
	clock_control_on(clk, (clock_control_subsys_t *) &data->uart_cc_as);
	clock_control_on(clk, (clock_control_subsys_t *) &data->uart_cc_ss);
	clock_control_on(clk, (clock_control_subsys_t *) &data->uart_cc_dss);
#endif /* CONFIG_SOC_SERIES_BEETLE */
#endif /* CONFIG_CLOCK_CONTROL */

	/* Set baud rate */
	baudrate_set(dev);

	/* Enable receiver and transmitter */
	uart->ctrl = UART_RX_EN | UART_TX_EN;

#ifdef CONFIG_UART_INTERRUPT_DRIVEN
	dev_cfg->irq_config_func(dev);
#endif

	return 0;
}
コード例 #5
0
ファイル: uart_stm32.c プロジェクト: loicpoulain/zephyr
static int uart_stm32_irq_is_pending(struct device *dev)
{
	USART_TypeDef *UartInstance = UART_STRUCT(dev);

	return ((LL_USART_IsActiveFlag_RXNE(UartInstance) &&
		 LL_USART_IsEnabledIT_RXNE(UartInstance)) ||
		(LL_USART_IsActiveFlag_TC(UartInstance) &&
		 LL_USART_IsEnabledIT_TC(UartInstance)));
}
コード例 #6
0
ファイル: uart_nrf5.c プロジェクト: hudkmr/zephyr
/**
 * @brief Initialize UART channel
 *
 * This routine is called to reset the chip in a quiescent state.
 * It is assumed that this function is called only once per UART.
 *
 * @param dev UART device struct
 *
 * @return 0 on success
 */
static int uart_nrf5_init(struct device *dev)
{
	volatile struct _uart *uart = UART_STRUCT(dev);
	struct device *gpio_dev;

	gpio_dev = device_get_binding(CONFIG_GPIO_NRF5_P0_DEV_NAME);
	(void) gpio_pin_configure(gpio_dev,
				  CONFIG_UART_NRF5_GPIO_TX_PIN,
				  (GPIO_DIR_OUT | GPIO_PUD_PULL_UP));
	(void) gpio_pin_configure(gpio_dev,
				  CONFIG_UART_NRF5_GPIO_RX_PIN,
				  (GPIO_DIR_IN));

	uart->PSELTXD = CONFIG_UART_NRF5_GPIO_TX_PIN;
	uart->PSELRXD = CONFIG_UART_NRF5_GPIO_RX_PIN;

#ifdef CONFIG_UART_NRF5_FLOW_CONTROL

	(void) gpio_pin_configure(gpio_dev,
				  CONFIG_UART_NRF5_GPIO_RTS_PIN,
				  (GPIO_DIR_OUT | GPIO_PUD_PULL_UP));
	(void) gpio_pin_configure(gpio_dev,
				  CONFIG_UART_NRF5_GPIO_CTS_PIN,
				  (GPIO_DIR_IN));

	uart->PSELRTS = CONFIG_UART_NRF5_GPIO_RTS_PIN;
	uart->PSELCTS = CONFIG_UART_NRF5_GPIO_CTS_PIN;
	uart->CONFIG = (UART_CONFIG_HWFC_Enabled << UART_CONFIG_HWFC_Pos);

#endif /* CONFIG_UART_NRF5_FLOW_CONTROL */

	DEV_DATA(dev)->baud_rate = CONFIG_UART_NRF5_BAUD_RATE;
	DEV_CFG(dev)->sys_clk_freq = CONFIG_UART_NRF5_CLK_FREQ;

	/* Set baud rate */
	baudrate_set(dev, DEV_DATA(dev)->baud_rate,
		     DEV_CFG(dev)->sys_clk_freq);

	/* Enable receiver and transmitter */
	uart->ENABLE = (UART_ENABLE_ENABLE_Enabled << UART_ENABLE_ENABLE_Pos);

	uart->EVENTS_TXDRDY = 0;
	uart->EVENTS_RXDRDY = 0;

	uart->TASKS_STARTTX = 1;
	uart->TASKS_STARTRX = 1;

	dev->driver_api = &uart_nrf5_driver_api;

#ifdef CONFIG_UART_INTERRUPT_DRIVEN
	DEV_CFG(dev)->irq_config_func(dev);
#endif

	return 0;
}
コード例 #7
0
ファイル: uart_k20.c プロジェクト: CurieBSP/zephyr
/**
 * @brief Disable error interrupt
 *
 * @param dev UART device struct
 *
 * @return N/A
 */
static void uart_k20_irq_err_disable(struct device *dev)
{
	volatile struct K20_UART *uart = UART_STRUCT(dev);
	union C3 c3 = uart->c3;

	c3.field.parity_err_int_en = 0;
	c3.field.frame_err_int_en = 0;
	c3.field.noise_err_int_en = 0;
	c3.field.overrun_err_int_en = 0;
	uart->c3 = c3;
}
コード例 #8
0
ファイル: uart_k20.c プロジェクト: CurieBSP/zephyr
/**
 * @brief Read data from FIFO
 *
 * @param dev UART device struct
 * @param rx_data Pointer to data container
 * @param size Container size in bytes
 *
 * @return number of bytes read
 */
static int uart_k20_fifo_read(struct device *dev, uint8_t *rx_data,
			      const int size)
{
	volatile struct K20_UART *uart = UART_STRUCT(dev);
	uint8_t num_rx = 0;

	while ((size - num_rx > 0) && (uart->s1.field.rx_data_full != 0)) {
		rx_data[num_rx++] = uart->d;
	}

	return num_rx;
}
コード例 #9
0
static void uart_stm32_lpuart_set_baud_rate(struct device *dev,
					    u32_t clock_rate, u32_t baud_rate)
{
	USART_TypeDef *UartInstance = UART_STRUCT(dev);

	LL_LPUART_SetBaudRate(UartInstance,
			      clock_rate,
#ifdef USART_PRESC_PRESCALER
			      LL_USART_PRESCALER_DIV1,
#endif
			      baud_rate);
}
コード例 #10
0
ファイル: uart_k20.c プロジェクト: CurieBSP/zephyr
/**
 * @brief Fill FIFO with data
 *
 * @param dev UART device struct
 * @param tx_data Data to transmit
 * @param len Number of bytes to send
 *
 * @return number of bytes sent
 */
static int uart_k20_fifo_fill(struct device *dev, const uint8_t *tx_data,
			      int len)
{
	volatile struct K20_UART *uart = UART_STRUCT(dev);
	uint8_t num_tx = 0;

	while ((len - num_tx > 0) && (uart->s1.field.tx_data_empty == 1)) {
		uart->d = tx_data[num_tx++];
	}

	return num_tx;
}
コード例 #11
0
ファイル: uart_k20.c プロジェクト: CurieBSP/zephyr
/**
 * @brief Poll the device for input.
 *
 * @param dev UART device struct
 * @param c Pointer to character
 *
 * @return 0 if a character arrived, -1 if the input buffer if empty.
 */
static int uart_k20_poll_in(struct device *dev, unsigned char *c)
{
	volatile struct K20_UART *uart = UART_STRUCT(dev);

	if (uart->s1.field.rx_data_full == 0)
		return (-1);

	/* got a character */
	*c = uart->d;

	return 0;
}
コード例 #12
0
ファイル: uart_cmsdk_apb.c プロジェクト: bboozzoo/zephyr
/**
 * @brief Read data from FIFO
 *
 * @param dev UART device struct
 * @param rx_data Pointer to data container
 * @param size Container size in bytes
 *
 * @return the number of characters that have been read
 */
static int uart_cmsdk_apb_fifo_read(struct device *dev,
				    u8_t *rx_data, const int size)
{
	volatile struct uart_cmsdk_apb *uart = UART_STRUCT(dev);

	/* No hardware FIFO present */
	if (size && uart->state & UART_RX_BF) {
		*rx_data = (unsigned char)uart->data;
		return 1;
	}

	return 0;
}
コード例 #13
0
ファイル: uart_cmsdk_apb.c プロジェクト: bboozzoo/zephyr
/**
 * @brief Fill FIFO with data
 *
 * @param dev UART device struct
 * @param tx_data Data to transmit
 * @param len Number of bytes to send
 *
 * @return the number of characters that have been read
 */
static int uart_cmsdk_apb_fifo_fill(struct device *dev,
				    const u8_t *tx_data, int len)
{
	volatile struct uart_cmsdk_apb *uart = UART_STRUCT(dev);

	/* No hardware FIFO present */
	if (len && !(uart->state & UART_TX_BF)) {
		uart->data = *tx_data;
		return 1;
	}

	return 0;
}
コード例 #14
0
ファイル: uart_stm32.c プロジェクト: loicpoulain/zephyr
static void uart_stm32_poll_out(struct device *dev,
					unsigned char c)
{
	USART_TypeDef *UartInstance = UART_STRUCT(dev);

	/* Wait for TXE flag to be raised */
	while (!LL_USART_IsActiveFlag_TXE(UartInstance))
		;

	LL_USART_ClearFlag_TC(UartInstance);

	LL_USART_TransmitData8(UartInstance, (u8_t)c);
}
コード例 #15
0
ファイル: uart_cmsdk_apb.c プロジェクト: loicpoulain/zephyr
/**
 * @brief Output a character in polled mode.
 *
 * Checks if the transmitter is empty. If empty, a character is written to
 * the data register.
 *
 * @param dev UART device struct
 * @param c Character to send
 */
static void uart_cmsdk_apb_poll_out(struct device *dev,
					     unsigned char c)
{
	volatile struct uart_cmsdk_apb *uart = UART_STRUCT(dev);

	/* Wait for transmitter to be ready */
	while (uart->state & UART_TX_BF) {
		; /* Wait */
	}

	/* Send a character */
	uart->data = (u32_t)c;
}
コード例 #16
0
ファイル: uart_k20.c プロジェクト: CurieBSP/zephyr
/**
 * @brief Output a character in polled mode.
 *
 * Checks if the transmitter is empty. If empty, a character is written to
 * the data register.
 *
 * If the hardware flow control is enabled then the handshake signal CTS has to
 * be asserted in order to send a character.
 *
 * @param dev UART device struct
 * @param c Character to send
 *
 * @return sent character
 */
static unsigned char uart_k20_poll_out(struct device *dev,
				       unsigned char c)
{
	volatile struct K20_UART *uart = UART_STRUCT(dev);

	/* wait for transmitter to ready to accept a character */
	while (uart->s1.field.tx_data_empty == 0)
		;

	uart->d = c;

	return c;
}
コード例 #17
0
ファイル: uart_stm32.c プロジェクト: loicpoulain/zephyr
/**
 * @brief Initialize UART channel
 *
 * This routine is called to reset the chip in a quiescent state.
 * It is assumed that this function is called only once per UART.
 *
 * @param dev UART device struct
 *
 * @return 0
 */
static int uart_stm32_init(struct device *dev)
{
	const struct uart_stm32_config *config = DEV_CFG(dev);
	struct uart_stm32_data *data = DEV_DATA(dev);
	USART_TypeDef *UartInstance = UART_STRUCT(dev);

	__uart_stm32_get_clock(dev);
	/* enable clock */
	if (clock_control_on(data->clock,
			(clock_control_subsys_t *)&config->pclken) != 0) {
		return -EIO;
	}

	LL_USART_Disable(UartInstance);

	/* TX/RX direction */
	LL_USART_SetTransferDirection(UartInstance,
				      LL_USART_DIRECTION_TX_RX);

	/* 8 data bit, 1 start bit, 1 stop bit, no parity */
	LL_USART_ConfigCharacter(UartInstance,
				 LL_USART_DATAWIDTH_8B,
				 LL_USART_PARITY_NONE,
				 LL_USART_STOPBITS_1);

	if (config->hw_flow_control) {
		uart_stm32_set_hwctrl(dev, LL_USART_HWCONTROL_RTS_CTS);
	}

	/* Set the default baudrate */
	uart_stm32_set_baudrate(dev, data->baud_rate);

	LL_USART_Enable(UartInstance);

#ifdef USART_ISR_TEACK
	/* Wait until TEACK flag is set */
	while (!(LL_USART_IsActiveFlag_TEACK(UartInstance)))
		;
#endif /* !USART_ISR_TEACK */

#ifdef USART_ISR_REACK
	/* Wait until REACK flag is set */
	while (!(LL_USART_IsActiveFlag_REACK(UartInstance)))
		;
#endif /* !USART_ISR_REACK */

#ifdef CONFIG_UART_INTERRUPT_DRIVEN
	config->uconf.irq_config_func(dev);
#endif
	return 0;
}
コード例 #18
0
ファイル: uart_cmsdk_apb.c プロジェクト: bboozzoo/zephyr
/**
 * @brief Interrupt service routine.
 *
 * Calls the callback function, if exists.
 *
 * @param arg argument to interrupt service routine.
 *
 * @return N/A
 */
void uart_cmsdk_apb_isr(void *arg)
{
	struct device *dev = arg;
	volatile struct uart_cmsdk_apb *uart = UART_STRUCT(dev);
	struct uart_cmsdk_apb_dev_data *data = DEV_DATA(dev);

	/* Clear pending interrupts */
	uart->intclear = UART_RX_IN | UART_TX_IN;

	/* Verify if the callback has been registered */
	if (data->irq_cb) {
		data->irq_cb(dev);
	}
}
コード例 #19
0
ファイル: uart_cmsdk_apb.c プロジェクト: bboozzoo/zephyr
static int uart_cmsdk_apb_poll_in(struct device *dev, unsigned char *c)
{
	volatile struct uart_cmsdk_apb *uart = UART_STRUCT(dev);

	/* If the receiver is not ready returns -1 */
	if (!(uart->state & UART_RX_BF)) {
		return -1;
	}

	/* got a character */
	*c = (unsigned char)uart->data;

	return 0;
}
コード例 #20
0
static inline u32_t uart_stm32_get_databits(struct device *dev)
{
	USART_TypeDef *UartInstance = UART_STRUCT(dev);

#ifdef CONFIG_LPUART_1
	if (IS_LPUART_INSTANCE(UartInstance)) {
		return LL_LPUART_GetDataWidth(UartInstance);
	} else {
		return LL_USART_GetDataWidth(UartInstance);
	}
#else
	return LL_USART_GetDataWidth(UartInstance);
#endif	/* CONFIG_LPUART_1 */
}
コード例 #21
0
static inline void uart_stm32_set_parity(struct device *dev, u32_t parity)
{
	USART_TypeDef *UartInstance = UART_STRUCT(dev);

#ifdef CONFIG_LPUART_1
	if (IS_LPUART_INSTANCE(UartInstance)) {
		LL_LPUART_SetParity(UartInstance, parity);
	} else {
		LL_USART_SetParity(UartInstance, parity);
	}
#else
	LL_USART_SetParity(UartInstance, parity);
#endif	/* CONFIG_LPUART_1 */
}
コード例 #22
0
static inline void uart_stm32_set_databits(struct device *dev, u32_t databits)
{
	USART_TypeDef *UartInstance = UART_STRUCT(dev);

#ifdef CONFIG_LPUART_1
	if (IS_LPUART_INSTANCE(UartInstance)) {
		LL_LPUART_SetDataWidth(UartInstance, databits);
	} else {
		LL_USART_SetDataWidth(UartInstance, databits);
	}
#else
	LL_USART_SetDataWidth(UartInstance, databits);
#endif	/* CONFIG_LPUART_1 */
}
コード例 #23
0
ファイル: uart_cmsdk_apb.c プロジェクト: loicpoulain/zephyr
/**
 * @brief Enable TX interrupt
 *
 * @param dev UART device struct
 *
 * @return N/A
 */
static void uart_cmsdk_apb_irq_tx_enable(struct device *dev)
{
	unsigned int key;

	UART_STRUCT(dev)->ctrl |= UART_TX_IN_EN;
	/* The expectation is that TX is a level interrupt, active for as
	 * long as TX buffer is empty. But in CMSDK UART, it appears to be
	 * edge interrupt, firing on a state change of TX buffer. So, we
	 * need to "prime" it here by calling ISR directly, to get interrupt
	 * processing going.
	 */
	key = irq_lock();
	uart_cmsdk_apb_isr(dev);
	irq_unlock(key);
}
コード例 #24
0
ファイル: uart_stm32.c プロジェクト: loicpoulain/zephyr
static void uart_stm32_irq_err_disable(struct device *dev)
{
	USART_TypeDef *UartInstance = UART_STRUCT(dev);

	/* Disable FE, ORE interruptions */
	LL_USART_DisableIT_ERROR(UartInstance);
#if !defined(CONFIG_SOC_SERIES_STM32F0X) || defined(USART_LIN_SUPPORT)
	/* Disable Line break detection */
	if (IS_UART_LIN_INSTANCE(UartInstance)) {
		LL_USART_DisableIT_LBD(UartInstance);
	}
#endif
	/* Disable parity error interruption */
	LL_USART_DisableIT_PE(UartInstance);
}
コード例 #25
0
ファイル: uart_nrf5.c プロジェクト: hudkmr/zephyr
/** Interrupt driven FIFO fill function */
static int uart_nrf5_fifo_fill(struct device *dev, const uint8_t *tx_data, int len)
{
	volatile struct _uart *uart = UART_STRUCT(dev);
	uint8_t num_tx = 0;

	while ((len - num_tx > 0) && uart->EVENTS_TXDRDY) {
		/* Clear the interrupt */
		uart->EVENTS_TXDRDY = 0;

		/* Send a character */
		uart->TXD = (uint8_t)tx_data[num_tx++];
	}

	return (int)num_tx;
}
コード例 #26
0
ファイル: uart_nrf5.c プロジェクト: hudkmr/zephyr
/** Interrupt driven FIFO read function */
static int uart_nrf5_fifo_read(struct device *dev, uint8_t *rx_data, const int size)
{
	volatile struct _uart *uart = UART_STRUCT(dev);
	uint8_t num_rx = 0;

	while ((size - num_rx > 0) && uart->EVENTS_RXDRDY) {
		/* Clear the interrupt */
		uart->EVENTS_RXDRDY = 0;

		/* Receive a character */
		rx_data[num_rx++] = (uint8_t)uart->RXD;
	}

	return num_rx;
}
コード例 #27
0
ファイル: uart_cmsdk_apb.c プロジェクト: bboozzoo/zephyr
/**
 * @brief Set the baud rate
 *
 * This routine set the given baud rate for the UART.
 *
 * @param dev UART device struct
 *
 * @return N/A
 */
static void baudrate_set(struct device *dev)
{
	volatile struct uart_cmsdk_apb *uart = UART_STRUCT(dev);
	const struct uart_device_config * const dev_cfg = DEV_CFG(dev);
	struct uart_cmsdk_apb_dev_data *const dev_data = DEV_DATA(dev);
	/*
	 * If baudrate and/or sys_clk_freq are 0 the configuration remains
	 * unchanged. It can be useful in case that Zephyr it is run via
	 * a bootloader that brings up the serial and sets the baudrate.
	 */
	if ((dev_data->baud_rate != 0) && (dev_cfg->sys_clk_freq != 0)) {
		/* calculate baud rate divisor */
		uart->bauddiv = (dev_cfg->sys_clk_freq / dev_data->baud_rate);
	}
}
コード例 #28
0
ファイル: uart_stm32.c プロジェクト: loicpoulain/zephyr
static int uart_stm32_fifo_fill(struct device *dev, const u8_t *tx_data,
				  int size)
{
	USART_TypeDef *UartInstance = UART_STRUCT(dev);
	u8_t num_tx = 0U;

	while ((size - num_tx > 0) &&
	       LL_USART_IsActiveFlag_TXE(UartInstance)) {
		/* TXE flag will be cleared with byte write to DR|RDR register */

		/* Send a character (8bit , parity none) */
		LL_USART_TransmitData8(UartInstance, tx_data[num_tx++]);
	}

	return num_tx;
}
コード例 #29
0
ファイル: uart_nrf5.c プロジェクト: hudkmr/zephyr
static int uart_nrf5_poll_in(struct device *dev, unsigned char *c)
{
	volatile struct _uart *uart = UART_STRUCT(dev);

	if (!uart->EVENTS_RXDRDY) {
		return -1;
	}

	/* Clear the interrupt */
	uart->EVENTS_RXDRDY = 0;

	/* got a character */
	*c = (unsigned char)uart->RXD;

	return 0;
}
コード例 #30
0
ファイル: uart_nrf5.c プロジェクト: hudkmr/zephyr
/**
 * @brief Output a character in polled mode.
 *
 * Checks if the transmitter is empty. If empty, a character is written to
 * the data register.
 *
 * @param dev UART device struct
 * @param c Character to send
 *
 * @return Sent character
 */
static unsigned char uart_nrf5_poll_out(struct device *dev,
					unsigned char c)
{
	volatile struct _uart *uart = UART_STRUCT(dev);

	/* send a character */
	uart->TXD = (uint8_t)c;

	/* Wait for transmitter to be ready */
	while (!uart->EVENTS_TXDRDY) {
	}

	uart->EVENTS_TXDRDY = 0;

	return c;
}