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 #include <string.h>
00047 #include <sys/atom.h>
00048 #include <sys/heap.h>
00049 #include <sys/event.h>
00050 #include <sys/timer.h>
00051 #include <sys/device.h>
00052 #include <dev/irqreg.h>
00053 #include <dev/tlc16c550.h>
00054 #include <fcntl.h>
00055 #include <stdio.h>
00056
00057
00058
00059
00060
00061 #ifndef _IOFBF
00062 #define _IOFBF 0x00
00063 #define _IOLBF 0x01
00064 #define _IONBF 0x02
00065 #endif
00066
00071
00072
00073
00074
00075 #define ACE_RBR_OFS 0
00076 #define ACE_THR_OFS 0
00077 #define ACE_DLL_OFS 0
00078 #define ACE_DLM_OFS 1
00079 #define ACE_IER_OFS 1
00080 #define ACE_FCR_OFS 2
00081 #define ACE_IIR_OFS 2
00082 #define ACE_LCR_OFS 3
00083 #define ACE_MCR_OFS 4
00084 #define ACE_LSR_OFS 5
00085 #define ACE_MSR_OFS 6
00086 #define ACE_SRC_OFS 7
00087
00088
00089 #define IER_RDA_MSK 0x01 // receiver data avaialbe
00090 #define IER_THE_MSK 0x02 // transmit holding empty
00091 #define IER_LST_MSK 0x04 // line status
00092 #define IER_MST_MSK 0x08 // modem status
00093
00094
00095 #define FCR_ENABLE 0x01 //fifo enable
00096 #define FCR_PURGE_I 0x02 //purge all data from input fifo
00097 #define FCR_PURGE_O 0x04 //purge all data from output fifo
00098 #define FCR_LEVEL_1 0x00 //receive trigger level 1
00099 #define FCR_LEVEL_4 0x40 //receive trigger level 4
00100 #define FCR_LEVEL_8 0x80 //receive trigger level 8
00101 #define FCR_LEVEL_14 0xc0 //receive trigger level 14
00102
00103
00104 #define IIR_MST_MSK 0x00 // modem status interrupt
00105 #define IIR_TXE_MSK 0x02 // transmit buffer empty
00106 #define IIR_RDA_MSK 0x04 // receive data available
00107 #define IIR_TDA_MSK 0x0c // timeout receive data available
00108 #define IIR_LST_MSK 0x06 // line status interrupt
00109 #define IIR_NON_MSK 0x01 // no interrupt
00110 #define IIR_FIFO_MSK 0xc0 // mask to eliminate the fifo status
00111
00112
00113 #define LCR_WS0_MSK 0x01
00114 #define LCR_WS1_MSK 0x02
00115 #define LCR_STB_MSK 0x04
00116 #define LCR_PEN_MSK 0x08
00117 #define LCR_PRE_MSK 0x10
00118 #define LCR_PRS_MSK 0x20
00119 #define LCR_BRK_MSK 0x40
00120 #define LCR_ENB_MSK 0x80
00121
00122
00123 #define MCR_DTR_MSK 0x01
00124 #define MCR_RTS_MSK 0x02
00125 #define MCR_GP1_MSK 0x04
00126 #define MCR_GP2_MSK 0x08
00127 #define MCR_LOP_MSK 0x10
00128
00129
00130 #define LSR_RDR_MSK 0x01
00131 #define LSR_OVR_MSK 0x02
00132 #define LSR_PER_MSK 0x04
00133 #define LSR_FER_MSK 0x08
00134 #define LSR_BDT_MSK 0x10
00135 #define LSR_THE_MSK 0x20
00136 #define LSR_TXE_MSK 0x40
00137 #define LSR_EIF_MSK 0x80
00138
00139
00140 #define MSR_DCTS_MSK 0x01
00141 #define MSR_DDSR_MSK 0x02
00142 #define MSR_DRI_MSK 0x04
00143 #define MSR_DDCD_MSK 0x08
00144 #define MSR_CTS_MSK 0x10
00145 #define MSR_DSR_MSK 0x20
00146 #define MSR_RI_MSK 0x40
00147 #define MSR_DCD_MSK 0x80
00148
00149
00150 typedef struct tagIRQDEFS {
00151 IRQ_HANDLER *pvIrq;
00152 volatile u_char *pnIrqMskPort;
00153 u_char nMask;
00154 } IRQDEFS;
00155
00156
00157 static CONST PROGMEM IRQDEFS atIrqDefs[] = {
00158 {&sig_INTERRUPT0, &EICRA, 0x00},
00159 {&sig_INTERRUPT1, &EICRA, 0x00},
00160 {&sig_INTERRUPT2, &EICRA, 0x00},
00161 {&sig_INTERRUPT3, &EICRA, 0x00},
00162 {&sig_INTERRUPT4, &EICRB, 0x00},
00163 {&sig_INTERRUPT5, &EICRB, 0x00},
00164 {&sig_INTERRUPT6, &EICRB, 0x00},
00165 {&sig_INTERRUPT7, &EICRB, 0x00}
00166 };
00167
00168
00169
00170 static NUTDEVICE *pIrqDev[8] = { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL };
00171 static u_char irqMask = 0;
00172 #ifdef ACE_HDX_LINE
00173 static u_int ByteOcrTime(NUTDEVICE * dev);
00174 static void AceTmr3Init(void);
00175 static void AceOutComp3AInt(void *arg);
00176 static void AceAddHdxTime(ACEDCB * dev);
00177 #endif
00178
00179
00180
00181
00182 static void AceIrqHandler(void *arg)
00183 {
00184 NUTDEVICE *dev = (NUTDEVICE *) arg;
00185 IFSTREAM *ifs;
00186 ACEDCB *dcb;
00187 volatile u_char event;
00188 u_char maxData;
00189
00190 do {
00191 ifs = dev->dev_icb;
00192 dcb = dev->dev_dcb;
00193
00194
00195 while (((event = *(u_char *) (dev->dev_base + ACE_IIR_OFS)) & ~IIR_FIFO_MSK) != IIR_NON_MSK) {
00196 switch (event & ~IIR_FIFO_MSK) {
00197 case IIR_RDA_MSK:
00198 case IIR_TDA_MSK:
00199
00200
00201
00202 maxData = (dcb->dcb_rfifo == 0) ? 1 : dcb->dcb_rfifo;
00203 for (; (*(u_char *) (dev->dev_base + ACE_LSR_OFS) & LSR_RDR_MSK) && (maxData > 0); --maxData) {
00204
00205 ifs->if_rx_buf[ifs->if_rx_idx] = *(u_char *) (dev->dev_base + ACE_RBR_OFS);
00206
00207 if (ifs->if_rd_idx == ifs->if_rx_idx) {
00208 NutEventPostFromIrq(&(dcb->dcb_rx_rdy));
00209 }
00210
00211 ifs->if_rx_idx++;
00212 }
00213 break;
00214
00215 case IIR_TXE_MSK:
00216 dcb->dcb_wfifo = (event & IIR_FIFO_MSK) ? ACE_FIFO_SIZE : 1;
00217 if (ifs->if_tx_idx != ifs->if_wr_idx) {
00218 for (; (ifs->if_tx_idx != ifs->if_wr_idx) && (dcb->dcb_wfifo > 0); ++ifs->if_tx_idx) {
00219 --dcb->dcb_wfifo;
00220
00221 *(u_char *) (dev->dev_base + ACE_THR_OFS) = ifs->if_tx_buf[ifs->if_tx_idx];
00222 }
00223 } else {
00224 #ifdef ACE_HDX_LINE
00225 if (dcb->dcb_modeflags & ACE_MF_HALFDUPLEX) {
00226 AceAddHdxTime(dcb);
00227 }
00228 #endif
00229 ifs->if_tx_act = 0;
00230 NutEventPostFromIrq(&(dcb->dcb_tx_rdy));
00231 }
00232 break;
00233
00234 case IIR_MST_MSK:
00235 break;
00236
00237 case IIR_LST_MSK:
00238 break;
00239 }
00240 }
00241
00242 dev = dcb->dev_next;
00243 } while (dev != NULL);
00244
00245 }
00246
00247 #ifdef ACE_HDX_LINE
00248 static u_int ByteOcrTime(NUTDEVICE * dev)
00249 {
00250 u_char bv;
00251 u_char tb = 14;
00252 u_int sv;
00253 u_long s, c;
00254
00255
00256 *(u_char *) (dev->dev_base + ACE_LCR_OFS) |= LCR_ENB_MSK;
00257 sv = *(u_char *) (dev->dev_base + ACE_DLL_OFS);
00258 sv |= *(u_char *) (dev->dev_base + ACE_DLM_OFS) << 8;
00259 *(u_char *) (dev->dev_base + ACE_LCR_OFS) &= (u_char) ~ LCR_ENB_MSK;
00260
00261 bv = *(u_char *) (dev->dev_base + ACE_LCR_OFS);
00262
00263
00264 tb += (bv & (LCR_WS0_MSK | LCR_WS1_MSK)) << 1;
00265
00266
00267 if (bv & LCR_STB_MSK) {
00268 tb += 1 + !!(bv & (LCR_WS0_MSK | LCR_WS1_MSK));
00269 }
00270
00271
00272 tb += (!!(bv & LCR_PEN_MSK)) << 1;
00273
00274 s = ACE_CLOCK * 8UL;
00275 s = s / (u_long) (sv);
00276
00277 c = NutGetCpuClock();
00278 c = c * (u_long) tb;
00279
00280 sv = ((u_int) (c / s) & 0x0000ffff) - 1;
00281
00282 return sv;
00283 }
00284 #endif
00285
00298 int AceInput(NUTDEVICE * dev)
00299 {
00300 int rc = 0;
00301 IFSTREAM *ifs = dev->dev_icb;
00302 ACEDCB *dcb = dev->dev_dcb;
00303
00304 if (ifs->if_rd_idx == ifs->if_rx_idx) {
00305 rc = NutEventWaitNext(&(dcb->dcb_rx_rdy), dcb->dcb_rtimeout);
00306 }
00307 return rc;
00308 }
00309
00324 int AceOutput(NUTDEVICE * dev)
00325 {
00326 IFSTREAM *ifs = dev->dev_icb;
00327 ACEDCB *dcb = dev->dev_dcb;
00328 volatile u_char tmp;
00329
00330 if ((ifs->if_tx_act == 0) && (ifs->if_tx_idx != ifs->if_wr_idx)) {
00331 ifs->if_tx_act = 1;
00332 --dcb->dcb_wfifo;
00333 tmp = ifs->if_tx_idx;
00334 ++ifs->if_tx_idx;
00335 #ifdef ACE_HDX_LINE
00336 if (dcb->dcb_modeflags & ACE_MF_HALFDUPLEX) {
00337 ACE_HDX_TRANSMIT(dev->dev_base);
00338 }
00339 #endif
00340
00341 *(u_char *) (dev->dev_base + ACE_THR_OFS) = ifs->if_tx_buf[tmp];
00342
00343 }
00344
00345 return 0;
00346 }
00347
00358 int AceFlush(NUTDEVICE * dev)
00359 {
00360 IFSTREAM *ifs = dev->dev_icb;
00361 ACEDCB *dcb = dev->dev_dcb;
00362
00363
00364
00365
00366 if (AceOutput(dev))
00367 return -1;
00368
00369
00370
00371
00372 while (ifs->if_tx_idx != ifs->if_wr_idx) {
00373 NutEventWaitNext(&dcb->dcb_tx_rdy, 100);
00374 }
00375
00376 return 0;
00377 }
00378
00379
00380
00381
00382
00383
00384
00385 static int AceGetStatus(NUTDEVICE * dev, u_long * status)
00386 {
00387 IFSTREAM *ifs = dev->dev_icb;
00388 u_char us;
00389
00390 *status = 0;
00391 us = *(u_char *) (dev->dev_base + ACE_LSR_OFS);
00392 if (us & LSR_FER_MSK)
00393 *status |= ACE_FRAMINGERROR;
00394 if (us & LSR_OVR_MSK)
00395 *status |= ACE_OVERRUNERROR;
00396 if (ifs->if_tx_idx == ifs->if_wr_idx)
00397 *status |= ACE_TXBUFFEREMPTY;
00398 if (ifs->if_rd_idx == ifs->if_rx_idx)
00399 *status |= ACE_RXBUFFEREMPTY;
00400 return 0;
00401 }
00402
00403
00404
00405
00406 static void AceEnable(u_short base)
00407 {
00408
00409
00410
00411
00412
00413 NutEnterCritical();
00414 *(u_char *) (base + ACE_IER_OFS) = IER_RDA_MSK | IER_THE_MSK;
00415 NutExitCritical();
00416 }
00417
00418
00419
00420
00421 static void AceDisable(u_short base)
00422 {
00423
00424
00425
00426
00427
00428 NutEnterCritical();
00429 *(u_char *) (base + ACE_IER_OFS) &= (u_char) ~ (IER_RDA_MSK);
00430 NutExitCritical();
00431
00432
00433
00434
00435 NutDelay(10);
00436 }
00437
00477 int AceIOCtl(NUTDEVICE * dev, int req, void *conf)
00478 {
00479 int rc = 0;
00480 ACEDCB *dcb;
00481 IFSTREAM *ifs;
00482 u_long *lvp = (u_long *) conf;
00483 u_long lv = *lvp;
00484 u_char bv = (u_char) lv;
00485 u_short sv;
00486 u_short devnum;
00487 u_char tv;
00488
00489 if (dev == 0) {
00490 return -1;
00491 }
00492
00493 devnum = dev->dev_base;
00494 dcb = dev->dev_dcb;
00495
00496 switch (req) {
00497 case ACE_SETSPEED:
00498 AceDisable(devnum);
00499 sv = (u_short) (ACE_CLOCK / (lv * 16UL));
00500 *(u_char *) (dev->dev_base + ACE_LCR_OFS) |= LCR_ENB_MSK;
00501 *(u_char *) (dev->dev_base + ACE_DLL_OFS) = (u_char) (sv & 0xFF);
00502 *(u_char *) (dev->dev_base + ACE_DLM_OFS) = (u_char) (sv >> 8);
00503 *(u_char *) (dev->dev_base + ACE_LCR_OFS) &= (u_char) ~ LCR_ENB_MSK;
00504 #ifdef ACE_HDX_LINE
00505 dcb->hdxByteTime = ByteOcrTime(dev);
00506 #endif
00507 AceEnable(devnum);
00508 break;
00509
00510 case ACE_GETSPEED:
00511 *(u_char *) (dev->dev_base + ACE_LCR_OFS) |= LCR_ENB_MSK;
00512 sv = *(u_char *) (dev->dev_base + ACE_DLL_OFS);
00513 sv |= *(u_char *) (dev->dev_base + ACE_DLM_OFS) << 8;
00514 *(u_char *) (dev->dev_base + ACE_LCR_OFS) &= (u_char) ~ LCR_ENB_MSK;
00515 *lvp = ACE_CLOCK / (16UL * (u_long) (sv));
00516 break;
00517
00518 case ACE_SETDATABITS:
00519 AceDisable(devnum);
00520 if ((bv >= 5) && (bv <= 8)) {
00521 bv -= 5;
00522 tv = *(u_char *) (dev->dev_base + ACE_LCR_OFS);
00523 tv &= (u_char) ~ (LCR_WS0_MSK | LCR_WS1_MSK);
00524 tv |= (bv & (LCR_WS0_MSK | LCR_WS1_MSK));
00525 *(u_char *) (dev->dev_base + ACE_LCR_OFS) = tv;
00526 #ifdef ACE_HDX_LINE
00527 dcb->hdxByteTime = ByteOcrTime(dev);
00528 #endif
00529 }
00530 AceEnable(devnum);
00531 break;
00532
00533 case ACE_GETDATABITS:
00534 *lvp = *(u_char *) (dev->dev_base + ACE_LCR_OFS) & (LCR_WS0_MSK | LCR_WS1_MSK);
00535 break;
00536
00537 case ACE_SETPARITY:
00538 AceDisable(devnum);
00539 if (bv <= 4) {
00540 switch (bv) {
00541 case 1:
00542 bv = LCR_PEN_MSK;
00543 break;
00544
00545 case 2:
00546 bv = LCR_PEN_MSK | LCR_PRE_MSK;
00547 break;
00548
00549 case 3:
00550 bv = LCR_PEN_MSK;
00551 break;
00552
00553 case 4:
00554 bv = LCR_PEN_MSK | LCR_PRS_MSK;
00555
00556 default:
00557 bv = 0;
00558 break;
00559 }
00560
00561 tv = *(u_char *) (dev->dev_base + ACE_LCR_OFS);
00562 tv &= (u_char) ~ (LCR_PEN_MSK | LCR_PRE_MSK | LCR_PRS_MSK);
00563 tv |= bv;
00564 *(u_char *) (dev->dev_base + ACE_LCR_OFS) = tv;
00565 #ifdef ACE_HDX_LINE
00566 dcb->hdxByteTime = ByteOcrTime(dev);
00567 #endif
00568 }
00569 AceEnable(devnum);
00570 break;
00571
00572 case ACE_GETPARITY:
00573 tv = *(u_char *) (dev->dev_base + ACE_LCR_OFS) & (LCR_PEN_MSK | LCR_PRE_MSK | LCR_PRS_MSK);
00574 switch (tv) {
00575 case 0:
00576 *lvp = 0;
00577 break;
00578
00579 case LCR_PEN_MSK:
00580 *lvp = 1;
00581 break;
00582
00583 case LCR_PEN_MSK | LCR_PRE_MSK:
00584 *lvp = 2;
00585 break;
00586
00587 case LCR_PEN_MSK | LCR_PRS_MSK:
00588 *lvp = 4;
00589 break;
00590 }
00591 break;
00592
00593 case ACE_SETSTOPBITS:
00594 AceDisable(devnum);
00595 if (bv == 1 || bv == 2) {
00596 tv = *(u_char *) (dev->dev_base + ACE_LCR_OFS);
00597 tv &= (u_char) ~ (LCR_STB_MSK);
00598 tv |= (bv == 2) ? LCR_STB_MSK : 0;
00599 *(u_char *) (dev->dev_base + ACE_LCR_OFS) = tv;
00600 #ifdef ACE_HDX_LINE
00601 dcb->hdxByteTime = ByteOcrTime(dev);
00602 #endif
00603 }
00604 AceEnable(devnum);
00605 break;
00606
00607 case ACE_GETSTOPBITS:
00608 tv = *(u_char *) (dev->dev_base + ACE_LCR_OFS);
00609 *lvp = (tv & LCR_STB_MSK) ? 2 : 1;
00610 break;
00611
00612 case ACE_SETFIFO:
00613 AceDisable(devnum);
00614 dcb->dcb_wfifo = ACE_FIFO_SIZE;
00615 switch (bv) {
00616 case 1:
00617 tv = FCR_ENABLE | FCR_LEVEL_1 | FCR_PURGE_I | FCR_PURGE_O;
00618 break;
00619
00620 case 4:
00621 tv = FCR_ENABLE | FCR_LEVEL_4 | FCR_PURGE_I | FCR_PURGE_O;
00622 break;
00623
00624 case 8:
00625 tv = FCR_ENABLE | FCR_LEVEL_8 | FCR_PURGE_I | FCR_PURGE_O;
00626 break;
00627
00628 case 14:
00629 tv = FCR_ENABLE | FCR_LEVEL_14 | FCR_PURGE_I | FCR_PURGE_O;
00630 break;
00631
00632 default:
00633 bv = 0;
00634 tv = 0;
00635 dcb->dcb_wfifo = 1;
00636 break;
00637 }
00638 *(u_char *) (dev->dev_base + ACE_FCR_OFS) = tv;
00639
00640 *(u_char *) (dev->dev_base + ACE_FCR_OFS) = tv;
00641 dcb->dcb_rfifo = bv;
00642
00643
00644 ifs = dev->dev_icb;
00645
00646 ifs->if_tx_act = 0;
00647 ifs->if_tx_idx = ifs->if_wr_idx;
00648 NutEventPostAsync(&(dcb->dcb_tx_rdy));
00649
00650 AceEnable(devnum);
00651 break;
00652
00653 case ACE_GETFIFO:
00654 *lvp = (u_long) (dcb->dcb_rfifo);
00655 break;
00656
00657 case ACE_GETSTATUS:
00658 AceGetStatus(dev, lvp);
00659 break;
00660
00661 case ACE_SETSTATUS:
00662 rc = -1;
00663 break;
00664
00665 case ACE_SETREADTIMEOUT:
00666 dcb->dcb_rtimeout = lv;
00667 break;
00668 case ACE_GETREADTIMEOUT:
00669 *lvp = dcb->dcb_rtimeout;
00670 break;
00671
00672 case ACE_SETWRITETIMEOUT:
00673 dcb->dcb_wtimeout = lv;
00674 break;
00675 case ACE_GETWRITETIMEOUT:
00676 *lvp = dcb->dcb_wtimeout;
00677 break;
00678
00679 case ACE_SETLOCALECHO:
00680 if (bv)
00681 dcb->dcb_modeflags |= ACE_MF_LOCALECHO;
00682 else
00683 dcb->dcb_modeflags &= ~ACE_MF_LOCALECHO;
00684 break;
00685 case ACE_GETLOCALECHO:
00686 *lvp = (dcb->dcb_modeflags & ACE_MF_LOCALECHO) ? 1 : 0;
00687 break;
00688
00689 case ACE_SETFLOWCONTROL:
00690 #ifdef ACE_HDX_LINE
00691 if (lv & ACE_MF_HALFDUPLEX) {
00692
00693 dcb->dcb_modeflags |= ACE_MF_HALFDUPLEX;
00694 } else {
00695 dcb->dcb_modeflags &= ~ACE_MF_HALFDUPLEX;
00696 }
00697 dcb->hdxOcrTime = 0;
00698
00699 ACE_HDX_RECEIVE(dev->dev_base);
00700 #endif
00701 break;
00702
00703 case ACE_GETFLOWCONTROL:
00704 #ifdef ACE_HDX_LINE
00705 *lvp = (u_long) (dcb->dcb_modeflags & ACE_MF_HALFDUPLEX);
00706 #endif
00707 break;
00708
00709 case ACE_SETCOOKEDMODE:
00710 if (bv)
00711 dcb->dcb_modeflags |= ACE_MF_COOKEDMODE;
00712 else
00713 dcb->dcb_modeflags &= ~ACE_MF_COOKEDMODE;
00714 break;
00715 case ACE_GETCOOKEDMODE:
00716 *lvp = (dcb->dcb_modeflags & ACE_MF_COOKEDMODE) ? 1 : 0;
00717 break;
00718
00719 default:
00720 rc = -1;
00721 break;
00722 }
00723 return rc;
00724 }
00725
00736 int AceInit(NUTDEVICE * dev)
00737 {
00738 IFSTREAM *ifs;
00739 ACEDCB *dcb, *pFirstDcb;
00740 u_long baudrate = 9600;
00741 u_long databits = 8;
00742 u_long parity = 0;
00743 u_long stopbits = 1;
00744 IRQ_HANDLER *irq;
00745 u_char *pnPort;
00746 u_char nMask;
00747 #ifdef ACE_HDX_LINE
00748 u_long flowcontrol = 0;
00749 #endif
00750
00751
00752
00753 if (dev->dev_type != IFTYP_STREAM) {
00754 return -1;
00755 }
00756
00757
00758
00759
00760 ifs = dev->dev_icb;
00761 memset(ifs, 0, sizeof(IFSTREAM));
00762 ifs->if_input = AceInput;
00763 ifs->if_output = AceOutput;
00764 ifs->if_flush = AceFlush;
00765
00766
00767
00768
00769 dcb = dev->dev_dcb;
00770 memset(dcb, 0, sizeof(ACEDCB));
00771 dcb->dcb_modeflags = ACE_MF_NOBUFFER;
00772 dcb->dcb_rfifo = 0;
00773 dcb->dcb_wfifo = 1;
00774 dcb->dev_next = NULL;
00775 #ifdef ACE_HDX_LINE
00776 dcb->hdxOcrTime = 0;
00777 #endif
00778
00779
00780
00781
00782 if (dev->dev_base) {
00783
00784 if (pIrqDev[dev->dev_irq] != NULL) {
00785 pFirstDcb = pIrqDev[dev->dev_irq]->dev_dcb;
00786 dcb->dev_next = pFirstDcb->dev_next;
00787 pFirstDcb->dev_next = dev;
00788 } else {
00789 #ifdef ACE_HDX_LINE
00790 if (irqMask == 0) {
00791
00792 if (NutRegisterIrqHandler(&sig_OUTPUT_COMPARE3A, AceOutComp3AInt, NULL)) {
00793 return -1;
00794 }
00795 AceTmr3Init();
00796 }
00797 #endif
00798
00799 irq = (IRQ_HANDLER *) pgm_read_word(&(atIrqDefs[dev->dev_irq].pvIrq));
00800
00801 if (NutRegisterIrqHandler(irq, AceIrqHandler, dev)) {
00802 return -1;
00803 }
00804
00805 pnPort = (u_char *) pgm_read_word(&(atIrqDefs[dev->dev_irq].pnIrqMskPort));
00806 nMask = pgm_read_byte(&(atIrqDefs[dev->dev_irq].nMask));
00807 *pnPort |= nMask;
00808
00809 pIrqDev[dev->dev_irq] = dev;
00810 irqMask |= 0x01 << dev->dev_irq;
00811 }
00812 }
00813
00814
00815
00816
00817
00818 AceIOCtl(dev, ACE_SETSPEED, (void *) &baudrate);
00819 AceIOCtl(dev, ACE_SETDATABITS, (void *) &databits);
00820 AceIOCtl(dev, ACE_SETPARITY, (void *) &parity);
00821 AceIOCtl(dev, ACE_SETSTOPBITS, (void *) &stopbits);
00822 #ifdef ACE_HDX_LINE
00823
00824 AceIOCtl(dev, ACE_SETFLOWCONTROL, (void *) &flowcontrol);
00825 #endif
00826 sbi(EIMSK, dev->dev_irq);
00827
00828 AceEnable(dev->dev_base);
00829
00830 return 0;
00831 }
00832
00836 int AceRead(NUTFILE * fp, void *buffer, int size)
00837 {
00838 int rc;
00839 NUTDEVICE *dev;
00840 IFSTREAM *ifs;
00841 ACEDCB *dcb;
00842 u_char elmode;
00843 u_char ch;
00844 u_char *cp = buffer;
00845
00846 dev = fp->nf_dev;
00847 ifs = (IFSTREAM *) dev->dev_icb;
00848 dcb = dev->dev_dcb;
00849
00850 if (dcb->dcb_modeflags & ACE_MF_COOKEDMODE)
00851 elmode = 1;
00852 else
00853 elmode = 0;
00854
00855
00856
00857
00858 if (buffer == 0) {
00859 ifs->if_rd_idx = ifs->if_rx_idx;
00860 return 0;
00861 }
00862
00863
00864
00865
00866 for (rc = 0; rc < size;) {
00867
00868 if (ifs->if_rd_idx == ifs->if_rx_idx) {
00869
00870 while (ifs->if_rd_idx == ifs->if_rx_idx) {
00871
00872 if (AceInput(dev)) {
00873
00874 return 0;
00875 }
00876 }
00877 }
00878 ch = ifs->if_rx_buf[ifs->if_rd_idx++];
00879 if (elmode && (ch == '\r' || ch == '\n')) {
00880 if ((ifs->if_last_eol == 0) || (ifs->if_last_eol == ch)) {
00881 ifs->if_last_eol = ch;
00882 *cp++ = '\n';
00883 rc++;
00884 }
00885 } else {
00886 ifs->if_last_eol = 0;
00887 *cp++ = ch;
00888 rc++;
00889 }
00890 }
00891 return rc;
00892 }
00893
00897 int AcePut(NUTDEVICE * dev, CONST void *buffer, int len, int pflg)
00898 {
00899 int rc;
00900 IFSTREAM *ifs;
00901 ACEDCB *dcb;
00902 CONST u_char *cp;
00903 u_char lbmode;
00904 u_char elmode;
00905 u_char ch;
00906
00907 ifs = dev->dev_icb;
00908 dcb = dev->dev_dcb;
00909
00910 if (dcb->dcb_modeflags & ACE_MF_LINEBUFFER)
00911 lbmode = 1;
00912 else
00913 lbmode = 0;
00914
00915 if (dcb->dcb_modeflags & ACE_MF_COOKEDMODE)
00916 elmode = 1;
00917 else
00918 elmode = 0;
00919
00920
00921
00922
00923 if (buffer == 0) {
00924 rc = AceFlush(dev);
00925 return rc;
00926 }
00927
00928
00929
00930
00931 cp = buffer;
00932 for (rc = 0; rc < len;) {
00933 if ((u_char) (ifs->if_wr_idx + 1) == ifs->if_tx_idx) {
00934 if (AceFlush(dev)) {
00935 return -1;
00936 }
00937 }
00938 ch = pflg ? PRG_RDB(cp) : *cp;
00939 if (elmode == 1 && ch == '\n') {
00940 elmode = 2;
00941 if (lbmode == 1)
00942 lbmode = 2;
00943 ch = '\r';
00944 } else {
00945 if (elmode == 2)
00946 elmode = 1;
00947 cp++;
00948 rc++;
00949 }
00950 ifs->if_tx_buf[ifs->if_wr_idx++] = ch;
00951 }
00952
00953 if (lbmode > 1 || (dcb->dcb_modeflags & ACE_MF_NOBUFFER) != 0) {
00954 if (AceFlush(dev))
00955 rc = -1;
00956 }
00957 return rc;
00958 }
00959
00960 int AceWrite(NUTFILE * fp, CONST void *buffer, int len)
00961 {
00962 return AcePut(fp->nf_dev, buffer, len, 0);
00963 }
00964
00965 int AceWrite_P(NUTFILE * fp, PGM_P buffer, int len)
00966 {
00967 return AcePut(fp->nf_dev, (CONST char *) buffer, len, 1);
00968 }
00969
00970
00974 NUTFILE *AceOpen(NUTDEVICE * dev, CONST char *name, int mode, int acc)
00975 {
00976 NUTFILE *fp = NutHeapAlloc(sizeof(NUTFILE));
00977 ACEDCB *dcb;
00978
00979 if (fp == 0)
00980 return NUTFILE_EOF;
00981
00982 dcb = dev->dev_dcb;
00983 if (mode & _O_BINARY)
00984 dcb->dcb_modeflags &= ~ACE_MF_COOKEDMODE;
00985 else
00986 dcb->dcb_modeflags |= ACE_MF_COOKEDMODE;
00987
00988 fp->nf_next = 0;
00989 fp->nf_dev = dev;
00990 fp->nf_fcb = 0;
00991
00992 return fp;
00993 }
00994
00998 int AceClose(NUTFILE * fp)
00999 {
01000 NutHeapFree(fp);
01001
01002 return 0;
01003 }
01004
01008 long AceSize(NUTFILE * fp)
01009 {
01010 NUTDEVICE *dev;
01011 IFSTREAM *ifs;
01012
01013 dev = fp->nf_dev;
01014 ifs = (IFSTREAM *) dev->dev_icb;
01015 return ((u_char) (ifs->if_rx_idx - ifs->if_rd_idx));
01016 }
01017
01018 #ifdef ACE_HDX_LINE
01019 static void AceTmr3Init(void)
01020 {
01021
01022 TCCR3A &= ~(_BV(COM3A1) | _BV(COM3A0) | _BV(WGM31) | _BV(WGM30));
01023
01024 TCCR3B &= ~(_BV(WGM33) | _BV(WGM32) | _BV(CS32) | _BV(CS31) | _BV(CS30));
01025 TCCR3B |= _BV(CS31) | _BV(CS30);
01026
01027
01028 ETIMSK &= ~_BV(OCIE3A);
01029 }
01030
01031 static void AceOutComp3AInt(void *arg)
01032 {
01033 NUTDEVICE *dev;
01034 ACEDCB *dcb;
01035 int i;
01036 u_int nextOcr = 0xffff, ocr;
01037 u_int timerOcrDiff;
01038
01039
01040 TCCR3B &= ~(_BV(CS31) | _BV(CS30));
01041
01042 timerOcrDiff = (u_int )((u_int )TCNT3 - (u_int )OCR3A);
01043
01044
01045
01046
01047 EIMSK &= ~irqMask;
01048
01049 for (i = 0; i < 8; ++i) {
01050 for (dev = pIrqDev[i]; dev != NULL; dev = dcb->dev_next) {
01051 dcb = dev->dev_dcb;
01052
01053 if (dcb->hdxOcrTime != 0) {
01054 if ((u_int )(dcb->hdxOcrTime - (u_int )OCR3A) <= timerOcrDiff) {
01055 dcb->hdxOcrTime = 0;
01056 ACE_HDX_RECEIVE(dev->dev_base);
01057 } else {
01058 ocr = (u_int )(dcb->hdxOcrTime - (u_int )TCNT3);
01059 if (ocr < nextOcr) {
01060 nextOcr = ocr;
01061 }
01062 }
01063 }
01064 }
01065 }
01066
01067 if (nextOcr == 0xffff) {
01068
01069 ETIMSK &= ~_BV(OCIE3A);
01070 } else {
01071 OCR3A = nextOcr;
01072
01073 TCCR3B |= _BV(CS31) | _BV(CS30);
01074 }
01075
01076
01077 EIMSK |= irqMask;
01078 }
01079
01080 static void AceAddHdxTime(ACEDCB * dcb)
01081 {
01082
01083 TCCR3B &= ~(_BV(CS31) | _BV(CS30));
01084
01085
01086 if ((ETIMSK & _BV(OCIE3A)) == 0) {
01087
01088 OCR3A = 0;
01089 TCNT3 = 1;
01090 }
01091
01092
01093 dcb->hdxOcrTime = (u_int )((u_int )TCNT3 + dcb->hdxByteTime);
01094
01095 if (dcb->hdxOcrTime == 0) {
01096 dcb->hdxOcrTime = 1;
01097 }
01098
01099 if (dcb->hdxByteTime < (u_int )((u_int )OCR3A - (u_int )TCNT3)) {
01100 OCR3A = dcb->hdxOcrTime;
01101 }
01102
01103 ETIMSK |= _BV(OCIE3A);
01104
01105
01106 TCCR3B |= _BV(CS31) | _BV(CS30);
01107 }
01108 #endif
01109