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

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

Go to the documentation of this file.
00001 /*  src_experimental/drivers/tty/io_sci.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 <cubeos.h>
00018 #include <sys_var.h>
00019 #include <iobuf.h>
00020 #include <kerror.h>
00021 #include <ttyio.h>
00022 #include <mc68332.h>
00023 #include <ivtab.h>
00024 #include <qsm.h>
00025 #include <softreset.h>
00026 
00027 struct TTY_tty_dev *_QSM_sci_tty;
00028 
00029 int _QSM_sci_int_count;
00030 
00031 void QSM_sci_int (void)
00032 {
00033         char c;
00034         short statesave;
00035         struct iobuf *sci_in;
00036         struct iobuf *sci_out;
00037         _QSM_sci_int_count++;
00038 
00039 
00040         sci_in = _QSM_sci_tty->inq;
00041         sci_out = _QSM_sci_tty->outq;
00042 
00043         /* SCSR:
00044            Bit8: TDRE (transmit data reg empty)
00045            Bit7: TC   (transmit complete)
00046            Bit6: RDRF (receive data reg full)
00047            Bit5: RAF  (receiver busy)
00048            Bit4: IDLE (idle line detected)
00049            Bit3: OR   (overrun error)
00050            Bit2: NF   (noise error)
00051            Bit1: FE   (framing error)
00052            Bit0: PF   (parity error)
00053          */
00054         while ((statesave = readshort (SCI_SCSR)) & (0x40 | 0x02)) {    // RDRF | FE 
00055 
00056                 if ((statesave | 0x02) && (_QSM_sci_tty->break_process))
00057                         _QSM_sci_tty->break_process ();
00058                 if (!_QSM_sci_tty->char_process) {
00059                         if (sci_in->cnt < sci_in->buflen) {
00060                                 c = (char) (readshort (SCI_SCDR) & 0xff);
00061                                 if (c == RESET_CHAR)
00062                                         KERN_softreset ();
00063                                 sci_in->data[sci_in->head] = c;
00064                                 sci_in->head = (sci_in->head + 1) % sci_in->buflen;
00065                                 sci_in->cnt++;
00066                         } else {
00067                                 _KERN_sys_error |= SYS_ERR_SCIBUF_OVF;
00068                                 c = (char) (readshort (SCI_SCDR) & 0xff);
00069                                 if (c == RESET_CHAR)
00070                                         KERN_softreset ();
00071                                 sci_in->data[sci_in->head] = c;
00072                         }
00073                 } else {
00074                         _QSM_sci_tty->char_process ((char) readshort (SCI_SCDR) & 0xff);
00075                 }
00076         }
00077 
00078         while ((sci_out->cnt > 0) && (readshort (SCI_SCSR) & 0x100)) {
00079                 writeshort (SCI_SCDR, ((unsigned short) sci_out->data[sci_out->tail]) & 0xff);
00080                 sci_out->tail = (sci_out->tail + 1) % sci_out->buflen;
00081                 sci_out->cnt--;
00082         }
00083         /* hold possibly pending transmitter interrupt */
00084         if (sci_out->cnt == 0)
00085                 writeshort (SCI_SCCR1, readshort (SCI_SCCR1) & 0xff7f);
00086 
00087 }
00088 
00089 char QSM_sci_rxchar ()
00090 {
00091         short x;
00092         char c;
00093         do {
00094                 x = readshort (SCI_SCSR);
00095                 if (x & 0x5f) { // any receiver flags set ?
00096 
00097                         c = readshort (SCI_SCDR) & 0xff;
00098                 }
00099         } while (!(x & 0x40));
00100 
00101         return c;
00102 }
00103 
00104 //void TTY_soutchar (char byte);
00105 //
00106 //char TTY_sinchar (void)
00107 //{
00108 //      struct iobuf *sci_in;
00109 //      char c;
00110 //
00111 //      sci_in = _QSM_sci_tty->inq;
00112 //
00113 //      /* Block until char is there */
00114 //      while (sci_in->cnt == 0);
00115 //      disable ();
00116 //      c = sci_in->data[sci_in->tail];
00117 //      sci_in->tail = (sci_in->tail + 1) % sci_in->buflen;
00118 //      sci_in->cnt--;
00119 //      if (sci_in->cnt > sci_in->buflen) {
00120 //              KERN_complain (ERR_PANIC, "More than BUFLEN bytes in the buffer");
00121 //      }
00122 //      enable ();
00123 //      if (_TTY_console_echo)
00124 //              TTY_soutchar (c);
00125 //      return (c);
00126 //}
00127 
00128 
00129 void _QSM_sci_dis_tx ()
00130 {
00131         writeshort (SCI_SCCR1, readshort (SCI_SCCR1) & 0xff7f);
00132 }
00133 
00134 void _QSM_sci_en_tx ()
00135 {
00136         writeshort (SCI_SCCR1, readshort (SCI_SCCR1) | 0x80);
00137 }
00138 
00139 void _QSM_sci_dis_rx ()
00140 {
00141         writeshort (SCI_SCCR1, readshort (SCI_SCCR1) & 0xffdf);
00142 }
00143 
00144 void _QSM_sci_en_rx ()
00145 {
00146         writeshort (SCI_SCCR1, readshort (SCI_SCCR1) | 0x20);
00147 }
00148 void _QSM_sci_txbyte (char byte)
00149 {
00150         while (!(readshort (SCI_SCSR) & 0x100));
00151         writeshort (SCI_SCDR, ((unsigned short) byte) & 0xff);
00152 }
00153 
00154 int _QSM_sci_sethandshake (char handshake)
00155 {
00156         switch (handshake) {
00157         case TTY_HS_NONE:
00158         case TTY_HS_XONXOFF:
00159         case TTY_HS_RTSCTS:
00160                 break;
00161         default:
00162                 return (-1);
00163         }
00164         _QSM_sci_tty->hsmode = handshake;
00165         return (0);
00166 }
00167 int _QSM_sci_setbps (int bpsrate)
00168 {
00169  int res = -1;
00170  switch(bpsrate)
00171  {
00172   case(600) :
00173   {
00174    writeshort (SCI_SCCR0, 874);
00175    res = 0;
00176    break;
00177   }
00178   case(1200) :
00179     {
00180                         writeshort (SCI_SCCR0, 437);
00181    res = 0;
00182                         break;
00183     }
00184   case(2400) :
00185     {
00186                         writeshort (SCI_SCCR0, 218);
00187    res = 0;
00188                         break;
00189     }
00190   case(4800) :
00191     {
00192                         writeshort (SCI_SCCR0, 109);
00193    res = 0;
00194                         break;
00195     }
00196   case(9600) :
00197     {
00198                         writeshort (SCI_SCCR0, 55);
00199    res = 0;
00200                         break;
00201     }
00202   case(14400) :
00203     {
00204                         writeshort (SCI_SCCR0, 36);
00205    res = 0;
00206                         break;
00207     }
00208   case(19200) :
00209     {
00210                         writeshort (SCI_SCCR0, 27);
00211    res = 0;
00212                         break;
00213     }
00214   case(28800) :
00215   {
00216                         writeshort (SCI_SCCR0, 18);
00217    res = 0;
00218                         break;
00219   }
00220   case(38400) :
00221     {
00222                         writeshort (SCI_SCCR0, 14);
00223    res = 0;
00224                         break;
00225     }
00226          case(57600) :
00227     {
00228                         writeshort (SCI_SCCR0, 9);
00229    res = 0;
00230                         break;
00231     }
00232  }
00233  return(res);
00234 }
00235 
00236 
00237 void _QSM_sci_setrts (int how)
00238 {
00239         return;
00240 };
00241 
00242 
00243 
00244 //void TTY_soutchar (char byte)
00245 //{
00246 //      struct iobuf *sci_out;
00247 //
00248 //      sci_out = _QSM_sci_tty->outq;
00249 //      disable ();
00250 //
00251 //      if (TTY_Blocking_Serial_Out) {
00253 //              writeshort (SCI_SCCR1, readshort (SCI_SCCR1) & 0xff7f);
00254 //              while (sci_out->cnt > 0) {
00255 //                      while (!(readshort (SCI_SCSR) & 0x100));
00256 //                      writeshort (SCI_SCDR, ((unsigned short) sci_out->data[sci_out->tail]) & 0xff);
00257 //                      sci_out->tail = (sci_out->tail + 1) % sci_out->buflen;
00258 //                      sci_out->cnt--;
00259 //              }
00260 //              while (!(readshort (SCI_SCSR) & 0x100));
00261 //              writeshort (SCI_SCDR, ((unsigned short) byte) & 0xff);
00262 //      } else {
00263 //
00264 //              if (sci_out->cnt == sci_out->buflen) {
00265 //                      enable ();
00266 //                      return;
00267 //              }               /* Ignore overflow */
00268 //              sci_out->data[sci_out->head] = byte;
00269 //              sci_out->head = (sci_out->head + 1) % sci_out->buflen;
00270 //              sci_out->cnt++;
00271 //
00272 //              /* enable pending transmitter interrupt */
00273 //              if (sci_out->cnt == 1)
00274 //                      writeshort (SCI_SCCR1, readshort (SCI_SCCR1) | 0x80);
00275 //
00276 //      }
00277 //      enable ();
00278 //
00279 //}
00280 
00281 
00282 void QSM_sciinit (struct TTY_tty_dev *TTY_tty)
00283 {
00284 //      short v;
00285 
00286         _QSM_sci_int_count = 0x42;
00287         _QSM_sci_tty = TTY_tty;
00288 
00289         iobuf_init (_QSM_sci_tty->inq, BUFLEN);
00290         iobuf_init (_QSM_sci_tty->outq, BUFLEN);
00291 
00292         _QSM_sci_tty->txchar = _QSM_sci_txbyte;
00293         _QSM_sci_tty->en_tx_irq = _QSM_sci_en_tx;
00294         _QSM_sci_tty->dis_tx_irq = _QSM_sci_dis_tx;
00295         _QSM_sci_tty->en_rx_irq = _QSM_sci_en_rx;
00296         _QSM_sci_tty->dis_rx_irq = _QSM_sci_dis_rx;
00297         _QSM_sci_tty->sethandshake = _QSM_sci_sethandshake;
00298         _QSM_sci_tty->setbps = _QSM_sci_setbps;
00299         _QSM_sci_tty->setrts = _QSM_sci_setrts;
00300         _QSM_sci_tty->hsmode = TTY_HS_NONE;
00301         _QSM_sci_tty->mode = 0;
00302         _QSM_sci_tty->state = 0;
00303         _QSM_sci_tty->char_process = NULL;
00304         _QSM_sci_tty->break_process = NULL;
00305 
00306         QSM_init ();
00307 
00308         writeshort (SCI_SCCR0, 9);      /* 58200 baud @ 16.77MHz */
00309         /* Bit12..0: SCBR  (baud rate divider 1 = 1/32(CK)) */
00310         writeshort (SCI_SCCR1, 0x002c);
00311         /* 
00312            Bit14: LOOPS (feedback loop mode)
00313            Bit13: WOMS  (TXD in wired-or mode)
00314            Bit12: ILT   (idle line detect type [long,short])
00315            Bit11: PT    (parity type [odd,even])
00316            Bit10: PE    (parity enable)
00317            Bit9 : M     (mode select: [9,8] data bits)
00318            Bit8 : WAKE  (wake up by address mark)
00319            Bit7 : TIE   (transmit interupt enable)
00320            Bit6 : TCIE  (transmit complete interupt enable)
00321            *Bit5 : RIE   (receiver interupt enable)
00322            Bit4 : ILIE  (idle line interupt enable)
00323            *Bit3 : TE    (transmitter enable)
00324            *Bit2 : RE    (receiver enable)
00325            Bit1 : RWU   (call receiver wakeup function)
00326            Bit0 : SBK   (send break)
00327          */
00328 //      v=readshort(SCI_SCSR);
00329         //      writeshort(SCI_SCDR,'?');
00330         //      v=readshort(SCI_SCSR);
00331         //      v=readshort(SCI_SCDR);
00332 
00333 
00334 }

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