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