Last active
June 16, 2024 17:02
-
-
Save lupyuen/4df6624c9691149099f177a18618e6a7 to your computer and use it in GitHub Desktop.
Apache NuttX RTOS 16550 UART Driver: Print Baud Divisor. See https://lupyuen.github.io/articles/release#appendix-uart-clock-for-jh7110
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Output for Star64 JH7110: dlm=0x0, dll=0xd | |
// Output for Milk-V Duo S / Sophgo SG2000: dlm=0x0, dll=0xe | |
/**************************************************************************** | |
* Name: u16550_setup | |
* | |
* Description: | |
* Configure the UART baud, bits, parity, fifos, etc. This | |
* method is called the first time that the serial port is | |
* opened. | |
* | |
****************************************************************************/ | |
static int u16550_setup(FAR struct uart_dev_s *dev) | |
{ | |
#ifndef CONFIG_16550_SUPRESS_CONFIG | |
FAR struct u16550_s *priv = (FAR struct u16550_s *)dev->priv; | |
uint16_t div; | |
uint32_t lcr; | |
#if defined(CONFIG_SERIAL_IFLOWCONTROL) || defined(CONFIG_SERIAL_OFLOWCONTROL) | |
uint32_t mcr; | |
#endif | |
/* Clear fifos */ | |
u16550_serialout(priv, UART_FCR_OFFSET, | |
(UART_FCR_RXRST | UART_FCR_TXRST)); | |
/* Set trigger */ | |
u16550_serialout(priv, UART_FCR_OFFSET, | |
(UART_FCR_FIFOEN | UART_FCR_RXTRIGGER_8)); | |
/* Set up the IER */ | |
priv->ier = u16550_serialin(priv, UART_IER_OFFSET); | |
/* Set up the LCR */ | |
lcr = 0; | |
switch (priv->bits) | |
{ | |
case 5 : | |
lcr |= UART_LCR_WLS_5BIT; | |
break; | |
case 6 : | |
lcr |= UART_LCR_WLS_6BIT; | |
break; | |
case 7 : | |
lcr |= UART_LCR_WLS_7BIT; | |
break; | |
default: | |
case 8 : | |
lcr |= UART_LCR_WLS_8BIT; | |
break; | |
} | |
if (priv->stopbits2) | |
{ | |
lcr |= UART_LCR_STB; | |
} | |
if (priv->parity == 1) | |
{ | |
lcr |= UART_LCR_PEN; | |
} | |
else if (priv->parity == 2) | |
{ | |
lcr |= (UART_LCR_PEN | UART_LCR_EPS); | |
} | |
#ifdef CONFIG_16550_WAIT_LCR | |
/* Wait till UART is not busy before setting LCR */ | |
if (u16550_wait(priv) < 0) | |
{ | |
_err("UART wait failed\n"); | |
return ERROR; | |
} | |
#endif /* CONFIG_16550_WAIT_LCR */ | |
/* Enter DLAB=1 */ | |
u16550_serialout(priv, UART_LCR_OFFSET, (lcr | UART_LCR_DLAB)); | |
uint32_t dlm = u16550_serialin(priv, UART_DLM_OFFSET);//// | |
uint32_t dll = u16550_serialin(priv, UART_DLL_OFFSET);//// | |
#ifdef TODO //// | |
/* Set the BAUD divisor */ | |
div = u16550_divisor(priv); | |
u16550_serialout(priv, UART_DLM_OFFSET, div >> 8); | |
u16550_serialout(priv, UART_DLL_OFFSET, div & 0xff); | |
#endif //// TODO | |
#ifdef CONFIG_16550_WAIT_LCR | |
/* Wait till UART is not busy before setting LCR */ | |
if (u16550_wait(priv) < 0) | |
{ | |
_err("UART wait failed\n"); | |
return ERROR; | |
} | |
#endif /* CONFIG_16550_WAIT_LCR */ | |
/* Clear DLAB */ | |
u16550_serialout(priv, UART_LCR_OFFSET, lcr); | |
/* Configure the FIFOs */ | |
u16550_serialout(priv, UART_FCR_OFFSET, | |
(UART_FCR_RXTRIGGER_8 | UART_FCR_TXRST | UART_FCR_RXRST | | |
UART_FCR_FIFOEN)); | |
/* Set up the auto flow control */ | |
#if defined(CONFIG_SERIAL_IFLOWCONTROL) || defined(CONFIG_SERIAL_OFLOWCONTROL) | |
mcr = u16550_serialin(priv, UART_MCR_OFFSET); | |
if (priv->flow) | |
{ | |
mcr |= UART_MCR_AFCE; | |
} | |
else | |
{ | |
mcr &= ~UART_MCR_AFCE; | |
} | |
mcr |= UART_MCR_RTS; | |
u16550_serialout(priv, UART_MCR_OFFSET, mcr); | |
#endif /* defined(CONFIG_SERIAL_IFLOWCONTROL) || defined(CONFIG_SERIAL_OFLOWCONTROL) */ | |
/* Reconfigure DMA Rx timeout value */ | |
#ifdef HAVE_16550_UART_DMA | |
u16550_dmarxconfig(dev); | |
#endif | |
#endif | |
_info("dlm=0x%x, dll=0x%x\n", dlm, dll);//// | |
return OK; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment