4 * Copyright (C) 2013-06-20 K.Ohta <whatisthis.sowhat ai gmail.com>
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2,
9 * or (at your option) any later version.
10 * This library / program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
13 * See the GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this library; see the file COPYING. If not, write to the
17 * Free Software Foundation, 51 Franklin Street, Fifth Floor, Boston,
20 * As a special exception, if you link this(includeed from sdcc) library
21 * with other files, some of which are compiled with SDCC,
22 * to produce an executable, this library does not by itself cause
23 * the resulting executable to be covered by the GNU General Public License.
24 * This exception does not however invalidate any other reasons why
25 * the executable file might be covered by the GNU General Public License.
30 #include <pic18fregs.h> /* ONLY FOR PIC18x */
42 static char uart_rfifo[UART_BUF_SIZE];
44 static unsigned int uart_rx_rptr;
45 static unsigned int uart_rx_wptr;
46 static int uart_rx_bytes;
47 static unsigned char uart_rx_sts;
48 static unsigned char uart_rx_xon;
49 static unsigned char uart_tx_xon;
51 static unsigned char uart_rx_wakeup;
52 #define UART_BAUD_FACTOR 34 // 57600bps on 8MHz,BRGH=1,BRG16=1
58 IPR1bits.TX1IP = 0; // Low
59 IPR1bits.RC1IP = 1; // High
60 RCSTA = 0b10010000; //SPEN, 8bit, ASYNC, CREN = 0
61 BAUDCON = 0b00001010; // IDLE High, DTRXP=0(Positive), BRG16, -ABDEN, WUE
62 TXSTA = 0b00100100; //8bit, ASYNC, TXEN, Break, BRGH=1
67 SPBRGH = UART_BAUD_FACTOR / 256;
68 SPBRG = UART_BAUD_FACTOR % 256;
71 void uart_wakeup(void)
75 IPR1bits.TX1IP = 0; // Low
76 IPR1bits.RC1IP = 1; // High
77 RCSTA = 0b10010000; //SPEN, 8bit, ASYNC, CREN
78 BAUDCON = 0b00001010; // IDLE High, DTRXP=0(Positive),BRG16, -ABDEN, WUE
79 TXSTA = 0b00100100; //8bit, ASYNC, TXEN, Break, BRGH=1
83 // uart_rx_wakeup = 0xff;
84 SPBRGH = UART_BAUD_FACTOR / 256;
85 SPBRG = UART_BAUD_FACTOR % 256;
100 void uart_inthdr_rx(void)
104 if(uart_rx_wakeup == 0){
105 if(BAUDCONbits.WUE != 1){ // Okay, Wakeup interrupt
106 uart_rx_wakeup = 0xff;
110 if(BAUDCONbits.ABDEN == 1) { // Still configure baudrate
115 if(RCSTAbits.OERR == 0) {
116 if(RCSTAbits.FERR == 0) {
117 uart_rx_sts = 0; // Clear error
118 uart_rfifo[uart_rx_wptr] = c;
120 if(uart_rx_wptr >= UART_BUF_SIZE) uart_rx_wptr = 0;
122 if(uart_rx_bytes >= UART_BUF_SIZE) uart_rx_bytes = UART_BUF_SIZE;
123 if((uart_rx_xon != 0) && (uart_rx_bytes >= ((UART_BUF_SIZE * 8) / 10))) { // Buffer will be full
124 UART_CTSOUT = 1; // OFF
127 } else { // Frame Error
128 uart_rx_sts != UART_FRAMEERROR;
131 uart_rx_sts != UART_OVERFLOW;
141 * Pull char from RX FIFO.
143 unsigned char uart_pullchar(void)
146 while(PIR1bits.RC1IF == 1) {
147 idle(100); // Wait for RX completed
149 if(uart_rx_bytes <= 0) return 0; // EMPTY
150 c = uart_rfifo[uart_rx_rptr++];
151 if(uart_rx_rptr > UART_BUF_SIZE) uart_rx_rptr = 0;
153 if(uart_rx_bytes <= 0) uart_rx_bytes = 0;
154 if((uart_rx_xon == 0) && (uart_rx_bytes < ((UART_BUF_SIZE * 3) / 10))) { // Buffer will be empty
155 UART_CTSOUT = 0; // ON
161 unsigned char uart_pushchar(unsigned char c, unsigned int timeout)
165 for(i = timeout; i > 0; i--){
166 if((UART_RTSIN == 0) && (TXSTAbits.TRMT1 == 1)) break;
169 if(i != 0) goto _l1; // Send and return;
170 return UART_TIMEOUT; // Timeout
172 if((TXSTAbits.TRMT1 == 0) || (UART_RTSIN != 0)) return UART_TIMEOUT; // If timeout=0 return immidiately.
178 void uart_pushxon(unsigned int timeout)
182 if(uart_rx_wakeup == 0) return;
184 for(i = timeout; i > 0; i--){
185 if(TXSTAbits.TRMT1 == 1) break;
190 while(TXSTAbits.TRMT1 == 0) idle(100);
193 // TXREG = UART_CH_XON;
197 void uart_pushxoff(unsigned int timeout)
201 if(uart_rx_wakeup == 0) return;
203 for(i = timeout; i > 0; i--){
204 if(TXSTAbits.TRMT1 == 1) break;
209 while(TXSTAbits.TRMT1 == 0) idle(100);
212 // TXREG = UART_CH_XOFF;
216 void uart_break(void)
218 TXSTAbits.SENDB1 = 1;
221 unsigned char uart_getstat(void)
223 unsigned char s = uart_rx_sts;
224 if(uart_rx_wakeup != 0) s |= UART_WAKEUP;