Hi Guys
I am playing about with the USART at the moment and I am using the ICD2 to
debug the program but the program gets stuck.
I am pulling the TXIF flag to see if the TX register is empty and then I
transfer another byte into it, i.e.:

;------------------transmit routine-------------------
; TXIF is tested to check if TXREG is empty,
; if set data in w register is transferred to TXREG

txch btfss PIR1,TXIF
goto txch
movwf TXREG
return

the problem is that I get stuck on the loop even after a reset and it will
not return from this subroutine. is there a problem with debugging programs
using the USART on the ICD2 or is my program ?
I just need to transmit continuously at first.
My program is bellow.

>the problem is that I get stuck on the loop
>even after a reset and it will not return
>from this subroutine. is there a problem with
>debugging programs using the USART on the ICD2
>or is my program ?
>I just need to transmit continuously at first.

1. do be aware that when using the ICD mode that the usart will stop and
corrupt any transmission when the ICD goes into stop mode. The same holds
for any of the hardware peripherals (MSSP etc).

2. It sounds as though you may not be initialising the hardware completely.
It is not obvious from your email if you stuff the uart with the first
character, and then look for the flag, or if you are looking for the flag
before you stuff it with the first character. You definitely need to put a
character into the uart when initialising it, disregarding the txif flag, as
the flag does not get set until the first character has finished the
transmission.

3. get a copy of Fr. MacGhees uart.zip for an example set of working code,
and a heap of comments on the pitfalls of how to initialise the uart. I
don't have a weblink handy for the file, but a search should soon find it.

Alan B. Pearce wrote:
> It is not obvious from your email if you stuff the uart
> with the first character, and then look for the flag, or if you are
> looking for the flag before you stuff it with the first character.
> You definitely need to put a character into the uart when
> initialising it, disregarding the txif flag, as the flag does not get
> set until the first character has finished the transmission.

Where did you get this from? I've never seen this symptom. I just checked
my standard UART code (QQQ_UART.ASPIC at http://www.embedinc.com/pic), and
it does nothing special for the first character. It sets the TXIE bit
whenever a byte is stuffed into the output FIFO, and relies on the TXIF bit
being set whenever TXREG can accept another byte.

>Where did you get this from? I've never seen
>this symptom. I just checked my standard UART
>code (QQQ_UART.ASPIC at http://www.embedinc.com/pic),
>and it does nothing special for the first
>character. It sets the TXIE bit whenever a byte
>is stuffed into the output FIFO, and relies on
>the TXIF bit being set whenever TXREG can accept
>another byte.

I got the info from Fr. MacGhees uart.zip file. It is a problem with
interrupt driven code. The flags are not correctly set if a character is not
stuffed into the txreg before relying on the state of the flags, as they are
not set to the state of the uart when the uart is turned on, and if you then
expect a "transmitter empty" interrupt without sending a character first,
then you wait forever.

It is possible that this has been fixed in later examples of the chips, but
I like to send CR/LF as part of the initialisation anyway.

PS, in your description above do you have the flags swapped? Just reading it
through it sounds like they might be.

Luis Moreira wrote:
>> txch btfss PIR1,TXIF
>> goto txch
>> movwf TXREG
>> return
>>
>> the problem is that I get stuck on the loop even after a reset and it
>> will not return from this subroutine.
>
> I can not see where the banking is not been changed as require.

Huh!? None of the 4 instructions you showed addresses banking at all. Both
PIR1 and TXREG exist only in bank 0, but there is no code ensuring bank 0 is
set, nor is there a comment specifying that this routine must be called with
bank 0 selected.

It's generally a better idea to have each subroutine be defensive and not
assume the caller has set the bank properly. Calling routines should assume
that subroutines will trash the bank setting. At least put BANKSEL
directives in the code liberally. There are more elegant ways to make sure
the bank is set properly, but BANKSEL makes it clear to everyone reading the
code that you've considered banking and that the bank is set correctly.

Hi Olin
That's a fair comment, I do change bank but I should have it inside the
subroutine.
the code is working now but the only change I made was to change the order
that I set all the registers!!!!
Is there a set way that you should follow when configuring all the registers
required ? I just followed the datasheet for the 16F876.
best regards
Luis

> the code is working now but the only change I made was to
> change the order that I set all the registers!!!!
> Is there a set way that you should follow when configuring
> all the registers required ? I just followed the datasheet for
> the 16F876.

First, changing the order that registers are accessed during
debuging, and at the same time forgetting to look over
the bank setting stuff, is a very common error... :-)

Second, It's close to impossible to answer your questions
without seeing your code before and after the changes !
Best would be if you could strip it down into two short (but
still complete and working) examples that shows this problem.

Hi Alan/Olin
I just tryed to use it without sending a byte to TXREG and the routine got
stuck and when I first send a byte to TXREG and then run the routine it
works fine!!!! So Alan you are right.
I would still like to have a clear order in which you should set up the
registers for transmitting and receiving
thank you both for your help
regards
Luis

Alan B. Pearce wrote:
>> Where did you get this from? I've never seen
>> this symptom. I just checked my standard UART
>> code (QQQ_UART.ASPIC at http://www.embedinc.com/pic),
>> and it does nothing special for the first
>> character. It sets the TXIE bit whenever a byte
>> is stuffed into the output FIFO, and relies on
>> the TXIF bit being set whenever TXREG can accept
>> another byte.
>
> in your description above do you have the flags swapped?

I don't think so. I leave the transmit interrupt disabled unless there is a
character waiting to go out. The routine that stuffs a byte into the output
FIFO therefore enables the interrupt, which means setting TXIE. All output
bytes, including the first one, get sent from the output interrupt routine,
which only gets run if the TXIF bit is set.

> I got the info from Fr. MacGhees uart.zip file. It is a problem with
> interrupt driven code. The flags are not correctly set if a character is not
> stuffed into the txreg before relying on the state of the flags, as they are
> not set to the state of the uart when the uart is turned on, and if you then
> expect a "transmitter empty" interrupt without sending a character first,
> then you wait forever.

I have never heard of, nor encountered such a problem, in nearly
seven years of writing PIC code.

Luis Moreira wrote:
> I just tryed to use it without sending a byte to TXREG and the
> routine got stuck and when I first send a byte to TXREG and then run
> the routine it works fine!!!! So Alan you are right.
> I would still like to have a clear order in which you should set up
> the registers for transmitting and receiving

Hmm. Maybe that's where the supposed first byte dependency comes from. If
the UART is not set up in the right order, then TXIF doesn't come on
initially?

I have never had this problem, but maybe that's because of the order I
initialize the UART in. Again, take a look at QQQ_UART.ASPIC inhttp://www.embedinc.com/pic because that definitely works and does not need
any special handling of the first byte. In other words, TXIF comes on right
after initialization.

One thing to remember here is that every "interupt flag" is set/driven
by something actualy happening. A pin changing state, ADC completion,
a timer overflow or somehing else. They are not set becuse something
happen to be in some steady state. Something have to *happen* !

Now, regarding the TXIF flag. I think the documentation is
somewhare between unclear and wrong in the description of the
TXIF flag (and the RXIF flag also, b.t.w). At least on page 24 of
DS39582A (data sheet for 16F87xA). When reading that page,
all other flags are described like "has taken place", "occurred"
or "overflowed". That is, something actualy happened !

For the TXIF and RXIF flags, it *looks* (from the data sheet)
like those flags directly reflects the current status of the transmit
and receive register ("is empty", "is full"). I don't think they do !

I think they are set at the very moment that the registers are switching
from "full" to "empty" (I don't realy like "empty" here, a register,
technicaly speaking, can never be empty, right...)

It's quite logical, the definition of an "interrupt" is that something
actualy happend, right ?

Now, judging from this thread, is seems as if you setup
the UART register in the "currect" way, it's possible to
have the TXIF flag to be set *even* if the transmit buffer
never have been "full" and no full->empty event have ever
occured. This shoud have been documentet better maybe.

The common workaround seems to be to send some
dummy character so there is an initial event that sets TXIF.

> One thing to remember here is that every "interupt flag" is set/driven
> by something actualy happening. A pin changing state, ADC completion,
> a timer overflow or somehing else. They are not set becuse something
> happen to be in some steady state. Something have to *happen* !

Yes, setting TXEN is what happens.

> Now, regarding the TXIF flag. I think the documentation is
> somewhare between unclear and wrong in the description of the
> TXIF flag

It is very clearly documented. "Flag bit TXIF is set when enable bit
TXEN is set." This verbiage appears in both the midrange and 18
family documents, as well as individual datasheets.

> The common workaround seems to be to send some
> dummy character so there is an initial event that sets TXIF.
>
> Seems reasonable ?

No. It sounds like voodoo that someone used to work around broken
software.

> > Now, regarding the TXIF flag. I think the documentation is
> > somewhare between unclear and wrong in the description of the
> > TXIF flag
>
> It is very clearly documented. "Flag bit TXIF is set when enable bit
> TXEN is set." This verbiage appears in both the midrange and 18
> family documents, as well as individual datasheets.

Correct, but I was *specificaly* talking about what's written on page 24
in the description of the flags in PIR1. Do you think *that* also is
"clearly documented" ?

My point was that while reading page 24, you could get the
impression that RXIF and TXIF directly reflects the actual
steady state of the USART buffers, and I don't think they do.

> My point was that while reading page 24, you could get the
> impression that RXIF and TXIF directly reflects the actual
> steady state of the USART buffers, and I don't think they do.

Why do you think that? Page 115 states, "Flag bit TXIF is set when
enable bit TXEN is set. TXIF is cleared by loading TXREG." I see no
contradiction between that and what is on page 28. If TXEN is set,
TXIF reflects the state of the transmit buffer.