/*** *** Serial Port driver for 16f1455 and kin ***/ #include "system.h" #include #include #include /* outgoing text buffer */ char outbuff[100]; char * outp = 0; uint8_t outlen = 0; /* incoming text buffer */ char inbuff[10]; uint8_t inlen = 0; void serial_init(void) { /* Enabling transmitter 26.1.1.1 page 259 - TX/CK I/O pin */ TXSTAbits.TXEN = 1; TXSTAbits.SYNC = 0; RCSTAbits.SPEN = 1; /* Enabling receiver 26.1.2 page 262 - RX/DT I/O pin */ RCSTAbits.CREN = 1; /* Select pins 4&5 as the uart - page 102 */ TRISCbits.TRISC5 = 0; /* RC5 as output */ TRISCbits.TRISC4 = 1; /* RC4 as input */ #if _XTAL_FREQ != 4000000L #error "Adjust serial port baudrate settings" #endif /* assume 4MHz clock, 19k2 baud */ TXSTAbits.BRGH = 0; BAUDCONbits.BRG16 = 1; SPBRGL = 12; /* Enable interrupts */ INTCONbits.GIE = 1; INTCONbits.PEIE = 1; /* enable uart receiver interupt */ PIE1bits.RCIE = 1; } /* is the queue empty yet */ bool msg_empty(void) { if (outp == 0) return 1; return 0; } /* new message in the queue */ void msg_write(const char *msg) { char * p = outbuff + outlen; while (outlen < sizeof(outbuff) && *msg != 0) { *(p++) = *(msg++); outlen++; } *p = 0; if (outp == 0) { outp = outbuff; PIE1bits.TXIE = 1; } } void msg_writebyte(const char msg) { if (outlen+1 >= (uint8_t)sizeof(outbuff)) return; outbuff[outlen++] = msg; outbuff[outlen] = 0; if (outp == 0) { outp = outbuff; PIE1bits.TXIE = 1; } } /* some library functions will use this if defined, eg printf */ void putch(char data) { msg_writebyte(data); } /* called from interrupt routine to send next char */ void msg_sendnext(void) { /* we have finished, turn off the iterrupt */ if (outp == 0 || *outp == 0) { PIE1bits.TXIE = 0; outp = 0; outlen = 0; return; } TXREG = *outp; outp++; } /* called from interrupt routine to receive next byte */ void msg_recvnext(void) { while (PIR1bits.RCIF) { bool err = RCSTAbits.FERR; char new = RCREG; /* bad char, skip it */ if (err) continue; /* our input buffer has overflowed */ if (inlen > sizeof(inbuff)) return; /* keep this one */ inbuff[inlen++] = new; } } /* is there text waiting to be read */ bool msg_recvready(void) { if (inlen > 0) return 1; return 0; } /* read next byte from inpout buffer */ char msg_recv(void) { if (inlen == 0) return 0; /* record and disable the interupt */ bool in = PIE1bits.RCIE; PIE1bits.RCIE = 0; char new = inbuff[0]; inlen--; /* shuffle them down one */ for (char i=0;i