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 ARM_HAVE_MPU_UNIFIED
|
||||||
select ARCH_HAVE_FPU
|
select ARCH_HAVE_FPU
|
||||||
select ARCH_HAVE_PWM_MULTICHAN
|
select ARCH_HAVE_PWM_MULTICHAN
|
||||||
|
select ARCH_HAVE_SERIAL_TERMIOS
|
||||||
---help---
|
---help---
|
||||||
Nordic NRF52 architectures (ARM Cortex-M4).
|
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)
|
static void nrf52_setbaud(uintptr_t base, const struct uart_config_s *config)
|
||||||
{
|
{
|
||||||
uint32_t br = 0;
|
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);
|
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
|
#endif
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: nrf52_sethwflow
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
static void nrf52_sethwflow(uintptr_t base,
|
||||||
|
const struct uart_config_s *config)
|
||||||
|
{
|
||||||
|
/* TODO */
|
||||||
|
}
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Public Functions
|
* Public Functions
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
@ -174,9 +340,9 @@ void nrf52_usart_configure(uintptr_t base,
|
|||||||
putreg32(1, base + NRF52_UART_TASKS_STOPTX_OFFSET);
|
putreg32(1, base + NRF52_UART_TASKS_STOPTX_OFFSET);
|
||||||
putreg32(NRF52_UART_ENABLE_DISABLE, base + NRF52_UART_ENABLE_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 */
|
/* Config GPIO pins for uart */
|
||||||
|
|
||||||
@ -263,3 +429,33 @@ void arm_lowputc(char ch)
|
|||||||
putreg32(1, CONSOLE_BASE + NRF52_UART_TASKS_STOPTX_OFFSET);
|
putreg32(1, CONSOLE_BASE + NRF52_UART_TASKS_STOPTX_OFFSET);
|
||||||
#endif
|
#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 <stdint.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <nrf52_gpio.h>
|
#include <nrf52_gpio.h>
|
||||||
|
#include <nrf52_config.h>
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Public Types
|
* Public Types
|
||||||
@ -114,4 +115,15 @@ void nrf52_usart_disable(uintptr_t base,
|
|||||||
FAR const struct uart_config_s *config);
|
FAR const struct uart_config_s *config);
|
||||||
#endif
|
#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 */
|
#endif /* __ARCH_ARM_SRC_NRF52_NRF52_LOWPUTC_H */
|
||||||
|
@ -49,8 +49,13 @@
|
|||||||
|
|
||||||
#include <nuttx/irq.h>
|
#include <nuttx/irq.h>
|
||||||
#include <nuttx/arch.h>
|
#include <nuttx/arch.h>
|
||||||
|
#include <nuttx/fs/ioctl.h>
|
||||||
#include <nuttx/serial/serial.h>
|
#include <nuttx/serial/serial.h>
|
||||||
|
|
||||||
|
#ifdef CONFIG_SERIAL_TERMIOS
|
||||||
|
# include <termios.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <arch/board/board.h>
|
#include <arch/board/board.h>
|
||||||
|
|
||||||
#include "arm_arch.h"
|
#include "arm_arch.h"
|
||||||
@ -422,6 +427,23 @@ static int nrf52_interrupt(int irq, void *context, FAR void *arg)
|
|||||||
return OK;
|
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
|
* 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)
|
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…
x
Reference in New Issue
Block a user