Main Page Data Structures File List Data Fields Globals Related Pages

# clib/fossil.c

Go to the documentation of this file.

    00001 /****************************************************************************
    00002 *
    00003 * (C) 2001 by Beck IPC GmbH
    00004 *
    00005 *
    00006 *
    00007 *
    00008 * Beck IPC GmbH
    00009 * Garbenheimerstr. 36-38
    00010 * D-35578 Wetzlar
    00011 * http://www.beck-ipc.com/chip
    00012 *
    00013 * ---------------------------------------------------------------------------
    00014 * Module    : IPC@CHIP SC12 API: fossil.c
    00015 *             Fossil interface, accessing the serial devices of the SC12
    00016 *        Use memory model large!!
    00017 *
    00018 * Author    : Detlef Gerhardt
    00019 * Date      : 20.01.01
    00020 * ---------------------------------------------------------------------------
    00021 $Header: fossil.c, 12, 13.06.2002 16:29:11, Christoph Stoidner$
    00022
    00023 $Log:
    00024  3    IPC@CHIP  1.2         12.03.01 13:20:34    Christoph Stoidner Changed
    00025       Interrupt call in write block function. ("int86" to "int86x" to comitt the
    00026       segment registers, too)
    00027  2    IPC@CHIP  1.1         09.03.01 15:37:31    Christoph Stoidner removed
    00028       printf call from WriteBlock function
    00029  1    IPC@CHIP  1.0         09.03.01 15:35:57    Christoph Stoidner
    00030 $
    00031
    00032
    00033 * History   :
    00034 *
    00035 *  Vx.yy          Author  Changes
    00036 *
    00037 *             10.01.01      dg    Create
    00038 *             14.01.01      dg    Bugfix in fossil_setbaud,
    00039 *                 ext. baudrates and line-control
    00040 *             27.01.01      dg    bugfix in fossil_setbaud()
    00041 *                 baudrates now up to 115000 bps
    00042               10.01.02      cs      correct comments
    00043                                     add GetDriverInfo function
    00044                                     add FOSSILVECT define
    00045 *
    00046 *****************************************************************************/
    00047
    00048 #include <dos.h>
    00049 #include <stdio.h>
    00050 #include "fossil.h"
    00051
    00052 #define FOSSILVECT 0x14
    00053
    00054 /*****************************************************************************
    00055 *
    00056 * initialize fossil interface
    00057 *
    00058 * port = 1: COM
    00059 * port = 0: EXT
    00060 * return = 0x1954: success
    00061 * return = 0: error
    00062 */
    00063
    00064 int fossil_init(int port)
    00065 {
    00066   union REGS inregs;
    00067   union REGS outregs;
    00068
    00069   inregs.h.ah = 0x04;
    00070   inregs.x.dx = port;
    00071   int86(FOSSILVECT,&inregs,&outregs);
    00072   if (outregs.x.ax==0x1954) return outregs.x.ax;
    00073
    00074    return 0;
    00075 } // fossil_init()
    00076
    00077
    00078
    00079 /*****************************************************************************
    00080 *
    00081 * Deinitialize fossil interface
    00082 *
    00083 * port = 1: COM
    00084 * port = 0: EXT
    00085 */
    00086
    00087 void fossil_deinit(int port)
    00088 {
    00089   union REGS inregs;
    00090   union REGS outregs;
    00091
    00092   inregs.h.ah = 0x05;
    00093   inregs.x.dx = port;
    00094   int86( FOSSILVECT, &inregs, &outregs);
    00095 } // fossil_deinit()
    00096
    00097
    00098
    00099 /*****************************************************************************
    00100 *
    00101 * Set baudrate
    00102 *
    00103 * standard values:
    00104 * port = 1: COM
    00105 * port = 0: EXT
    00106 * baudrate = 300,600,1200,2400,4800,9600,19200,38400
    00107 * parity: 0=non, 1=odd, 2=even, 3=mark, 4=space
    00108 * wordlen = 7,8
    00109 * stopbits = 1,2
    00110 * return = status (see fossil_status_request)
    00111 *
    00112 * extended values:
    00113 * baudrate = any values <= 115200
    00114 * parity: 0=non, 1=odd, 2=even, 3=mark, 4=space
    00115 *
    00116 * comment: 2 stop bits are only available if no parity is set
    00117 */
    00118
    00119 int fossil_setbaud(int port, long baudrate, int parity, int wordlen, int stopbits)
    00120 {
    00121   union REGS inregs;
    00122   union REGS outregs;
    00123   long baudtab[8] = {19200l,38400l,300l,600l,1200l,2400l,4800l,9600l};
    00124   int baud_idx;
    00125   long baud_max,baud_div;
    00126
    00127    // check parameters
    00128    for (baud_idx=0; baud_idx<=7; baud_idx++)
    00129    {
    00130      if (baudrate==baudtab[baud_idx]) break;
    00131    }
    00132
    00133    // init port
    00134    if (baud_idx<=7)
    00135    {
    00136      // use function 0x00 for baudrates smaller 38400
    00137
    00138      if (parity<0 || parity>2) return -1;
    00139      if (parity==2) parity = 3;
    00140     if (wordlen<7 || wordlen>8) return -1;
    00141     wordlen = wordlen - 5;
    00142      if (stopbits<1 || stopbits>2) return -1;
    00143     stopbits--;
    00144
    00145     inregs.h.ah = 0x00;
    00146     inregs.h.al = wordlen + (stopbits<<2) + (parity<<3) + (baud_idx<<5);
    00147      inregs.x.dx = port;
    00148     int86(0x14,&inregs,&outregs);
    00149    } // if (baud_idx<=7)
    00150    else
    00151    {
    00152      // use extended line control init for other baudrates
    00153      if (parity<0 || parity>4) return -1;
    00154      if (wordlen<7 || wordlen>8) return -1;
    00155
    00156      // calculate divider value
    00157     // get max. baudrate value
    00158      inregs.h.ah = 0x8A;
    00159     inregs.h.al = 2;  // mode: maximum baud rate
    00160     int86(0xA1,&inregs,&outregs);
    00161     baud_max = (long) outregs.x.ax + ((long) outregs.x.dx << 16);
    00162
    00163     // calc divider with integer rounding
    00164     baud_div = baud_max*10l / baudrate;
    00165     if ((baud_div % 10l) < 5l) baud_div = baud_max / baudrate;
    00166     else baud_div = baud_max / baudrate + 1;
    00167
    00168     inregs.x.cx = (unsigned int) baud_div;
    00169     inregs.h.ah = 0x81; // Extended line control initialization
    00170     inregs.h.al = wordlen - 5;
    00171     inregs.h.bh = parity;
    00172     inregs.h.bl = stopbits - 1;
    00173     inregs.x.dx = port;
    00174     inregs.x.cx = (unsigned int) baud_div;
    00175     int86(0x14,&inregs,&outregs);
    00176
    00177      // get status of port
    00178      inregs.h.ah = 0x03;
    00179      inregs.x.dx = port;
    00180      int86(0x14,&inregs,&outregs);
    00181    } // else (baud_idx<=7)
    00182   return outregs.h.ah;
    00183 } // fossil_setbaud()
    00184
    00185 /****************************************************************************/
    00186 //
    00187 // Put byte in output buffer (with wait)
    00188 //
    00189 // port = 1: COM
    00190 // port = 0: EXT
    00191 // ch: byte to send
    00192 // return = status (see fossil_status_request)
    00193
    00194 int fossil_putbyte_wait(int port, int ch)
    00195 {
    00196   union REGS inregs;
    00197   union REGS outregs;
    00198
    00199   inregs.h.ah = 0x01;
    00200   inregs.h.al = (char)ch;
    00201   inregs.x.dx = port;
    00202   int86( FOSSILVECT, &inregs, &outregs);
    00203   return outregs.h.ah;
    00204
    00205 } // fossil_putbyte_wait()
    00206
    00207
    00208 /****************************************************************************/
    00209 //
    00210 // Put byte in output buffer (without wait)
    00211 //
    00212 // port = 1: COM
    00213 // port = 0: EXT
    00214 // ch: byte to send
    00215 // return = 1: byte accepted
    00216 // return = 0: byte not accepted (output buffer full)
    00217 int fossil_putbyte(int port, int ch)
    00218 {
    00219   union REGS inregs;
    00220   union REGS outregs;
    00221
    00222   inregs.h.ah = 0x0B;
    00223   inregs.h.al = (char)ch;
    00224   inregs.x.dx = port;
    00225   int86( FOSSILVECT, &inregs, &outregs);
    00226   return outregs.x.ax;
    00227
    00228 } // fossil_putbyte()
    00229
    00230
    00231 /****************************************************************************/
    00232 //
    00233 // Get byte from input buffer (with wait)
    00234 //
    00235 // port = 1: COM
    00236 // port = 0: EXT
    00237 // return = received byte
    00238 int fossil_getbyte_wait(int port)
    00239 {
    00240   union REGS inregs;
    00241   union REGS outregs;
    00242
    00243   inregs.h.ah = 0x02;
    00244   inregs.x.dx = port;
    00245   int86( FOSSILVECT, &inregs, &outregs);
    00246   return (int)outregs.h.al;
    00247 } // fossil_getbyte_wait()
    00248
    00249
    00250 /****************************************************************************/
    00251 //
    00252 // Peek if next byte is available (without removing it from input buffer)
    00253 //
    00254 // port = 1: COM
    00255 // port = 0: EXT
    00256 // return = received byte
    00257 // return = -1: no byte available
    00258 int fossil_peek_input(int port)
    00259 {
    00260   union REGS inregs;
    00261   union REGS outregs;
    00262
    00263   inregs.h.ah = 0x0C;
    00264   inregs.x.dx = port;
    00265   int86( FOSSILVECT, &inregs, &outregs);
    00266    if (outregs.x.ax==0xFFFF) return -1; // no data available
    00267
    00268    return (int)outregs.h.al;
    00269 } // fossil_peek_input()
    00270
    00271
    00272 /****************************************************************************/
    00273 //
    00274 // Status request
    00275 //
    00276 // port = 1: COM
    00277 // port = 0: EXT
    00278 // return = status
    00279 // bit 6: set if output buffer is empty.
    00280 // bit 5: set if output buffer is not full.
    00281 // bit 4: line break detected
    00282 // bit 3: framing error detected
    00283 // bit 2: parity error detected
    00284 // bit 1: set if overrun occured on receiver.
    00285 // bit 0: set if data is available in receiver buffer.
    00286 int fossil_status_request(int port)
    00287 {
    00288   union REGS inregs;
    00289   union REGS outregs;
    00290
    00291   inregs.h.ah = 0x03;
    00292   inregs.x.dx = port;
    00293   int86( FOSSILVECT, &inregs, &outregs);
    00294   return outregs.h.ah;
    00295 } // fossil_status_request()
    00296
    00297
    00298 /****************************************************************************/
    00299 //
    00300 // Flush output buffer (with wait)
    00301 //
    00302 // port = 1: COM
    00303 // port = 0: EXT
    00304 // return = none
    00305 void fossil_flush_output(int port)
    00306 {
    00307   union REGS inregs;
    00308   union REGS outregs;
    00309
    00310   inregs.h.ah = 0x08;
    00311   inregs.x.dx = port;
    00312   int86( FOSSILVECT, &inregs, &outregs);
    00313 } // fossil_flush_output()
    00314
    00315
    00316 /****************************************************************************/
    00317 //
    00318 // Purge output buffer
    00319 //
    00320 // port = 1: COM
    00321 // port = 0: EXT
    00322 // return = none
    00323 void fossil_purge_output(int port)
    00324 {
    00325   union REGS inregs;
    00326   union REGS outregs;
    00327
    00328   inregs.h.ah = 0x09;
    00329   inregs.x.dx = port;
    00330   int86( FOSSILVECT, &inregs, &outregs);
    00331 } // fossil_purge_output()
    00332
    00333
    00334 /****************************************************************************/
    00335 //
    00336 // Purge input buffer
    00337 //
    00338 // port = 1: COM
    00339 // port = 0: EXT
    00340 // return = none
    00341 void fossil_purge_input(int port)
    00342 {
    00343   union REGS inregs;
    00344   union REGS outregs;
    00345
    00346   inregs.h.ah = 0x0A;
    00347   inregs.x.dx = port;
    00348   int86( FOSSILVECT, &inregs, &outregs);
    00349 } // fossil_purge_input()
    00350
    00351
    00352 /****************************************************************************/
    00353 //
    00354 // Enable/disable flow control
    00355 //
    00356 // port = 1: COM
    00357 // port = 0: EXT
    00358 // flowcontrol:
    00359 // 0: XON/XOFF on transmit (watch for XOFF while sending)
    00360 // 1: RTS/CTS (CTS on transmit/RTS on receive)
    00361 // 2: reserved
    00362 // 3: XON/XOFF on receive (send XOFF when buffer near full)
    00363 // 4-7: ignored
    00364 // both XON/XOFF and CTS/RTS is not allowed at the same time.
    00365 // XON/XOFF mode is only available, if serialdma access is disabled at chip.ini
    00366 //
    00367 // return = none
    00368 void fossil_set_flowcontrol(int port, int flowctrl)
    00369 {
    00370   union REGS inregs;
    00371   union REGS outregs;
    00372
    00373   inregs.h.ah = 0x0F;
    00374   inregs.h.al = flowctrl;
    00375   inregs.x.dx = port;
    00376   int86( FOSSILVECT, &inregs, &outregs);
    00377 } // fossil_set_flowcontrol()
    00378
    00379
    00380 /****************************************************************************/
    00381 //
    00382 // Read block from input buffer
    00383 //
    00384 // port = 1: COM
    00385 // port = 0: EXT
    00386 // buffer: pointer to buffer for input data
    00387 // count: maximum number of bytes to transfer.
    00388 //
    00389 // return = number of bytes transfered
    00390 unsigned int fossil_readblock(int port, unsigned char *buffer, unsigned int count)
    00391 {
    00392   struct SREGS sregs;
    00393   union REGS inregs;
    00394   union REGS outregs;
    00395
    00396   inregs.h.ah = 0x18;
    00397   inregs.x.cx = count;
    00398   inregs.x.dx = port;
    00399   sregs.es    = FP_SEG(buffer);
    00400   inregs.x.di = FP_OFF(buffer);
    00401   int86x( FOSSILVECT, &inregs, &outregs, &sregs);
    00402    return (unsigned int)outregs.x.ax;
    00403 } // fossil_readblock()
    00404
    00405
    00406 /****************************************************************************/
    00407 //
    00408 // Write block to output buffer
    00409 //
    00410 // port = 1: COM
    00411 // port = 0: EXT
    00412 // buffer: pointer to buffer for output data
    00413 // count: maximum number of bytes to transfer
    00414 //
    00415 // return = actual number of bytes to transfer (may be limited by space in output buffer)
    00416 unsigned int fossil_writeblock(int port, unsigned char *buffer, unsigned int count)
    00417 {
    00418   struct SREGS sregs;
    00419   union REGS inregs;
    00420   union REGS outregs;
    00421
    00422   inregs.h.ah = 0x19;
    00423   inregs.x.cx = count;
    00424   inregs.x.dx = port;
    00425   sregs.es    = FP_SEG(buffer);
    00426   inregs.x.di = FP_OFF(buffer);
    00427   int86x( FOSSILVECT, &inregs, &outregs, &sregs);
    00428   return outregs.x.ax;
    00429 } // fossil_writeblock()
    00430
    00431
    00432 /****************************************************************************/
    00433 //
    00434 // Set RS485 mode
    00435 //
    00436 // port = 1: COM
    00437 // port = 0: EXT
    00438 // mode =
    00439 //    0: TxEnable low active
    00440 //    1: TxEnable high active
    00441 //    2: Disable RS485 mode
    00442 //
    00443 // return = none
    00444 //
    00445 // Comment: By default the RTS0 and RTS1 signal (pin) is used to enable/disable the
    00446 // transmitter (TxEnable)
    00447 void fossil_set_rs485(int port, int mode)
    00448 {
    00449   union REGS inregs;
    00450   union REGS outregs;
    00451
    00452   inregs.h.ah = 0x80;
    00453   inregs.h.al = mode;
    00454   inregs.x.dx = port;
    00455   int86( FOSSILVECT, &inregs, &outregs);
    00456
    00457 } // fossil_set_rs485()
    00458
    00459
    00460 /****************************************************************************/
    00461 //
    00462 // Set RS485 transmitter enable pin
    00463 //
    00464 // port = 1: COM
    00465 // port = 0: EXT
    00466 // pin = 0..13
    00467 //
    00468 // return = none
    00469 //
    00470 // Comment: By default the RTS0 and RTS1 signal (pin) is used to enable/disable
    00471 // the transmitter. (TxEnable)
    00472 // To change the default, call this function before you call the RS485 Enable function.
    00473 // This function let's you select any PIO from 0-13 as TxEnable, but not any makes sense.
    00474 void fossil_set_rs485_txenable(int port, int pin)
    00475 {
    00476   union REGS inregs;
    00477   union REGS outregs;
    00478
    00479   inregs.h.ah = 0x82;
    00480   inregs.h.al = pin;
    00481   inregs.x.dx = port;
    00482   int86( FOSSILVECT, &inregs, &outregs);
    00483 } // fossil_set_rs485_txenable()
    00484
    00485
    00486 /****************************************************************************/
    00487 //
    00488 // Extended line control initialization
    00489 //
    00490 // port = 1: COM
    00491 // port = 0: EXT
    00492 // baud_divider: baudrate divider (for maximum baudrate see HAL function 0x8A)
    00493 // parity =
    00494 //    0: no parity
    00495 //   1: odd parity
    00496 //   2: even parity
    00497 //   3: mark parity (always 1)
    00498 //   4: space parity (always 0)
    00499 // wordlen = 7,8
    00500 // stopbits = 1,2
    00501 //
    00502 // return = none
    00503 void fossil_set_extctrl(int port, int baud_divider, int parity, int wordlen, int stopbits)
    00504 {
    00505   union REGS inregs;
    00506   union REGS outregs;
    00507
    00508   if (parity<0 || parity>4) return;
    00509   if (wordlen<7 || wordlen>8) return;
    00510   if (stopbits<1 || stopbits>2) return;
    00511
    00512   inregs.h.ah = 0x81;
    00513   inregs.h.al = wordlen-5;
    00514    inregs.h.bh = parity;
    00515   inregs.h.bl = stopbits-1;
    00516   inregs.x.cx = baud_divider;
    00517   inregs.x.dx = port;
    00518   int86( FOSSILVECT, &inregs, &outregs);
    00519 } // fossil_set_rs485_txenable()
    00520
    00521
    00522
    00523 /****************************************************************************/
    00524 //
    00525 // Get Driver Info
    00526 //
    00527 // port = 1: COM
    00528 // port = 0: EXT
    00529 // drv_info: driver Infos
    00530 //
    00531 // return = Number of bytes actually transfered
    00532 int fossil_get_driver_info(int port, FossilDriverInfo_t *drv_info)
    00533 {
    00534   union  REGS  inregs;
    00535   union  REGS  outregs;
    00536    struct SREGS segregs;
    00537
    00538   inregs.h.ah = 0x1B;
    00539   inregs.x.cx = sizeof(FossilDriverInfo_t);
    00540   inregs.x.dx = port;
    00541    segregs.es  = FP_SEG(drv_info);
    00542    inregs.x.di = FP_OFF(drv_info);
    00543   int86( FOSSILVECT, &inregs, &outregs);
    00544
    00545    return outregs.x.ax;
    00546 } // fossil_get_driver_info()
    00547
    00548 /*****************************************************************************
    00549 *
    00550 * send Break
    00551 *
    00552 * port = 1: COM
    00553 * port = 0: EXT
    00554   longbreak =
    00555      0: short break
    00556      1: long break
    00557 * return none
    00558 */
    00559
    00560 void fossil_send_break(int port, unsigned char longbreak )
    00561 {
    00562   union REGS inregs;
    00563
    00564   inregs.h.ah = 0x83;
    00565    inregs.h.al = longbreak;
    00566   inregs.x.dx = port;
    00567   int86(FOSSILVECT,&inregs,&outregs);
    00568    return;
    00569 } // fossil_init()
    00570
    00571
    00572 /*****************************************************************************
    00573 *
    00574 * get number or bytes currently in UART
    00575 *
    00576 * port = 1: COM
    00577 * port = 0: EXT
    00578 * return = number of bytes in UART
    00579 */
    00580
    00581 int fossil_get_bytes_in_uart(int port)
    00582 {
    00583   union REGS inregs;
    00584   union REGS outregs;
    00585
    00586   inregs.h.ah = 0xA0;
    00587   inregs.x.dx = port;
    00588   int86(FOSSILVECT,&inregs,&outregs);
    00589    return outregs.x.ax;
    00590 } // fossil_init()
    00591
    00592
    00593 /****************************************************************************/
    00594 // end of file
    00595 /****************************************************************************/
    00596