130
Rabbit 2000 Microprocessor User’s Manual
an exception to be aware of when a serial port has to operate at an extremely high speed. At
115,200 bps, the highest speed of a PC serial port, the interrupts must be serviced in 10 baud
times, or 86 s, in order not to lose the received characters. If all four serial ports were operat-
ing at this receive speed, it would be necessary to service the interrupt in less than 21.5 s to
assure no lost characters. In addition, the time taken by other interrupts of equal or higher
priority would have to be considered. A receiver service routine might appear as follows
below. The byte at bufptr is used to address the buffer where data bits are stored. It is nec-
essary to save and increment this byte because characters could be handled out of order if
two receiver interrupts take place in quick succession.
receive:
PUSH HL
; 10 save hl
PUSH DE
; 10 save de
LD HL,STRUCT
; 6
LD A,(HL)
; 5 getin-pointer
LD E,A
; 2 save in pointer in e
INC HL
; 2 point to out-pointer
CMP A,(HL)
; 5 see if in-pointer=out-pointer (buffer full)
JR Z,roverrun
; 5 go fix up receiver over run
INC A
; 2 incement the in pointer
AND A,MASK
; 4 mask such as 11110000 if 16 buffer locs
DEC HL
; 2
LD (HL),A
; 6 update the in pointer
IOI LD A,(SCDR) ; 11 get data register port C, clears interrupt request
IPRES
; 4 restore the interrupt priority
; 68 clocks to here
; to level before interrupt took place
; more interrupts could now take place,
; but receiver data is in registers
; now handle the rest of the receiver interrupt routine
LD HL,BUFBASE
; 6
LD D,0
; 6
ADD HL,DE
; 2 location to store data
LD (HL),A
;
6 put away the data byte
POP DE
;7
POP HL
; 7
POP AF
; 7
RET
; 8 from interrupt
; 117 clocks to here
This routine gets the interrupts turned on in about 68 clocks or 3.5 s at a clock speed of
20 MHz. Although two characters may be handled out of order, this will be invisible to a
higher level routine checking the status of the input buffer because all the interrupts will
be completed before the higher level routine can perform a check on the buffer status.
A typical way to organize the buffers is to have an in-pointer and an out-pointer that incre-
ment through the addresses in the data buffer in a circular manner. The interrupt routine
manipulates the in-pointer and the higher level routine manipulates the out-pointer. If the in-
pointer equals the out-pointer, the buffer is considered full. If the out-pointer plus 1 equals
the in-pointer, the buffer is empty. All increments are done in a circular fashion, most easily
accomplished by making the buffer a power of two in length, then anding a mask after the
increment. The actual memory address is the pointer plus a buffer base address.