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 <string.h>
00087
00088 #include <sys/atom.h>
00089 #include <sys/heap.h>
00090 #include <sys/event.h>
00091 #include <sys/timer.h>
00092 #include <sys/device.h>
00093
00094 #include <dev/irqreg.h>
00095 #include <dev/uartavr.h>
00096
00097 #include <fcntl.h>
00098
00099
00100
00101
00102
00103 #ifndef _IOFBF
00104 #define _IOFBF 0x00
00105 #define _IOLBF 0x01
00106 #define _IONBF 0x02
00107 #endif
00108
00113
00114
00115
00116
00117 static void TxComplete(void *arg)
00118 {
00119 NUTDEVICE *dev = (NUTDEVICE *) arg;
00120 IFSTREAM *ifs = dev->dev_icb;
00121 UARTDCB *dcb;
00122
00123 if (ifs->if_tx_idx != ifs->if_wr_idx) {
00124 #ifdef UDR1
00125 if (dev->dev_base)
00126 UDR1 = ifs->if_tx_buf[ifs->if_tx_idx];
00127 else
00128 #endif
00129 outp(ifs->if_tx_buf[ifs->if_tx_idx], UDR);
00130 ifs->if_tx_idx++;
00131 } else {
00132 ifs->if_tx_act = 0;
00133 dcb = dev->dev_dcb;
00134 NutEventPostFromIrq(&dcb->dcb_tx_rdy);
00135 }
00136 }
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146 static void RxComplete(void *arg)
00147 {
00148 NUTDEVICE *dev = (NUTDEVICE *) arg;
00149 IFSTREAM *ifs = dev->dev_icb;
00150 UARTDCB *dcb;
00151
00152 #ifdef UDR1
00153 if (dev->dev_base)
00154 ifs->if_rx_buf[ifs->if_rx_idx] = inp(UDR1);
00155 else
00156 #endif
00157 ifs->if_rx_buf[ifs->if_rx_idx] = inp(UDR);
00158
00159 if (ifs->if_rd_idx == ifs->if_rx_idx) {
00160 dcb = dev->dev_dcb;
00161 NutEventPostFromIrq(&dcb->dcb_rx_rdy);
00162 }
00163
00164 ifs->if_rx_idx++;
00165 }
00166
00179 int UartAvrInput(NUTDEVICE * dev)
00180 {
00181 int rc = 0;
00182 int empty;
00183 IFSTREAM *ifs = dev->dev_icb;
00184 UARTDCB *dcb = dev->dev_dcb;
00185
00186 NutEnterCritical();
00187 empty = ifs->if_rd_idx == ifs->if_rx_idx;
00188 NutExitCritical();
00189
00190 if (empty) {
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202 do {
00203
00204 rc = NutEventWait(&dcb->dcb_rx_rdy, dcb->dcb_rtimeout);
00205
00206 NutEnterCritical();
00207 empty = ifs->if_rd_idx == ifs->if_rx_idx;
00208 NutExitCritical();
00209
00210 } while (rc == 0 && empty);
00211 }
00212
00213 return rc;
00214 }
00215
00230 int UartAvrOutput(NUTDEVICE * dev)
00231 {
00232 IFSTREAM *ifs = dev->dev_icb;
00233
00234 if (ifs->if_tx_act == 0 && ifs->if_tx_idx != ifs->if_wr_idx) {
00235 ifs->if_tx_act = 1;
00236 #ifdef UDR1
00237 if (dev->dev_base)
00238 UDR1 = ifs->if_tx_buf[ifs->if_tx_idx];
00239 else
00240 #endif
00241 outp(ifs->if_tx_buf[ifs->if_tx_idx], UDR);
00242 ifs->if_tx_idx++;
00243 }
00244 return 0;
00245 }
00246
00257 int UartAvrFlush(NUTDEVICE * dev)
00258 {
00259 IFSTREAM *ifs = dev->dev_icb;
00260 UARTDCB *dcb = dev->dev_dcb;
00261
00262
00263
00264
00265 if (UartAvrOutput(dev))
00266 return -1;
00267
00268
00269
00270
00271 NutEnterCritical();
00272 while (ifs->if_tx_idx != ifs->if_wr_idx)
00273 NutEventWait(&dcb->dcb_tx_rdy, 100);
00274 NutExitCritical();
00275
00276 return 0;
00277 }
00278
00279
00280
00281
00282
00283
00284
00285 static int UartAvrGetStatus(NUTDEVICE * dev, u_long * status)
00286 {
00287 IFSTREAM *ifs = dev->dev_icb;
00288 u_char us;
00289
00290 *status = 0;
00291
00292 #ifdef UDR1
00293 if (dev->dev_base)
00294 us = inp(UCSR1A);
00295 else
00296 #endif
00297 us = inp(USR);
00298 if (us & FE)
00299 *status |= UART_FRAMINGERROR;
00300 if (us & DOR)
00301 *status |= UART_OVERRUNERROR;
00302 if (ifs->if_tx_idx == ifs->if_wr_idx)
00303 *status |= UART_TXBUFFEREMPTY;
00304 if (ifs->if_rd_idx == ifs->if_rx_idx)
00305 *status |= UART_RXBUFFEREMPTY;
00306 return 0;
00307 }
00308
00309
00310
00311
00312 static void UartAvrEnable(u_short base)
00313 {
00314 NutEnterCritical();
00315 #ifdef UCSR1B
00316 if (base)
00317 UCSR1B = BV(RXCIE) | BV(TXCIE) | BV(RXEN) | BV(TXEN);
00318 else
00319 #endif
00320 UCR = BV(RXCIE) | BV(TXCIE) | BV(RXEN) | BV(TXEN);
00321 NutExitCritical();
00322 }
00323
00324
00325
00326
00327 static void UartAvrDisable(u_short base)
00328 {
00329
00330
00331
00332 NutEnterCritical();
00333 #ifdef UCSR1B
00334 if (base)
00335 UCSR1B &= ~(BV(RXCIE) | BV(TXCIE));
00336 else
00337 #endif
00338 UCR &= ~(BV(RXCIE) | BV(TXCIE));
00339 NutExitCritical();
00340
00341
00342
00343
00344 NutDelay(10);
00345
00346
00347
00348
00349 #ifdef UCSR1B
00350 if (base)
00351 UCSR1B &= ~(BV(RXEN) | BV(TXEN));
00352 else
00353 #endif
00354 UCR &= ~(BV(RXEN) | BV(TXEN));
00355 }
00356
00397 int UartAvrIOCtl(NUTDEVICE * dev, int req, void *conf)
00398 {
00399 int rc = 0;
00400 UARTDCB *dcb;
00401 u_long *lvp = (u_long *) conf;
00402 u_long lv = *lvp;
00403 u_char bv = (u_char) lv;
00404 u_short sv;
00405 u_char devnum;
00406
00407 if (dev == 0)
00408 dev = &devUart0;
00409
00410 devnum = dev->dev_base;
00411 dcb = dev->dev_dcb;
00412
00413 switch (req) {
00414 case UART_SETSPEED:
00415 UartAvrDisable(devnum);
00416 #ifdef __AVR_ENHANCED__
00417 if (devnum) {
00418 if (bit_is_set(UCSR1A, U2X1)) {
00419 lv <<= 2;
00420 } else {
00421 lv <<= 3;
00422 }
00423 } else {
00424 if (bit_is_set(UCSR0A, U2X0)) {
00425 lv <<= 2;
00426 } else {
00427 lv <<= 3;
00428 }
00429 }
00430 #else
00431 lv <<= 3;
00432 #endif
00433 sv = (u_short) ((NutGetCpuClock() / lv + 1UL) / 2UL) - 1;
00434 #ifdef UBRR1H
00435 if (devnum) {
00436 UBRR1L = (u_char) sv;
00437 UBRR1H = (u_char) (sv >> 8);
00438 } else {
00439 UBRR0L = (u_char) sv;
00440 UBRR0H = (u_char) (sv >> 8);
00441 }
00442 #else
00443 UBRR = (u_char) sv;
00444 #endif
00445 UartAvrEnable(devnum);
00446 break;
00447
00448 case UART_GETSPEED:
00449 #ifdef UBRR1H
00450 if (devnum) {
00451 if (bit_is_set(UCSR1A, U2X1))
00452 lv = 8UL;
00453 else
00454 lv = 16UL;
00455 sv = (u_short) (UBRR1H) << 8 | UBRR1L;
00456 }
00457 else
00458 {
00459 if (bit_is_set(UCSR0A, U2X0))
00460 lv = 8UL;
00461 else
00462 lv = 16UL;
00463 sv = (u_short) (UBRR0H) << 8 | UBRR0L;
00464 }
00465 #else
00466 sv = UBRR;
00467 lv = 16UL;
00468 #endif
00469 *lvp = NutGetCpuClock() / (lv * (u_long) (sv + 1));
00470 break;
00471
00472 case UART_SETDATABITS:
00473 UartAvrDisable(devnum);
00474 #ifdef UCSR1C
00475 if (bv >= 5 && bv <= 8) {
00476 bv = (bv - 5) << 1;
00477 if (devnum) {
00478 UCSR1C = (UCSR1C & 0xF9) | bv;
00479 UCSR1B &= 0xFB;
00480 } else {
00481 UCSR0C = (UCSR0C & 0xF9) | bv;
00482 UCSR0B &= 0xFB;
00483 }
00484 } else
00485 rc = -1;
00486 #else
00487 if (bv != 8)
00488 rc = -1;
00489 #endif
00490 UartAvrEnable(devnum);
00491 break;
00492
00493 case UART_GETDATABITS:
00494 #ifdef UCSR1C
00495 if (devnum)
00496 *lvp = ((UCSR1C & 0x06) >> 1) + 5;
00497 else
00498 *lvp = ((UCSR0C & 0x06) >> 1) + 5;
00499 #else
00500 *lvp = 8;
00501 #endif
00502 break;
00503
00504 case UART_SETPARITY:
00505 UartAvrDisable(devnum);
00506 #ifdef UCSR1C
00507 if (bv <= 2) {
00508 if (bv == 1)
00509 bv = 3;
00510 bv <<= 4;
00511 if (devnum)
00512 UCSR1C = (UCSR1C & 0xCF) | bv;
00513 else
00514 UCSR0C = (UCSR0C & 0xCF) | bv;
00515 } else
00516 rc = -1;
00517 #endif
00518 if (bv)
00519 rc = -1;
00520 UartAvrEnable(devnum);
00521 break;
00522
00523 case UART_GETPARITY:
00524 #ifdef UCSR1C
00525 if (devnum)
00526 bv = (UCSR1C & 0x30) >> 4;
00527 else
00528 bv = (UCSR0C & 0x30) >> 4;
00529 if (bv == 3)
00530 bv = 1;
00531 #else
00532 bv = 0;
00533 #endif
00534 break;
00535
00536 case UART_SETSTOPBITS:
00537 UartAvrDisable(devnum);
00538 #ifdef UCSR1C
00539 if (bv == 1 || bv == 2) {
00540 bv = (bv - 1) << 3;
00541 if (devnum)
00542 UCSR1C = (UCSR1C & 0xF7) | bv;
00543 else
00544 UCSR0C = (UCSR0C & 0xF7) | bv;
00545 } else
00546 rc = -1;
00547 #else
00548 if (bv != 1)
00549 rc = -1;
00550 #endif
00551 UartAvrEnable(devnum);
00552 break;
00553
00554 case UART_GETSTOPBITS:
00555 #ifdef UCSR1C
00556 if (devnum)
00557 *lvp = ((UCSR1C & 0x08) >> 3) + 1;
00558 else
00559 *lvp = ((UCSR0C & 0x08) >> 3) + 1;
00560 #else
00561 *lvp = 1;
00562 #endif
00563 break;
00564
00565 case UART_GETSTATUS:
00566 UartAvrGetStatus(dev, lvp);
00567 break;
00568 case UART_SETSTATUS:
00569 rc = -1;
00570 break;
00571
00572 case UART_SETREADTIMEOUT:
00573 dcb->dcb_rtimeout = lv;
00574 break;
00575 case UART_GETREADTIMEOUT:
00576 *lvp = dcb->dcb_rtimeout;
00577 break;
00578
00579 case UART_SETWRITETIMEOUT:
00580 dcb->dcb_wtimeout = lv;
00581 break;
00582 case UART_GETWRITETIMEOUT:
00583 *lvp = dcb->dcb_wtimeout;
00584 break;
00585
00586 case UART_SETLOCALECHO:
00587 if (bv)
00588 dcb->dcb_modeflags |= UART_MF_LOCALECHO;
00589 else
00590 dcb->dcb_modeflags &= ~UART_MF_LOCALECHO;
00591 break;
00592 case UART_GETLOCALECHO:
00593 if (dcb->dcb_modeflags & UART_MF_LOCALECHO)
00594 *lvp = 1;
00595 else
00596 *lvp = 0;
00597 break;
00598
00599 case UART_SETFLOWCONTROL:
00600 if (bv)
00601 dcb->dcb_modeflags |= UART_MF_LOCALECHO;
00602 else
00603 dcb->dcb_modeflags &= ~UART_MF_LOCALECHO;
00604 break;
00605 case UART_GETFLOWCONTROL:
00606 break;
00607
00608 case UART_SETCOOKEDMODE:
00609 if (bv)
00610 dcb->dcb_modeflags |= UART_MF_COOKEDMODE;
00611 else
00612 dcb->dcb_modeflags &= ~UART_MF_COOKEDMODE;
00613 break;
00614 case UART_GETCOOKEDMODE:
00615 if (dcb->dcb_modeflags & UART_MF_COOKEDMODE)
00616 *lvp = 1;
00617 else
00618 *lvp = 0;
00619 break;
00620
00621 default:
00622 rc = -1;
00623 break;
00624 }
00625 return rc;
00626 }
00627
00638 int UartAvrInit(NUTDEVICE * dev)
00639 {
00640 IFSTREAM *ifs;
00641 UARTDCB *dcb;
00642 u_long baudrate = 9600;
00643
00644
00645
00646
00647 if (dev->dev_type != IFTYP_STREAM || dev->dev_irq != 0 ||
00648 (dev->dev_base != 0 && dev->dev_base != 1))
00649 return -1;
00650
00651
00652
00653
00654 ifs = dev->dev_icb;
00655 memset(ifs, 0, sizeof(IFSTREAM));
00656 ifs->if_input = UartAvrInput;
00657 ifs->if_output = UartAvrOutput;
00658 ifs->if_flush = UartAvrFlush;
00659
00660
00661
00662
00663 dcb = dev->dev_dcb;
00664 memset(dcb, 0, sizeof(UARTDCB));
00665 dcb->dcb_modeflags = UART_MF_NOBUFFER;
00666
00667
00668
00669
00670 if (dev->dev_base) {
00671 #ifdef UDR1
00672 if (NutRegisterIrqHandler(&sig_UART1_RECV, RxComplete, dev))
00673 return -1;
00674 if (NutRegisterIrqHandler(&sig_UART1_TRANS, TxComplete, dev))
00675 #endif
00676 return -1;
00677 } else {
00678 if (NutRegisterIrqHandler(&sig_UART0_RECV, RxComplete, dev))
00679 return -1;
00680 if (NutRegisterIrqHandler(&sig_UART0_TRANS, TxComplete, dev))
00681 return -1;
00682 }
00683
00684
00685
00686
00687
00688 UartAvrIOCtl(dev, UART_SETSPEED, &baudrate);
00689
00690 return 0;
00691 }
00692
00696 int UartAvrRead(NUTFILE * fp, void *buffer, int size)
00697 {
00698 int rc;
00699 NUTDEVICE *dev;
00700 IFSTREAM *ifs;
00701 UARTDCB *dcb;
00702 u_char elmode;
00703 u_char ch;
00704 u_char *cp = buffer;
00705
00706 dev = fp->nf_dev;
00707 ifs = (IFSTREAM *) dev->dev_icb;
00708 dcb = dev->dev_dcb;
00709
00710 if (dcb->dcb_modeflags & UART_MF_COOKEDMODE)
00711 elmode = 1;
00712 else
00713 elmode = 0;
00714
00715
00716
00717
00718 if (buffer == 0) {
00719 ifs->if_rd_idx = ifs->if_rx_idx;
00720 return 0;
00721 }
00722
00723
00724
00725
00726 for (rc = 0; rc < size;) {
00727 if (ifs->if_rd_idx == ifs->if_rx_idx) {
00728 if (rc)
00729 break;
00730 while (ifs->if_rd_idx == ifs->if_rx_idx) {
00731 if (UartAvrInput(dev)) {
00732 return 0;
00733 }
00734 }
00735 }
00736 ch = ifs->if_rx_buf[ifs->if_rd_idx++];
00737 if (elmode && (ch == '\r' || ch == '\n')) {
00738 if (ifs->if_last_eol == 0 || ifs->if_last_eol == ch) {
00739 ifs->if_last_eol = ch;
00740 *cp++ = '\n';
00741 rc++;
00742 }
00743 } else {
00744 ifs->if_last_eol = 0;
00745 *cp++ = ch;
00746 rc++;
00747 }
00748 }
00749 return rc;
00750 }
00751
00755 int UartAvrPut(NUTDEVICE * dev, CONST void *buffer, int len, int pflg)
00756 {
00757 int rc;
00758 IFSTREAM *ifs;
00759 UARTDCB *dcb;
00760 CONST u_char *cp;
00761 u_char lbmode;
00762 u_char elmode;
00763 u_char ch;
00764
00765 ifs = dev->dev_icb;
00766 dcb = dev->dev_dcb;
00767
00768 if (dcb->dcb_modeflags & UART_MF_LINEBUFFER)
00769 lbmode = 1;
00770 else
00771 lbmode = 0;
00772
00773 if (dcb->dcb_modeflags & UART_MF_COOKEDMODE)
00774 elmode = 1;
00775 else
00776 elmode = 0;
00777
00778
00779
00780
00781 if (buffer == 0) {
00782 rc = UartAvrFlush(dev);
00783 return rc;
00784 }
00785
00786
00787
00788
00789 cp = buffer;
00790 for (rc = 0; rc < len;) {
00791 if ((u_char) (ifs->if_wr_idx + 1) == ifs->if_tx_idx) {
00792 if (UartAvrFlush(dev)) {
00793 return -1;
00794 }
00795 }
00796 ch = pflg ? PRG_RDB(cp) : *cp;
00797 if (elmode == 1 && ch == '\n') {
00798 elmode = 2;
00799 if (lbmode == 1)
00800 lbmode = 2;
00801 ch = '\r';
00802 } else {
00803 if (elmode == 2)
00804 elmode = 1;
00805 cp++;
00806 rc++;
00807 }
00808 ifs->if_tx_buf[ifs->if_wr_idx++] = ch;
00809 }
00810
00811 if (lbmode > 1 || (dcb->dcb_modeflags & UART_MF_NOBUFFER) != 0) {
00812 if (UartAvrFlush(dev))
00813 rc = -1;
00814 }
00815 return rc;
00816 }
00817
00818 int UartAvrWrite(NUTFILE * fp, CONST void *buffer, int len)
00819 {
00820 return UartAvrPut(fp->nf_dev, buffer, len, 0);
00821 }
00822
00823 int UartAvrWrite_P(NUTFILE * fp, PGM_P buffer, int len)
00824 {
00825 return UartAvrPut(fp->nf_dev, (CONST char *) buffer, len, 1);
00826 }
00827
00828
00832 NUTFILE *UartAvrOpen(NUTDEVICE * dev, CONST char *name, int mode, int acc)
00833 {
00834 NUTFILE *fp = NutHeapAlloc(sizeof(NUTFILE));
00835 UARTDCB *dcb;
00836
00837 if (fp == 0)
00838 return NUTFILE_EOF;
00839
00840 dcb = dev->dev_dcb;
00841 if (mode & _O_BINARY)
00842 dcb->dcb_modeflags &= ~UART_MF_COOKEDMODE;
00843 else
00844 dcb->dcb_modeflags |= UART_MF_COOKEDMODE;
00845
00846 fp->nf_next = 0;
00847 fp->nf_dev = dev;
00848 fp->nf_fcb = 0;
00849
00850 return fp;
00851 }
00852
00856 int UartAvrClose(NUTFILE * fp)
00857 {
00858 NutHeapFree(fp);
00859
00860 return 0;
00861 }
00862
00866 long UartAvrSize(NUTFILE * fp)
00867 {
00868 NUTDEVICE *dev;
00869 IFSTREAM *ifs;
00870
00871 dev = fp->nf_dev;
00872 ifs = (IFSTREAM *) dev->dev_icb;
00873 return ((u_char)(ifs->if_rx_idx - ifs->if_rd_idx));
00874 }
00875
00876