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