Re: Interrupt driven UART
- From: Mark Borgerson <mborgerson.at.comcast.net>
- Date: Fri, 13 Oct 2006 15:29:36 -0700
In article <1160710154.445591.255650@xxxxxxxxxxxxxxxxxxxxxxxxxxxx>,
goister@xxxxxxxxx says...
If your processor has 16 or 32-bit registers, it will probably do a
Mark Borgerson wrote:
In article <1160642892.522507.50970@xxxxxxxxxxxxxxxxxxxxxxxxxxxx>,
goister@xxxxxxxxx says...
That's the general scheme. There are a few details to consider:
Ico wrote:
goister@xxxxxxxxx <goister@xxxxxxxxx> wrote:Hmm disregard my previous message. I think I know what you mean. I
Hi,
I'm working with a Toshiba TMP91 series MCU that doesn't seem to have
any UART control/status bits to check for empty data register, rx/tx
ready, etc, but does have interrupt vectors for serial tx and rx, which
is why I think I have to use interrupt driven UART rather than polling
it.
I have functions that expect to receive and send a single byte by
calling receivebyte and sendbyte functions. However, since it's
interrupt based, receivebyte seems to be pretty redundant. What I have
now is a UART receive ISR that first does error checking, then copies
the rx buffer to a global rx byte variable, and setting a global
rx_ready flag to 1. Then my receivebyte function does nothing until the
rx ready flag is set, after which it just clears it. Does this make
sense?
This might work, but imagine what would happen if a byte is received on the
uart while your code happens to be doing something else then calling the
uart_receive function ? Instead of having only one 'global rx variable',
consider using a ringbuffer aka 'circular buffer' aka fifo for this. The RX
interrupt stores incoming bytes into the buffer and updates the head and tail
pointers, while your uart_receive function reads one byte from the buffer, or -
if the buffer is empty - waits until new data comes available.
think I can implement the fifo with a fixed array size of n, and a head
and tail index rather than pointer(both initialized to 0). The rx isr
will move a byte from the rxbuffer to the fifo head, increment the
head(wrapping back to 0 when head == n) and set the global rx ready
flag, and the receivebyte function will simply wait for the rx ready
flag set by the ISR, then move a byte from the the fifo tail to a local
variable, and increment the tail(wrapping too). Makes sense?
1. why not keep a counter of the bytes in the queue rather than
a simple flag. That way, if your main application goes away
for a long time, it can note that there are many byte in the
buffer, rather than just an indication that one or more
bytes are available.
2. You may need to keep track of the possibility of queue
overflow.
3. An oft-used trick for circular buffers is to make the
buffer length an exact power of two. Then you can
skip the wraparound test and simply mask the index with
an appropriate value to accomplish the wraparound.
#define BUFFERLENGTH 64
unsigned char buffer[BUFFERLENGTH];
short bufInputIndex, bufInputAvailable;
//
// add character to buffer and wrap as required
buffer[bufInputIndex++] = ch;
bufInputAvailable++;
bufInputIndex &= (BUFFERLENGTH-1); // masking handles wrap
You can find the source code for a ring buffer, interrupt
driven, serial handler at www.oes.to. Look for the
U4SCFX library link. The code is for an M68K system, but
the source is pretty generic C.
Mark Borgerson
1/2) Point taken, but at 9600bps and the amount of data that I intend
to send, I don't think queue overflow is going to be a big problem, if
at all. Still, it's good practice to handle any possible errors. I'll
probably do that.
3) Makes sense. I don't know why I didn't think of the powers of 2
solution. Anyway, if I set my buflen to 256 and set the index to
unsigned char, I wouldn't even need do any wraparound check would I?
It'd automatically wrap :)
masking operation after the increment in any case. It will just
be hidden from you by the compiler.
Mark Borgerson
.
- References:
- Interrupt driven UART
- From: goister@xxxxxxxxx
- Re: Interrupt driven UART
- From: Ico
- Re: Interrupt driven UART
- From: goister@xxxxxxxxx
- Re: Interrupt driven UART
- From: Mark Borgerson
- Re: Interrupt driven UART
- From: goister@xxxxxxxxx
- Interrupt driven UART
- Prev by Date: Re: Regarding H1 visa and job in US
- Next by Date: ColdFire XCF5206EFT40 Info
- Previous by thread: Re: Interrupt driven UART
- Next by thread: Re: Interrupt driven UART
- Index(es):
Relevant Pages
|