
////////////////////////////////////////////////
//
// circular buffer code template
//

//////////////////////////////////////////////
//


// dummies to make sample code compile
unsigned char YouStoreWhereItmustGo_ForIndependence = 0;
unsigned char ThereAreCharaftersToBeTransmittesd_ForIndependence = 0;
unsigned char TheCharafterToBeTransmittesd_ForIndependence = 0;
unsigned char WhereverTheHardwareStoresFetchedCharacter_ForIndependence = 0;
unsigned char WhereverTheHardwareRequiresCharacterToBeTransmitted_ForIndependence = 0;
// testing aids
unsigned char Test1 = 0;
unsigned char Test2 = 0;
//unsigned char Test3 = 0;
//unsigned char Test4 = 0;
void RxISR (void);
void TxISR (void);
// constants and variables
//
#define FALSE 0
#define TRUE 1
#define CIRCULAR_BUFFER_SIZE 3 // if changed to >255 RxBufFetch and RxBufStore must be changed to int
unsigned char RxBuffer[CIRCULAR_BUFFER_SIZE];
unsigned char TxBuffer[CIRCULAR_BUFFER_SIZE];
unsigned char RxBufFetch ;
unsigned char RxBufStore ;
unsigned char TxBufFetch ;
unsigned char TxBufStore ;
unsigned char RxBufferFull;
unsigned char TxBufferFull;
unsigned char TransmitInProgress;

void main(void)
{
// some initialization  
// initialize the circular buffers
RxBufFetch = 0;
RxBufStore = 0;  
TxBufFetch = 0;
TxBufStore = 0;
RxBufferFull = FALSE ;
TxBufferFull = FALSE ;
  
// in main loop
	while(1)
  {
  // ........
  // process fetched characters
    while ( (RxBufFetch |= RxBufStore) | RxBufferFull)
    {
      YouStoreWhereItmustGo_ForIndependence =  RxBuffer[RxBufFetch];
      RxBufFetch++;
      RxBufferFull = FALSE;
    }
  //...........
  // process charafters to be transmittesd
    if (ThereAreCharaftersToBeTransmittesd_ForIndependence)
    {
      if(TxBufferFull)
      { // a character may have been transmitted sice last 'visit here'
        if (TxBufStore == TxBufFetch)
        {
        // take apropiate action
        }
      }
      else
      {
        // here there is a slight chance that a fast transmit and a main holdup will cause problems
        // thus here disable transmit interrupt
        TxBuffer[RxBufStore] = TheCharafterToBeTransmittesd_ForIndependence;
        TxBufStore++;
        TxBufStore %= CIRCULAR_BUFFER_SIZE; // if size is a power of two an 'and' is more efficient here 
        if (TxBufStore == TxBufFetch)
        {
           TxBufferFull = TRUE;
        }
      // here reenable the transmit interrupt  
        if (!TransmitInProgress)
        {
          WhereverTheHardwareRequiresCharacterToBeTransmitted_ForIndependence = RxBuffer[RxBufFetch];
          TxBufFetch++;
          TxBufFetch %= CIRCULAR_BUFFER_SIZE; // if size is a power of two an 'and' is more efficient here 
          TransmitInProgress = TRUE;
        }
      }
    }
    
    if (Test1) RxISR();
    if (Test2) TxISR();
  } // end workloop 
}


//////////////////////////////////////////
//
// Code in Receive ISR OR part of UART ISR conditioned by Char available

void RxISR (void)
{
  if (RxBufferFull)
  {
    //You are hosed
  }
  RxBuffer[RxBufStore] = WhereverTheHardwareStoresFetchedCharacter_ForIndependence;
  RxBufStore++;
  RxBufStore %= CIRCULAR_BUFFER_SIZE; // if size is a power of two an 'and' is more efficient here 
  if (RxBufStore  == RxBufFetch)
  {
     RxBufferFull = TRUE;
  }
}


//////////////////////////////////////////
//
// Code in Transmit ISR OR part of UART ISR conditioned by transmit buffer empty

void TxISR (void)
{
  if ((TxBufFetch != TxBufStore) | TxBufferFull)
  {
    WhereverTheHardwareRequiresCharacterToBeTransmitted_ForIndependence = TxBuffer[TxBufFetch];
    TxBufFetch++;
    TxBufFetch %= CIRCULAR_BUFFER_SIZE; // if size is a power of two an 'and' is more efficient here 
    TxBufferFull = FALSE;
  }
  else  
  {
    TransmitInProgress = FALSE;
  }
}
