EmbeddedRelated.com
Forums

UART stuck waiting for THRE

Started by mattwoolsey May 10, 2008
More info:

The int vs. char parameter is not what fixes it. It apparently has to
do with spacing of the code from the beginning of the function. Even
with the char parameter, I added an if{ statement at the beginning of
the function which checked for '\n' and then added a '\r' if it
matched. This didn't work. So I added a couple dummy statements to
the beginning and then it worked again. Very strange.

MX

An Engineer's Guide to the LPC2100 Series

--- In l..., "mattwoolsey" wrote:
>
> More info:
>
> The int vs. char parameter is not what fixes it. It apparently has
to
> do with spacing of the code from the beginning of the function. Even
> with the char parameter, I added an if{ statement at the beginning of
> the function which checked for '\n' and then added a '\r' if it
> matched. This didn't work. So I added a couple dummy statements to
> the beginning and then it worked again. Very strange.
>
> MX
>

Changing from Level 0 optimization to seems to have fixed it
for now. I still would like to figure out what's going on.

MX

--- In l..., "mattwoolsey" wrote:
>
> This should work but it doesn't. I'm just running the simple
> blinky.c example, but my UART 0 gets stuck waiting for the tranmit
> hold register empty bit to set:
>
> //-------------------------------
> #include void init_serial (void)
> {
> PINSEL0 = 0x00000005;
> UxLCR = 0x83;
> UxDLL = (VPB_CLOCK/16/BAUD_RATE) & 0xFF;
> UxDLM = ((VPB_CLOCK/16/BAUD_RATE) >> 8) & 0xFF;
> UxLCR = 0x03;
> }
>
> int sendchar (int ch)
> {
> while (!(U0LSR & 0x20)); <------------ stuck here!!!
>
> return (UxTHR = ch);
> }
> //-------------------------------
>
> From main, I'm calling init_serial, then calling sendchar a few
> times. Only the first character comes out the serial port. If I
> comment out the while loop waiting for the THRE bit, then all the
> characters print just fine. Is this a bug in the LPC2103 or maybe a
> compiler problem with the Keil Realview compiler? Or am I just
> missing something really simple?
>
> Thanks for any help.
>
> MX
>

MX,
Try adding:
UxFCR = 0x01;
in your UART initialization code.

Regards
Zdravko Dimitrov

----- Original Message -----
From: "mattwoolsey"
To:
Sent: Sunday, May 11, 2008 3:32 AM
Subject: [lpc2000] Re: UART stuck waiting for THRE
> Yes, custom hardware. By the way, I added code to turn an LED on
> before the loop and off afterward. That should have changed the
> timing significantly, but still had the same results.
>
> MX
> --- In l..., "Paul Claessen" wrote:
>>
>> Is this 'custom' made hardware?
>> I'm beginning to suspect hardware.. I base this on the fact that MX
> just sent me his project files.
>> Not having a 21xx I ran it on the emulator.
>> It just works fine... as expected.

I don't think there is anything wrong with the code, I've had something
similar working on an LPC2148.

Leon
> I don't think there is anything wrong with the code, I've had something similar working on an
> LPC2148.

==> And did you figure out what it was? How did you resolve it?

~ Paul Claessen
----- Original Message -----
From: "Leon"
To:
Sent: Sunday, May 11, 2008 4:54 AM
Subject: Re: [lpc2000] Re: UART stuck waiting for THRE
> ----- Original Message -----
> From: "mattwoolsey"
> To:
> Sent: Sunday, May 11, 2008 3:32 AM
> Subject: [lpc2000] Re: UART stuck waiting for THRE
>> Yes, custom hardware. By the way, I added code to turn an LED on
>> before the loop and off afterward. That should have changed the
>> timing significantly, but still had the same results.
>>
>> MX
>> --- In l..., "Paul Claessen" wrote:
>>>
>>> Is this 'custom' made hardware?
>>> I'm beginning to suspect hardware.. I base this on the fact that MX
>> just sent me his project files.
>>> Not having a 21xx I ran it on the emulator.
>>> It just works fine... as expected.
>
> I don't think there is anything wrong with the code, I've had something
> similar working on an LPC2148.
>
> Leon
Hi,

> The int vs. char parameter is not what fixes it. It apparently has to
> do with spacing of the code from the beginning of the function. Even
> with the char parameter, I added an if{ statement at the beginning of
> the function which checked for '\n' and then added a '\r' if it
> matched. This didn't work. So I added a couple dummy statements to
> the beginning and then it worked again. Very strange.

If it's a code placement issue, then perhaps you're suffering from MAM
issues?

--
Paul Curtis, Rowley Associates Ltd http://www.rowley.co.uk
CrossWorks for ARM, MSP430, AVR, MAXQ, and now Cortex-M3 processors

Hi,

> > > A compiler could return that value instead.
> >
> >
> >==> [Paul] No it couldn't. It has NO CLUE that U0BRB is the 'read'
> >counter part of U0THR.
>
> Yes it could. The value of U0THR = x; (1) is U0THR. U0THR is defined
> as
> the location that U0THR is at. When you read that location you get
> U0RBR. Thus the value of U0THR = x; should be U0RBR ;)
>
> The compiler is operating under the erroneous assumption that what is
> written to the location should be read from it. Actually if U0THR is
> volatile I think this may be a bug in the compiler although not one
> many are going to run into I hope(2).
>
> You could make a philosophical argument that for a write only register
> you should return the value assigned to it.

If you read the ISO C standard, you will find the statement that the value
of an assignment operator, '=' for example, is the value stored. In many
cases, BUT NOT ALL, the statement x = y = k will store k to both y and x.
HOWEVER, there are times when the value stored to x will NOT be k because
the value stored in y is *not* k! (Bonus points for all those that can
identify when this could possibly happen!)

This is a perennial problem: arguing over what you expect rather than what
is demanded by the ISO standard.

I suggest you all go read ISO before throwing your hat into the ring. :-)

In general, if you are using the value of an assignment expression, you had
better know exactly what you've written and what the compiler *must* do in
that situation.

--
Paul Curtis, Rowley Associates Ltd http://www.rowley.co.uk
CrossWorks for ARM, MSP430, AVR, MAXQ, and now Cortex-M3 processors

Are you using flash magic or some other program that can automatically
insert a code read protection value?
Maybe this overwrites one critical instruction in this code sequence,
for example the compare/bit test.

Regards,
Richard.
Paul Curtis wrote:
> Hi,
>
>
>> The int vs. char parameter is not what fixes it. It apparently has to
>> do with spacing of the code from the beginning of the function. Even
>> with the char parameter, I added an if{ statement at the beginning of
>> the function which checked for '\n' and then added a '\r' if it
>> matched. This didn't work. So I added a couple dummy statements to
>> the beginning and then it worked again. Very strange.
>>
>
> If it's a code placement issue, then perhaps you're suffering from MAM
> issues?
>
> --
> Paul Curtis, Rowley Associates Ltd http://www.rowley.co.uk
> CrossWorks for ARM, MSP430, AVR, MAXQ, and now Cortex-M3 processors
>
>
----- Original Message -----
From: "Paul Curtis"
To:
Sent: Sunday, May 11, 2008 6:16 AM
Subject: RE: [lpc2000] Re: UART stuck waiting for THRE
> Hi,
>
>> > > A compiler could return that value instead.
>> >
>> >
>> >==> [Paul] No it couldn't. It has NO CLUE that U0BRB is the 'read'
>> >counter part of U0THR.
>>
>> Yes it could. The value of U0THR = x; (1) is U0THR. U0THR is defined
>> as
>> the location that U0THR is at. When you read that location you get
>> U0RBR. Thus the value of U0THR = x; should be U0RBR ;)
>>
>> The compiler is operating under the erroneous assumption that what is
>> written to the location should be read from it. Actually if U0THR is
>> volatile I think this may be a bug in the compiler although not one
>> many are going to run into I hope(2).
>>
>> You could make a philosophical argument that for a write only register
>> you should return the value assigned to it.
>
> If you read the ISO C standard, you will find the statement that the value
> of an assignment operator, '=' for example, is the value stored. In many
> cases, BUT NOT ALL, the statement x = y = k will store k to both y and x.
> HOWEVER, there are times when the value stored to x will NOT be k because
> the value stored in y is *not* k! (Bonus points for all those that can
> identify when this could possibly happen!)
>
> This is a perennial problem: arguing over what you expect rather than what
> is demanded by the ISO standard.
>
> I suggest you all go read ISO before throwing your hat into the ring. :-)
>
> In general, if you are using the value of an assignment expression, you had
> better know exactly what you've written and what the compiler *must* do in
> that situation.
>
> --
> Paul Curtis, Rowley Associates Ltd http://www.rowley.co.uk
> CrossWorks for ARM, MSP430, AVR, MAXQ, and now Cortex-M3 processors
>

I'm not sure how this relates to the discussion.

That an assignment expression has the value of the left operand after the assignment is not
something that was disputed, in fact that was what Robert started the discussion with. (And, while
interesting. the construct x =y = k never played a role in this discussion)

Robert's argument was that 'the value stored' (value of assignment expression) should be read back
from the memory location if it has been deemed volatile, AFTER it has been stored.

So, for instance, the compiler generated code that came up with the value of the expression in a
register, and as its last act it writes that register to memory (the lvalue). Now, Robert's argument
was, that since that memory location was specified as volatile, the register cannot be used as the
final expression value, but the memory should be read back.

I objected to that notion.

As for your, in itself valuable, suggestion to read the standard isn't of much help here, since it
states:
"What constitutes an access to an object that has volatile-qualified type is
implementation-defined."

~ Paul Claessen
You can do very nasty things with CRP, but I don't think overwriting one instruction in a code
sequence is part of that ...

~ Paul Claessen

----- Original Message -----
From: "Richard Duits"
To:
Sent: Sunday, May 11, 2008 7:23 AM
Subject: Re: [lpc2000] Re: UART stuck waiting for THRE
> Are you using flash magic or some other program that can automatically
> insert a code read protection value?
> Maybe this overwrites one critical instruction in this code sequence,
> for example the compare/bit test.
>
> Regards,
> Richard.
> Paul Curtis wrote:
>> Hi,
>>> The int vs. char parameter is not what fixes it. It apparently has to
>>> do with spacing of the code from the beginning of the function. Even
>>> with the char parameter, I added an if{ statement at the beginning of
>>> the function which checked for '\n' and then added a '\r' if it
>>> matched. This didn't work. So I added a couple dummy statements to
>>> the beginning and then it worked again. Very strange.
>>> If it's a code placement issue, then perhaps you're suffering from MAM
>> issues?
>>
>> --
>> Paul Curtis, Rowley Associates Ltd http://www.rowley.co.uk
>> CrossWorks for ARM, MSP430, AVR, MAXQ, and now Cortex-M3 processors