📄 uart16550.c
字号:
#include "config.h"
#include "uart16550.h"
/* Generic (hopefully) 16550 uart code for use as a MicroMonitor
* console serial port driver.
*
* The baud-rate divisor can be derived in one of two ways:
* If BRD_115200 is defined, then this code assumes that the full
* set of BRD_XXX definitions are defined (in config.h) and they
* are used. If BRD_115200 is not defined, then this driver assumes
* the getUartDivisor() function is externally provided by the
* port-specific code.
*
* The base address of the UART used as the console port must be
* defined as CONSOLE_UART_BASE (also in config.h).
*
* Also, if the uart is configured in the memory map such that the
* gap between registers is not 1, then set SIO_STEP (see uart16550.h)
* to 2 or 4 appropriately.
*/
#define CONSOLE(offset) *(volatile unsigned char *)(CONSOLE_UART_BASE+offset)
#ifdef MORE_GOTACHAR
extern void MORE_GOTACHAR();
#endif
#ifdef MORE_GETCHAR
extern void MORE_GETCHAR();
#endif
#ifdef MORE_PUTCHAR
extern void MORE_PUTCHAR();
#endif
/* Establish default initialization values that can be overridden
* in config.h:
*/
#ifndef MCTL_DEFAULT
#define MCTL_DEFAULT (SIO_MCTL_DTR | SIO_MCTL_RTS)
#endif
#ifndef FCTL_DEFAULT
#define FCTL_DEFAULT (SIO_FCTL_FEN | SIO_FCTL_RXDC | SIO_FCTL_TXDC)
#endif
#ifndef SPR_DEFAULT
#define SPR_DEFAULT 0x00 // Clear scratchpad
#endif
#ifndef IEN_DEFAULT
#define IEN_DEFAULT 0x00 // Ints used
#endif
#ifndef LCTL_DEFAULT
#define LCTL_DEFAULT SIO_LCTL_W8
#endif
/* getDlLsb():
* Populate hi & lo, default to 9600...
*/
#ifdef BRD_115200
int
getUartDivisor(int baud, unsigned char *hi, unsigned char *lo)
{
switch(baud) {
case 115200:
*lo = BRD_115200;
break;
case 57600:
*lo = BRD_57600;
break;
case 38400:
*lo = BRD_38400;
break;
case 19200:
*lo = BRD_19200;
break;
case 9600:
*lo = BRD_9600;
break;
default:
return(-1);
}
*hi = 0;
return(0);
}
#endif
int
ConsoleBaudSet(int baud)
{
unsigned char tmp, hi, lo;
/* If either getDivisor returns -1 or both hi & lo are zero we
* return failure to indicate that the requested baud rate could
* not be established.
*/
if (getUartDivisor(baud,&hi,&lo) == -1)
return(-1);
if ((hi == 0) && (lo == 0))
return(-1);
tmp = CONSOLE(SIO_LCTL); /* Save linectl reg */
CONSOLE(SIO_LCTL) = SIO_LCTL_DLAB;
CONSOLE(SIO_BAUDLO) = lo; /* Set baud */
CONSOLE(SIO_BAUDHI) = hi;
CONSOLE(SIO_LCTL) = tmp; /* Restore linectl reg */
return(0);
}
void
InitUART(int baud)
{
unsigned char tmp, hi, lo;
getUartDivisor(baud,&hi,&lo);
CONSOLE(SIO_LCTL) = SIO_LCTL_DLAB;
CONSOLE(SIO_BAUDLO) = lo; /* Set baud */
CONSOLE(SIO_BAUDHI) = hi;
CONSOLE(SIO_LCTL) = LCTL_DEFAULT; /* 8-bits, no parity */
CONSOLE(SIO_MCTL) = MCTL_DEFAULT;
tmp = CONSOLE(SIO_LSTAT); /* clear line stat */
tmp = CONSOLE(SIO_RXD); /* read receive buffer */
CONSOLE(SIO_IEN) = IEN_DEFAULT;
CONSOLE(SIO_FCTL) = FCTL_DEFAULT;
CONSOLE(SIO_SPR) = SPR_DEFAULT;
}
int
target_console_empty(void)
{
if (CONSOLE(SIO_LSTAT) & SIO_LSTAT_TRDY)
return(0);
return(1);
}
int
target_putchar(char c)
{
while(!(CONSOLE(SIO_LSTAT) & SIO_LSTAT_TRDY));
CONSOLE(SIO_TXD) = c;
#ifdef MORE_PUTCHAR
MORE_PUTCHAR(c);
#endif
return((int)c);
}
int
target_getchar(void)
{
char c;
#ifdef MORE_GETCHAR
if (MORE_GOTACHAR())
c = MORE_GETCHAR();
else
#endif
c = CONSOLE(SIO_RXD);
return((int)c);
}
int
target_gotachar(void)
{
if (CONSOLE(SIO_LSTAT) & SIO_LSTAT_RRDY)
return(1);
#ifdef MORE_GOTACHAR
if (MORE_GOTACHAR())
return(1);
#endif
return(0);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -