Main Page   Modules   Alphabetical List   Compound List   File List   Compound Members   File Members   Related Pages  

/projects/cubeos/src_current/drivers/tty/io_duart.c

Go to the documentation of this file.
00001 /*  src_experimental/drivers/tty/io_duart.c
00002    CubeOS Version 0.4.90 experimental
00003    Copyright (C) 1999,2000 Holger Kenn
00004 
00005    CubeOS is free software; you can redistribute it and/or
00006    modify it under the terms of the GNU Library General Public
00007    License as published by the Free Software Foundation; either
00008    version 2 of the License, or any later version.
00009 
00010    CubeOS is distributed in the hope that it will be useful,
00011    but WITHOUT ANY WARRANTY; without even the implied warranty of
00012    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013    Library General Public License for more details.
00014 
00015  */
00016 #include <stddef.h>
00017 #include <mc68681.h>
00018 #include <cubeos.h>
00019 #include <sys_var.h>
00020 #include <iobuf.h>
00021 #include <kerror.h>
00022 #include <ttyio.h>
00023 #include <rsm.h>
00024 #include <rdio.h>
00025 #include <ivtab.h>
00026 #include <softreset.h>
00027 
00032 /* 
00033  * The DUART is mapped into the IDP address space in an unusual 
00034  * manner.  The mc68681 is an 8 bit device located on the least
00035  * significant byte (byte0) of the data bus.  Bytes 3, 2, and 
00036  * one have nothing in them and writes to these locations are
00037  * not valid.
00038  */
00039 
00040 struct TTY_tty_dev *_DUART_t_a;
00041 struct TTY_tty_dev *_DUART_t_b;
00042 
00043 unsigned char _DUART_opcrsave; 
00044 
00045 
00046 unsigned char _DUART_imrsave;  
00047 
00048 unsigned char _DUART_isr;
00049 
00050 //void iTTY_outchar(char byte);
00051 
00052 #ifdef DUART_BASE
00053 void DUART_setDIMR (unsigned char bit)
00054 {
00055         _DUART_imrsave |= bit;
00056         writebyte (DUART_IMR, _DUART_imrsave);
00057 }
00058 
00059 
00060 void DUART_clearDIMR (unsigned char bit)
00061 {
00062         _DUART_imrsave &= (0xff - bit);
00063         writebyte (DUART_IMR, _DUART_imrsave);
00064 }
00065 
00066 void _DUART_setrts_a (int how)
00067 {
00068 
00069 }
00070 void _DUART_setrts_b (int how)
00071 {
00072 
00073 }
00074 
00075 
00076 void DUART_en_txirq_a ()
00077 {
00078         DUART_setDIMR (0x01);
00079 }
00080 
00081 void DUART_dis_txirq_a ()
00082 {
00083         DUART_clearDIMR (0x01);
00084 }
00085 
00086 void DUART_en_txirq_b ()
00087 {
00088         DUART_setDIMR (0x10);
00089 }
00090 
00091 void DUART_dis_txirq_b ()
00092 {
00093         DUART_clearDIMR (0x10);
00094 }
00095 
00096 void DUART_en_rxirq_a ()
00097 {
00098         DUART_setDIMR (0x02);
00099 }
00100 
00101 void DUART_dis_rxirq_a ()
00102 {
00103         DUART_clearDIMR (0x02);
00104 }
00105 
00106 void DUART_en_rxirq_b ()
00107 {
00108         DUART_setDIMR (0x20);
00109 }
00110 
00111 void DUART_dis_rxirq_b ()
00112 {
00113         DUART_clearDIMR (0x20);
00114 }
00115 
00116 void DUART_setOPCR (unsigned char bit)
00117 {
00118         _DUART_opcrsave |= bit;
00119         writebyte (DUART_OPCR, _DUART_opcrsave);
00120 }
00121 
00122 
00123 void DUART_clearOPCR (unsigned char bit)
00124 {
00125         _DUART_opcrsave &= (0xff - bit);
00126         writebyte (DUART_OPCR, _DUART_opcrsave);
00127 }
00128 
00129 void DUART_txbyte_b (char byte)
00130 {
00131         while (!(readbyte (DUART_SRB) & 4));
00132         writebyte (DUART_TBB, byte);
00133 }
00134 void DUART_txbyte_a (char byte)
00135 {
00136         while (!(readbyte (DUART_SRA) & 4));
00137         writebyte (DUART_TBA, byte);
00138 }
00139 
00140 int DUART_sethandshake_a (char handshake)
00141 {
00142         switch (handshake) {
00143         case TTY_HS_NONE:
00144         case TTY_HS_XONXOFF:
00145         case TTY_HS_RTSCTS:
00146                 writebyte (DUART_MR2A, readbyte (DUART_MR2A) & (0xff - 0x30));
00147                 break;
00148         case TTY_HS_RTSCTSHW:
00149                 writebyte (DUART_MR2A, readbyte (DUART_MR2A) | 0x30);
00150                 DUART_setOPCR (0x10);
00151                 break;
00152         default:
00153                 return (-1);
00154         }
00155         _DUART_t_a->hsmode = handshake;
00156         return (0);
00157 }
00158 
00159 int DUART_setbps_a(int bpsrate)
00160 {
00161  int res = -1;
00162  switch(bpsrate)
00163  {
00164   case(600) :
00165   {
00166    writebyte(DUART_CSRA,0x55);
00167    res = 0;
00168    break;
00169   }
00170   case(1200) :
00171   {
00172                         writebyte(DUART_CSRA,0x66);
00173                         res = 0;
00174    break;
00175   }
00176   case(2400) :
00177     {
00178                         writebyte(DUART_CSRA,0x88);
00179                         res = 0;
00180    break;
00181     }
00182   case(4800) :
00183   {
00184                         writebyte(DUART_CSRA,0x99);
00185                         res = 0;
00186    break;
00187   }
00188   case(9600) :
00189     {
00190                         writebyte(DUART_CSRA,0xbb);
00191                         res = 0;
00192    break;
00193     }
00194   case(19200) :
00195     {
00196                         writebyte(DUART_CSRA,0xcc);
00197                         res = 0;
00198    break;
00199     }
00200   case(57600) : // IS THIS CORRECT ???
00201     {
00202                         writebyte(DUART_CSRA,0xdd);
00203                         res = 0;
00204    break;
00205     }
00206  }
00207  return(res);
00208 }
00209 
00210 
00211 int DUART_sethandshake_b (char handshake)
00212 {
00213         switch (handshake) {
00214         case TTY_HS_NONE:
00215         case TTY_HS_XONXOFF:
00216         case TTY_HS_RTSCTS:
00217                 writebyte (DUART_MR2B, readbyte (DUART_MR2B) & (0xff - 0x30));
00218                 break;
00219         case TTY_HS_RTSCTSHW:
00220                 writebyte (DUART_MR2B, readbyte (DUART_MR2B) | 0x30);
00221                 DUART_setOPCR (0x20);
00222                 break;
00223         default:
00224                 return (-1);
00225         }
00226         _DUART_t_b->hsmode = handshake;
00227         return (0);
00228 }
00229 
00230 
00231 int DUART_setbps_b(int bpsrate)
00232 {
00233  int res = -1;
00234  switch(bpsrate)
00235  {
00236   case(600) :
00237   {
00238    writebyte(DUART_CSRB,0x55);
00239    res = 0;
00240    break;
00241   }
00242   case(1200) :
00243   {
00244                         writebyte(DUART_CSRB,0x66);
00245                         res = 0;
00246    break;
00247   }
00248   case(2400) :
00249     {
00250                         writebyte(DUART_CSRB,0x88);
00251                         res = 0;
00252    break;
00253     }
00254   case(4800) :
00255   {
00256                         writebyte(DUART_CSRB,0x99);
00257                         res = 0;
00258    break;
00259   }
00260   case(9600) :
00261     {
00262                         writebyte(DUART_CSRB,0xbb);
00263                         res = 0;
00264    break;
00265     }
00266   case(19200) :
00267     {
00268                         writebyte(DUART_CSRB,0xcc);
00269                         res = 0;
00270    break;
00271     }
00272   case(57600) : // IS THIS CORRECT ???
00273     {
00274                         writebyte(DUART_CSRB,0xdd);
00275                         res = 0;
00276    break;
00277     }
00278  }
00279  return(res);
00280 }
00281 
00282 
00283 
00284 void DUART_isr_a (struct iobuf *in, struct iobuf *out)
00285 {
00286 // This should be a while loop, but breaks SMBII and Cube1 if so.
00287         if (readbyte (DUART_SRA) & (char) (0x1 | 0x80)) {       /* char or break */
00288                 if ((readbyte (DUART_SRA) & (char) (0x80)) && (_DUART_t_a->break_process)) {
00289                         writebyte (DUART_CRA, 0x40);/* remove break condition? */
00290                         _DUART_t_a->break_process ();
00291                 }
00292 //              if (!_RSM_enabled) 
00293                 if (!_DUART_t_a->char_process) {
00294                         if (in->cnt < (in->buflen - TTY_RTS_TRESHOLD)) {
00295                                 _DUART_setrts_a (0);
00296                         }
00297                         if (in->cnt < in->buflen) {
00298                                 in->data[in->head] = readbyte (DUART_RBA);
00299                                 in->head = (in->head + 1) % in->buflen;
00300                                 in->cnt++;
00301                         } else {
00302                                 _KERN_sys_error |= SYS_ERR_DUARTABUF_OVF;
00303                                 in->data[in->head] = readbyte (DUART_RBA);
00304                         }
00305                 } else {
00306 //                      RSM_process(readbyte (DUART_RBA));
00307                         _DUART_t_a->char_process (readbyte (DUART_RBA));
00308                 }
00309         }
00310 
00311         while ((out->cnt > 0) && (readbyte (DUART_SRA) & 4)) {
00312                 writebyte (DUART_TBA, out->data[out->tail]);
00313                 out->tail = (out->tail + 1) % out->buflen;
00314                 out->cnt--;
00315         }
00316         /* hold possibly pending transmitter interrupt */
00317         if (out->cnt == 0) {
00318                 DUART_clearDIMR (0x01);
00319         } else {
00320                 DUART_setDIMR (0x01);
00321         }
00322 }
00323 
00324 
00325 
00326 void DUART_isr_b (struct iobuf *in, struct iobuf *out)
00327 {
00328         char c;
00329 // This should be a while loop, but breaks SMBII and Cube1 if so.
00330         if (readbyte (DUART_SRB) & (char) (0x1 | 0x80)) {       /* char or break */
00331                 if ((readbyte (DUART_SRB) & (char) (0x80)) && (_DUART_t_b->break_process)){
00332                         writebyte (DUART_CRA, 0x40);/* remove break condition? */
00333                         _DUART_t_b->break_process ();
00334                 }
00335                 if (!_DUART_t_b->char_process) {
00336                         if (in->cnt < (in->buflen - TTY_RTS_TRESHOLD)) {
00337                                 _DUART_setrts_b (0);
00338                         }
00339                         if (in->cnt < in->buflen) {
00340                                 c = readbyte (DUART_RBB);
00341 //                              if (c == RESET_CHAR)
00342 //                                      KERN_softreset ();
00343                                 in->data[in->head] = c;
00344                                 in->head = (in->head + 1) % in->buflen;
00345                                 in->cnt++;
00346                         } else {
00347                                 _KERN_sys_error |= SYS_ERR_DUARTBBUF_OVF;
00348                                 c = readbyte (DUART_RBB);
00349 //                              if (c == RESET_CHAR)
00350 //                                      KERN_softreset ();
00351                                 in->data[in->head] = c;
00352                         }
00353                 } else {
00354                         _DUART_t_b->char_process (readbyte (DUART_RBB));
00355                 }
00356         }
00357 
00358 
00359         while ((out->cnt > 0) && (readbyte (DUART_SRB) & 4)) {
00360                 writebyte (DUART_TBB, out->data[out->tail]);
00361                 out->tail = (out->tail + 1) % out->buflen;
00362                 out->cnt--;
00363         }
00364         /* hold possibly pending transmitter interrupt */
00365         if (out->cnt == 0)
00366                 DUART_clearDIMR (0x10);         /* writebyte(DUART_IMR, 0x20); */
00367 
00368 }
00369 
00370 void DUART_int ()
00371 {
00372         DUART_isr_b (_DUART_t_b->inq, _DUART_t_b->outq);
00373         DUART_isr_a (_DUART_t_a->inq, _DUART_t_a->outq);
00374 
00375 }
00376 
00377 void _DUART_duart_bugfix (void)
00378 {
00379 /* try to determine if we are in a bugfix condition */
00380 
00381         if (
00382               ((_DUART_t_a->outq->cnt > 0) && (readbyte (DUART_SRA) & 4)) ||
00383                    ((readbyte (DUART_SRA) & (char) 0x1)) ||
00384               (( _DUART_t_b->outq->cnt > 0) && (readbyte (DUART_SRB) & 4)) ||
00385                    ((readbyte (DUART_SRB) & (char) 0x1)) )
00386                 DUART_int ();   /* then call the duart interrupt */
00387 
00388 }
00389 
00390 //void TTY_koutchar(char byte);
00391 //
00392 //char TTY_kinchar(void)
00393 //{
00394 //      char c;
00395 //
00396 //      /* Block until char is there */
00397 //      while (_DUART_t_b->inq->cnt == 0);
00398 //      disable ();
00399 //      c = _DUART_t_b->inq->data[_DUART_t_b->inq->tail];
00400 //      _DUART_t_b->inq->tail = (_DUART_t_b->inq->tail + 1) % _DUART_t_b->inq->buflen;
00401 //      _DUART_t_b->inq->cnt--;
00402 //      if (_DUART_t_b->inq->cnt > _DUART_t_b->inq->buflen) {
00403 //              KERN_complain(ERR_PANIC, "More than _DUART_t_b->inq->buflen bytes in the buffer");
00404 //      }
00405 //      enable ();
00406 //      if (_TTY_console_echo)
00407 //              TTY_koutchar(c);
00408 //      return (c);
00409 //}
00410 
00411 char TTY_rdioget (void)
00412 {
00413         char c;
00414 
00415         while (_DUART_t_a->inq->cnt == 0);      /* Block until char is there */
00416         disable ();
00417         c = _DUART_t_a->inq->data[_DUART_t_a->inq->tail];
00418         _DUART_t_a->inq->tail = (_DUART_t_a->inq->tail + 1) % _DUART_t_a->inq->buflen;
00419         _DUART_t_a->inq->cnt--;
00420         enable ();
00421         return (c);
00422 }
00423 
00424 
00425 //void TTY_koutchar(char byte)
00426 //{
00427 //      disable ();
00428 //
00429 //      if (TTY_Blocking_Serial_Out) {
00430 //              DUART_dis_txirq_b();
00431 //              while (_DUART_t_b->outq->cnt > 0) {
00432 //                      DUART_txbyte_b(_DUART_t_b->outq->data[_DUART_t_b->outq->tail]);
00433 //                      _DUART_t_b->outq->tail = (_DUART_t_b->outq->tail + 1) % _DUART_t_b->outq->buflen;
00434 //                      _DUART_t_b->outq->cnt--;
00435 //              }
00436 //              DUART_txbyte_b(byte);
00437 //      } else {
00438 //
00439 //              if (_DUART_t_b->outq->cnt == _DUART_t_b->outq->buflen) {
00440 //                      DUART_en_txirq_b();
00441 //                      enable ();
00442 //                      return;
00443 //              }               /* Ignore overflow */
00444 //              _DUART_t_b->outq->data[_DUART_t_b->outq->head] = byte;
00445 //              _DUART_t_b->outq->head = (_DUART_t_b->outq->head + 1) % _DUART_t_b->outq->buflen;
00446 //              _DUART_t_b->outq->cnt++;
00447 //
00448 //              /* enable pending transmitter interrupt */
00449 //              if (_DUART_t_b->outq->cnt > 0)
00450 //                      DUART_en_txirq_b();
00451 //      }
00452 //      enable ();
00453 //
00454 //}
00455 
00456 //void iTTY_outchar(char byte)
00457 //{
00458 //
00459 //      if (_DUART_t_b->outq->cnt == _DUART_t_b->outq->buflen) {
00460 //              return;
00461 //      }                       /* Ignore overflow */
00462 //      _DUART_t_b->outq->data[_DUART_t_b->outq->head] = byte;
00463 //      _DUART_t_b->outq->head = (_DUART_t_b->outq->head + 1) % _DUART_t_b->outq->buflen;
00464 //      _DUART_t_b->outq->cnt++;
00465 //
00466 //      /* enable pending transmitter interrupt */
00467 //      if (_DUART_t_b->outq->cnt > 0)
00468 //                      DUART_en_txirq_b();
00469 //              
00470 //
00471 //}
00472 
00473 
00474 int TTY_rdioput (char byte)
00475 {
00476         disable ();
00477 
00478         if (_DUART_t_a->outq->cnt == _DUART_t_a->outq->buflen) {
00479                 DUART_en_txirq_a ();
00480                 enable ();
00481                 return -1;
00482         }                       /* Ignore overflow */
00483         _DUART_t_a->outq->data[_DUART_t_a->outq->head] = byte;
00484         _DUART_t_a->outq->head = (_DUART_t_a->outq->head + 1) % _DUART_t_a->outq->buflen;
00485         _DUART_t_a->outq->cnt++;
00486 
00487 /* enable pending transmitter interrupt */
00488         if (_DUART_t_a->outq->cnt > 0)
00489                 DUART_en_txirq_a ();
00490 
00491         enable ();
00492         return (0);
00493 }
00494 
00495 void RSM_rdio_flush ()
00496 {
00497         while (_DUART_t_a->outq->cnt);
00498 }
00499 
00500 
00501 void RSM_rdio_enable_rx ()
00502 {
00503         DUART_en_rxirq_a ();
00504 }
00505 
00506 void RSM_rdio_disable_rx ()
00507 {
00508         DUART_dis_rxirq_a ();
00509 }
00510 
00511 #else
00512 void DUART_int ()
00513 {
00514 }
00515 
00516 #endif
00517 
00518 void DUART_duart (struct TTY_tty_dev *TTY_tty_a, struct TTY_tty_dev *TTY_tty_b)
00519 {
00520         unsigned char temp;
00521 
00522         _DUART_t_a = TTY_tty_a;
00523         _DUART_t_b = TTY_tty_b;
00524 
00525         iobuf_init (_DUART_t_b->inq, BUFLEN);
00526         iobuf_init (_DUART_t_b->outq, BUFLEN);
00527         iobuf_init (_DUART_t_a->inq, BUFLEN);
00528         iobuf_init (_DUART_t_a->outq, 128);
00529 
00530 #ifdef DUART_BASE
00531         _DUART_t_a->txchar = DUART_txbyte_a;
00532         _DUART_t_a->en_tx_irq = DUART_en_txirq_a;
00533         _DUART_t_a->dis_tx_irq = DUART_dis_txirq_a;
00534         _DUART_t_a->en_rx_irq = DUART_en_rxirq_a;
00535         _DUART_t_a->dis_rx_irq = DUART_dis_rxirq_a;
00536         _DUART_t_a->sethandshake = DUART_sethandshake_a;
00537         _DUART_t_a->setbps = DUART_setbps_a;
00538         _DUART_t_a->setrts = _DUART_setrts_a;
00539         _DUART_t_a->hsmode = TTY_HS_NONE;
00540         _DUART_t_a->mode = 0;
00541         _DUART_t_a->state = 0;
00542         _DUART_t_a->char_process = NULL;
00543         _DUART_t_a->break_process = NULL;
00544 
00545         _DUART_t_b->txchar = DUART_txbyte_b;
00546         _DUART_t_b->en_tx_irq = DUART_en_txirq_b;
00547         _DUART_t_b->dis_tx_irq = DUART_dis_txirq_b;
00548         _DUART_t_b->en_rx_irq = DUART_en_rxirq_b;
00549         _DUART_t_b->dis_rx_irq = DUART_dis_rxirq_b;
00550         _DUART_t_b->sethandshake = DUART_sethandshake_b;
00551         _DUART_t_b->setbps = DUART_setbps_b;
00552         _DUART_t_b->setrts = _DUART_setrts_b;
00553         _DUART_t_b->hsmode = TTY_HS_NONE;
00554         _DUART_t_b->mode = 0;
00555         _DUART_t_b->state = 0;
00556         _DUART_t_b->char_process = NULL;
00557         _DUART_t_b->break_process = NULL;
00558 
00559         TTY_conecho_on ();
00560 //      _KERN_KERN_IVTab_setvector(AVEC5,DUART_Wrapper);
00561 
00562         writebyte (DUART_IMR, 0);
00563         writebyte (DUART_OPCR, 0);
00564         _DUART_opcrsave = 0;    /* Maybe we shouldn't do this */
00565         writebyte (DUART_CRA, 0x2a);
00566         writebyte (DUART_CRB, 0x2a);
00567         writebyte (DUART_CRA, 0x3a);
00568         writebyte (DUART_CRB, 0x3a);
00569         writebyte (DUART_ACR, 0xE0);    // 19.200
00570         // writebyte (DUART_ACR, 0x60); // 9.600
00571 
00572         writebyte (DUART_CTUR, 0);
00573         writebyte (DUART_CTLR, 2);
00574         temp = readbyte (DUART_STRTCC);
00575         writebyte (DUART_CSRA, 0xcc);
00576         writebyte (DUART_CSRB, 0xdd);
00577         writebyte (DUART_MR1A, 0x13);
00578         writebyte (DUART_MR1B, 0x13);
00579         writebyte (DUART_MR2A, 0x7);
00580         writebyte (DUART_MR2B, 0x7);
00581         writebyte (DUART_OPRRST, 0xff);
00582         writebyte (DUART_CRA, 5);
00583         writebyte (DUART_CRB, 5);
00584         writebyte (DUART_IMR,0x20);
00585         _DUART_imrsave = 0x20;
00586 //      DUART_en_rxirq_b ();
00587 #endif
00588 /* now, radio reception is disabled by not setting the RxRDYA bit */
00589 /* the tx irq is set via the TTY_rdioput(char) routine */
00590 
00591 }

Generated on Thu Feb 20 15:38:44 2003 for cubeOS by doxygen1.2.14 written by Dimitri van Heesch, © 1997-2002