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
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086 #include <sys/atom.h>
00087 #include <sys/event.h>
00088 #include <sys/timer.h>
00089
00090 #include <dev/irqreg.h>
00091
00092 #include <dev/usartavr.h>
00093
00094 #ifdef NUTTRACER
00095 #include <sys/tracer.h>
00096 #endif
00097
00102
00103
00104 #define ASCII_XON 0x11
00105
00106 #define ASCII_XOFF 0x13
00107
00108
00109 #define XON_PENDING 0x10
00110
00111 #define XOFF_PENDING 0x20
00112
00113 #define XOFF_SENT 0x40
00114
00115 #define XOFF_RCVD 0x80
00116
00117
00121 static ureg_t rx_errors;
00122
00126 static ureg_t flow_control;
00127
00131 static ureg_t tx_aframe;
00132
00133 #ifdef UART_HDX_BIT
00134
00135 #ifdef UART_HDX_FLIP_BIT
00136 #define UART_HDX_TX cbi
00137 #define UART_HDX_RX sbi
00138 #else
00139 #define UART_HDX_TX sbi
00140 #define UART_HDX_RX cbi
00141 #endif
00142 #endif
00143
00144
00145 #ifdef UART_HDX_BIT
00146
00152 static ureg_t hdx_control;
00153 #endif
00154
00155 #ifdef UART_RTS_BIT
00156
00162 static ureg_t rts_control;
00163 #endif
00164
00165 #ifdef UART_CTS_BIT
00166
00172 static ureg_t cts_sense;
00173 #endif
00174
00175 #ifdef UART_CTS_BIT
00176
00186 static void AvrUsartCts(void *arg)
00187 {
00188
00189 sbi(UCSRnB, UDRIE);
00190
00191 cbi(EIMSK, UART_CTS_BIT);
00192 }
00193 #endif
00194
00195 #ifdef UART_HDX_BIT
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207 static void AvrUsartTxComplete(void *arg)
00208 {
00209 register RINGBUF *rbf = (RINGBUF *) arg;
00210
00211
00212
00213
00214
00215 if (hdx_control && rbf->rbf_cnt == 0) {
00216
00217 UART_HDX_RX(UART_HDX_PORT, UART_HDX_BIT);
00218 }
00219 }
00220 #endif
00221
00222
00223
00224
00225
00226
00227 #ifdef USE_USART
00228
00229 SIGNAL( SIG_UART_DATA ) {
00230 register RINGBUF *rbf = &dcb_usart.dcb_tx_rbf;
00231
00232 #else
00233
00234 static void AvrUsartTxEmpty(void *arg) {
00235 register RINGBUF *rbf = (RINGBUF *) arg;
00236
00237 #endif
00238
00239 register u_char *cp = rbf->rbf_tail;
00240
00241
00242 #ifdef NUTTRACER
00243 TRACE_ADD_ITEM(TRACE_TAG_INTERRUPT_ENTER,TRACE_INT_UART_TXEMPTY);
00244 #endif
00245
00246 #ifndef UART_NO_SW_FLOWCONTROL
00247
00248
00249
00250
00251 if (flow_control & (XON_PENDING | XOFF_PENDING)) {
00252 if (flow_control & XON_PENDING) {
00253 outb(UDRn, ASCII_XOFF);
00254 flow_control |= XOFF_SENT;
00255 } else {
00256 outb(UDRn, ASCII_XON);
00257 flow_control &= ~XOFF_SENT;
00258 }
00259 flow_control &= ~(XON_PENDING | XOFF_PENDING);
00260 #ifdef NUTTRACER
00261 TRACE_ADD_ITEM(TRACE_TAG_INTERRUPT_EXIT,TRACE_INT_UART_TXEMPTY);
00262 #endif
00263 return;
00264 }
00265
00266 if (flow_control & XOFF_RCVD) {
00267
00268
00269
00270
00271 cbi(UCSRnB, UDRIE);
00272 #ifdef NUTTRACER
00273 TRACE_ADD_ITEM(TRACE_TAG_INTERRUPT_EXIT,TRACE_INT_UART_TXEMPTY);
00274 #endif
00275 return;
00276 }
00277 #endif
00278
00279 if (rbf->rbf_cnt) {
00280
00281 #ifdef UART_CTS_BIT
00282
00283
00284
00285
00286 if (cts_sense && bit_is_set(UART_CTS_PIN, UART_CTS_BIT)) {
00287 cbi(UCSRnB, UDRIE);
00288 sbi(EIMSK, UART_CTS_BIT);
00289 #ifdef NUTTRACER
00290 TRACE_ADD_ITEM(TRACE_TAG_INTERRUPT_EXIT,TRACE_INT_UART_TXEMPTY);
00291 #endif
00292 return;
00293 }
00294 #endif
00295 rbf->rbf_cnt--;
00296
00297
00298
00299
00300
00301
00302 if (tx_aframe) {
00303 sbi(UCSRnB, TXB8);
00304 } else {
00305 cbi(UCSRnB, TXB8);
00306 }
00307
00308
00309
00310
00311 outb(UDRn, *cp);
00312
00313
00314
00315
00316 if (++cp == rbf->rbf_last) {
00317 cp = rbf->rbf_start;
00318 }
00319 rbf->rbf_tail = cp;
00320 if (rbf->rbf_cnt == rbf->rbf_lwm) {
00321 NutEventPostFromIrq(&rbf->rbf_que);
00322 }
00323 }
00324
00325
00326
00327
00328 else {
00329 cbi(UCSRnB, UDRIE);
00330 rbf->rbf_cnt = 0;
00331 NutEventPostFromIrq(&rbf->rbf_que);
00332 }
00333 #ifdef NUTTRACER
00334 TRACE_ADD_ITEM(TRACE_TAG_INTERRUPT_EXIT,TRACE_INT_UART_TXEMPTY);
00335 #endif
00336 }
00337
00338
00339
00340
00341
00342
00343
00344
00345
00346 #ifdef USE_USART
00347 SIGNAL( SIG_UART_RECV ){
00348 register RINGBUF *rbf = &dcb_usart.dcb_rx_rbf;
00349
00350 #else
00351
00352 static void AvrUsartRxComplete(void *arg) {
00353 register RINGBUF *rbf = (RINGBUF *) arg;
00354
00355 #endif
00356
00357 register size_t cnt;
00358 register u_char ch;
00359
00360
00361 #ifdef NUTTRACER
00362 TRACE_ADD_ITEM(TRACE_TAG_INTERRUPT_ENTER,TRACE_INT_UART_RXCOMPL);
00363 #endif
00364
00365 #ifdef UART_READMULTIBYTE
00366 register u_char postEvent = 0;
00367 do {
00368 #endif
00369
00370
00371
00372
00373
00374
00375 rx_errors |= inb(UCSRnA);
00376 ch = inb(UDRn);
00377
00378 #ifndef UART_NO_SW_FLOWCONTROL
00379
00380
00381
00382
00383
00384 if (flow_control) {
00385
00386 if (ch == ASCII_XOFF) {
00387 cbi(UCSRnB, UDRIE);
00388 flow_control |= XOFF_RCVD;
00389 #ifdef NUTTRACER
00390 TRACE_ADD_ITEM(TRACE_TAG_INTERRUPT_EXIT,TRACE_INT_UART_RXCOMPL);
00391 #endif
00392 return;
00393 }
00394
00395 else if (ch == ASCII_XON) {
00396 sbi(UCSRnB, UDRIE);
00397 flow_control &= ~XOFF_RCVD;
00398 #ifdef NUTTRACER
00399 TRACE_ADD_ITEM(TRACE_TAG_INTERRUPT_EXIT,TRACE_INT_UART_RXCOMPL);
00400 #endif
00401 return;
00402 }
00403 }
00404 #endif
00405
00406
00407
00408
00409 cnt = rbf->rbf_cnt;
00410 if (cnt >= rbf->rbf_siz) {
00411 rx_errors |= _BV(DOR);
00412 #ifdef NUTTRACER
00413 TRACE_ADD_ITEM(TRACE_TAG_INTERRUPT_EXIT,TRACE_INT_UART_RXCOMPL);
00414 #endif
00415 return;
00416 }
00417
00418
00419 if (cnt++ == 0){
00420 #ifdef UART_READMULTIBYTE
00421
00422 postEvent = 1;
00423 #else
00424 NutEventPostFromIrq(&rbf->rbf_que);
00425 #endif
00426 }
00427
00428 #ifndef UART_NO_SW_FLOWCONTROL
00429
00430
00431
00432
00433
00434 else if (flow_control) {
00435 if(cnt >= rbf->rbf_hwm) {
00436 if((flow_control & XOFF_SENT) == 0) {
00437 if (inb(UCSRnA) & _BV(UDRE)) {
00438 outb(UDRn, ASCII_XOFF);
00439 flow_control |= XOFF_SENT;
00440 flow_control &= ~XOFF_PENDING;
00441 } else {
00442 flow_control |= XOFF_PENDING;
00443 }
00444 }
00445 }
00446 }
00447 #endif
00448
00449
00450 #ifdef UART_RTS_BIT
00451
00452
00453
00454
00455 else if (rts_control && cnt >= rbf->rbf_hwm) {
00456 sbi(UART_RTS_PORT, UART_RTS_BIT);
00457 }
00458 #endif
00459
00460
00461
00462
00463 *rbf->rbf_head++ = ch;
00464 if (rbf->rbf_head == rbf->rbf_last) {
00465 rbf->rbf_head = rbf->rbf_start;
00466 }
00467
00468
00469 rbf->rbf_cnt = cnt;
00470
00471 #ifdef UART_READMULTIBYTE
00472 } while ( inb(UCSRnA) & _BV(RXC) );
00473
00474
00475 if (postEvent)
00476 NutEventPostFromIrq(&rbf->rbf_que);
00477 #endif
00478
00479 #ifdef NUTTRACER
00480 TRACE_ADD_ITEM(TRACE_TAG_INTERRUPT_EXIT,TRACE_INT_UART_RXCOMPL);
00481 #endif
00482
00483 }
00484
00485
00492 static void AvrUsartEnable(void)
00493 {
00494 NutEnterCritical();
00495
00496 outb(UCSRnB, _BV(RXCIE) | _BV(UDRIE) | _BV(RXEN) | _BV(TXEN));
00497
00498 #ifdef UART_HDX_BIT
00499 if (hdx_control) {
00500
00501 sbi(UCSRnB, TXCIE);
00502 }
00503 #endif
00504
00505 NutExitCritical();
00506 }
00507
00511 static void AvrUsartDisable(void)
00512 {
00513
00514
00515
00516 NutEnterCritical();
00517 cbi(UCSRnB, RXCIE);
00518 cbi(UCSRnB, TXCIE);
00519 cbi(UCSRnB, UDRIE);
00520 NutExitCritical();
00521
00522
00523
00524
00525 NutDelay(10);
00526
00527
00528
00529
00530 cbi(UCSRnB, RXEN);
00531 cbi(UCSRnB, TXEN);
00532 }
00533
00542 static u_long AvrUsartGetSpeed(void)
00543 {
00544 u_long fct;
00545 u_short sv = (u_short) inb(UBRRnL);
00546
00547 #ifdef __AVR_ENHANCED__
00548 sv |= ((u_short) inb(UBRRnH) << 8);
00549
00550
00551 if (bit_is_set(UCSRnC, UMSEL)) {
00552 fct = 2UL;
00553 }
00554
00555
00556 else if (bit_is_set(UCSRnA, U2X)) {
00557 fct = 8UL;
00558 }
00559
00560
00561 else {
00562 fct = 16UL;
00563 }
00564 #else
00565 fct = 16UL;
00566 #endif
00567
00568 return NutGetCpuClock() / (fct * ((u_long) sv + 1UL));
00569 }
00570
00581 static int AvrUsartSetSpeed(u_long rate)
00582 {
00583 u_short sv;
00584
00585 AvrUsartDisable();
00586
00587
00588
00589
00590 #ifdef __AVR_ENHANCED__
00591 if (bit_is_clear(UCSRnC, UMSEL)) {
00592 if (bit_is_set(UCSRnA, U2X)) {
00593 rate <<= 2;
00594 } else {
00595 rate <<= 3;
00596 }
00597 }
00598 #else
00599 rate <<= 3;
00600 #endif
00601 sv = (u_short) ((NutGetCpuClock() / rate + 1UL) / 2UL) - 1;
00602
00603 outb(UBRRnL, (u_char) sv);
00604 #ifdef __AVR_ENHANCED__
00605 outb(UBRRnH, (u_char) (sv >> 8));
00606 #endif
00607 AvrUsartEnable();
00608
00609 return 0;
00610 }
00611
00620 static u_char AvrUsartGetDataBits(void)
00621 {
00622 if (bit_is_set(UCSRnB, UCSZ2)) {
00623 return 9;
00624 }
00625 #ifdef __AVR_ENHANCED__
00626 if (bit_is_set(UCSRnC, UCSZ1)) {
00627 if (bit_is_set(UCSRnC, UCSZ0)) {
00628 return 8;
00629 } else {
00630 return 7;
00631 }
00632 } else if (bit_is_set(UCSRnC, UCSZ0)) {
00633 return 6;
00634 }
00635 return 5;
00636 #else
00637 return 8;
00638 #endif
00639 }
00640
00649 static int AvrUsartSetDataBits(u_char bits)
00650 {
00651 AvrUsartDisable();
00652 cbi(UCSRnB, UCSZ2);
00653 #ifdef __AVR_ENHANCED__
00654 cbi(UCSRnC, UCSZ0);
00655 cbi(UCSRnC, UCSZ1);
00656 switch (bits) {
00657 case 6:
00658 sbi(UCSRnC, UCSZ0);
00659 break;
00660 case 9:
00661 sbi(UCSRnB, UCSZ2);
00662 case 8:
00663 sbi(UCSRnC, UCSZ0);
00664 case 7:
00665 sbi(UCSRnC, UCSZ1);
00666 break;
00667 }
00668 #else
00669 if(bits == 9) {
00670 sbi(UCSRnB, UCSZ2);
00671 }
00672 #endif
00673 AvrUsartEnable();
00674
00675
00676
00677
00678 if (AvrUsartGetDataBits() != bits) {
00679 return -1;
00680 }
00681 return 0;
00682 }
00683
00692 static u_char AvrUsartGetParity(void)
00693 {
00694 #ifdef __AVR_ENHANCED__
00695 if (bit_is_set(UCSRnC, UPM1)) {
00696 if (bit_is_set(UCSRnC, UPM0)) {
00697 return 1;
00698 } else {
00699 return 2;
00700 }
00701 }
00702 #endif
00703 return 0;
00704 }
00705
00716 static int AvrUsartSetParity(u_char mode)
00717 {
00718 #ifdef __AVR_ENHANCED__
00719 AvrUsartDisable();
00720 switch (mode) {
00721 case 0:
00722 cbi(UCSRnC, UPM0);
00723 cbi(UCSRnC, UPM1);
00724 break;
00725 case 1:
00726 sbi(UCSRnC, UPM0);
00727 sbi(UCSRnC, UPM1);
00728 break;
00729 case 2:
00730 cbi(UCSRnC, UPM0);
00731 sbi(UCSRnC, UPM1);
00732 break;
00733 }
00734 AvrUsartEnable();
00735 #endif
00736
00737
00738
00739
00740 if (AvrUsartGetParity() != mode) {
00741 return -1;
00742 }
00743 return 0;
00744 }
00745
00754 static u_char AvrUsartGetStopBits(void)
00755 {
00756 #ifdef __AVR_ENHANCED__
00757 if (bit_is_set(UCSRnC, USBS)) {
00758 return 2;
00759 }
00760 #endif
00761 return 1;
00762 }
00763
00772 static int AvrUsartSetStopBits(u_char bits)
00773 {
00774 #ifdef __AVR_ENHANCED__
00775 AvrUsartDisable();
00776 if (bits == 1) {
00777 cbi(UCSRnC, USBS);
00778 } else if (bits == 2) {
00779 sbi(UCSRnC, USBS);
00780 }
00781 AvrUsartEnable();
00782 #endif
00783
00784
00785
00786
00787 if (AvrUsartGetStopBits() != bits) {
00788 return -1;
00789 }
00790 return 0;
00791 }
00792
00798 static u_long AvrUsartGetStatus(void)
00799 {
00800 u_long rc = 0;
00801
00802
00803
00804
00805 if ((rx_errors & _BV(FE)) != 0) {
00806 rc |= UART_FRAMINGERROR;
00807 }
00808 if ((rx_errors & _BV(DOR)) != 0) {
00809 rc |= UART_OVERRUNERROR;
00810 }
00811 #ifdef __AVR_ENHANCED__
00812 if ((rx_errors & _BV(UPE)) != 0) {
00813 rc |= UART_PARITYERROR;
00814 }
00815 #endif
00816
00817
00818
00819
00820
00821 if (flow_control) {
00822 if (flow_control & XOFF_SENT) {
00823 rc |= UART_RXDISABLED;
00824 }
00825 if (flow_control & XOFF_RCVD) {
00826 rc |= UART_TXDISABLED;
00827 }
00828 }
00829 #ifdef UART_RTS_BIT
00830
00831
00832
00833 if (bit_is_set(UART_RTS_PORT, UART_RTS_BIT)) {
00834 rc |= UART_RTSDISABLED;
00835 if (rts_control) {
00836 rc |= UART_RXDISABLED;
00837 }
00838 } else {
00839 rc |= UART_RTSENABLED;
00840 }
00841 #endif
00842
00843 #ifdef UART_CTS_BIT
00844
00845
00846
00847 if (bit_is_set(UART_CTS_PIN, UART_CTS_BIT)) {
00848 rc |= UART_CTSDISABLED;
00849 if (cts_sense) {
00850 rc |= UART_RXDISABLED;
00851 }
00852 } else {
00853 rc |= UART_CTSENABLED;
00854 }
00855 #endif
00856
00857
00858
00859
00860
00861 if ((rc & UART_RXDISABLED) == 0) {
00862 rc |= UART_RXENABLED;
00863 }
00864 if ((rc & UART_TXDISABLED) == 0) {
00865 rc |= UART_TXENABLED;
00866 }
00867
00868
00869
00870
00871 if (tx_aframe) {
00872 rc |= UART_TXADDRFRAME;
00873 } else {
00874 rc |= UART_TXNORMFRAME;
00875 }
00876
00877 #ifdef __AVR_ENHANCED__
00878 if (bit_is_set(UCSRnA, MPCM)) {
00879 rc |= UART_RXADDRFRAME;
00880 } else {
00881 rc |= UART_RXNORMFRAME;
00882 }
00883 #else
00884 rc |= UART_RXNORMFRAME;
00885 #endif
00886
00887 return rc;
00888 }
00889
00897 static int AvrUsartSetStatus(u_long flags)
00898 {
00899
00900
00901
00902 if (flow_control) {
00903
00904
00905 NutEnterCritical();
00906
00907
00908
00909
00910
00911 if (flags & UART_RXENABLED) {
00912 flow_control &= ~XOFF_SENT;
00913 } else if (flags & UART_RXDISABLED) {
00914 flow_control |= XOFF_SENT;
00915 }
00916
00917
00918
00919
00920
00921 if (flags & UART_TXENABLED) {
00922 flow_control &= ~XOFF_RCVD;
00923 } else if (flags & UART_TXDISABLED) {
00924 flow_control |= XOFF_RCVD;
00925 }
00926 NutExitCritical();
00927 }
00928 #ifdef UART_RTS_BIT
00929
00930
00931
00932 if (rts_control) {
00933 if (flags & UART_RXDISABLED) {
00934 sbi(UART_RTS_PORT, UART_RTS_BIT);
00935 }
00936 if (flags & UART_RXENABLED) {
00937 cbi(UART_RTS_PORT, UART_RTS_BIT);
00938 }
00939 }
00940 if (flags & UART_RTSDISABLED) {
00941 sbi(UART_RTS_PORT, UART_RTS_BIT);
00942 }
00943 if (flags & UART_RTSENABLED) {
00944 cbi(UART_RTS_PORT, UART_RTS_BIT);
00945 }
00946 #endif
00947
00948
00949
00950
00951 if (flags & UART_TXADDRFRAME) {
00952 tx_aframe = 1;
00953 }
00954 if (flags & UART_TXNORMFRAME) {
00955 tx_aframe = 0;
00956 }
00957 #ifdef __AVR_ENHANCED__
00958 if (flags & UART_RXADDRFRAME) {
00959 sbi(UCSRnA, MPCM);
00960 }
00961 if (flags & UART_RXNORMFRAME) {
00962 cbi(UCSRnA, MPCM);
00963 }
00964 #endif
00965
00966
00967
00968
00969 if (flags & UART_FRAMINGERROR) {
00970 rx_errors &= ~_BV(FE);
00971 }
00972 if (flags & UART_OVERRUNERROR) {
00973 rx_errors &= ~_BV(DOR);
00974 }
00975 #ifdef __AVR_ENHANCED__
00976 if (flags & UART_PARITYERROR) {
00977 rx_errors &= ~_BV(UPE);
00978 }
00979 #endif
00980
00981
00982
00983
00984 if ((AvrUsartGetStatus() & ~UART_ERRORS) != flags) {
00985 return -1;
00986 }
00987 return 0;
00988 }
00989
00999 static u_char AvrUsartGetClockMode(void)
01000 {
01001 u_char rc = 0;
01002
01003 #ifdef __AVR_ENHANCED__
01004 if (bit_is_set(UCSRnC, UMSEL)) {
01005 rc |= UART_SYNC;
01006 if (bit_is_set(DDRE, 2)) {
01007 rc |= UART_MASTER;
01008 }
01009 if (bit_is_set(UCSRnC, UCPOL)) {
01010 rc |= UART_NCLOCK;
01011 }
01012 } else if (bit_is_set(UCSRnA, U2X)) {
01013 rc |= UART_HIGHSPEED;
01014 }
01015 #endif
01016
01017 return rc;
01018 }
01019
01031 static int AvrUsartSetClockMode(u_char mode)
01032 {
01033 #ifdef __AVR_ENHANCED__
01034 AvrUsartDisable();
01035
01036
01037
01038
01039 if (mode & UART_SYNC) {
01040 if (mode & UART_MASTER) {
01041
01042 sbi(DDRE, 2);
01043 } else {
01044
01045 cbi(DDRE, 2);
01046 }
01047 if (mode & UART_NCLOCK) {
01048
01049 sbi(UCSRnC, UCPOL);
01050 } else {
01051
01052 cbi(UCSRnC, UCPOL);
01053 }
01054
01055 cbi(UCSRnA, U2X);
01056
01057 sbi(UCSRnA, UMSEL);
01058 }
01059
01060
01061
01062
01063 else {
01064 if (mode & UART_HIGHSPEED) {
01065
01066 sbi(UCSRnA, U2X);
01067 } else {
01068
01069 cbi(UCSRnA, U2X);
01070 }
01071
01072 cbi(UCSRnC, UCPOL);
01073
01074 cbi(UCSRnC, UMSEL);
01075 }
01076 AvrUsartEnable();
01077 #endif
01078
01079
01080
01081
01082 if (AvrUsartGetClockMode() != mode) {
01083 return -1;
01084 }
01085 return 0;
01086 }
01087
01096 static u_long AvrUsartGetFlowControl(void)
01097 {
01098 u_long rc = 0;
01099
01100 if (flow_control) {
01101 rc |= USART_MF_XONXOFF;
01102 } else {
01103 rc &= ~USART_MF_XONXOFF;
01104 }
01105
01106 #ifdef UART_RTS_BIT
01107 if (rts_control) {
01108 rc |= USART_MF_RTSCONTROL;
01109 } else {
01110 rc &= ~USART_MF_RTSCONTROL;
01111 }
01112 #endif
01113
01114 #ifdef UART_CTS_BIT
01115 if (cts_sense) {
01116 rc |= USART_MF_CTSSENSE;
01117 } else {
01118 rc &= ~USART_MF_CTSSENSE;
01119 }
01120 #endif
01121
01122 #ifdef UART_HDX_BIT
01123 if (hdx_control) {
01124 rc |= USART_MF_HALFDUPLEX;
01125 } else {
01126 rc &= ~USART_MF_HALFDUPLEX;
01127 }
01128 #endif
01129
01130 return rc;
01131 }
01132
01143 static int AvrUsartSetFlowControl(u_long flags)
01144 {
01145
01146
01147
01148 if (flags & USART_MF_XONXOFF) {
01149 if(flow_control == 0) {
01150 NutEnterCritical();
01151 flow_control = 1 | XOFF_SENT;
01152 NutExitCritical();
01153 }
01154 } else {
01155 NutEnterCritical();
01156 flow_control = 0;
01157 NutExitCritical();
01158 }
01159
01160 #ifdef UART_RTS_BIT
01161
01162
01163
01164 if (flags & USART_MF_RTSCONTROL) {
01165 sbi(UART_RTS_PORT, UART_RTS_BIT);
01166 sbi(UART_RTS_DDR, UART_RTS_BIT);
01167 rts_control = 1;
01168 } else if (rts_control) {
01169 rts_control = 0;
01170 cbi(UART_RTS_DDR, UART_RTS_BIT);
01171 }
01172 #endif
01173
01174 #ifdef UART_CTS_BIT
01175
01176
01177
01178 if (flags & USART_MF_CTSSENSE) {
01179
01180 if (NutRegisterIrqHandler(&UART_CTS_SIGNAL, AvrUsartCts, 0)) {
01181 return -1;
01182 }
01183 sbi(UART_CTS_PORT, UART_CTS_BIT);
01184 cbi(UART_CTS_DDR, UART_CTS_BIT);
01185 cts_sense = 1;
01186 } else if (cts_sense) {
01187 cts_sense = 0;
01188
01189 NutRegisterIrqHandler(&UART_CTS_SIGNAL, 0, 0);
01190 cbi(UART_CTS_DDR, UART_CTS_BIT);
01191 }
01192 #endif
01193
01194 #ifdef UART_HDX_BIT
01195
01196
01197
01198 if (flags & USART_MF_HALFDUPLEX) {
01199
01200 if (NutRegisterIrqHandler(&sig_UART_TRANS, AvrUsartTxComplete, &dcb_usart.dcb_tx_rbf)) {
01201 return -1;
01202 }
01203
01204 UART_HDX_RX(UART_HDX_PORT, UART_HDX_BIT);
01205 sbi(UART_HDX_DDR, UART_HDX_BIT);
01206 hdx_control = 1;
01207
01208 sbi(UCSRnB, TXCIE);
01209 } else if (hdx_control) {
01210 hdx_control = 0;
01211
01212 cbi(UCSRnB, TXCIE);
01213
01214 NutRegisterIrqHandler(&sig_UART_TRANS, 0, 0);
01215 cbi(UART_HDX_DDR, UART_HDX_BIT);
01216 }
01217 #endif
01218
01219
01220
01221
01222 if (AvrUsartGetFlowControl() != flags) {
01223 return -1;
01224 }
01225 return 0;
01226 }
01227
01235 static void AvrUsartTxStart(void)
01236 {
01237 #ifdef UART_HDX_BIT
01238 if (hdx_control) {
01239
01240 UART_HDX_TX(UART_HDX_PORT, UART_HDX_BIT);
01241 }
01242 #endif
01243
01244 sbi(UCSRnB, UDRIE);
01245 }
01246
01255 static void AvrUsartRxStart(void)
01256 {
01257
01258
01259
01260 if (flow_control && (flow_control & XOFF_SENT) != 0) {
01261 NutEnterCritical();
01262 if (inb(UCSRnA) & _BV(UDRE)) {
01263 outb(UDRn, ASCII_XON);
01264 flow_control &= ~XON_PENDING;
01265 } else {
01266 flow_control |= XON_PENDING;
01267 }
01268 flow_control &= ~(XOFF_SENT | XOFF_PENDING);
01269 NutExitCritical();
01270 }
01271 #ifdef UART_RTS_BIT
01272 if (rts_control) {
01273
01274 cbi(UART_RTS_PORT, UART_RTS_BIT);
01275 }
01276 #endif
01277 }
01278
01279
01280
01281
01282
01283
01284
01285
01286
01287 static int AvrUsartInit(void)
01288 {
01289 #ifndef USE_USART
01290
01291
01292
01293 if (NutRegisterIrqHandler(&sig_UART_RECV, AvrUsartRxComplete, &dcb_usart.dcb_rx_rbf))
01294 return -1;
01295 if (NutRegisterIrqHandler(&sig_UART_DATA, AvrUsartTxEmpty, &dcb_usart.dcb_tx_rbf)) {
01296 NutRegisterIrqHandler(&sig_UART_RECV, 0, 0);
01297 return -1;
01298 }
01299 #endif
01300 return 0;
01301 }
01302
01303
01304
01305
01306
01307
01308
01309
01310
01311 static int AvrUsartDeinit(void)
01312 {
01313
01314 #ifndef USE_USART
01315
01316 NutRegisterIrqHandler(&sig_UART_RECV, 0, 0);
01317 NutRegisterIrqHandler(&sig_UART_DATA, 0, 0);
01318 #endif
01319
01320
01321
01322
01323
01324
01325 #ifdef UART_HDX_BIT
01326
01327 if (hdx_control) {
01328 hdx_control = 0;
01329 NutRegisterIrqHandler(&sig_UART_TRANS, 0, 0);
01330 }
01331 #endif
01332
01333 #ifdef UART_CTS_BIT
01334 if (cts_sense) {
01335 cts_sense = 0;
01336 cbi(UART_CTS_DDR, UART_CTS_BIT);
01337
01338 NutRegisterIrqHandler(&UART_CTS_SIGNAL, 0, 0);
01339 }
01340 #endif
01341
01342 #ifdef UART_RTS_BIT
01343 if (rts_control) {
01344 rts_control = 0;
01345 cbi(UART_RTS_DDR, UART_RTS_BIT);
01346 }
01347 #endif
01348
01349 return 0;
01350 }
01351