home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: OtherApp / OtherApp.zip / wincam.zip / winc_src.zip / comms.c < prev    next >
Text File  |  1997-03-01  |  10KB  |  440 lines

  1. /*
  2.  *
  3.  * device specific code.  with any luck, when porting to a new
  4.  * platform, this may be the only module that needs changing.
  5.  *
  6.  * Copyright (C) 1996, Paul G. Fox
  7.  *
  8.  * This program is free software; you can redistribute it and/or modify it
  9.  * under the terms of the GNU General Public License as published by the
  10.  * Free Software Foundation; either version 2 of the License, or (at your
  11.  * option) any later version.
  12.  * 
  13.  * This program is distributed in the hope that it will be useful, but
  14.  * WITHOUT ANY WARRANTY; without even the implied warranty of
  15.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  16.  * General Public License for more details.
  17.  * 
  18.  * You should have received a copy of the GNU General Public License along
  19.  * with this program; if not, write to the Free Software Foundation, Inc.,
  20.  * 675 Mass Ave, Cambridge, MA 02139, USA.
  21.  *
  22.  * This software was created with the help of proprietary information
  23.  * belonging to StarDot Technologies.
  24.  *
  25.  * $Header: E:/winc/RCS/comms.c 1.1 1997/03/01 03:44:14 Derek Exp Derek $
  26.  */
  27.  
  28. #define INCL_DOSFILEMGR
  29. #define INCL_DOSDEVIOCTL
  30. #define INCL_DOSDEVICES
  31.  
  32. #include <os2.h>
  33.  
  34.  
  35. #include <stdlib.h>
  36. #include <unistd.h>
  37. #include <string.h>
  38. #include <errno.h>
  39. #include <fcntl.h>
  40. #include <signal.h>
  41. #include <sys/time.h>
  42. #include <sys/types.h>
  43. #include <sys/ioctl.h>
  44. #include <signal.h>
  45. #include "private.h"
  46. #include "trace.h"
  47.  
  48. /* static int comms_token2index(speed_t token); */
  49. /* static int comms_rate2index(int rate); */
  50.  
  51. static DCBINFO CommInfo;
  52.  
  53. static int
  54. get_input_fd(int ofd)
  55. {
  56.     return ofd;
  57. }
  58.  
  59. /* 
  60.  * static jmp_buf timed_read_jmpbuf;
  61.  *
  62.  * static void
  63.  * alarmcatcher(int sig)
  64.  * {
  65.  *   (void) signal(SIGALRM, alarmcatcher);
  66.  *   longjmp(timed_read_jmpbuf, 1);
  67.  * }
  68.  */
  69.  
  70. /*
  71.  * initialize the camera's serial port
  72.  */
  73. result
  74. comms_initialize_port( cam_t cam )
  75. {
  76.    APIRET rc;
  77.    ULONG ulAction;
  78.    LINECONTROL linctrl;
  79.    ULONG ulParmLen;
  80.     
  81.     TRACE("ac",__FILE__ ": opening %s\n", cam->ttyname);
  82.  
  83.     rc = DosOpen(cam->ttyname,
  84.                  &cam->ofd,
  85.                  &ulAction,
  86.                  0,
  87.                  FILE_NORMAL,
  88.                  FILE_OPEN,
  89.                  OPEN_ACCESS_READWRITE | OPEN_SHARE_DENYREADWRITE,
  90.                  (PEAOP2) NULL);
  91.  
  92.  
  93.     if (rc != 0) {
  94.     errormsg(__FILE__ ": couldn't open tty %s\n", cam->ttyname);
  95.     return NotOK;
  96.     }
  97.  
  98.     cam->ifd = get_input_fd(cam->ofd);
  99.     if (cam->ifd == -1) {
  100.     errormsg(__FILE__ ": couldn't re-open tty %s\n", cam->ttyname);
  101.     close(cam->ofd);
  102.     return NotOK;
  103.     }
  104.  
  105.    /* disable parity, both in and out */
  106.    /* two stop bits on transmit */
  107.    /* no modem control, 8bit chars, */
  108.    /* receiver enabled, */
  109.    /* ignore break, ignore parity errors */
  110.  
  111.    ulParmLen = 4;
  112.    linctrl.bDataBits = 8;
  113.    linctrl.bParity = 0;
  114.    linctrl.bStopBits = 2;
  115.    linctrl.fTransBreak = 0;
  116.  
  117.    rc = DosDevIOCtl(cam->ofd,
  118.                     IOCTL_ASYNC,
  119.                     ASYNC_SETLINECTRL,
  120.                     (PULONG) &linctrl,
  121.                     sizeof(linctrl),
  122.                     (PULONG) &ulParmLen,
  123.                     (PULONG) NULL,
  124.                     0,
  125.                     (PULONG) NULL);
  126.    rc = DosDevIOCtl(cam->ofd,
  127.                     IOCTL_ASYNC,
  128.                     ASYNC_SETLINECTRL,
  129.                     (PULONG) &linctrl,
  130.                     sizeof(linctrl),
  131.                     (PULONG) &ulParmLen,
  132.                     (PULONG) NULL,
  133.                     0,
  134.                     (PULONG) NULL);
  135.    rc = DosDevIOCtl(cam->ofd,
  136.                     IOCTL_ASYNC,
  137.                     ASYNC_SETLINECTRL,
  138.                     (PULONG) &linctrl,
  139.                     sizeof(linctrl),
  140.                     (PULONG) &ulParmLen,
  141.                     (PULONG) NULL,
  142.                     0,
  143.                     (PULONG) NULL);
  144.  
  145.     if (rc != 0) {
  146.     comms_close_port(cam);
  147.     return NotOK;
  148.     }
  149.  
  150.     /* Fill out the CommInfo DCBINFO block - we'll need this for */
  151.     /* setting the timeouts for reads                            */
  152.  
  153.     rc = DosDevIOCtl(cam->ofd,
  154.                      IOCTL_ASYNC,
  155.                      ASYNC_GETDCBINFO,
  156.                      (PULONG) NULL,
  157.                      0,
  158.                      (PULONG) NULL,
  159.                      (PULONG) &CommInfo,
  160.                      sizeof(CommInfo),
  161.                      (PULONG) &ulParmLen);
  162.  
  163.     if (rc != 0) {
  164.     comms_close_port(cam);
  165.     return NotOK;
  166.     }
  167.     return OK;
  168. }
  169.  
  170.  
  171. /*
  172.  * close the camera's serial port.
  173.  */
  174. void
  175. comms_close_port(cam_t cam)
  176. {
  177.    APIRET rc; 
  178.  
  179.     TRACE("ac",__FILE__ ": closing %s\n", cam->ttyname);
  180.     rc = DosClose(cam->ifd);
  181.     rc = DosClose(cam->ofd);
  182. }
  183.  
  184. /*
  185.  * the bauds[] table is a mapping of system baudrate tokens to
  186.  * bits/sec values.
  187.  */
  188. struct {
  189.     speed_t token;
  190.     int integer;
  191. } bauds[] = {
  192.     {0x0013,    460800},
  193.     {0x0012,    230400},
  194.     {0x0011,    115200},
  195.     {0x0010,    57600},
  196.     {B38400,    38400},
  197.     {B19200,    19200},
  198.     {B9600,    9600},
  199.     {B4800,    4800},
  200.     {B2400,    2400},
  201.     {B1200,    1200},
  202. };
  203. #define NUMBAUDS (sizeof(bauds)/sizeof(bauds[0]))
  204.  
  205. /*
  206.  * convert a baudrate, represented by a token,
  207.  * to an index in the bauds[] table.
  208.  */
  209. /* int
  210.  * comms_token2index(speed_t token)
  211.  * {
  212.  *   int i = 0;
  213.  *   while (i < NUMBAUDS && token != bauds[i].token)
  214.  *    i++;
  215.  *
  216.  *   if (i == NUMBAUDS)
  217.  *    return -1;
  218.  *
  219.  *   return i;
  220.  * }
  221.  */
  222. /*
  223.  * convert a baudrate, in bits/sec,
  224.  * to an index in the bauds[] table.
  225.  */
  226. /* int
  227.  * comms_rate2index(int rate)
  228.  * {
  229.  *   int i = 0;
  230.  *   while (i < NUMBAUDS && rate < bauds[i].integer)
  231.  *    i++;
  232.  *
  233.  *   
  234.  *   if (i == NUMBAUDS)
  235.  *    return NUMBAUDS - 1;
  236.  *
  237.  *    return i;
  238.  * }
  239.  */
  240. /*
  241.  * return the actual baudrate corresponding to an index
  242.  */
  243. /* int 
  244.  * comms_index2rate(int bindex)
  245.  * {
  246.  *   return bauds[bindex].integer;
  247.  * }
  248.  */
  249. /*
  250.  * choose the baud rate equal or less than the configured default,
  251.  * and return its index.
  252.  */
  253. int
  254. comms_first_baud(void)
  255. {
  256.     int wantbaud;
  257.  
  258.     /* the following default be at least as fast as the fastest in table */
  259.     wantbaud = cfg_number(winc_configvar("WinCamBaudRate", "115200"));
  260.     return wantbaud;
  261. }
  262.  
  263. /*
  264.  * given a baudrate index, return index of next, or -1 if there are no more
  265.  */
  266. int 
  267. comms_next_baud(int bindex)
  268. {
  269.     if (bindex < NUMBAUDS-1)
  270.     return ++bindex;
  271.     return -1;
  272. }
  273.  
  274. /*
  275.  * set port to given baud, based on index to bauds[] array 
  276.  */
  277. result
  278. comms_set_baud(cam_t cam, int rate)
  279. {
  280.   APIRET rc;
  281.   ULONG ulParmLen;
  282.   ULONG usBPS;
  283.  
  284.  
  285.    ulParmLen = 2;
  286.    usBPS = rate;
  287.    TRACE("ac", __FILE__ ": baud rate (%ld): \n", usBPS);
  288.  
  289.    if(usBPS <= 19200)
  290.     {
  291.       rc = DosDevIOCtl(cam->ofd,
  292.                        IOCTL_ASYNC,
  293.                        ASYNC_SETBAUDRATE,
  294.                        (PULONG) &usBPS,
  295.                        ulParmLen,
  296.                        (PULONG) &ulParmLen,
  297.                        (PULONG) NULL,
  298.                        0,
  299.                        (PULONG) NULL);
  300.     }
  301.    else
  302.     {
  303.       ulParmLen = 4;
  304.       rc = DosDevIOCtl(cam->ofd,
  305.                        IOCTL_ASYNC,
  306.                        ASYNC_EXTSETBAUDRATE,
  307.                        (PULONG) &usBPS,
  308.                        ulParmLen,
  309.                        (PULONG) &ulParmLen,
  310.                        (PULONG) NULL,
  311.                        0,
  312.                        (PULONG) NULL);
  313.     }
  314.  
  315.     if(rc != 0)
  316.        {
  317.     TRACE("ac", __FILE__ ": couldn't set baud rate (%d): %d\n",
  318.         rate, errno);
  319.     return NotOK;
  320.     }
  321.     cam->baud_index = rate;
  322.     return OK;
  323. }
  324.  
  325. /*
  326.  * sets camera to given baud rate 
  327.  */
  328. int
  329. winc_set_baud(cam_t cam, int rate)
  330. {
  331.     TRACE("ac",__FILE__ ": setting baud rate %d\n", rate);
  332.     return comms_set_baud(cam, rate);
  333. }
  334.  
  335. /*
  336.  * gets camera's current baud rate 
  337.  */
  338. int
  339. winc_get_baud(cam_t cam)
  340. {
  341.     return (cam->baud_index);
  342. }
  343.  
  344. /*
  345.  * read a buffer's worth of chars from the camera, taking at
  346.  * with a guaranteed maximum timeout.
  347.  */
  348. int
  349. comms_timed_read(cam_t cam, char *buf, int len, int millisec)
  350. {
  351.  
  352.         USHORT sec;
  353.     int ret, totret = 0;
  354.     int cps;
  355.         ULONG bytesread;
  356.         ULONG ulParmLen;
  357.  
  358.     sec = (millisec + 999)/1000;
  359.     cps = cam->baud_index/10; /* assume 10 bits/char */
  360.     CommInfo.usReadTimeout = (sec + (len/cps + 1)) * 100;
  361.         CommInfo.fbTimeout     = 0xD4;     /* SIO defaults + MODE_WAIT_READ_TIMEOUT */
  362.         DosDevIOCtl(cam->ofd,
  363.                     IOCTL_ASYNC,
  364.                     ASYNC_SETDCBINFO,
  365.                     (PULONG) &CommInfo,
  366.                     sizeof(CommInfo),
  367.                     (PULONG) &ulParmLen,
  368.                     (PULONG) NULL,
  369.                     0,
  370.                     (PULONG) NULL);
  371.  
  372.     while(totret < len)
  373.          {
  374.         ret = DosRead(cam->ifd, buf + totret, len - totret, &bytesread);
  375.         if (ret == -1)
  376.              {
  377.         errormsg(__FILE__ ": read failed: %s\n", strerror(errno));
  378.         totret = -1;
  379.         break;
  380.          }
  381.             else if (bytesread == 0)
  382.              {
  383.                    TRACE("ac", __FILE__ ": timeout waiting for response\n");
  384.             return -2;
  385.              }
  386.  
  387.         totret += bytesread;
  388.      }
  389.     return totret;
  390. }
  391.  
  392. /*
  393.  * comms_write:  send content of buffer to camera
  394.  */
  395. int
  396. comms_write(cam_t cam, char *buf, int n)
  397. {
  398.     ULONG byteswritten; 
  399.  
  400.     return DosWrite(cam->ofd, buf, n, &byteswritten);
  401. }
  402.  
  403.  
  404. result
  405. comms_send_break(cam_t cam, int milli)
  406. {
  407.   APIRET rc;
  408.   ULONG  packet;
  409.   ULONG  ulParmLen;
  410.  
  411.       TRACE("ac", __FILE__ ": sending break\n");
  412.  
  413.       ulParmLen = 2;
  414.       rc = DosDevIOCtl(cam->ofd,
  415.                        IOCTL_ASYNC,
  416.                        ASYNC_SETBREAKON,
  417.                        (PULONG) NULL,
  418.                        0,
  419.                        (PULONG) NULL,
  420.                        (PULONG) &packet,
  421.                        ulParmLen,
  422.                        (PULONG) &ulParmLen);
  423.  
  424.       _sleep2(1000);
  425.  
  426.       ulParmLen = 2;
  427.       rc = DosDevIOCtl(cam->ofd,
  428.                        IOCTL_ASYNC,
  429.                        ASYNC_SETBREAKOFF,
  430.                        (PULONG) NULL,
  431.                        0,
  432.                        (PULONG) NULL,
  433.                        (PULONG) &packet,
  434.                        ulParmLen,
  435.                        (PULONG) &ulParmLen);
  436.  
  437.  
  438.     return OK;
  439. }
  440.