2 *** Serial Port driver for 12f1840 and kin
12 /* outgoing text buffer */
17 /* incoming text buffer */
22 void serial_init(void)
24 /* Enabling transmitter 26.1.1.1 page 259 - TX/CK I/O pin */
28 /* Enabling receiver 26.1.2 page 262 - RX/DT I/O pin */
31 /* Select pins 4&5 as the uart - page 102 */
32 APFCONbits.RXDTSEL = 1; /* RX/DT on RA5 */
33 APFCONbits.TXCKSEL = 1; /* TX/CK on RA4 */
34 TRISAbits.TRISA5 = 1; /* RA5 as input */
35 TRISAbits.TRISA4 = 0; /* RA4 as output */
37 ANSELAbits.ANSA4 = 0; /* no analog */
39 #if _XTAL_FREQ != 4000000L
40 #error "Adjust serial port baudrate settings"
43 /* assume 4MHz clock, 19k2 baud */
45 BAUDCONbits.BRG16 = 1;
48 /* Enable interrupts */
52 /* enable uart receiver interupt */
57 /* is the queue empty yet */
60 if (outp == 0) return 1;
64 /* new message in the queue */
65 void msg_write(const char *msg)
67 char * p = outbuff + outlen;
68 while (outlen < sizeof(outbuff) && *msg != 0) {
79 void msg_writebyte(const char msg)
81 if (outlen+1 >= (uint8_t)sizeof(outbuff)) return;
82 outbuff[outlen++] = msg;
95 /* called from interrupt routine to send next char */
96 void msg_sendnext(void)
98 /* we have finished, turn off the iterrupt */
99 if (outp == 0 || *outp == 0) {
109 /* called from interrupt routine to receive next byte */
110 void msg_recvnext(void)
112 while (PIR1bits.RCIF) {
113 bool err = RCSTAbits.FERR;
116 /* bad char, skip it */
119 /* our input buffer has overflowed */
120 if (inlen > sizeof(inbuff)) return;
123 inbuff[inlen++] = new;
127 bool msg_recvready(void)
129 if (inlen > 0) return 1;
135 if (inlen == 0) return 0;
137 /* record and disable the interupt */
138 bool in = PIE1bits.RCIE;
141 char new = inbuff[0];
144 /* shuffle them down one */
145 for (char i=0;i<inlen;i++)
146 inbuff[i] = inbuff[i+1];
148 /* restore the interupt */