nrf52: add serial termios support
This commit is contained in:
parent
b422f49fa7
commit
35a5036e32
@ -213,6 +213,7 @@ config ARCH_CHIP_NRF52
|
||||
#select ARM_HAVE_MPU_UNIFIED
|
||||
select ARCH_HAVE_FPU
|
||||
select ARCH_HAVE_PWM_MULTICHAN
|
||||
select ARCH_HAVE_SERIAL_TERMIOS
|
||||
---help---
|
||||
Nordic NRF52 architectures (ARM Cortex-M4).
|
||||
|
||||
|
@ -113,20 +113,186 @@ static const struct uart_config_s g_console_config =
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef HAVE_UART_DEVICE
|
||||
static void nrf52_setbaud(uintptr_t base, const struct uart_config_s *config)
|
||||
{
|
||||
uint32_t br = 0;
|
||||
|
||||
if (config->baud == 115200)
|
||||
switch (config->baud)
|
||||
{
|
||||
br = UART_BAUDRATE_115200;
|
||||
case 1200:
|
||||
{
|
||||
br = UART_BAUDRATE_1200;
|
||||
break;
|
||||
}
|
||||
|
||||
case 2400:
|
||||
{
|
||||
br = UART_BAUDRATE_2400;
|
||||
break;
|
||||
}
|
||||
|
||||
case 4800:
|
||||
{
|
||||
br = UART_BAUDRATE_4800;
|
||||
break;
|
||||
}
|
||||
|
||||
case 9600:
|
||||
{
|
||||
br = UART_BAUDRATE_9600;
|
||||
break;
|
||||
}
|
||||
|
||||
case 14400:
|
||||
{
|
||||
br = UART_BAUDRATE_14400;
|
||||
break;
|
||||
}
|
||||
|
||||
case 19200:
|
||||
{
|
||||
br = UART_BAUDRATE_19200;
|
||||
break;
|
||||
}
|
||||
|
||||
case 28800:
|
||||
{
|
||||
br = UART_BAUDRATE_28800;
|
||||
break;
|
||||
}
|
||||
|
||||
case 31250:
|
||||
{
|
||||
br = UART_BAUDRATE_31250;
|
||||
break;
|
||||
}
|
||||
|
||||
case 38400:
|
||||
{
|
||||
br = UART_BAUDRATE_38400;
|
||||
break;
|
||||
}
|
||||
|
||||
case 56000:
|
||||
{
|
||||
br = UART_BAUDRATE_56000;
|
||||
break;
|
||||
}
|
||||
|
||||
case 57600:
|
||||
{
|
||||
br = UART_BAUDRATE_57600;
|
||||
break;
|
||||
}
|
||||
|
||||
case 76000:
|
||||
{
|
||||
br = UART_BAUDRATE_76000;
|
||||
break;
|
||||
}
|
||||
|
||||
case 115200:
|
||||
{
|
||||
br = UART_BAUDRATE_115200;
|
||||
break;
|
||||
}
|
||||
|
||||
case 230400:
|
||||
{
|
||||
br = UART_BAUDRATE_230400;
|
||||
break;
|
||||
}
|
||||
|
||||
case 250000:
|
||||
{
|
||||
br = UART_BAUDRATE_250000;
|
||||
break;
|
||||
}
|
||||
|
||||
case 460800:
|
||||
{
|
||||
br = UART_BAUDRATE_460800;
|
||||
break;
|
||||
}
|
||||
|
||||
case 921600:
|
||||
{
|
||||
br = UART_BAUDRATE_921600;
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
{
|
||||
DEBUGASSERT(0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
putreg32(br, base + NRF52_UART_BAUDRATE_OFFSET);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: nrf52_setparity
|
||||
****************************************************************************/
|
||||
|
||||
static void nrf52_setparity(uintptr_t base,
|
||||
const struct uart_config_s *config)
|
||||
{
|
||||
uint32_t regval = 0;
|
||||
|
||||
regval = getreg32(base + NRF52_UART_CONFIG_OFFSET);
|
||||
|
||||
if (config->parity == 2)
|
||||
{
|
||||
/* Include even parity */
|
||||
|
||||
regval |= UART_CONFIG_PARITY;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Exclude parity */
|
||||
|
||||
regval &= ~UART_CONFIG_PARITY;
|
||||
}
|
||||
|
||||
putreg32(regval, base + NRF52_UART_CONFIG_OFFSET);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: nrf52_setstops
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef HAVE_UART_STOPBITS
|
||||
static void nrf52_setstops(uintptr_t base,
|
||||
const struct uart_config_s *config)
|
||||
{
|
||||
uint32_t regval = 0;
|
||||
|
||||
regval = getreg32(base + NRF52_UART_CONFIG_OFFSET);
|
||||
|
||||
if (config->stopbits2 == true)
|
||||
{
|
||||
regval |= UART_CONFIG_STOP;
|
||||
}
|
||||
else
|
||||
{
|
||||
regval &= ~UART_CONFIG_STOP;
|
||||
}
|
||||
|
||||
putreg32(regval, base + NRF52_UART_CONFIG_OFFSET);
|
||||
}
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Name: nrf52_sethwflow
|
||||
****************************************************************************/
|
||||
|
||||
static void nrf52_sethwflow(uintptr_t base,
|
||||
const struct uart_config_s *config)
|
||||
{
|
||||
/* TODO */
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
@ -174,9 +340,9 @@ void nrf52_usart_configure(uintptr_t base,
|
||||
putreg32(1, base + NRF52_UART_TASKS_STOPTX_OFFSET);
|
||||
putreg32(NRF52_UART_ENABLE_DISABLE, base + NRF52_UART_ENABLE_OFFSET);
|
||||
|
||||
/* Configure baud */
|
||||
/* Set UART format */
|
||||
|
||||
nrf52_setbaud(base, config);
|
||||
nrf52_usart_setformat(base, config);
|
||||
|
||||
/* Config GPIO pins for uart */
|
||||
|
||||
@ -263,3 +429,33 @@ void arm_lowputc(char ch)
|
||||
putreg32(1, CONSOLE_BASE + NRF52_UART_TASKS_STOPTX_OFFSET);
|
||||
#endif
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: nrf52_usart_setformat
|
||||
*
|
||||
* Description:
|
||||
* Set the USART line format and speed.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void nrf52_usart_setformat(uintptr_t base,
|
||||
FAR const struct uart_config_s *config)
|
||||
{
|
||||
/* Configure baud */
|
||||
|
||||
nrf52_setbaud(base, config);
|
||||
|
||||
/* Configure polarity */
|
||||
|
||||
nrf52_setparity(base, config);
|
||||
|
||||
#ifdef HAVE_UART_STOPBITS
|
||||
/* Configure STOP bits */
|
||||
|
||||
nrf52_setstops(base, config);
|
||||
#endif
|
||||
|
||||
/* Configure hardware flow control */
|
||||
|
||||
nrf52_sethwflow(base, config);
|
||||
}
|
||||
|
@ -45,6 +45,7 @@
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <nrf52_gpio.h>
|
||||
#include <nrf52_config.h>
|
||||
|
||||
/****************************************************************************
|
||||
* Public Types
|
||||
@ -114,4 +115,15 @@ void nrf52_usart_disable(uintptr_t base,
|
||||
FAR const struct uart_config_s *config);
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Name: nrf52_usart_setformat
|
||||
*
|
||||
* Description:
|
||||
* Set the USART line format and speed.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void nrf52_usart_setformat(uintptr_t base,
|
||||
FAR const struct uart_config_s *config);
|
||||
|
||||
#endif /* __ARCH_ARM_SRC_NRF52_NRF52_LOWPUTC_H */
|
||||
|
@ -49,8 +49,13 @@
|
||||
|
||||
#include <nuttx/irq.h>
|
||||
#include <nuttx/arch.h>
|
||||
#include <nuttx/fs/ioctl.h>
|
||||
#include <nuttx/serial/serial.h>
|
||||
|
||||
#ifdef CONFIG_SERIAL_TERMIOS
|
||||
# include <termios.h>
|
||||
#endif
|
||||
|
||||
#include <arch/board/board.h>
|
||||
|
||||
#include "arm_arch.h"
|
||||
@ -422,6 +427,23 @@ static int nrf52_interrupt(int irq, void *context, FAR void *arg)
|
||||
return OK;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: nrf52_set_format
|
||||
*
|
||||
* Description:
|
||||
* Set the serial line format and speed.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_SERIAL_TERMIOS
|
||||
void nrf52_set_format(struct uart_dev_s *dev)
|
||||
{
|
||||
struct nrf52_dev_s *priv = (struct nrf52_dev_s *)dev->priv;
|
||||
|
||||
nrf52_usart_setformat(priv->uartbase, &priv->config);
|
||||
}
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Name: nrf52_ioctl
|
||||
*
|
||||
@ -432,7 +454,118 @@ static int nrf52_interrupt(int irq, void *context, FAR void *arg)
|
||||
|
||||
static int nrf52_ioctl(struct file *filep, int cmd, unsigned long arg)
|
||||
{
|
||||
return -ENOTTY;
|
||||
struct inode *inode = filep->f_inode;
|
||||
struct uart_dev_s *dev = inode->i_private;
|
||||
struct nrf52_dev_s *priv = (struct nrf52_dev_s *)dev->priv;
|
||||
struct uart_config_s *config = &priv->config;
|
||||
int ret = OK;
|
||||
|
||||
switch (cmd)
|
||||
{
|
||||
#ifdef CONFIG_SERIAL_TERMIOS
|
||||
case TCGETS:
|
||||
{
|
||||
struct termios *termiosp = (struct termios *)arg;
|
||||
|
||||
if (!termiosp)
|
||||
{
|
||||
ret = -EINVAL;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Get baud */
|
||||
|
||||
cfsetispeed(termiosp, config->baud);
|
||||
|
||||
/* Get flags */
|
||||
|
||||
termiosp->c_cflag = ((config->parity != 0) ? PARENB : 0)
|
||||
| ((config->parity == 1) ? PARODD : 0)
|
||||
| ((config->stopbits2) ? CSTOPB : 0) |
|
||||
#ifdef CONFIG_SERIAL_OFLOWCONTROL
|
||||
((config->oflow) ? CCTS_OFLOW : 0) |
|
||||
#endif
|
||||
#ifdef CONFIG_SERIAL_IFLOWCONTROL
|
||||
((config->iflow) ? CRTS_IFLOW : 0) |
|
||||
#endif
|
||||
CS8;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case TCSETS:
|
||||
{
|
||||
struct termios *termiosp = (struct termios *)arg;
|
||||
|
||||
if (!termiosp)
|
||||
{
|
||||
ret = -EINVAL;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Perform some sanity checks before accepting any changes */
|
||||
|
||||
if ((termiosp->c_cflag & CSIZE) != CS8)
|
||||
{
|
||||
ret = -EINVAL;
|
||||
break;
|
||||
}
|
||||
|
||||
#ifndef HAVE_UART_STOPBITS
|
||||
if ((termiosp->c_cflag & CSTOPB) != 0)
|
||||
{
|
||||
ret = -EINVAL;
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (termiosp->c_cflag & PARODD)
|
||||
{
|
||||
ret = -EINVAL;
|
||||
break;
|
||||
}
|
||||
|
||||
/* TODO: CCTS_OFLOW and CRTS_IFLOW */
|
||||
|
||||
/* Parity */
|
||||
|
||||
if (termiosp->c_cflag & PARENB)
|
||||
{
|
||||
config->parity = (termiosp->c_cflag & PARODD) ? 1 : 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
config->parity = 0;
|
||||
}
|
||||
|
||||
#ifdef HAVE_UART_STOPBITS
|
||||
/* Stop bits */
|
||||
|
||||
config->stopbits2 = (termiosp->c_cflag & CSTOPB) != 0;
|
||||
#endif
|
||||
|
||||
/* Note that only cfgetispeed is used because we have knowledge
|
||||
* that only one speed is supported.
|
||||
*/
|
||||
|
||||
config->baud = cfgetispeed(termiosp);
|
||||
|
||||
/* Effect the changes */
|
||||
|
||||
nrf52_set_format(dev);
|
||||
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
|
||||
default:
|
||||
{
|
||||
ret = -ENOTTY;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
|
Loading…
Reference in New Issue
Block a user