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