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