RX baudrate different than TX baudrate on LPC2148 using U1FDR
2005-11-02 by jp_thrower
I'm not able to get the LPC2148 chip to receive at the same baudrate
that it sends at when using the fractional devisor U1FDR. Does anyone
else have this problem, or is there a register setting that I'm
unaware of that allows the Rx and Tx to operate at different baud rates?
Details:
I'm using the Keil MCB2140 board to interface to an RS485-based bus at
500,000 bps.
I can use the fractional divider option to get the board to transmit
at exactly 500,000 bps, as confirmed on an oscilloscope. The same
UART, however, won't receive/decode the response signal properly. I
can see that the response signal is getting on the pin, and I can see
that the receive buffer is filling with something. The whole system
worked fine as a 9600 bps com port test, but that was without using
the fractional divisor (having U1FDR set as 0x00).
In a test, the signal sent to the receive port of the lpc2148 UART1 is
{0x21, 0x00, 0x00, 0x00, 0x00, 0x93}. This signal is properly picked
up by other test equipment and verified on the oscilloscope as
correct. My receive buffer, however, shows {0x06, 0x03, 0x00, 0x00,
0x00, 0x00, 0x1E, 0xD8} (repeating sequence, so it's not noise)
At first this looks random, but if you examine the bits, you actually
see that the receiver is operating at almost twice the transmit
frequency. The RS485 protocol is using a wakeup bit of 0.
0x21 is thus transmitted as 01000010001,
interpretation: (start=0)(1000 0100)(wakeup_bit=0)(stop=1).
The character is sent lsb first.
If you received at twice the baud rate you would get
0011000000001100000011. This would be interpreted as
(start=0)(0110 0000)(wakeup=0)(stop=0 Frame Error!)
(start=0)(1100 0000)(wakeup=1)(stop=1)
This yields a sequence starting with 0x06, 0x03.
I see the frame error on the first byte too.
for some reason the correct number of 0x00 bytes are captured.
If you do the same doubling of bits for the last byte, you get a
sequence of 0x1E, 0x98, which is not the same as 0x1E, 0xD8. I'm
guessing that the baud rate is not exactly doubled and is getting off
sync at the last part (msb) of the character.
This is why I'm thinking that the U1FDR is not being used for the RX
baudrate. I read that this is a new feature for the 214x chips.
If you read the code below, you may note that U1FDR multiplies the
baud rate by 8/15. If this is not used, then the baud rate is almost
doubled.
My Baud rate setting is as follows:
// for the Arm 7 with a 12 MHz crystal,
// UART_baudrate = PCLK/(16*(16*U1DLM+U1DLL)) *
// (MulVal/(MulVal+DivAddVal))
// 500000 = 15000000/16/(1)*(8/15)
// so U1DLM = 0, U1DLL = 1, MulVal = 8, DivAddVal = 7
U1LCR |= 0x80; /* Set DLAB to allow access to divisor latches */
U1DLL = 0x01; /* load 0x0001 into [U1DLM:U1DLL] */
U1DLM = 0x00;
U1FDR = 0x87; /* load 8/(8+7) into U1FDR = [MulVal:DivAddVal] */
U1LCR &= ~0x80; /* Clear DLAB to disable access to divisor
latches and allow access to Rx register U1RBR*/
Has anyone else run into this issue?
JP
PS, I set U1FCR = 0x07 to enable FIFO, just in case. But it changed
nothing.