Subversion Repositories f9daq

Rev

Blame | Last modification | View Log | RSS feed

  1. //****************************************************************************
  2. // Copyright (C) 2000-2004  ARW Elektronik Germany
  3. //
  4. //
  5. // This program is free software; you can redistribute it and/or modify
  6. // it under the terms of the GNU Lesser General Public License as published by
  7. // the Free Software Foundation; either version 2 of the License, or
  8. // (at your option) any later version.
  9. //
  10. // This program is distributed in the hope that it will be useful,
  11. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13. // GNU General Public License for more details.
  14. //
  15. // You should have received a copy of the GNU General Public License
  16. // along with this program; if not, write to the Free Software
  17. // Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  18. //
  19. // This product is not authorized for use as critical component in
  20. // life support systems without the express written approval of
  21. // ARW Elektronik Germany.
  22. //  
  23. // Please announce changes and hints to ARW Elektronik
  24. //
  25. // Maintainer(s): Klaus Hitschler (klaus.hitschler@gmx.de)
  26. //
  27. //****************************************************************************
  28.  
  29. //****************************************************************************
  30. //
  31. // cc32lib.c -- a simple access library for the PCICC32 PCI to CAMAC Interface
  32. //
  33. // $Log: libcc32.c,v $
  34. // Revision 1.9  2004/11/29 20:45:36  klaus
  35. // Bug remove. Still release libcc32.so.2.
  36. //
  37. // Revision 1.8  2004/11/29 20:43:12  klaus
  38. // added _qx functions to get Q and X for every transfer. Release libcc32.so.2.
  39. //
  40. // Revision 1.7  2004/08/13 19:48:25  klaus
  41. // changed license from GPL to LGPL
  42. //
  43. // Revision 1.6  2004/08/12 20:00:41  klaus
  44. // conversion to kernel-version 2.6, released version 6.0
  45. //
  46. // Revision 1.5  2002/05/20 21:24:19  klaus
  47. // Small changes for kernel 2.4.18
  48. //
  49. // Revision 1.4  2002/04/17 19:41:06  klaus
  50. // added support for autoread
  51. //
  52. // Revision 1.3  2002/04/14 18:25:38  klaus
  53. // added interrupt handling, driver 4.4. ...3.5.tar.gz
  54. //
  55. // Revision 1.2  2001/11/20 20:12:50  klaus
  56. // included new header and CVS log
  57. //
  58. //
  59. // first steps                                                 AR   25.02.2000
  60. //
  61. //****************************************************************************
  62.  
  63. /*--- INCLUDES -----------------------------------------------------------------------------------*/
  64. #include <stdio.h>
  65. #include <stdlib.h>
  66. #include <string.h>
  67. #include <unistd.h>
  68. #include <sys/mman.h>
  69. #include <errno.h>
  70. #include <ctype.h>
  71. #include <sys/ioctl.h>
  72. #include "../driver/pcicc32.h" /* PCI common ioctl commands and structures between driver and library  */
  73. #include "libcc32.h"      /* shared header bewteen application and library                        */
  74.  
  75. /*--- DEFINES ------------------------------------------------------------------------------------*/
  76. #define pwCC32_ADR(adr, N, A, F) (__u16 *)((N << 10) + (A << 6) + ((F & 0xF) << 2) + adr)
  77. #define plCC32_ADR(adr, N, A, F) (__u32 *)((N << 10) + (A << 6) + ((F & 0xF) << 2) + adr)
  78. #define WINDOW_SIZE 32768
  79.  
  80. /*--- EXTERNALS ----------------------------------------------------------------------------------*/
  81.  
  82. /*--- TYPEDEFS -----------------------------------------------------------------------------------*/
  83. typedef struct
  84. {
  85.         FILE *f;                  /* the handle of this device */
  86.   int  fileNo;  /* equals fileno(f)          */
  87.         char *base;             /* base of range, got with mmap */
  88. } CC32_DEVICE;
  89.  
  90. /*--- FUNCTIONS ----------------------------------------------------------------------------------*/
  91. static int cc32_interrupt_control(CC32_HANDLE handle, int enable)
  92. {
  93.         CC32_DEVICE *dev = (CC32_DEVICE *)handle;
  94.         PCICC32_IRQ_CONTROL control;
  95.  
  96.   control.bEnable = enable;
  97.  
  98.   return ioctl(dev->fileNo, PCICC32_CONTROL_INTERRUPTS, &control);
  99. }
  100.  
  101. static int cc32_xxxx_event(CC32_HANDLE handle, int *nTimeout, int *nLam, int nCode)
  102. {
  103.         CC32_DEVICE *dev = (CC32_DEVICE *)handle;
  104.         PCICC32_STATUS state;
  105.         int error;
  106.        
  107.   if ((error = ioctl(dev->fileNo, nCode, &state)))
  108.           return error;
  109.                
  110.         *nTimeout = state.bFail;
  111.         *nLam     = state.bIrq;
  112.        
  113.         if (state.bFail)  /* clear error */
  114.         {
  115.                 if ((error = ioctl(dev->fileNo, PCICC32_IOCNTRL, 0)))
  116.                         return error;  
  117.         }
  118.        
  119.         return 0;
  120. }
  121.  
  122. static int cc32_autoread_control(CC32_HANDLE handle, int nOn)
  123. {
  124.         CC32_DEVICE *dev = (CC32_DEVICE *)handle;
  125.         PCICC32_AUTOREAD control;
  126.  
  127.   control.bOn = nOn;
  128.  
  129.   return ioctl(dev->fileNo, PCICC32_AUTOREAD_SWITCH, &control);
  130. }
  131.  
  132. static void cc32_get_qx(CC32_DEVICE *dev, int *Q,  int *X)
  133. {
  134.   __u16 wstatus = *pwCC32_ADR(dev->base, 0, 0, 0);
  135.        
  136.   *Q = (wstatus & 8) ? 1 : 0;
  137.   *X = (wstatus & 4) ? 1 : 0;
  138. }
  139.  
  140. int cc32_open(char *cszPath, CC32_HANDLE *handle)
  141. {
  142.         CC32_DEVICE *dev;
  143.        
  144.         *handle = (CC32_HANDLE)0;
  145.        
  146.         dev = (CC32_DEVICE *)malloc(sizeof(CC32_DEVICE));
  147.         if (!dev) return errno;
  148.        
  149.         dev->fileNo = 0;
  150.         dev->base   = (char *)0;
  151.        
  152.         if (!(dev->f = fopen(cszPath,"rw")))
  153.   {
  154.                 int error = errno;
  155.                
  156.                 free(dev);
  157.                 printf("Cannot Open Device %s\n",cszPath);
  158.                 return error;
  159.         }
  160.        
  161.         dev->fileNo = fileno(dev->f);
  162.        
  163.         dev->base = (char *)mmap(0, WINDOW_SIZE, PROT_READ, MAP_FILE | MAP_PRIVATE, dev->fileNo, 0);
  164.         if (dev->base == (char *)-1)
  165.         {
  166.                 int error = errno;
  167.                
  168.                 fclose(dev->f);
  169.                 free(dev);
  170.                 printf("Cannot MMap Device %s\n",cszPath);
  171.  
  172.                 return error;  
  173.         }
  174.  
  175.         *handle = (CC32_HANDLE)dev;
  176.        
  177.         return 0;
  178. }
  179.  
  180. int cc32_close(CC32_HANDLE handle)
  181. {
  182.         CC32_DEVICE *dev = (CC32_DEVICE *)handle;
  183.         int error = 0;
  184.        
  185.         if (dev)
  186.         {
  187.                 munmap(dev->base, WINDOW_SIZE);
  188.                        
  189.                 if (dev->f)
  190.                         fclose(dev->f);
  191.                 else
  192.                         error = -EINVAL;
  193.        
  194.                 free(dev);
  195.         }
  196.         else
  197.                 error = -EINVAL;
  198.                
  199.         return error;
  200. }
  201.  
  202. __u16 cc32_read_word(CC32_HANDLE handle, unsigned int N, unsigned int A, unsigned int F)
  203. {
  204.         CC32_DEVICE *dev = (CC32_DEVICE *)handle;
  205.        
  206.         return *pwCC32_ADR(dev->base, N, A, F);
  207. }
  208.  
  209. __u16 cc32_read_word_qx(CC32_HANDLE handle, unsigned int N, unsigned int A, unsigned int F, int *Q, int *X)
  210. {
  211.         CC32_DEVICE *dev = (CC32_DEVICE *)handle;
  212.         __u32 erg = *plCC32_ADR(dev->base, N, A, F);
  213.        
  214.         *Q = (erg & 0x80000000) ? 1 : 0;
  215.         *X = (erg & 0x40000000) ? 1 : 0;
  216.        
  217.         return erg & 0x0000FFFF; // get only the lower 16 bits
  218. }
  219.  
  220. __u32 cc32_read_long_all(CC32_HANDLE handle, unsigned int N, unsigned int A, unsigned int F)
  221. {
  222.         CC32_DEVICE *dev = (CC32_DEVICE *)handle;
  223.        
  224.         return *plCC32_ADR(dev->base, N, A, F);;
  225. }
  226.  
  227. __u32 cc32_read_long(CC32_HANDLE handle, unsigned int N, unsigned int A, unsigned int F)
  228. {
  229.         CC32_DEVICE *dev = (CC32_DEVICE *)handle;
  230.         __u32 erg = *plCC32_ADR(dev->base, N, A, F);
  231.        
  232.         return erg & 0x00FFFFFF;
  233. }
  234.  
  235. __u32 cc32_read_long_qx(CC32_HANDLE handle, unsigned int N, unsigned int A, unsigned int F, int *Q, int *X)
  236. {
  237.         CC32_DEVICE *dev = (CC32_DEVICE *)handle;
  238.         __u32 erg = *plCC32_ADR(dev->base, N, A, F);
  239.        
  240.         *Q = (erg & 0x80000000) ? 1 : 0;
  241.         *X = (erg & 0x40000000) ? 1 : 0;
  242.        
  243.         return erg & 0x00FFFFFF;
  244. }
  245.  
  246. void cc32_write_word(CC32_HANDLE handle, unsigned int N, unsigned int A, unsigned int F, __u16 uwData)
  247. {
  248.         CC32_DEVICE *dev = (CC32_DEVICE *)handle;
  249.        
  250.         *pwCC32_ADR(dev->base, N, A, F) = uwData;
  251. }
  252.  
  253. void cc32_write_word_qx(CC32_HANDLE handle, unsigned int N, unsigned int A, unsigned int F, __u16 uwData, int *Q, int *X)
  254. {
  255.         CC32_DEVICE *dev = (CC32_DEVICE *)handle;
  256.        
  257.         *pwCC32_ADR(dev->base, N, A, F) = uwData;
  258.  
  259.   cc32_get_qx(dev, Q,  X);
  260. }
  261.  
  262. void cc32_write_long(CC32_HANDLE handle, unsigned int N, unsigned int A, unsigned int F, __u32 ulData)
  263. {
  264.         CC32_DEVICE *dev = (CC32_DEVICE *)handle;
  265.  
  266.         *plCC32_ADR(dev->base, N, A, F) = ulData;
  267. }
  268.  
  269. void cc32_write_long_qx(CC32_HANDLE handle, unsigned int N, unsigned int A, unsigned int F, __u32 ulData, int *Q, int *X)
  270. {
  271.         CC32_DEVICE *dev = (CC32_DEVICE *)handle;
  272.        
  273.         *plCC32_ADR(dev->base, N, A, F) = ulData;
  274.  
  275.   cc32_get_qx(dev, Q,  X);
  276. }
  277.  
  278. int cc32_poll_event(CC32_HANDLE handle, int *nTimeout, int *nLam)
  279. {
  280.   return cc32_xxxx_event(handle, nTimeout, nLam, PCICC32_IOSTATE);
  281. }
  282.  
  283. int cc32_wait_event(CC32_HANDLE handle, int *nTimeout, int *nLam)
  284. {
  285.   return cc32_xxxx_event(handle, nTimeout, nLam, PCICC32_IOSTATE_BLOCKING);
  286. }
  287.  
  288. int cc32_interrupt_disable(CC32_HANDLE handle)
  289. {
  290.   return cc32_interrupt_control(handle, 0);
  291. }
  292.  
  293. int cc32_interrupt_enable(CC32_HANDLE handle)
  294. {
  295.   return cc32_interrupt_control(handle, 1);
  296. }
  297.  
  298. int cc32_autoread_on(CC32_HANDLE handle)
  299. {
  300.   return cc32_autoread_control(handle, 1);
  301. }
  302.  
  303. int cc32_autoread_off(CC32_HANDLE handle)
  304. {
  305.   return cc32_autoread_control(handle, 0);
  306. }
  307.  
  308.