00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016 #include "config.h"
00017 #include "pic_utils.h"
00018 #include "pic_serial.h"
00019 #include <string.h>
00020 #include <stdlib.h>
00021
00023 uns8 tx_buffer[SERIAL_TX_BUFFER_SIZE];
00025 uns8 tx_start=0;
00027 uns8 tx_end=0;
00028
00030 uns8 rx_buffer[SERIAL_RX_BUFFER_SIZE];
00032 uns8 rx_start = 0;
00034 uns8 rx_end = 0;
00035
00036 #ifdef SERIAL_DEBUG
00037 uns8 rx_soft_overflow = 0;
00038 uns8 rx_hard_overflow = 0;
00039 uns8 rx_framing_error = 0;
00040 #endif
00041
00042
00043
00044 inline uns8 bin2Hex(uns8 x)
00045 {
00046 if (x < 10) {
00047 return '0' + x;
00048 } else {
00049 return 'A' -10 + x;
00050 }
00051 }
00052
00053
00054 void serial_setup(bit req_brgh, uns8 req_spbrg)
00055 {
00056 #ifdef _PIC16F88
00057 set_bit(trisb, 5);
00058 set_bit(trisb, 2);
00059 #define TRIS_SET
00060 #endif
00061 #ifdef _PIC16F876A
00062 set_bit(trisc,6);
00063 set_bit(trisc,7);
00064 #define TRIS_SET
00065 #endif
00066 #ifdef _PIC18F2620
00067 set_bit(trisc,6);
00068 set_bit(trisc,7);
00069 #define TRIS_SET
00070 #endif
00071 #ifdef _PIC18F4520
00072 set_bit(trisc,6);
00073 set_bit(trisc,7);
00074 #define TRIS_SET
00075 #endif
00076 #ifdef _PIC18F4550
00077 set_bit(trisc,6);
00078 set_bit(trisc,7);
00079 #define TRIS_SET
00080 #endif
00081
00082 #ifndef TRIS_SET
00083 #warning "You must set tris bits for serial use yourself, I don't know your pic"
00084 #warning "Please send your tris bits in so they can be included in the library"
00085 #endif
00086
00087 txsta.BRGH = req_brgh;
00088
00089 spbrg = req_spbrg;
00090
00091 clear_bit(txsta, SYNC);
00092 set_bit(rcsta, SPEN);
00093
00094
00095
00096 kill_interrupts();
00097
00098 clear_bit(txsta, TX9);
00099 clear_bit(txsta, TX9D);
00100
00101 set_bit(txsta, TXEN);
00102
00103
00104
00105 clear_bit(rcsta, RX9);
00106 clear_bit(rcsta, FERR);
00107
00108 _asm {
00109 MOVF _rcreg,W
00110 MOVF _rcreg,W
00111 MOVF _rcreg,W
00112 }
00113
00114 clear_bit(rcsta, CREN);
00115 set_bit(rcsta, CREN);
00116
00117 set_bit(pie1, RCIE);
00118
00119 }
00120
00121
00122
00123
00124 void serial_putc(uns8 c)
00125 {
00126 uns8 tx_next;
00127 bit my_store_gie;
00128 #ifdef SERIAL_IDE_DEBUG
00129 return;
00130 #endif
00131
00132 if ((tx_end == tx_start) &&
00133 test_bit(pir1, TXIF)) {
00134 txreg = c;
00135 } else {
00136 tx_next = tx_end + 1;
00137 if (tx_next == SERIAL_TX_BUFFER_SIZE) {
00138 tx_next = 0;
00139 }
00140 #ifdef SERIAL_DISCARD_ON_TX_FULL_DURING_INT
00141 if ((!intcon.GIE) && (tx_next == tx_start)) {
00142 return;
00143 }
00144 #endif
00145 while (tx_next == tx_start) {
00146
00147
00148
00149 #ifndef SERIAL_DISCARD_ON_TX_FULL_DURING_INT
00150 if (!intcon.GIE) {
00151 serial_handle_tx_isr();
00152 }
00153 #endif
00154 }
00155 my_store_gie = intcon.GIE;
00156 kill_interrupts();
00157
00158 tx_buffer[tx_end] = c;
00159 tx_end = tx_next;
00160
00161 set_bit(pie1, TXIE);
00162 intcon.GIE = my_store_gie;
00163 }
00164 }
00165
00166
00167
00168 void serial_tx_isr()
00169 {
00170 uns8 tx_next;
00171
00172 if (tx_end == tx_start) {
00173 return;
00174 }
00175 tx_next = tx_start + 1;
00176 if (tx_next == SERIAL_TX_BUFFER_SIZE) {
00177 tx_next = 0;
00178 }
00179 if (tx_end == tx_next) {
00180 clear_bit(pie1, TXIE);
00181 }
00182 txreg = tx_buffer[tx_start];
00183 tx_start = tx_next;
00184
00185 }
00186
00187
00188 void serial_rx_isr()
00189 {
00190 uns8 rx_next;
00191
00192
00193 if (test_bit(rcsta, OERR)) {
00194 clear_bit(rcsta, CREN);
00195 _asm {
00196 MOVF _rcreg,W
00197 MOVF _rcreg,W
00198 MOVF _rcreg,W
00199 }
00200 #ifdef SERIAL_DEBUG
00201 rx_hard_overflow++;
00202 #endif
00203 set_bit(rcsta, CREN);
00204 } else {
00205 if (test_bit(rcsta, FERR)) {
00206 #ifdef SERIAL_DEBUG
00207 rx_framing_error++;
00208 #endif
00209 }
00210 rx_next = rx_end + 1;
00211 if (rx_next == SERIAL_RX_BUFFER_SIZE) {
00212 rx_next = 0;
00213 }
00214 if (rx_next != rx_start) {
00215 rx_buffer[rx_end] = rcreg;
00216 rx_end = rx_next;
00217 } else {
00218 _asm MOVF _rcreg,W
00219 #ifdef SERIAL_DEBUG
00220 rx_soft_overflow++;
00221 #endif
00222 }
00223 }
00224 }
00225
00226
00227
00228 uns8 serial_getc(void)
00229 {
00230 uns8 rx_char, rx_next;
00231
00232 while(rx_end == rx_start);
00233
00234 start_crit_sec();
00235
00236 rx_char = rx_buffer[rx_start];
00237 rx_start++;
00238 if (rx_start == SERIAL_RX_BUFFER_SIZE) {
00239 rx_start = 0;
00240 }
00241
00242 end_crit_sec();
00243
00244 return (rx_char);
00245
00246 }
00247
00248
00249
00250 void serial_print_str(char *str) {
00251
00252 uns8 count;
00253
00254 for(count = 0 ; str[count] != 0; count++)
00255 {
00256 serial_putc(str[count]);
00257 }
00258 }
00259
00260
00261
00262 void serial_print_str(rom char *str) {
00263
00264 uns8 count;
00265
00266 for(count = 0 ; str[count] != 0; count++)
00267 {
00268 serial_putc(str[count]);
00269 }
00270 }
00271
00272
00273
00274 void serial_print_int(uns16 i) {
00275
00276 char buffer[6];
00277 uns8 count = 5;
00278 buffer[5] = '\0';
00279 do {
00280 count--;
00281 buffer[count] = '0' + i % 10;
00282 i = i / 10;
00283 } while (i > 0);
00284 while (buffer[count]) {
00285 serial_putc(buffer[count]);
00286 count++;
00287 }
00288
00289
00290
00291
00292
00293 }
00294
00295 void serial_print_int_hex(uns8 i) {
00296
00297 serial_putc(bin2Hex(i >> 4));
00298 serial_putc(bin2Hex((i & 0x0f)));
00299
00300 }
00301
00302 void serial_print_int_hex_16bit(uns16 i) {
00303 serial_print_int_hex(i >> 8);
00304 serial_print_int_hex(i & 0xff);
00305 }
00306
00307
00308 void serial_print_spc() {
00309 serial_putc(' ');
00310 }
00311
00312
00313 void serial_print_nl() {
00314 serial_putc('\n');
00315 }
00316
00317
00318
00319 uns8 serial_rx_avail() { return rx_start != rx_end; }
00320 uns8 serial_tx_empty() { return tx_start == tx_end; }
00321