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