Forums

LPC2468 UART1 Anomaly

Started by yellowlaser November 13, 2009
I am using an IAR LPC2468 development board and the IAR compiler for a company project. Just recently I noticed a strange issue with UART1. On the LPC2468, UART1 has modem control support but we are not using it. The pin selects use these pins for GPIO.

On rare occasions (once every 10 minutes) I receive on the LPC2468 more bytes than I transmit. The extra byte has always been a null character. The extra byte was always inserted into the valid characters and not clobbering one. As an example I might send ABCDEFG and receive ABCDEFG. Using a protocol analyzer, I am quite sure the sender (a Perl script running on a PC) is not sending the null.

I also know that the sent string has minimal inter character delays. There is NO possibility of a gap in the sent string large enough for a glitch to be interpreted as a start bit and inject a null.

I have all the interrupts enabled and I am decoding all the various reasons. I am never getting any LSR or MSR interrupts just RDA and THRE.

My data rate is 57600 baud or about 176usec per byte. In the ISR I record the time each byte is received. It is always the case that the null byte has come in before the 176 usec has elapsed. Hence I am fairly sure the UART is providing me these bytes as a love offering rather than as real data.

It is always the case that the byte is inserted at the first iteration of an ISR loop. And only if the last loop happened less that 150 usec ago. This would lead me to believe that the UART finishes it business and then "Something happens" before the next character comes in to cause it to generate a new RDA interrupt. But that RDA can't be from having gotten a character as not enough time has gone by!

I have read the errata for the chip and found nothing to do with the UARTs generating extra bytes.
I have read the User Manual and see nothing that would indicate why it is generating an extra byte.
I have Googled with no luck.

I am now placing myself at the mercy of this court.

Has anybody seen this behavior? Anybody have even a guess as to what is happening?

Here is the code for the ISR. Note the check for a null byte in the RDA section. This should not get hit with just simple text strings.

static void Uart1_isr(void)
{
INT32U iir;
INT8U counter;
char data = 0;
BOOLEAN brk = FALSE, got_int = FALSE;
INT8U loops =0;

do {

loops++;

/* Read the interrupt identification register */
iir = U1IIR;

/* If the IntStatus bit is 1, no interrupt happened */
if ((iir & 0x00000001) == 0x1) {
brk = TRUE;

} else {

/* Recognize the interrupt event */
switch (iir&0x0000000E) {

case MODEM_INTR_ID: /* Modem Status */
data = U1MSR; /* Read MSR to clear */
break;

case RLS_INTR_ID: /* Line status change */
uart_ports[1].ls_f_int++;
data = U1LSR;
got_int = TRUE;
break;

case CDI_INTR_ID: /* Read timeout */
uart_ports[1].cdi_p_int++;
/* Do nothing */
got_int = TRUE;
break;

case RDA_INTR_ID: /* Receive data Available */
uart_ports[1].rx_received++;

/* get data from FIFO */
data = U1RBR;

prev_time = time;
time = CTC;
delta = time - prev_time;

/*
* Isolate the problem to the first pass of a new ISR event where the
* previous event occured less than 150 usec ago.
* 5 counts of CTC is about 5 * 1/32768 = 152 usec
* One character time is 10/57600 = 173.6 usec
*/
if (data == '\0') {
(uart_ports[1].nulls)++;
if ((delta < 5) && (loops == 1) ) {
(uart_ports[1].good_cnt)++;
} else {
(uart_ports[1].bad_cnt)++;
}
}
/* Push new data into the receiver buffer */
if(DD_cirbuf_push(&(uart_ports[1].rx_cirbuf), data) == FALSE){
/* if the push fails, add one to number of bytes missed */
(uart_ports[1].rx_missed)++;
}
got_int = TRUE;
break;

case THRE_INTR_ID: /* THRE Interrupt */
/* Transmitter is empty, fill with as much data as possible.
Since the interrupt is for Transmitter Empty and the FIFO
is 16 bytes deep, 15 bytes will fit */
for (counter = 15; counter; counter--) {
/* Pop data from the transmit buffer
If the pop fails, then cirbuf is empty
Otherwise, put data into transmit FIFO */
if(DD_cirbuf_pop(&(uart_ports[1].tx_cirbuf),&data) == FALSE) {
break;
}
else {
uart_ports[1].tx_sent++;
U1THR = data;
}
}
got_int = TRUE;
break;

default:
if(got_int == FALSE){
uart_ports[1].default_int++;
}
/* No interrupt */
brk = TRUE;
break;
} // Switch

} // If interrupt

} while(brk == FALSE);

VICADDRESS = 0; /* Clear interrupt in VIC. */
} /* End of Uart1_isr() */

Here is the code for the initialization of the UART:
void DD_init_uart(Port_num_t uart, INT32U irq_slot)
{
Port_line_coding_t uart_coding;
INT8U tmp;

if(irq_slot != 0){
uart_ports[uart].priority = irq_slot;
}
if(uart_ports[uart].priority == 0){
uart_ports[uart].priority = 15;
}

switch (uart) {
case PORT_0:

break;
case PORT_1:
/* Initialize circular buffers */
DD_cirbuf_init(&(uart_ports[1].tx_cirbuf), (INT16U)PORT1_TX_FEED_SIZE, uart1_tx_buf);
DD_cirbuf_init(&(uart_ports[1].rx_cirbuf), (INT16U)PORT1_RX_FEED_SIZE, uart1_rx_buf);

/* Initialize statistics */
uart_ports[1].good_cnt = 0;
uart_ports[1].bad_cnt = 0;
uart_ports[1].nulls = 0;
uart_ports[1].lsr = &U1LSR;
uart_ports[1].thr = &U1THR;
uart_ports[1].port_vic_addr = VIC_UART1;
uart_ports[1].rx_received = 0;
uart_ports[1].tx_sent = 0;
uart_ports[1].cdi_p_int = 0;
uart_ports[1].ls_f_int = 0;
uart_ports[1].default_int = 0;

/* Enable UART1 */
PCONP_bit.PCUART1 = 1;

/* Word Length =8, no parity , 1 stop */
U1LCR = 0x03;

/* No full modem support */
U1MCR = 0x00;

/* Enable and Clear the UART1 buf, Set RX buf interrupt level to 1 char */
U1FCR = 0x07;

/* Transmit enable */
U1TER_bit.TXEN = 1;

/* Clear pending interrupts */
tmp = U1IER;

/* Enable Interrupts */
U1IER = UART_IER_RBR |
UART_IER_THRE |
UART_IER_LSR |
UART_IER_MSR;

tmp = U1IIR; /* clear interrupt ID */
tmp = U1RBR; /* clear receive register */
tmp = U1LSR; /* clear line status register */

/* put ISR in vectored interrupt controller */
DD_set_vectored_irq((void *)Uart1_isr,uart_ports[uart].priority,VIC_UART1);

break;

case PORT_2:

break;

case PORT_3:

break;

default:
/* bad port */
break;
}

(void)tmp;

if(irq_slot != 0){
/* Set the default line conditions to 9600 8-n-1 */
uart_coding.dw_dte_rate = 9600;
uart_coding.b_stop_bits_format = UART_ONE_STOP_BIT;
uart_coding.b_parity_type = UART_NO_PARITY;
uart_coding.b_data_bits = UART_WORD_WIDTH_8;
DD_set_uart_line_coding(uart, uart_coding);
}

} /* End of DD_init_uart() */
-Skye Sweeney

An Engineer's Guide to the LPC2100 Series

You might want to search the Yahoo archives well back, looking for
issues to do with spurious interrupts. It could be due to another
unrelated program you have that enables and disables interrupts using
the VIC rather than the MSR, possibly inducing a spurious interrupt
(NULL char) if the serial ISR happens to just hit at the right moment.

Cheers,
Bruce

-----Original Message-----
From: l... [mailto:l...] On Behalf
Of yellowlaser
Sent: Friday, 13 November 2009 8:42 AM
To: l...
Subject: [lpc2000] LPC2468 UART1 Anomaly
I am using an IAR LPC2468 development board and the IAR compiler for a
company project. Just recently I noticed a strange issue with UART1. On
the LPC2468, UART1 has modem control support but we are not using it.
The pin selects use these pins for GPIO.

On rare occasions (once every 10 minutes) I receive on the LPC2468 more
bytes than I transmit. The extra byte has always been a null character.
The extra byte was always inserted into the valid characters and not
clobbering one. As an example I might send ABCDEFG and receive
ABCDEFG. Using a protocol analyzer, I am quite sure the sender (a
Perl script running on a PC) is not sending the null.

I also know that the sent string has minimal inter character delays.
There is NO possibility of a gap in the sent string large enough for a
glitch to be interpreted as a start bit and inject a null.

I have all the interrupts enabled and I am decoding all the various
reasons. I am never getting any LSR or MSR interrupts just RDA and THRE.

My data rate is 57600 baud or about 176usec per byte. In the ISR I
record the time each byte is received. It is always the case that the
null byte has come in before the 176 usec has elapsed. Hence I am fairly
sure the UART is providing me these bytes as a love offering rather than
as real data.

It is always the case that the byte is inserted at the first iteration
of an ISR loop. And only if the last loop happened less that 150 usec
ago. This would lead me to believe that the UART finishes it business
and then "Something happens" before the next character comes in to cause
it to generate a new RDA interrupt. But that RDA can't be from having
gotten a character as not enough time has gone by!

I have read the errata for the chip and found nothing to do with the
UARTs generating extra bytes.
I have read the User Manual and see nothing that would indicate why it
is generating an extra byte.
I have Googled with no luck.

I am now placing myself at the mercy of this court.

Has anybody seen this behavior? Anybody have even a guess as to what is
happening?

Here is the code for the ISR. Note the check for a null byte in the RDA
section. This should not get hit with just simple text strings.

static void Uart1_isr(void)
{
INT32U iir;
INT8U counter;
char data = 0;
BOOLEAN brk = FALSE, got_int = FALSE;
INT8U loops =0;

do {

loops++;

/* Read the interrupt identification register */
iir = U1IIR;

/* If the IntStatus bit is 1, no interrupt happened */
if ((iir & 0x00000001) == 0x1) {
brk = TRUE;

} else {

/* Recognize the interrupt event */
switch (iir&0x0000000E) {

case MODEM_INTR_ID: /* Modem Status */
data = U1MSR; /* Read MSR to clear */
break;

case RLS_INTR_ID: /* Line status change */
uart_ports[1].ls_f_int++;
data = U1LSR;
got_int = TRUE;
break;

case CDI_INTR_ID: /* Read timeout */
uart_ports[1].cdi_p_int++;
/* Do nothing */
got_int = TRUE;
break;

case RDA_INTR_ID: /* Receive data Available */
uart_ports[1].rx_received++;

/* get data from FIFO */
data = U1RBR;

prev_time = time;
time = CTC;
delta = time - prev_time;

/*
* Isolate the problem to the first pass of a new ISR
event where the
* previous event occured less than 150 usec ago.
* 5 counts of CTC is about 5 * 1/32768 = 152 usec
* One character time is 10/57600 = 173.6 usec
*/
if (data == '\0') {
(uart_ports[1].nulls)++;
if ((delta < 5) && (loops == 1) ) {
(uart_ports[1].good_cnt)++;
} else {
(uart_ports[1].bad_cnt)++;
}
}
/* Push new data into the receiver buffer */
if(DD_cirbuf_push(&(uart_ports[1].rx_cirbuf), data) =FALSE){
/* if the push fails, add one to number of bytes
missed */
(uart_ports[1].rx_missed)++;
}
got_int = TRUE;
break;

case THRE_INTR_ID: /* THRE Interrupt */
/* Transmitter is empty, fill with as much data as
possible.
Since the interrupt is for Transmitter Empty and the FIFO
is 16 bytes deep, 15 bytes will fit */
for (counter = 15; counter; counter--) {
/* Pop data from the transmit buffer
If the pop fails, then cirbuf is empty
Otherwise, put data into transmit FIFO */
if(DD_cirbuf_pop(&(uart_ports[1].tx_cirbuf),&data) =FALSE) {
break;
}
else {
uart_ports[1].tx_sent++;
U1THR = data;
}
}
got_int = TRUE;
break;

default:
if(got_int == FALSE){
uart_ports[1].default_int++;
}
/* No interrupt */
brk = TRUE;
break;
} // Switch

} // If interrupt

} while(brk == FALSE);

VICADDRESS = 0; /* Clear interrupt in VIC. */
} /* End of Uart1_isr() */

Here is the code for the initialization of the UART:
void DD_init_uart(Port_num_t uart, INT32U irq_slot)
{
Port_line_coding_t uart_coding;
INT8U tmp;

if(irq_slot != 0){
uart_ports[uart].priority = irq_slot;
}
if(uart_ports[uart].priority == 0){
uart_ports[uart].priority = 15;
}

switch (uart) {
case PORT_0:

break;
case PORT_1:
/* Initialize circular buffers */
DD_cirbuf_init(&(uart_ports[1].tx_cirbuf),
(INT16U)PORT1_TX_FEED_SIZE, uart1_tx_buf);
DD_cirbuf_init(&(uart_ports[1].rx_cirbuf),
(INT16U)PORT1_RX_FEED_SIZE, uart1_rx_buf);

/* Initialize statistics */
uart_ports[1].good_cnt = 0;
uart_ports[1].bad_cnt = 0;
uart_ports[1].nulls = 0;
uart_ports[1].lsr = &U1LSR;
uart_ports[1].thr = &U1THR;
uart_ports[1].port_vic_addr = VIC_UART1;
uart_ports[1].rx_received = 0;
uart_ports[1].tx_sent = 0;
uart_ports[1].cdi_p_int = 0;
uart_ports[1].ls_f_int = 0;
uart_ports[1].default_int = 0;

/* Enable UART1 */
PCONP_bit.PCUART1 = 1;

/* Word Length =8, no parity , 1 stop */
U1LCR = 0x03;

/* No full modem support */
U1MCR = 0x00;

/* Enable and Clear the UART1 buf, Set RX buf interrupt level to
1 char */
U1FCR = 0x07;

/* Transmit enable */
U1TER_bit.TXEN = 1;

/* Clear pending interrupts */
tmp = U1IER;

/* Enable Interrupts */
U1IER = UART_IER_RBR |
UART_IER_THRE |
UART_IER_LSR |
UART_IER_MSR;

tmp = U1IIR; /* clear interrupt ID */
tmp = U1RBR; /* clear receive register */
tmp = U1LSR; /* clear line status register */

/* put ISR in vectored interrupt controller */
DD_set_vectored_irq((void
*)Uart1_isr,uart_ports[uart].priority,VIC_UART1);

break;

case PORT_2:

break;

case PORT_3:

break;

default:
/* bad port */
break;
}

(void)tmp;

if(irq_slot != 0){
/* Set the default line conditions to 9600 8-n-1 */
uart_coding.dw_dte_rate = 9600;
uart_coding.b_stop_bits_format = UART_ONE_STOP_BIT;
uart_coding.b_parity_type = UART_NO_PARITY;
uart_coding.b_data_bits = UART_WORD_WIDTH_8;
DD_set_uart_line_coding(uart, uart_coding);
}

} /* End of DD_init_uart() */
-Skye Sweeney

Bruce,

Thank you very much for the reply. I will indeed spend tomorrow looking at spurious interrupts
and the difference between VIC and MSR blanking. Your reply at least gives me hope that
I might find this problem.

-Skye Sweeney

----- Original Message -----
From: Bruce Paterson
To: l...
Sent: Sunday, November 15, 2009 6:53 PM
Subject: RE: [lpc2000] LPC2468 UART1 Anomaly

You might want to search the Yahoo archives well back, looking for
issues to do with spurious interrupts. It could be due to another
unrelated program you have that enables and disables interrupts using
the VIC rather than the MSR, possibly inducing a spurious interrupt
(NULL char) if the serial ISR happens to just hit at the right moment.

Cheers,
Bruce

-----Original Message-----
From: l... [mailto:l...] On Behalf
Of yellowlaser
Sent: Friday, 13 November 2009 8:42 AM
To: l...
Subject: [lpc2000] LPC2468 UART1 Anomaly

I am using an IAR LPC2468 development board and the IAR compiler for a
company project. Just recently I noticed a strange issue with UART1. On
the LPC2468, UART1 has modem control support but we are not using it.
The pin selects use these pins for GPIO.

On rare occasions (once every 10 minutes) I receive on the LPC2468 more
bytes than I transmit. The extra byte has always been a null character.
The extra byte was always inserted into the valid characters and not
clobbering one. As an example I might send ABCDEFG and receive
ABCDEFG. Using a protocol analyzer, I am quite sure the sender (a
Perl script running on a PC) is not sending the null.

I also know that the sent string has minimal inter character delays.
There is NO possibility of a gap in the sent string large enough for a
glitch to be interpreted as a start bit and inject a null.

I have all the interrupts enabled and I am decoding all the various
reasons. I am never getting any LSR or MSR interrupts just RDA and THRE.

My data rate is 57600 baud or about 176usec per byte. In the ISR I
record the time each byte is received. It is always the case that the
null byte has come in before the 176 usec has elapsed. Hence I am fairly
sure the UART is providing me these bytes as a love offering rather than
as real data.

It is always the case that the byte is inserted at the first iteration
of an ISR loop. And only if the last loop happened less that 150 usec
ago. This would lead me to believe that the UART finishes it business
and then "Something happens" before the next character comes in to cause
it to generate a new RDA interrupt. But that RDA can't be from having
gotten a character as not enough time has gone by!

I have read the errata for the chip and found nothing to do with the
UARTs generating extra bytes.
I have read the User Manual and see nothing that would indicate why it
is generating an extra byte.
I have Googled with no luck.

I am now placing myself at the mercy of this court.

Has anybody seen this behavior? Anybody have even a guess as to what is
happening?

Here is the code for the ISR. Note the check for a null byte in the RDA
section. This should not get hit with just simple text strings.

static void Uart1_isr(void)
{
INT32U iir;
INT8U counter;
char data = 0;
BOOLEAN brk = FALSE, got_int = FALSE;
INT8U loops =0;

do {

loops++;

/* Read the interrupt identification register */
iir = U1IIR;

/* If the IntStatus bit is 1, no interrupt happened */
if ((iir & 0x00000001) == 0x1) {
brk = TRUE;

} else {

/* Recognize the interrupt event */
switch (iir&0x0000000E) {

case MODEM_INTR_ID: /* Modem Status */
data = U1MSR; /* Read MSR to clear */
break;

case RLS_INTR_ID: /* Line status change */
uart_ports[1].ls_f_int++;
data = U1LSR;
got_int = TRUE;
break;

case CDI_INTR_ID: /* Read timeout */
uart_ports[1].cdi_p_int++;
/* Do nothing */
got_int = TRUE;
break;

case RDA_INTR_ID: /* Receive data Available */
uart_ports[1].rx_received++;

/* get data from FIFO */
data = U1RBR;

prev_time = time;
time = CTC;
delta = time - prev_time;

/*
* Isolate the problem to the first pass of a new ISR
event where the
* previous event occured less than 150 usec ago.
* 5 counts of CTC is about 5 * 1/32768 = 152 usec
* One character time is 10/57600 = 173.6 usec
*/
if (data == '\0') {
(uart_ports[1].nulls)++;
if ((delta < 5) && (loops == 1) ) {
(uart_ports[1].good_cnt)++;
} else {
(uart_ports[1].bad_cnt)++;
}
}

/* Push new data into the receiver buffer */
if(DD_cirbuf_push(&(uart_ports[1].rx_cirbuf), data) = FALSE){
/* if the push fails, add one to number of bytes
missed */
(uart_ports[1].rx_missed)++;
}
got_int = TRUE;
break;

case THRE_INTR_ID: /* THRE Interrupt */
/* Transmitter is empty, fill with as much data as
possible.
Since the interrupt is for Transmitter Empty and the FIFO
is 16 bytes deep, 15 bytes will fit */
for (counter = 15; counter; counter--) {
/* Pop data from the transmit buffer
If the pop fails, then cirbuf is empty
Otherwise, put data into transmit FIFO */
if(DD_cirbuf_pop(&(uart_ports[1].tx_cirbuf),&data) = FALSE) {
break;
}
else {
uart_ports[1].tx_sent++;
U1THR = data;
}
}
got_int = TRUE;
break;

default:
if(got_int == FALSE){
uart_ports[1].default_int++;
}
/* No interrupt */
brk = TRUE;
break;
} // Switch

} // If interrupt

} while(brk == FALSE);

VICADDRESS = 0; /* Clear interrupt in VIC. */
} /* End of Uart1_isr() */

Here is the code for the initialization of the UART:

void DD_init_uart(Port_num_t uart, INT32U irq_slot)
{
Port_line_coding_t uart_coding;
INT8U tmp;

if(irq_slot != 0){
uart_ports[uart].priority = irq_slot;
}
if(uart_ports[uart].priority == 0){
uart_ports[uart].priority = 15;
}

switch (uart) {
case PORT_0:

break;
case PORT_1:
/* Initialize circular buffers */
DD_cirbuf_init(&(uart_ports[1].tx_cirbuf),
(INT16U)PORT1_TX_FEED_SIZE, uart1_tx_buf);
DD_cirbuf_init(&(uart_ports[1].rx_cirbuf),
(INT16U)PORT1_RX_FEED_SIZE, uart1_rx_buf);

/* Initialize statistics */
uart_ports[1].good_cnt = 0;
uart_ports[1].bad_cnt = 0;
uart_ports[1].nulls = 0;
uart_ports[1].lsr = &U1LSR;
uart_ports[1].thr = &U1THR;
uart_ports[1].port_vic_addr = VIC_UART1;
uart_ports[1].rx_received = 0;
uart_ports[1].tx_sent = 0;
uart_ports[1].cdi_p_int = 0;
uart_ports[1].ls_f_int = 0;
uart_ports[1].default_int = 0;

/* Enable UART1 */
PCONP_bit.PCUART1 = 1;

/* Word Length =8, no parity , 1 stop */
U1LCR = 0x03;

/* No full modem support */
U1MCR = 0x00;

/* Enable and Clear the UART1 buf, Set RX buf interrupt level to
1 char */
U1FCR = 0x07;

/* Transmit enable */
U1TER_bit.TXEN = 1;

/* Clear pending interrupts */
tmp = U1IER;

/* Enable Interrupts */
U1IER = UART_IER_RBR |
UART_IER_THRE |
UART_IER_LSR |
UART_IER_MSR;

tmp = U1IIR; /* clear interrupt ID */
tmp = U1RBR; /* clear receive register */
tmp = U1LSR; /* clear line status register */

/* put ISR in vectored interrupt controller */
DD_set_vectored_irq((void
*)Uart1_isr,uart_ports[uart].priority,VIC_UART1);

break;

case PORT_2:

break;

case PORT_3:

break;

default:
/* bad port */
break;
}

(void)tmp;

if(irq_slot != 0){
/* Set the default line conditions to 9600 8-n-1 */
uart_coding.dw_dte_rate = 9600;
uart_coding.b_stop_bits_format = UART_ONE_STOP_BIT;
uart_coding.b_parity_type = UART_NO_PARITY;
uart_coding.b_data_bits = UART_WORD_WIDTH_8;
DD_set_uart_line_coding(uart, uart_coding);
}

} /* End of DD_init_uart() */

-Skye Sweeney



Yahoo! Groups Links
Hello Skye

I'm not expert, and my English is poor, but let's try.

My guess is, that loop inside interrupt handler is source of trouble.

If MCU is in interrupt because of THRE, and RDY became active You read IIR
twice, and service two interrupts,
but VIC get ACK only once. Your RDY is serviced, but VIC know nothing about
it.
Then next ISR taken place with no data.

ISR routine without loop should help.

Albert

Bruce, Thank you very much for the reply. I will indeed spend tomorrow
looking at spurious interruptsand the difference between VIC and MSR
blanking. Your reply at least gives me hope thatI might find this
problem. -Skye Sweeney

----- Original Message ----- From: Bruce Paterson To:
l... Sent: Sunday, November 15, 2009 6:53 PMSubject:
RE: [lpc2000] LPC2468 UART1 Anomaly

You might want to search the Yahoo archives well back, looking for
issues to do with spurious interrupts. It could be due to another
unrelated program you have that enables and disables interrupts
using
the VIC rather than the MSR, possibly inducing a spurious interrupt
(NULL char) if the serial ISR happens to just hit at the right
moment.

Cheers,
Bruce

-----Original Message-----
From: l... [mailto:l...] On
Behalf
Of yellowlaser
Sent: Friday, 13 November 2009 8:42 AM
To: l...
Subject: [lpc2000] LPC2468 UART1 Anomaly

I am using an IAR LPC2468 development board and the IAR compiler for
a
company project. Just recently I noticed a strange issue with UART1.
On
the LPC2468, UART1 has modem control support but we are not using
it.
The pin selects use these pins for GPIO.

On rare occasions (once every 10 minutes) I receive on the LPC2468
more
bytes than I transmit. The extra byte has always been a null
character.
The extra byte was always inserted into the valid characters and not
clobbering one. As an example I might send ABCDEFG and receive
ABCDEFG. Using a protocol analyzer, I am quite sure the sender
(a
Perl script running on a PC) is not sending the null.

I also know that the sent string has minimal inter character delays.
There is NO possibility of a gap in the sent string large enough for
a
glitch to be interpreted as a start bit and inject a null.

I have all the interrupts enabled and I am decoding all the various
reasons. I am never getting any LSR or MSR interrupts just RDA and
THRE.

My data rate is 57600 baud or about 176usec per byte. In the ISR I
record the time each byte is received. It is always the case that
the
null byte has come in before the 176 usec has elapsed. Hence I am
fairly
sure the UART is providing me these bytes as a love offering rather
than
as real data.

It is always the case that the byte is inserted at the first
iteration
of an ISR loop. And only if the last loop happened less that 150
usec
ago. This would lead me to believe that the UART finishes it
business
and then "Something happens" before the next character comes in to
cause
it to generate a new RDA interrupt. But that RDA can't be from
having
gotten a character as not enough time has gone by!

I have read the errata for the chip and found nothing to do with the
UARTs generating extra bytes.
I have read the User Manual and see nothing that would indicate why
it
is generating an extra byte.
I have Googled with no luck.

I am now placing myself at the mercy of this court.

Has anybody seen this behavior? Anybody have even a guess as to what
is
happening?

Here is the code for the ISR. Note the check for a null byte in the
RDA
section. This should not get hit with just simple text strings.

static void Uart1_isr(void)
{
INT32U iir;
INT8U counter;
char data = 0;
BOOLEAN brk = FALSE, got_int = FALSE;
INT8U loops =0;

do {

loops++;

/* Read the interrupt identification register */
iir = U1IIR;

/* If the IntStatus bit is 1, no interrupt happened */
if ((iir & 0x00000001) == 0x1) {
brk = TRUE;

} else {

/* Recognize the interrupt event */
switch (iir&0x0000000E) {

case MODEM_INTR_ID: /* Modem Status */
data = U1MSR; /* Read MSR to clear */
break;

case RLS_INTR_ID: /* Line status change */
uart_ports[1].ls_f_int++;
data = U1LSR;
got_int = TRUE;
break;

case CDI_INTR_ID: /* Read timeout */
uart_ports[1].cdi_p_int++;
/* Do nothing */
got_int = TRUE;
break;

case RDA_INTR_ID: /* Receive data Available */
uart_ports[1].rx_received++;

/* get data from FIFO */
data = U1RBR;

prev_time = time;
time = CTC;
delta = time - prev_time;

/*
* Isolate the problem to the first pass of a new ISR
event where the
* previous event occured less than 150 usec ago.
* 5 counts of CTC is about 5 * 1/32768 = 152 usec
* One character time is 10/57600 = 173.6 usec
*/
if (data == '\0') {
(uart_ports[1].nulls)++;
if ((delta < 5) && (loops == 1) ) {
(uart_ports[1].good_cnt)++;
} else {
(uart_ports[1].bad_cnt)++;
}
}

/* Push new data into the receiver buffer */
if(DD_cirbuf_push(&(uart_ports[1].rx_cirbuf), data) = FALSE){
/* if the push fails, add one to number of bytes
missed */
(uart_ports[1].rx_missed)++;
}
got_int = TRUE;
break;

case THRE_INTR_ID: /* THRE Interrupt */
/* Transmitter is empty, fill with as much data as
possible.
Since the interrupt is for Transmitter Empty and the FIFO
is 16 bytes deep, 15 bytes will fit */
for (counter = 15; counter; counter--) {
/* Pop data from the transmit buffer
If the pop fails, then cirbuf is empty
Otherwise, put data into transmit FIFO */
if(DD_cirbuf_pop(&(uart_ports[1].tx_cirbuf),&data) = FALSE) {
break;
}
else {
uart_ports[1].tx_sent++;
U1THR = data;
}
}
got_int = TRUE;
break;

default:
if(got_int == FALSE){
uart_ports[1].default_int++;
}
/* No interrupt */
brk = TRUE;
break;
} // Switch

} // If interrupt

} while(brk == FALSE);

VICADDRESS = 0; /* Clear interrupt in VIC. */
} /* End of Uart1_isr() */

Here is the code for the initialization of the UART:

void DD_init_uart(Port_num_t uart, INT32U irq_slot)
{
Port_line_coding_t uart_coding;
INT8U tmp;

if(irq_slot != 0){
uart_ports[uart].priority = irq_slot;
}
if(uart_ports[uart].priority == 0){
uart_ports[uart].priority = 15;
}

switch (uart) {
case PORT_0:

break;
case PORT_1:
/* Initialize circular buffers */
DD_cirbuf_init(&(uart_ports[1].tx_cirbuf),
(INT16U)PORT1_TX_FEED_SIZE, uart1_tx_buf);
DD_cirbuf_init(&(uart_ports[1].rx_cirbuf),
(INT16U)PORT1_RX_FEED_SIZE, uart1_rx_buf);

/* Initialize statistics */
uart_ports[1].good_cnt = 0;
uart_ports[1].bad_cnt = 0;
uart_ports[1].nulls = 0;
uart_ports[1].lsr = &U1LSR;
uart_ports[1].thr = &U1THR;
uart_ports[1].port_vic_addr = VIC_UART1;
uart_ports[1].rx_received = 0;
uart_ports[1].tx_sent = 0;
uart_ports[1].cdi_p_int = 0;
uart_ports[1].ls_f_int = 0;
uart_ports[1].default_int = 0;

/* Enable UART1 */
PCONP_bit.PCUART1 = 1;

/* Word Length =8, no parity , 1 stop */
U1LCR = 0x03;

/* No full modem support */
U1MCR = 0x00;

/* Enable and Clear the UART1 buf, Set RX buf interrupt level to
1 char */
U1FCR = 0x07;

/* Transmit enable */
U1TER_bit.TXEN = 1;

/* Clear pending interrupts */
tmp = U1IER;

/* Enable Interrupts */
U1IER = UART_IER_RBR |
UART_IER_THRE |
UART_IER_LSR |
UART_IER_MSR;

tmp = U1IIR; /* clear interrupt ID */
tmp = U1RBR; /* clear receive register */
tmp = U1LSR; /* clear line status register */

/* put ISR in vectored interrupt controller */
DD_set_vectored_irq((void
*)Uart1_isr,uart_ports[uart].priority,VIC_UART1);

break;

case PORT_2:

break;

case PORT_3:

break;

default:
/* bad port */
break;
}

(void)tmp;

if(irq_slot != 0){
/* Set the default line conditions to 9600 8-n-1 */
uart_coding.dw_dte_rate = 9600;
uart_coding.b_stop_bits_format = UART_ONE_STOP_BIT;
uart_coding.b_parity_type = UART_NO_PARITY;
uart_coding.b_data_bits = UART_WORD_WIDTH_8;
DD_set_uart_line_coding(uart, uart_coding);
}

} /* End of DD_init_uart() */

-Skye Sweeney



Yahoo! Groups Links
Bruce et all,

I took your suggestion and searched on spurious interrupts. For whatever reason, the search facility in the Yahoo group seems broken. I was not even able to find my own message. But I did search in "the wild" and found an Application Note from NXT. It did not seem to address the problem. I am not getting a non-uart interrupt, but rather an extra UART interrupt with the IIR register claiming there is a byte available.

I did some further testing and found that this problem existed on three of the four UARTS. The only UART that was immune was the one with the highest priority (smallest number in the VIC). When I switched the priorities around, the problem follows the changed priorities.

I am now very confused. My first guess would be that the chip has somekind of cross-talk problem between UARTS. This seems unlikely as the chip has been in production for some time and there is no errata to that effect.

As a quick recap, I am experiencing "phantom" UART interrupts that when IIR is decoded indicates an available byte. Reading the byte yields a null. The time since the last byte received is always less time than needed to clock over a new byte. The problem gets worst the lower the VIC interrupt priority is set to. In a 12 hour period I may see 9000 failures on the lowest priority and zero on the highest.

Might anyone have any further hints they might like to pass along? Interrupt nesting? Bad acknowledgement of the UART interrupt? Bad Karma?

-Skye
--- In l..., "Bruce Paterson" wrote:
>
> You might want to search the Yahoo archives well back, looking for
> issues to do with spurious interrupts. It could be due to another
> unrelated program you have that enables and disables interrupts using
> the VIC rather than the MSR, possibly inducing a spurious interrupt
> (NULL char) if the serial ISR happens to just hit at the right moment.
>
> Cheers,
> Bruce
>
> -----Original Message-----
> From: l... [mailto:l...] On Behalf
> Of yellowlaser
> Sent: Friday, 13 November 2009 8:42 AM
> To: l...
> Subject: [lpc2000] LPC2468 UART1 Anomaly
> I am using an IAR LPC2468 development board and the IAR compiler for a
> company project. Just recently I noticed a strange issue with UART1. On
> the LPC2468, UART1 has modem control support but we are not using it.
> The pin selects use these pins for GPIO.
>
> On rare occasions (once every 10 minutes) I receive on the LPC2468 more
> bytes than I transmit. The extra byte has always been a null character.
> The extra byte was always inserted into the valid characters and not
> clobbering one. As an example I might send ABCDEFG and receive
> ABCDEFG. Using a protocol analyzer, I am quite sure the sender (a
> Perl script running on a PC) is not sending the null.
>
> I also know that the sent string has minimal inter character delays.
> There is NO possibility of a gap in the sent string large enough for a
> glitch to be interpreted as a start bit and inject a null.
>
> I have all the interrupts enabled and I am decoding all the various
> reasons. I am never getting any LSR or MSR interrupts just RDA and THRE.
>
> My data rate is 57600 baud or about 176usec per byte. In the ISR I
> record the time each byte is received. It is always the case that the
> null byte has come in before the 176 usec has elapsed. Hence I am fairly
> sure the UART is providing me these bytes as a love offering rather than
> as real data.
>
> It is always the case that the byte is inserted at the first iteration
> of an ISR loop. And only if the last loop happened less that 150 usec
> ago. This would lead me to believe that the UART finishes it business
> and then "Something happens" before the next character comes in to cause
> it to generate a new RDA interrupt. But that RDA can't be from having
> gotten a character as not enough time has gone by!
>
> I have read the errata for the chip and found nothing to do with the
> UARTs generating extra bytes.
> I have read the User Manual and see nothing that would indicate why it
> is generating an extra byte.
> I have Googled with no luck.
>
> I am now placing myself at the mercy of this court.
>
> Has anybody seen this behavior? Anybody have even a guess as to what is
> happening?
>
> Here is the code for the ISR. Note the check for a null byte in the RDA
> section. This should not get hit with just simple text strings.
>
> static void Uart1_isr(void)
> {
> INT32U iir;
> INT8U counter;
> char data = 0;
> BOOLEAN brk = FALSE, got_int = FALSE;
> INT8U loops =0;
>
> do {
>
> loops++;
>
> /* Read the interrupt identification register */
> iir = U1IIR;
>
> /* If the IntStatus bit is 1, no interrupt happened */
> if ((iir & 0x00000001) == 0x1) {
> brk = TRUE;
>
> } else {
>
> /* Recognize the interrupt event */
> switch (iir&0x0000000E) {
>
> case MODEM_INTR_ID: /* Modem Status */
> data = U1MSR; /* Read MSR to clear */
> break;
>
> case RLS_INTR_ID: /* Line status change */
> uart_ports[1].ls_f_int++;
> data = U1LSR;
> got_int = TRUE;
> break;
>
> case CDI_INTR_ID: /* Read timeout */
> uart_ports[1].cdi_p_int++;
> /* Do nothing */
> got_int = TRUE;
> break;
>
> case RDA_INTR_ID: /* Receive data Available */
> uart_ports[1].rx_received++;
>
> /* get data from FIFO */
> data = U1RBR;
>
> prev_time = time;
> time = CTC;
> delta = time - prev_time;
>
> /*
> * Isolate the problem to the first pass of a new ISR
> event where the
> * previous event occured less than 150 usec ago.
> * 5 counts of CTC is about 5 * 1/32768 = 152 usec
> * One character time is 10/57600 = 173.6 usec
> */
> if (data == '\0') {
> (uart_ports[1].nulls)++;
> if ((delta < 5) && (loops == 1) ) {
> (uart_ports[1].good_cnt)++;
> } else {
> (uart_ports[1].bad_cnt)++;
> }
> }
> /* Push new data into the receiver buffer */
> if(DD_cirbuf_push(&(uart_ports[1].rx_cirbuf), data) => FALSE){
> /* if the push fails, add one to number of bytes
> missed */
> (uart_ports[1].rx_missed)++;
> }
> got_int = TRUE;
> break;
>
> case THRE_INTR_ID: /* THRE Interrupt */
> /* Transmitter is empty, fill with as much data as
> possible.
> Since the interrupt is for Transmitter Empty and the FIFO
> is 16 bytes deep, 15 bytes will fit */
> for (counter = 15; counter; counter--) {
> /* Pop data from the transmit buffer
> If the pop fails, then cirbuf is empty
> Otherwise, put data into transmit FIFO */
> if(DD_cirbuf_pop(&(uart_ports[1].tx_cirbuf),&data) => FALSE) {
> break;
> }
> else {
> uart_ports[1].tx_sent++;
> U1THR = data;
> }
> }
> got_int = TRUE;
> break;
>
> default:
> if(got_int == FALSE){
> uart_ports[1].default_int++;
> }
> /* No interrupt */
> brk = TRUE;
> break;
> } // Switch
>
> } // If interrupt
>
> } while(brk == FALSE);
>
> VICADDRESS = 0; /* Clear interrupt in VIC. */
> } /* End of Uart1_isr() */
> Here is the code for the initialization of the UART:
> void DD_init_uart(Port_num_t uart, INT32U irq_slot)
> {
> Port_line_coding_t uart_coding;
> INT8U tmp;
>
> if(irq_slot != 0){
> uart_ports[uart].priority = irq_slot;
> }
> if(uart_ports[uart].priority == 0){
> uart_ports[uart].priority = 15;
> }
>
> switch (uart) {
> case PORT_0:
>
> break;
> case PORT_1:
> /* Initialize circular buffers */
> DD_cirbuf_init(&(uart_ports[1].tx_cirbuf),
> (INT16U)PORT1_TX_FEED_SIZE, uart1_tx_buf);
> DD_cirbuf_init(&(uart_ports[1].rx_cirbuf),
> (INT16U)PORT1_RX_FEED_SIZE, uart1_rx_buf);
>
> /* Initialize statistics */
> uart_ports[1].good_cnt = 0;
> uart_ports[1].bad_cnt = 0;
> uart_ports[1].nulls = 0;
> uart_ports[1].lsr = &U1LSR;
> uart_ports[1].thr = &U1THR;
> uart_ports[1].port_vic_addr = VIC_UART1;
> uart_ports[1].rx_received = 0;
> uart_ports[1].tx_sent = 0;
> uart_ports[1].cdi_p_int = 0;
> uart_ports[1].ls_f_int = 0;
> uart_ports[1].default_int = 0;
>
> /* Enable UART1 */
> PCONP_bit.PCUART1 = 1;
>
> /* Word Length =8, no parity , 1 stop */
> U1LCR = 0x03;
>
> /* No full modem support */
> U1MCR = 0x00;
>
> /* Enable and Clear the UART1 buf, Set RX buf interrupt level to
> 1 char */
> U1FCR = 0x07;
>
> /* Transmit enable */
> U1TER_bit.TXEN = 1;
>
> /* Clear pending interrupts */
> tmp = U1IER;
>
> /* Enable Interrupts */
> U1IER = UART_IER_RBR |
> UART_IER_THRE |
> UART_IER_LSR |
> UART_IER_MSR;
>
> tmp = U1IIR; /* clear interrupt ID */
> tmp = U1RBR; /* clear receive register */
> tmp = U1LSR; /* clear line status register */
>
> /* put ISR in vectored interrupt controller */
> DD_set_vectored_irq((void
> *)Uart1_isr,uart_ports[uart].priority,VIC_UART1);
>
> break;
>
> case PORT_2:
>
> break;
>
> case PORT_3:
>
> break;
>
> default:
> /* bad port */
> break;
> }
>
> (void)tmp;
>
> if(irq_slot != 0){
> /* Set the default line conditions to 9600 8-n-1 */
> uart_coding.dw_dte_rate = 9600;
> uart_coding.b_stop_bits_format = UART_ONE_STOP_BIT;
> uart_coding.b_parity_type = UART_NO_PARITY;
> uart_coding.b_data_bits = UART_WORD_WIDTH_8;
> DD_set_uart_line_coding(uart, uart_coding);
> }
>
> } /* End of DD_init_uart() */
> -Skye Sweeney
>
Hi Skye,

would it help (even though it looks superfluous) to check the LSR status register whether there is a byte available before you read
it? Something like:

...
else if (iirValue == IIR_RDA)
{
// Receive Data Available
while ((LSR & LSR_RDR) != 0)
_self->receiveByte(RBR);
}
...

Also, did you try to remove the loop (the do while (!brk)) from the ISR? I think it should be possible to do without it. Does it
make any difference?

With regards,
Jan
----- Original Message -----
From: "yellowlaser"
To:
Sent: Friday, November 20, 2009 5:38 PM
Subject: [lpc2000] Re: LPC2468 UART1 Anomaly (New information)
Bruce et all,

I took your suggestion and searched on spurious interrupts. For whatever reason, the search facility in the Yahoo group seems
broken. I was not even able to find my own message. But I did search in "the wild" and found an Application Note from NXT. It did
not seem to address the problem. I am not getting a non-uart interrupt, but rather an extra UART interrupt with the IIR register
claiming there is a byte available.

I did some further testing and found that this problem existed on three of the four UARTS. The only UART that was immune was the one
with the highest priority (smallest number in the VIC). When I switched the priorities around, the problem follows the changed
priorities.

I am now very confused. My first guess would be that the chip has somekind of cross-talk problem between UARTS. This seems unlikely
as the chip has been in production for some time and there is no errata to that effect.

As a quick recap, I am experiencing "phantom" UART interrupts that when IIR is decoded indicates an available byte. Reading the byte
yields a null. The time since the last byte received is always less time than needed to clock over a new byte. The problem gets
worst the lower the VIC interrupt priority is set to. In a 12 hour period I may see 9000 failures on the lowest priority and zero on
the highest.

Might anyone have any further hints they might like to pass along? Interrupt nesting? Bad acknowledgement of the UART interrupt? Bad
Karma?

-Skye
--- In l..., "Bruce Paterson" wrote:
>
> You might want to search the Yahoo archives well back, looking for
> issues to do with spurious interrupts. It could be due to another
> unrelated program you have that enables and disables interrupts using
> the VIC rather than the MSR, possibly inducing a spurious interrupt
> (NULL char) if the serial ISR happens to just hit at the right moment.
>
> Cheers,
> Bruce
>
> -----Original Message-----
> From: l... [mailto:l...] On Behalf
> Of yellowlaser
> Sent: Friday, 13 November 2009 8:42 AM
> To: l...
> Subject: [lpc2000] LPC2468 UART1 Anomaly
> I am using an IAR LPC2468 development board and the IAR compiler for a
> company project. Just recently I noticed a strange issue with UART1. On
> the LPC2468, UART1 has modem control support but we are not using it.
> The pin selects use these pins for GPIO.
>
> On rare occasions (once every 10 minutes) I receive on the LPC2468 more
> bytes than I transmit. The extra byte has always been a null character.
> The extra byte was always inserted into the valid characters and not
> clobbering one. As an example I might send ABCDEFG and receive
> ABCDEFG. Using a protocol analyzer, I am quite sure the sender (a
> Perl script running on a PC) is not sending the null.
>
> I also know that the sent string has minimal inter character delays.
> There is NO possibility of a gap in the sent string large enough for a
> glitch to be interpreted as a start bit and inject a null.
>
> I have all the interrupts enabled and I am decoding all the various
> reasons. I am never getting any LSR or MSR interrupts just RDA and THRE.
>
> My data rate is 57600 baud or about 176usec per byte. In the ISR I
> record the time each byte is received. It is always the case that the
> null byte has come in before the 176 usec has elapsed. Hence I am fairly
> sure the UART is providing me these bytes as a love offering rather than
> as real data.
>
> It is always the case that the byte is inserted at the first iteration
> of an ISR loop. And only if the last loop happened less that 150 usec
> ago. This would lead me to believe that the UART finishes it business
> and then "Something happens" before the next character comes in to cause
> it to generate a new RDA interrupt. But that RDA can't be from having
> gotten a character as not enough time has gone by!
>
> I have read the errata for the chip and found nothing to do with the
> UARTs generating extra bytes.
> I have read the User Manual and see nothing that would indicate why it
> is generating an extra byte.
> I have Googled with no luck.
>
> I am now placing myself at the mercy of this court.
>
> Has anybody seen this behavior? Anybody have even a guess as to what is
> happening?
>
> Here is the code for the ISR. Note the check for a null byte in the RDA
> section. This should not get hit with just simple text strings.
>
> static void Uart1_isr(void)
> {
> INT32U iir;
> INT8U counter;
> char data = 0;
> BOOLEAN brk = FALSE, got_int = FALSE;
> INT8U loops =0;
>
> do {
>
> loops++;
>
> /* Read the interrupt identification register */
> iir = U1IIR;
>
> /* If the IntStatus bit is 1, no interrupt happened */
> if ((iir & 0x00000001) == 0x1) {
> brk = TRUE;
>
> } else {
>
> /* Recognize the interrupt event */
> switch (iir&0x0000000E) {
>
> case MODEM_INTR_ID: /* Modem Status */
> data = U1MSR; /* Read MSR to clear */
> break;
>
> case RLS_INTR_ID: /* Line status change */
> uart_ports[1].ls_f_int++;
> data = U1LSR;
> got_int = TRUE;
> break;
>
> case CDI_INTR_ID: /* Read timeout */
> uart_ports[1].cdi_p_int++;
> /* Do nothing */
> got_int = TRUE;
> break;
>
> case RDA_INTR_ID: /* Receive data Available */
> uart_ports[1].rx_received++;
>
> /* get data from FIFO */
> data = U1RBR;
>
> prev_time = time;
> time = CTC;
> delta = time - prev_time;
>
> /*
> * Isolate the problem to the first pass of a new ISR
> event where the
> * previous event occured less than 150 usec ago.
> * 5 counts of CTC is about 5 * 1/32768 = 152 usec
> * One character time is 10/57600 = 173.6 usec
> */
> if (data == '\0') {
> (uart_ports[1].nulls)++;
> if ((delta < 5) && (loops == 1) ) {
> (uart_ports[1].good_cnt)++;
> } else {
> (uart_ports[1].bad_cnt)++;
> }
> }
> /* Push new data into the receiver buffer */
> if(DD_cirbuf_push(&(uart_ports[1].rx_cirbuf), data) => FALSE){
> /* if the push fails, add one to number of bytes
> missed */
> (uart_ports[1].rx_missed)++;
> }
> got_int = TRUE;
> break;
>
> case THRE_INTR_ID: /* THRE Interrupt */
> /* Transmitter is empty, fill with as much data as
> possible.
> Since the interrupt is for Transmitter Empty and the FIFO
> is 16 bytes deep, 15 bytes will fit */
> for (counter = 15; counter; counter--) {
> /* Pop data from the transmit buffer
> If the pop fails, then cirbuf is empty
> Otherwise, put data into transmit FIFO */
> if(DD_cirbuf_pop(&(uart_ports[1].tx_cirbuf),&data) => FALSE) {
> break;
> }
> else {
> uart_ports[1].tx_sent++;
> U1THR = data;
> }
> }
> got_int = TRUE;
> break;
>
> default:
> if(got_int == FALSE){
> uart_ports[1].default_int++;
> }
> /* No interrupt */
> brk = TRUE;
> break;
> } // Switch
>
> } // If interrupt
>
> } while(brk == FALSE);
>
> VICADDRESS = 0; /* Clear interrupt in VIC. */
> } /* End of Uart1_isr() */
> Here is the code for the initialization of the UART:
> void DD_init_uart(Port_num_t uart, INT32U irq_slot)
> {
> Port_line_coding_t uart_coding;
> INT8U tmp;
>
> if(irq_slot != 0){
> uart_ports[uart].priority = irq_slot;
> }
> if(uart_ports[uart].priority == 0){
> uart_ports[uart].priority = 15;
> }
>
> switch (uart) {
> case PORT_0:
>
> break;
> case PORT_1:
> /* Initialize circular buffers */
> DD_cirbuf_init(&(uart_ports[1].tx_cirbuf),
> (INT16U)PORT1_TX_FEED_SIZE, uart1_tx_buf);
> DD_cirbuf_init(&(uart_ports[1].rx_cirbuf),
> (INT16U)PORT1_RX_FEED_SIZE, uart1_rx_buf);
>
> /* Initialize statistics */
> uart_ports[1].good_cnt = 0;
> uart_ports[1].bad_cnt = 0;
> uart_ports[1].nulls = 0;
> uart_ports[1].lsr = &U1LSR;
> uart_ports[1].thr = &U1THR;
> uart_ports[1].port_vic_addr = VIC_UART1;
> uart_ports[1].rx_received = 0;
> uart_ports[1].tx_sent = 0;
> uart_ports[1].cdi_p_int = 0;
> uart_ports[1].ls_f_int = 0;
> uart_ports[1].default_int = 0;
>
> /* Enable UART1 */
> PCONP_bit.PCUART1 = 1;
>
> /* Word Length =8, no parity , 1 stop */
> U1LCR = 0x03;
>
> /* No full modem support */
> U1MCR = 0x00;
>
> /* Enable and Clear the UART1 buf, Set RX buf interrupt level to
> 1 char */
> U1FCR = 0x07;
>
> /* Transmit enable */
> U1TER_bit.TXEN = 1;
>
> /* Clear pending interrupts */
> tmp = U1IER;
>
> /* Enable Interrupts */
> U1IER = UART_IER_RBR |
> UART_IER_THRE |
> UART_IER_LSR |
> UART_IER_MSR;
>
> tmp = U1IIR; /* clear interrupt ID */
> tmp = U1RBR; /* clear receive register */
> tmp = U1LSR; /* clear line status register */
>
> /* put ISR in vectored interrupt controller */
> DD_set_vectored_irq((void
> *)Uart1_isr,uart_ports[uart].priority,VIC_UART1);
>
> break;
>
> case PORT_2:
>
> break;
>
> case PORT_3:
>
> break;
>
> default:
> /* bad port */
> break;
> }
>
> (void)tmp;
>
> if(irq_slot != 0){
> /* Set the default line conditions to 9600 8-n-1 */
> uart_coding.dw_dte_rate = 9600;
> uart_coding.b_stop_bits_format = UART_ONE_STOP_BIT;
> uart_coding.b_parity_type = UART_NO_PARITY;
> uart_coding.b_data_bits = UART_WORD_WIDTH_8;
> DD_set_uart_line_coding(uart, uart_coding);
> }
>
> } /* End of DD_init_uart() */
> -Skye Sweeney
>