AN93

Buffer Management, Status and Control Layer

Buffer Management

Sample code for this layer can be found in the application_buffers.c file. This code can be ported to other applications with minimal changes needed to compile on the host platform. This block contains the buffer- management routines for both modem and UART access. The buffer structure consists of two circular buffers implemented as the following array variables:

char gModemToUARTBuffer[ BUFFERSIZE ];

The above buffer is typically filled by modemInterrupt() and emptied by UART0Interrupt(). Once the buffer is empty, subsequent TI0 (UART) interrupts have no effect. If the buffer is filled again after all TI0 interrupts have been serviced, the TI0 interrupt needs jump starting. This is accomplished by calling UARTCommunicationUpdate() after filling the buffer.

char gUARTToModemBuffer[ BUFFERSIZE ];

The above buffer is typically filled by UART0Interrupt() and emptied by modemInterrupt(). Once the buffer is empty, subsequent TXE (modem) interrupts have no effect. If the buffer is filled again after all TXE interrupts have been serviced, the TXE interrupt needs jump starting. This is accomplished by calling modemCommunicationUpdate() after filling the buffer.

The two arrays above must be sized by choosing a power of two for the value of BUFFERSIZE, defined in modem_80C51.h. This is because keeping track of the circular-buffer indexes requires modulus operations. Instead of costly integer divisions with remainder, the modulus operation is achieved by bit masking using the all- one bit pattern equal to BUFFERSIZE minus one. For example, if BUFFERSIZE is 1024 (210), the bit mask (MODULUS_MASK) used for updating buffer pointers modulo BUFFERSIZE must be 1023 (0011 1111 1111). When a buffer index reaches the value 1024 (0100 0000 0000), a bitwise-AND operation with MODULUS_MASK will reset the index value to zero. If the value of BUFFERSIZE is changed in the header file, then the value of MODULUS_MASK must be set to the same value minus one. The following global variables track the state of the buffers. A value of zero indicates an empty buffer.

int gModemToUARTBufferSize; int gUARTToModemBufferSize;

Read and write addresses to the above buffers are tracked by the following pointers:

int gLastFromUART;

// The last

byte

that

was added to

gUARTToModemBuffer[]

int gNextToModem;

// The first byte that will

be

taken

out

of

gUARTToModemBuffer[]

int

gLastFromModem;

//

The last

byte

that

was added to

gModemToUARTBuffer[]

int

gNextToUART;

//

The first byte that will

be

taken

out

of

gModemToUARTBuffer[]

The flow of data between the modem and the UART is managed by the following functions:

char pullByteForModem( void );

// Remove a

byte

from

gUARTToModemBuffer[]

char pullByteForUART(

void );

// Remove a

byte

from

gModemToUARTBuffer[]

void

pushByteToModem(

char byteToSend );

//

Add

a

byte

to

gUARTToModemBuffer[]

void

pushByteToUART( char byteToSend );

//

Add

a

byte

to

gModemToUARTBuffer[]

Figure 77 summarizes the interactions between the function calls, pointers and buffers described above.

296

Rev. 1.3

Page 296
Image 296
Silicon Laboratories SI2493/57/34/15/04, SI2494/39 manual Buffer Management, Status and Control Layer