Line 56... |
Line 56... |
void uart_recv_char(void *dat);
|
void uart_recv_char(void *dat);
|
void uart_check_vapi(void *dat);
|
void uart_check_vapi(void *dat);
|
void uart_check_char(void *dat);
|
void uart_check_char(void *dat);
|
static void uart_sched_recv_check(struct dev_16450 *uart);
|
static void uart_sched_recv_check(struct dev_16450 *uart);
|
static void uart_vapi_cmd(void *dat);
|
static void uart_vapi_cmd(void *dat);
|
|
static void uart_clear_int(struct dev_16450 *uart, int intr);
|
void uart_tx_send(void *dat);
|
void uart_tx_send(void *dat);
|
|
|
/* Number of clock cycles (one clock cycle is one call to the uart_clock())
|
/* Number of clock cycles (one clock cycle is one call to the uart_clock())
|
before a single character is transmitted or received. */
|
before a single character is transmitted or received. */
|
static unsigned long char_clks(int dll, int dlh, int lcr)
|
static unsigned long char_clks(int dll, int dlh, int lcr)
|
Line 82... |
Line 83... |
bauds_per_char += 10 + ((lcr & 0x3) << 1);
|
bauds_per_char += 10 + ((lcr & 0x3) << 1);
|
|
|
return (char_clks * bauds_per_char) >> 1;
|
return (char_clks * bauds_per_char) >> 1;
|
}
|
}
|
|
|
|
/*---------------------------------------------------[ Interrupt handling ]---*/
|
|
/* Signals the specified interrupt. If a higher priority interrupt is already
|
|
* pending, do nothing */
|
|
static void uart_int_msi(void *dat)
|
|
{
|
|
struct dev_16450 *uart = dat;
|
|
|
|
uart->istat.ints |= 1 << UART_IIR_MSI;
|
|
|
|
if(!(uart->regs.ier & UART_IER_MSI))
|
|
return;
|
|
|
|
if((uart->regs.iir & UART_IIR_NO_INT) || (uart->regs.iir == UART_IIR_MSI)) {
|
|
TRACE("Raiseing modem status interrupt\n");
|
|
uart_clear_int(uart, uart->regs.iir);
|
|
|
|
uart->regs.iir = UART_IIR_MSI;
|
|
SCHED_ADD(uart_int_msi, dat, UART_CLOCK_DIVIDER);
|
|
report_interrupt(uart->irq);
|
|
}
|
|
}
|
|
|
|
static void uart_int_thri(void *dat)
|
|
{
|
|
struct dev_16450 *uart = dat;
|
|
|
|
uart->istat.ints |= 1 << UART_IIR_THRI;
|
|
|
|
if(!(uart->regs.ier & UART_IER_THRI))
|
|
return;
|
|
|
|
if((uart->regs.iir & UART_IIR_NO_INT) || (uart->regs.iir == UART_IIR_MSI) ||
|
|
(uart->regs.iir == UART_IIR_THRI)) {
|
|
TRACE("Raiseing transmitter holding register interrupt\n");
|
|
uart_clear_int(uart, uart->regs.iir);
|
|
|
|
uart->regs.iir = UART_IIR_THRI;
|
|
SCHED_ADD(uart_int_thri, dat, UART_CLOCK_DIVIDER);
|
|
report_interrupt(uart->irq);
|
|
}
|
|
}
|
|
|
|
static void uart_int_cti(void *dat)
|
|
{
|
|
struct dev_16450 *uart = dat;
|
|
|
|
uart->istat.ints |= 1 << UART_IIR_CTI;
|
|
|
|
if(!(uart->regs.ier & UART_IER_RDI))
|
|
return;
|
|
|
|
if((uart->regs.iir != UART_IIR_RLSI) && (uart->regs.iir != UART_IIR_RDI)) {
|
|
TRACE("Raiseing character timeout interrupt\n");
|
|
uart_clear_int(uart, uart->regs.iir);
|
|
|
|
uart->regs.iir = UART_IIR_CTI;
|
|
SCHED_ADD(uart_int_cti, dat, UART_CLOCK_DIVIDER);
|
|
report_interrupt(uart->irq);
|
|
}
|
|
}
|
|
|
|
static void uart_int_rdi(void *dat)
|
|
{
|
|
struct dev_16450 *uart = dat;
|
|
|
|
uart->istat.ints |= 1 << UART_IIR_RDI;
|
|
|
|
if(!(uart->regs.ier & UART_IER_RDI))
|
|
return;
|
|
|
|
if(uart->regs.iir != UART_IIR_RLSI) {
|
|
TRACE("Raiseing receiver data interrupt\n");
|
|
uart_clear_int(uart, uart->regs.iir);
|
|
|
|
uart->regs.iir = UART_IIR_RDI;
|
|
SCHED_ADD(uart_int_rdi, dat, UART_CLOCK_DIVIDER);
|
|
report_interrupt(uart->irq);
|
|
}
|
|
}
|
|
|
|
static void uart_int_rlsi(void *dat)
|
|
{
|
|
struct dev_16450 *uart = dat;
|
|
|
|
uart->istat.ints |= 1 << UART_IIR_RLSI;
|
|
|
|
if(!(uart->regs.ier & UART_IER_RLSI))
|
|
return;
|
|
|
|
uart_clear_int(uart, uart->regs.iir);
|
|
|
|
TRACE("Raiseing receiver line status interrupt\n");
|
|
|
|
/* Highest priority interrupt */
|
|
uart->regs.iir = UART_IIR_RLSI;
|
|
SCHED_ADD(uart_int_rlsi, dat, UART_CLOCK_DIVIDER);
|
|
report_interrupt(uart->irq);
|
|
}
|
|
|
|
/* Checks to see if an RLSI interrupt is due and schedules one if need be */
|
|
static void uart_check_rlsi(void *dat)
|
|
{
|
|
struct dev_16450 *uart = dat;
|
|
|
|
if(uart->regs.lsr & (UART_LSR_OVRRUN | UART_LSR_PARITY | UART_LSR_FRAME |
|
|
UART_LSR_BREAK))
|
|
uart_int_rlsi(uart);
|
|
}
|
|
|
|
/* Checks to see if an RDI interrupt is due and schedules one if need be */
|
|
static void uart_check_rdi(void *dat)
|
|
{
|
|
struct dev_16450 *uart = dat;
|
|
|
|
if(uart->istat.rxbuf_full >= UART_FIFO_TRIGGER(uart->regs.fcr >> 6))
|
|
uart_int_rdi(uart);
|
|
}
|
|
|
|
/* Raises the next highest priority interrupt */
|
|
static void uart_next_int(void *dat)
|
|
{
|
|
struct dev_16450 *uart = dat;
|
|
|
|
/* Interrupt detection in proper priority order. */
|
|
if((uart->istat.ints & (1 << UART_IIR_RLSI)) &&
|
|
(uart->regs.ier & UART_IER_RLSI))
|
|
uart_int_rlsi(uart);
|
|
else if((uart->istat.ints & (1 << UART_IIR_RDI)) &&
|
|
(uart->regs.ier & UART_IER_RDI))
|
|
uart_int_rdi(uart);
|
|
else if((uart->istat.ints & (1 << UART_IIR_CTI)) &&
|
|
(uart->regs.ier & UART_IER_RDI))
|
|
uart_int_cti(uart);
|
|
else if((uart->istat.ints & (1 << UART_IIR_THRI)) &&
|
|
(uart->regs.ier & UART_IER_THRI))
|
|
uart_int_thri(uart);
|
|
else if((uart->istat.ints & (1 << UART_IIR_MSI)) &&
|
|
(uart->regs.ier & UART_IER_MSI))
|
|
uart_int_msi(uart);
|
|
else
|
|
uart->regs.iir = UART_IIR_NO_INT;
|
|
}
|
|
|
|
/* Clears potentially pending interrupts */
|
|
static void uart_clear_int(struct dev_16450 *uart, int intr)
|
|
{
|
|
uart->istat.ints &= ~(1 << intr);
|
|
|
|
/* Short-circuit most likely case */
|
|
if(uart->regs.iir == UART_IIR_NO_INT)
|
|
return;
|
|
|
|
if(intr != uart->regs.iir)
|
|
return;
|
|
|
|
TRACE("Clearing interrupt 0x%x\n", intr);
|
|
|
|
uart->regs.iir = UART_IIR_NO_INT;
|
|
|
|
switch(intr) {
|
|
case UART_IIR_RLSI:
|
|
SCHED_FIND_REMOVE(uart_int_rlsi, uart);
|
|
break;
|
|
case UART_IIR_RDI:
|
|
SCHED_FIND_REMOVE(uart_int_rdi, uart);
|
|
break;
|
|
case UART_IIR_CTI:
|
|
SCHED_FIND_REMOVE(uart_int_cti, uart);
|
|
break;
|
|
case UART_IIR_THRI:
|
|
SCHED_FIND_REMOVE(uart_int_thri, uart);
|
|
break;
|
|
case UART_IIR_MSI:
|
|
SCHED_FIND_REMOVE(uart_int_msi, uart);
|
|
break;
|
|
}
|
|
|
|
/* Schedule this job as there is no rush to send the next interrupt (the or.
|
|
* code is probably still running with interrupts disabled and this function
|
|
* is called from the uart_{read,write}_byte functions. */
|
|
SCHED_ADD(uart_next_int, uart, 0);
|
|
}
|
|
|
/*----------------------------------------------------[ Transmitter logic ]---*/
|
/*----------------------------------------------------[ Transmitter logic ]---*/
|
/* Sends the data in the shift register to the outside world */
|
/* Sends the data in the shift register to the outside world */
|
static void send_char (struct dev_16450 *uart, int bits_send)
|
static void send_char (struct dev_16450 *uart, int bits_send)
|
{
|
{
|
PRINTF ("%c", (char)uart->iregs.txser);
|
PRINTF ("%c", (char)uart->iregs.txser);
|
Line 220... |
Line 404... |
/* When UART is in either character mode, i.e. 16450 emulation mode, or FIFO
|
/* When UART is in either character mode, i.e. 16450 emulation mode, or FIFO
|
* mode, the THRE interrupt is raised when THR transitions from full to empty.
|
* mode, the THRE interrupt is raised when THR transitions from full to empty.
|
*/
|
*/
|
if (!uart->istat.txbuf_full) {
|
if (!uart->istat.txbuf_full) {
|
uart->regs.lsr |= UART_LSR_TXBUFE;
|
uart->regs.lsr |= UART_LSR_TXBUFE;
|
uart->istat.thre_int = 1;
|
uart_int_thri(uart);
|
}
|
}
|
}
|
}
|
|
|
/*-------------------------------------------------------[ Receiver logic ]---*/
|
/*-------------------------------------------------------[ Receiver logic ]---*/
|
/* Adds a character to the RX FIFO */
|
/* Adds a character to the RX FIFO */
|
static void uart_add_char (struct dev_16450 *uart, int ch)
|
static void uart_add_char (struct dev_16450 *uart, int ch)
|
{
|
{
|
uart->regs.lsr |= UART_LSR_RDRDY;
|
uart->regs.lsr |= UART_LSR_RDRDY;
|
uart->istat.timeout_count = 0;
|
uart_clear_int(uart, UART_IIR_CTI);
|
|
SCHED_FIND_REMOVE(uart_int_cti, uart);
|
|
SCHED_ADD(uart_int_cti, uart,
|
|
uart->char_clks * UART_CHAR_TIMEOUT * UART_CLOCK_DIVIDER);
|
|
|
if (uart->istat.rxbuf_full + 1 > uart->fifo_len) {
|
if (uart->istat.rxbuf_full + 1 > uart->fifo_len) {
|
uart->regs.lsr |= UART_LSR_OVRRUN | UART_LSR_RXERR;
|
uart->regs.lsr |= UART_LSR_OVRRUN | UART_LSR_RXERR;
|
|
uart_int_rlsi(uart);
|
} else {
|
} else {
|
TRACE("add %02x\n", ch);
|
TRACE("add %02x\n", ch);
|
uart->regs.rxbuf[uart->istat.rxbuf_head] = ch;
|
uart->regs.rxbuf[uart->istat.rxbuf_head] = ch;
|
uart->istat.rxbuf_head = (uart->istat.rxbuf_head + 1) % uart->fifo_len;
|
uart->istat.rxbuf_head = (uart->istat.rxbuf_head + 1) % uart->fifo_len;
|
if(!uart->istat.rxbuf_full++) {
|
if(!uart->istat.rxbuf_full++) {
|
uart->regs.lsr |= ch >> 8;
|
uart->regs.lsr |= ch >> 8;
|
|
uart_check_rlsi(uart);
|
}
|
}
|
}
|
}
|
|
uart_check_rdi(uart);
|
}
|
}
|
|
|
/* Called when a break sequence is about to start. It stops receiveing
|
/* Called when a break sequence is about to start. It stops receiveing
|
* characters and schedules the uart_recv_break to send the break */
|
* characters and schedules the uart_recv_break to send the break */
|
void uart_recv_break_start(void *dat)
|
void uart_recv_break_start(void *dat)
|
Line 369... |
Line 559... |
if(!uart->istat.txbuf_full++ && (uart->regs.lsr & UART_LSR_TXSERE))
|
if(!uart->istat.txbuf_full++ && (uart->regs.lsr & UART_LSR_TXSERE))
|
SCHED_ADD(uart_tx_send, uart, 0);
|
SCHED_ADD(uart_tx_send, uart, 0);
|
} else
|
} else
|
uart->regs.txbuf[uart->istat.txbuf_head] = value;
|
uart->regs.txbuf[uart->istat.txbuf_head] = value;
|
|
|
if (uart->regs.iir & UART_IIR_THRI)
|
uart_clear_int(uart, UART_IIR_THRI);
|
uart->istat.thre_int = 0;
|
|
break;
|
break;
|
case UART_FCR:
|
case UART_FCR:
|
uart->regs.fcr = value & UART_VALID_FCR;
|
uart->regs.fcr = value & UART_VALID_FCR;
|
if ((uart->fifo_len == 1 && (value & UART_FCR_FIE))
|
if ((uart->fifo_len == 1 && (value & UART_FCR_FIE))
|
|| (uart->fifo_len != 1 && !(value & UART_FCR_FIE)))
|
|| (uart->fifo_len != 1 && !(value & UART_FCR_FIE)))
|
Line 383... |
Line 572... |
if (value & UART_FCR_RTXFI) {
|
if (value & UART_FCR_RTXFI) {
|
uart->istat.txbuf_head = uart->istat.txbuf_tail = 0;
|
uart->istat.txbuf_head = uart->istat.txbuf_tail = 0;
|
uart->istat.txbuf_full = 0;
|
uart->istat.txbuf_full = 0;
|
uart->regs.lsr |= UART_LSR_TXBUFE;
|
uart->regs.lsr |= UART_LSR_TXBUFE;
|
|
|
// For FIFO-mode only, THRE interrupt is set when THR and FIFO are empty
|
/* For FIFO-mode only, THRE interrupt is set when THR and FIFO are empty
|
uart->istat.thre_int = (uart->fifo_len == 16);
|
*/
|
|
if(uart->fifo_len == 16)
|
|
SCHED_ADD(uart_int_thri, uart, 0);
|
|
|
SCHED_FIND_REMOVE(uart_tx_send, uart);
|
SCHED_FIND_REMOVE(uart_tx_send, uart);
|
}
|
}
|
if (value & UART_FCR_RRXFI) {
|
if (value & UART_FCR_RRXFI) {
|
uart->istat.rxbuf_head = uart->istat.rxbuf_tail = 0;
|
uart->istat.rxbuf_head = uart->istat.rxbuf_tail = 0;
|
uart->istat.rxbuf_full = 0;
|
uart->istat.rxbuf_full = 0;
|
uart->regs.lsr &= ~UART_LSR_RDRDY;
|
uart->regs.lsr &= ~UART_LSR_RDRDY;
|
|
uart_clear_int(uart, UART_IIR_RDI);
|
|
uart_clear_int(uart, UART_IIR_CTI);
|
}
|
}
|
break;
|
break;
|
case UART_IER:
|
case UART_IER:
|
uart->regs.ier = value & UART_VALID_IER;
|
uart->regs.ier = value & UART_VALID_IER;
|
|
SCHED_ADD(uart_next_int, uart, 0);
|
break;
|
break;
|
case UART_LCR:
|
case UART_LCR:
|
if((uart->regs.lcr & UART_LCR_SBC) != (value & UART_LCR_SBC)) {
|
if((uart->regs.lcr & UART_LCR_SBC) != (value & UART_LCR_SBC)) {
|
if((value & UART_LCR_SBC) && !(uart->regs.lsr & UART_LSR_TXSERE)) {
|
if((value & UART_LCR_SBC) && !(uart->regs.lsr & UART_LSR_TXSERE)) {
|
/* Schedule a job to send the break char */
|
/* Schedule a job to send the break char */
|
Line 464... |
Line 658... |
uart->istat.rxbuf_full--;
|
uart->istat.rxbuf_full--;
|
TRACE("Reading %"PRIx8" out of RX FIFO\n", value);
|
TRACE("Reading %"PRIx8" out of RX FIFO\n", value);
|
} else
|
} else
|
TRACE("Trying to read out of RX FIFO but it's empty!\n");
|
TRACE("Trying to read out of RX FIFO but it's empty!\n");
|
|
|
if(uart->istat.rxbuf_full)
|
uart_clear_int(uart, UART_IIR_RDI);
|
|
uart_clear_int(uart, UART_IIR_CTI);
|
|
SCHED_FIND_REMOVE(uart_int_cti, uart);
|
|
|
|
if(uart->istat.rxbuf_full) {
|
uart->regs.lsr |= UART_LSR_RDRDY | uart->regs.rxbuf[uart->istat.rxbuf_tail] >> 8;
|
uart->regs.lsr |= UART_LSR_RDRDY | uart->regs.rxbuf[uart->istat.rxbuf_tail] >> 8;
|
else
|
SCHED_ADD(uart_int_cti, uart,
|
|
uart->char_clks * UART_CHAR_TIMEOUT * UART_CLOCK_DIVIDER);
|
|
/* Since we're not allowed to raise interrupts from read/write functions
|
|
* schedule them to run just after we have executed this read
|
|
* instruction. */
|
|
SCHED_ADD(uart_check_rlsi, uart, 0);
|
|
SCHED_ADD(uart_check_rdi, uart, 0);
|
|
} else {
|
uart->regs.lsr &= ~UART_LSR_RDRDY;
|
uart->regs.lsr &= ~UART_LSR_RDRDY;
|
|
}
|
uart->istat.timeout_count = 0;
|
|
break;
|
break;
|
case UART_IER:
|
case UART_IER:
|
value = uart->regs.ier & UART_VALID_IER;
|
value = uart->regs.ier & UART_VALID_IER;
|
break;
|
break;
|
case UART_IIR:
|
case UART_IIR:
|
value = (uart->regs.iir & UART_VALID_IIR) | 0xc0;
|
value = (uart->regs.iir & UART_VALID_IIR) | 0xc0;
|
if (uart->regs.iir & UART_IIR_THRI)
|
/* Only clear the thri interrupt if it is the one we are repporting */
|
uart->istat.thre_int = 0;
|
if(uart->regs.iir == UART_IIR_THRI)
|
|
uart_clear_int(uart, UART_IIR_THRI);
|
break;
|
break;
|
case UART_LCR:
|
case UART_LCR:
|
value = uart->regs.lcr & UART_VALID_LCR;
|
value = uart->regs.lcr & UART_VALID_LCR;
|
break;
|
break;
|
case UART_MCR:
|
case UART_MCR:
|
Line 490... |
Line 695... |
case UART_LSR:
|
case UART_LSR:
|
value = uart->regs.lsr & UART_VALID_LSR;
|
value = uart->regs.lsr & UART_VALID_LSR;
|
uart->regs.lsr &=
|
uart->regs.lsr &=
|
~(UART_LSR_OVRRUN | UART_LSR_BREAK | UART_LSR_PARITY
|
~(UART_LSR_OVRRUN | UART_LSR_BREAK | UART_LSR_PARITY
|
| UART_LSR_FRAME | UART_LSR_RXERR);
|
| UART_LSR_FRAME | UART_LSR_RXERR);
|
|
/* Clear potentially pending RLSI interrupt */
|
|
uart_clear_int(uart, UART_IIR_RLSI);
|
break;
|
break;
|
case UART_MSR:
|
case UART_MSR:
|
value = uart->regs.msr & UART_VALID_MSR;
|
value = uart->regs.msr & UART_VALID_MSR;
|
uart->regs.msr = 0;
|
uart->regs.msr = 0;
|
|
uart_clear_int(uart, UART_IIR_MSI);
|
break;
|
break;
|
case UART_SCR:
|
case UART_SCR:
|
value = uart->regs.scr;
|
value = uart->regs.scr;
|
break;
|
break;
|
default:
|
default:
|
Line 645... |
Line 853... |
uart->regs.msr |= ((uart->regs.mcr & UART_MCR_AUX2) << 4);
|
uart->regs.msr |= ((uart->regs.mcr & UART_MCR_AUX2) << 4);
|
uart->regs.msr |= ((uart->regs.mcr & UART_MCR_AUX1) << 4);
|
uart->regs.msr |= ((uart->regs.mcr & UART_MCR_AUX1) << 4);
|
uart->regs.msr |= ((uart->regs.mcr & UART_MCR_RTS) << 3);
|
uart->regs.msr |= ((uart->regs.mcr & UART_MCR_RTS) << 3);
|
uart->regs.msr |= ((uart->regs.mcr & UART_MCR_DTR) << 5);
|
uart->regs.msr |= ((uart->regs.mcr & UART_MCR_DTR) << 5);
|
}
|
}
|
|
|
if (uart->regs.lsr & UART_LSR_RDRDY)
|
|
uart->istat.timeout_count++;
|
|
|
|
/* Interrupt detection in proper priority order. */
|
|
uart->regs.iir = UART_IIR_NO_INT;
|
|
if (uart->regs.ier & UART_IER_RLSI && /* Receiver LS */
|
|
uart->regs.lsr & (UART_LSR_OVRRUN | UART_LSR_PARITY
|
|
| UART_LSR_FRAME | UART_LSR_BREAK)) {
|
|
uart->regs.iir = UART_IIR_RLSI;
|
|
} else if ((uart->regs.ier & UART_IER_RDI) /* RD available */
|
|
&& (uart->istat.rxbuf_full >= UART_FIFO_TRIGGER(uart->regs.fcr >> 6))
|
|
&& (uart->regs.lsr & UART_LSR_RDRDY)) {
|
|
uart->regs.iir = UART_IIR_RDI;
|
|
} else if ((uart->regs.ier & UART_IER_RDI) /* timeout */
|
|
&& (uart->istat.timeout_count >= UART_CHAR_TIMEOUT * uart->char_clks)
|
|
&& (uart->istat.rxbuf_head != uart->istat.rxbuf_tail)) {
|
|
uart->regs.iir = UART_IIR_CTI;
|
|
} else if (uart->regs.ier & UART_IER_THRI && /* Transm. empty */
|
|
uart->istat.thre_int == 1) {
|
|
uart->regs.iir = UART_IIR_THRI;
|
|
} else if (uart->regs.ier & UART_IER_MSI && /* Modem status */
|
|
uart->regs.msr & (UART_MSR_DCTS | UART_MSR_DDSR
|
|
| UART_MSR_TERI | UART_MSR_DDCD)) {
|
|
uart->regs.iir = UART_IIR_MSI;
|
|
}
|
|
if (!(uart->regs.iir & UART_IIR_NO_INT)) {
|
|
TRACE("\tuart->regs.iir = %i\t", uart->regs.iir);
|
|
report_interrupt(uart->irq);
|
|
}
|
|
}
|
}
|
|
|
/* Reset. It initializes all registers of all UART devices to zero values,
|
/* Reset. It initializes all registers of all UART devices to zero values,
|
(re)opens all RX/TX file streams and places devices in memory address
|
(re)opens all RX/TX file streams and places devices in memory address
|
space. */
|
space. */
|
Line 710... |
Line 888... |
uart->istat.rxbuf_head = uart->istat.rxbuf_tail = 0;
|
uart->istat.rxbuf_head = uart->istat.rxbuf_tail = 0;
|
uart->istat.txbuf_head = uart->istat.txbuf_tail = 0;
|
uart->istat.txbuf_head = uart->istat.txbuf_tail = 0;
|
|
|
uart->istat.txbuf_full = uart->istat.rxbuf_full = 0;
|
uart->istat.txbuf_full = uart->istat.rxbuf_full = 0;
|
|
|
uart->istat.thre_int = 0;
|
|
uart->istat.timeout_count = 0;
|
|
|
|
// For FIFO-mode only, THRE interrupt is set when both THR and FIFO are empty
|
|
uart->istat.thre_int = (uart->fifo_len == 16);
|
|
|
|
uart->char_clks = 0;
|
uart->char_clks = 0;
|
|
|
uart->iregs.txser = 0;
|
uart->iregs.txser = 0;
|
uart->iregs.rxser = 0;
|
uart->iregs.rxser = 0;
|
uart->iregs.loopback = 0;
|
uart->iregs.loopback = 0;
|
uart->istat.receiveing = 0;
|
uart->istat.receiveing = 0;
|
uart->istat.recv_break = 0;
|
uart->istat.recv_break = 0;
|
|
uart->istat.ints = 0;
|
|
|
memset(uart->regs.txbuf, 0, sizeof(uart->regs.txbuf));
|
memset(uart->regs.txbuf, 0, sizeof(uart->regs.txbuf));
|
memset(uart->regs.rxbuf, 0, sizeof(uart->regs.rxbuf));
|
memset(uart->regs.rxbuf, 0, sizeof(uart->regs.rxbuf));
|
|
|
uart->regs.dll = 0;
|
uart->regs.dll = 0;
|
uart->regs.dlh = 0;
|
uart->regs.dlh = 0;
|
uart->regs.ier = 0;
|
uart->regs.ier = 0;
|
uart->regs.iir = 0;
|
uart->regs.iir = UART_IIR_NO_INT;
|
uart->regs.fcr = 0;
|
uart->regs.fcr = 0;
|
uart->regs.lcr = UART_LCR_RESET;
|
uart->regs.lcr = UART_LCR_RESET;
|
uart->regs.mcr = 0;
|
uart->regs.mcr = 0;
|
uart->regs.lsr = UART_LSR_TXBUFE | UART_LSR_TXSERE;
|
uart->regs.lsr = UART_LSR_TXBUFE | UART_LSR_TXSERE;
|
uart->regs.msr = 0;
|
uart->regs.msr = 0;
|