/*
 Interrupt driven serial i/o routines.
 P. McGill 26May11
 Based on code by Shane Tolmie and Regulus Berdin at www.microchipc.com
*/

#ifndef _INTSERIAL_H_
#define _INTSERIAL_H_

/* Buffer size must be a power of 2 (e.g. 2, 4, ..., 64, 128) */
#define SER_BUFFER_SIZE	16
		
#define SER_FIFO_MASK 	(SER_BUFFER_SIZE - 1)

/* Insert this macro inside the interrupt routine */
#define ser_int() 				\
    if (RCIF && RCIE) {				\
        rxfifo[rxinptr] = RCREG;		\
        ser_tmp = (rxinptr + 1) & SER_FIFO_MASK;\
        if (ser_tmp != rxoutptr)		\
            rxinptr = ser_tmp;			\
    }						\
    if (TXIF && TXIE) {				\
        TXREG = txfifo[txoutptr];		\
        ++txoutptr;				\
        txoutptr &= SER_FIFO_MASK;		\
        if (txoutptr == txinptr) {		\
            TXIE = 0;				\
        }					\
    }

bit kbhit(void);
unsigned char getch(void);
unsigned char getche(void);
void putch(unsigned char byte);
void putst(const char *s);
void putst2(unsigned char *s);
void putchhex(unsigned char v);
void serial_setup(void);

#ifndef _INTSERIAL_C_
extern unsigned char rxfifo[SER_BUFFER_SIZE];
extern volatile unsigned char rxinptr, rxoutptr;
extern bank1 unsigned char txfifo[SER_BUFFER_SIZE];
extern volatile unsigned char txinptr, txoutptr;
extern unsigned char ser_tmp;
#endif

#endif
