OSDN Git Service

[SCHEMATIC] Modify SW/MW/LW Preamp, insert galbanic-isolator replace of common-mode...
[openi2cradio/OpenI2CRadio.git] / euart.c
1 /*
2  * OpenI2CRADIO
3  * EUSART Handler
4  * Copyright (C) 2013-06-20 K.Ohta <whatisthis.sowhat ai gmail.com>
5  *
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.
14  *
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,
18  *  MA 02110-1301, USA.
19  *
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.
26  */
27
28 #if defined(__SDCC)
29 #include <sdcc-lib.h>
30 #include <pic18fregs.h> /* ONLY FOR PIC18x */
31 #include <delay.h>
32 #else
33 #include <xc.h>
34 #endif
35 #include <signal.h>
36
37 #include "iodef.h"
38 #include "idle.h"
39 #include "ioports.h"
40 #include "euart.h"
41
42 static char uart_rfifo[UART_BUF_SIZE];
43
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;
50
51 static unsigned char uart_rx_wakeup;
52 #define UART_BAUD_FACTOR 34 // 57600bps on 8MHz,BRGH=1,BRG16=1
53
54 void uart_sleep(void)
55 {
56     PIR1bits.TX1IF = 0;
57     PIR1bits.RC1IF = 0;
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
63     PIE1bits.TX1IE = 0;
64     PIE1bits.RC1IE = 1;
65     uart_rx_wakeup = 0;
66     UART_CTSOUT = 0;
67     SPBRGH = UART_BAUD_FACTOR / 256;
68     SPBRG = UART_BAUD_FACTOR % 256;
69 }
70
71 void uart_wakeup(void)
72 {
73     PIR1bits.TX1IF = 0;
74     PIR1bits.RC1IF = 0;
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
80     PIE1bits.TX1IE = 0;
81     PIE1bits.RC1IE = 1;
82     UART_CTSOUT = 0;
83    //   uart_rx_wakeup = 0xff;
84    SPBRGH = UART_BAUD_FACTOR / 256;
85    SPBRG = UART_BAUD_FACTOR % 256;
86 }
87
88 void uart_init(void)
89 {
90     uart_rx_rptr = 0;
91     uart_rx_wptr = 0;
92     uart_rx_bytes = 0;
93     uart_rx_wakeup = 0;
94     uart_rx_xon = 0xff;
95     uart_tx_xon = 0xff;
96     uart_sleep();
97 }
98
99
100 void uart_inthdr_rx(void)
101 {
102     unsigned char c;
103 #if 1
104     if(uart_rx_wakeup == 0){
105         if(BAUDCONbits.WUE != 1){ // Okay, Wakeup interrupt
106             uart_rx_wakeup = 0xff;
107         }
108         goto _l0; // exit
109     }
110     if(BAUDCONbits.ABDEN == 1) { // Still configure baudrate
111         goto _l0; // Exit
112     }
113 #endif
114     c = RCREG;
115     if(RCSTAbits.OERR == 0) {
116         if(RCSTAbits.FERR == 0) {
117             uart_rx_sts = 0; // Clear error
118             uart_rfifo[uart_rx_wptr] = c;
119             uart_rx_wptr++;
120             if(uart_rx_wptr >= UART_BUF_SIZE) uart_rx_wptr = 0;
121             uart_rx_bytes++;
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
125                uart_rx_xon = 0;
126             }
127         } else { // Frame Error
128          uart_rx_sts != UART_FRAMEERROR;
129         }
130     } else {
131          uart_rx_sts != UART_OVERFLOW;
132     }
133
134 _l0:  // Exit
135  PIR1bits.RC1IF = 0;
136  RCSTAbits.CREN = 1;
137  return;
138 }
139
140 /*
141  * Pull char from RX FIFO.
142  */
143 unsigned char uart_pullchar(void)
144 {
145     unsigned char c;
146     while(PIR1bits.RC1IF == 1) {
147         idle(100); // Wait for RX completed
148     }
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;
152     uart_rx_bytes--;
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
156        uart_rx_xon = 0xff;
157     }
158     return c;
159 }
160
161 unsigned char uart_pushchar(unsigned char c, unsigned int timeout)
162 {
163     unsigned int i;
164     if(timeout != 0){
165         for(i = timeout; i > 0; i--){
166             if((UART_RTSIN == 0) && (TXSTAbits.TRMT1 == 1)) break;
167             idle(100);
168         }
169         if(i != 0) goto _l1;  // Send and return;
170         return UART_TIMEOUT; // Timeout
171     }
172     if((TXSTAbits.TRMT1 == 0) || (UART_RTSIN != 0)) return UART_TIMEOUT; // If timeout=0 return immidiately.
173 _l1:
174     TXREG = c;
175     return 0;
176 }
177
178 void uart_pushxon(unsigned int timeout)
179 {
180     unsigned int i;
181 #if 0
182    if(uart_rx_wakeup == 0) return;
183     if(timeout != 0) {
184         for(i = timeout; i > 0; i--){
185             if(TXSTAbits.TRMT1 == 1) break;
186             idle(100); // 100us
187         }
188         return;
189     } else {
190         while(TXSTAbits.TRMT1 == 0) idle(100);
191     }
192 #endif
193    //    TXREG = UART_CH_XON;
194     UART_CTSOUT = 0;
195 }
196
197 void uart_pushxoff(unsigned int timeout)
198 {
199     unsigned int i;
200 #if 0
201    if(uart_rx_wakeup == 0) return;
202     if(timeout != 0) {
203         for(i = timeout; i > 0; i--){
204             if(TXSTAbits.TRMT1 == 1) break;
205             idle(100); // 100us
206         }
207         return;
208     } else {
209         while(TXSTAbits.TRMT1 == 0) idle(100);
210     }
211 #endif
212    //    TXREG = UART_CH_XOFF;
213     UART_CTSOUT = 1;
214 }
215
216 void uart_break(void)
217 {
218     TXSTAbits.SENDB1 = 1;
219 }
220
221 unsigned char uart_getstat(void)
222 {
223     unsigned char s = uart_rx_sts;
224     if(uart_rx_wakeup != 0) s |= UART_WAKEUP;
225     return s;
226 }