Subversion Repositories f9daq

Rev

Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | RSS feed

  1. /*
  2.    cc32lib.c -- a simple access library for the PCICC32 PCI to CAMAC Interface from ARW Elektronik
  3.  
  4.    (c) 2000 ARW Elektronik
  5.  
  6.    this source code is published under GPL (Open Source). You can use, redistrubute and
  7.    modify it unless this header   is not modified or deleted. No warranty is given that
  8.    this software will work like expected.
  9.    This product is not authorized for use as critical component in life support systems
  10.    wihout the express written approval of ARW Elektronik Germany.
  11.  
  12.    Please announce changes and hints to ARW Elektronik
  13.  
  14.    first steps derived from the LINUX pcicc32 library                   AR   16.03.2000
  15.    added buffer, UNTIL_NOT_Q and AUTOREAD functionality                 AR   17.03.2001
  16.    corrected fault in setAccessParameter()                              AR   21.05.2002
  17.    added framework only fro future interrupt handling                   AR   08.06.2002
  18. */
  19.  
  20. /*--- INCLUDES -----------------------------------------------------------------------------------*/
  21. #include <windows.h>
  22. #include <stdio.h>
  23. #include <stdlib.h>
  24. #include <string.h>
  25. #include <errno.h>
  26. #include "Vpcic32D.h"     /* PCI common ioctl commands and structures between driver and library  */
  27. #include "libcc32_95.h"   /* shared header bewteen applictaion and library                        */
  28.  
  29. /*--- DEFINES ------------------------------------------------------------------------------------*/
  30. #define pwCC32_ADR(adr, N, A, F) (unsigned short *)((N << 10) + (A << 6) + ((F & 0xF) << 2) + adr)
  31. #define plCC32_ADR(adr, N, A, F) (unsigned long *)((N << 10) + (A << 6) + ((F & 0xF) << 2) + adr)
  32. #define WINDOW_SIZE 32768
  33.  
  34. /*--- EXTERNALS ----------------------------------------------------------------------------------*/
  35.  
  36. /*--- TYPEDEFS -----------------------------------------------------------------------------------*/
  37. typedef struct
  38. {
  39.         HANDLE nHandle;       /* the handle of this device */
  40.         int    nModuleNumber; /* the number of the module */
  41.         char   *base;             /* base of range             */
  42.         unsigned short wLastAttributes; /* switched attributes like UNTIL_NOT_Q or AUTOREAD */
  43. } CC32_DEVICE;
  44.  
  45. /*--- FUNCTIONS -----------------------------------------------------------------------*/
  46.  
  47. //--------------------------------------------------------------------------------------
  48. // a function to get the base address of the CAMAC range
  49. //
  50. static int attachWindow(HANDLE nHandle, DWORD dwInterface, void **base)
  51. {
  52.         VPCIC32D_WINDOW window;
  53.         DWORD DIOC_count;             // count of returned bytes of DeviceIoControl
  54.         DWORD result;
  55.  
  56.     *base = NULL;
  57.         if (nHandle == (HANDLE)-1) return ERROR_INVALID_HANDLE;
  58.  
  59.         // attach a window into the CC32 space ----------------
  60.         result = DeviceIoControl(nHandle, VPCIC32_ATTACH_CC32,
  61.                                                 &dwInterface, sizeof(dwInterface),
  62.                                                 &window,      sizeof(window),
  63.                                                                  &DIOC_count, NULL);
  64.  
  65.     if (!result)
  66.                 return GetLastError();
  67.         else
  68.         {
  69.                 *base = window.pvWindowBase;
  70.                 return 0;
  71.         }
  72. }
  73.  
  74. //--------------------------------------------------------------------------------------
  75. // a function to release a attached range
  76. //
  77. static int detachWindow(HANDLE nHandle, DWORD dwInterface)
  78. {
  79.         DWORD DIOC_count;             // count of returned bytes of DeviceIoControl
  80.         DWORD result;
  81.  
  82.         if (nHandle == (HANDLE)-1) return ERROR_INVALID_HANDLE;
  83.  
  84.         // attach a window into the CC32 space ----------------
  85.         result = DeviceIoControl(nHandle, VPCIC32_DETACH_CC32,
  86.                                                 &dwInterface, sizeof(dwInterface),
  87.                                                 NULL,      0, &DIOC_count, NULL);
  88.     if (!result)
  89.                 return GetLastError();
  90.         else
  91.                 return 0;
  92. }
  93.  
  94. //--------------------------------------------------------------------------------------
  95. // get the PCIADA status from the PCI side of the interface
  96. //
  97. static int getStatus(HANDLE nHandle, DWORD dwInterface, char *nTimeout, char *nLAM)
  98. {
  99.         VPCIC32D_STATUS status;
  100.         DWORD DIOC_count;             // count of returned bytes of DeviceIoControl
  101.         DWORD result;
  102.  
  103.         if (nHandle == (HANDLE)-1) return ERROR_INVALID_HANDLE;
  104.  
  105.         *nTimeout = *nLAM = 0;
  106.  
  107.         // attach a window into the CC32 space ----------------
  108.         result = DeviceIoControl(nHandle, VPCIC32_GET_STATUS,
  109.                                                 &dwInterface, sizeof(dwInterface),
  110.                                                 &status,      sizeof(status), &DIOC_count, NULL);
  111.  
  112.     if (!result)
  113.                 return GetLastError();
  114.         else
  115.         {
  116.                 *nTimeout = (char)status.bTimeout;
  117.                 *nLAM     = (char)status.bInterrupt;
  118.  
  119.                 return 0;
  120.         }
  121. }
  122.  
  123. //--------------------------------------------------------------------------------------
  124. // clear the PCIADA status
  125. //
  126. static int clearStatus(HANDLE nHandle, DWORD dwInterface)
  127. {
  128.         DWORD DIOC_count;             // count of returned bytes of DeviceIoControl
  129.         DWORD result;
  130.  
  131.         if (nHandle == (HANDLE)-1) return ERROR_INVALID_HANDLE;
  132.  
  133.         // attach a window into the CC32 space ----------------
  134.         result = DeviceIoControl(nHandle, VPCIC32_CLEAR_STATUS,
  135.                                                 &dwInterface, sizeof(dwInterface),
  136.                                                 NULL,      0, &DIOC_count, NULL);
  137.  
  138.     if (!result)
  139.                 return GetLastError();
  140.         else
  141.                 return 0;
  142. }
  143.  
  144. //-------------------------------------------------------------------------
  145. // set the future access parameters - override the current
  146. //
  147. static int setAccessParameter(HANDLE hHandle, DWORD dwInterface, USHORT wBlockTransfer)
  148. {
  149.         DWORD result;
  150.         DWORD   DIOC_count;     // count of returned bytes of DeviceIoControl
  151.     VPCIC32D_ACCESS_COMMAND access_parameter;
  152.  
  153.         if (hHandle == (HANDLE)-1) return ERROR_INVALID_HANDLE;
  154.  
  155.         access_parameter.dwInterface        = dwInterface;
  156.         access_parameter.wBlockTransfer         = wBlockTransfer;
  157.  
  158.         result = DeviceIoControl(hHandle, VPCIC32_SET_ACCESS_PARA,
  159.                                         &access_parameter, (DWORD)sizeof(access_parameter), NULL,
  160.                                                    0, &DIOC_count, NULL);        
  161.         if (!result)
  162.                 return GetLastError();
  163.         else
  164.                 return 0;
  165. }
  166.  
  167. //--------------------------------------------------------------------------------------
  168. // open the device
  169. //
  170. int cc32_open_95(char *cszPath, int nModuleNumber, void **handle)
  171. {
  172.         CC32_DEVICE *dev;
  173.         int error;
  174.        
  175.         *handle = (void *)-1;
  176.        
  177.         dev = (CC32_DEVICE *)malloc(sizeof(CC32_DEVICE));
  178.         if (!dev) return errno;
  179.        
  180.         dev->base   = (char *)0;
  181.         dev->nModuleNumber = nModuleNumber;
  182.         dev->wLastAttributes = 0;
  183.  
  184.         dev->nHandle = CreateFile(cszPath,
  185.                                                 0,
  186.                                                 0,
  187.                                                 NULL,
  188.                                                 0,
  189.                                                 FILE_FLAG_DELETE_ON_CLOSE,
  190.                                                 NULL);
  191.        
  192.         if (dev->nHandle != INVALID_HANDLE_VALUE)
  193.         error = attachWindow(dev->nHandle, nModuleNumber, &dev->base);
  194.         else
  195.                 error = GetLastError();
  196.  
  197.         if (error)
  198.         {
  199.                 free(dev);
  200.                 return error;
  201.         }
  202.  
  203.         *handle = (void *)dev;
  204.        
  205.         return NO_ERROR;
  206. }
  207.  
  208. //--------------------------------------------------------------------------------------
  209. // close the device
  210. //
  211. int cc32_close_95(void *handle)
  212. {
  213.         CC32_DEVICE *dev = (CC32_DEVICE *)handle;
  214.         int error = NO_ERROR;
  215.        
  216.         if (dev)
  217.         {
  218.                 if (dev->nHandle != INVALID_HANDLE_VALUE)
  219.                 {
  220.                         detachWindow(dev->nHandle, dev->nModuleNumber);
  221.                         CloseHandle(dev->nHandle);
  222.                 }
  223.        
  224.                 free(dev);
  225.         }
  226.         else
  227.                 error = ERROR_INVALID_FUNCTION;
  228.                
  229.         return error;
  230. }
  231.  
  232. //--------------------------------------------------------------------------------------
  233. // read a word
  234. //
  235. unsigned short cc32_read_word_95(void *handle, unsigned int N, unsigned int A, unsigned int F)
  236. {
  237.         CC32_DEVICE *dev = (CC32_DEVICE *)handle;
  238.        
  239.         return *pwCC32_ADR(dev->base, N, A, F);
  240. }
  241.  
  242. //--------------------------------------------------------------------------------------
  243. // read a long
  244. //
  245. unsigned long cc32_read_long_all_95(void *handle, unsigned int N, unsigned int A, unsigned int F)
  246. {
  247.         CC32_DEVICE *dev = (CC32_DEVICE *)handle;
  248.        
  249.         return *plCC32_ADR(dev->base, N, A, F);
  250. }
  251.  
  252. //--------------------------------------------------------------------------------------
  253. // read a long and get Q and X
  254. //
  255. unsigned long cc32_read_long_95(void *handle, unsigned int N, unsigned int A, unsigned int F, char *Q, char *X)
  256. {
  257.         CC32_DEVICE *dev = (CC32_DEVICE *)handle;
  258.         unsigned long erg = *plCC32_ADR(dev->base, N, A, F);
  259.        
  260.         *Q = (erg & 0x80000000) ? 1 : 0;
  261.         *X = (erg & 0x40000000) ? 1 : 0;
  262.        
  263.         return erg & 0x00FFFFFF;
  264. }
  265.  
  266. //--------------------------------------------------------------------------------------
  267. // write a word
  268. //
  269. void cc32_write_word_95(void *handle, unsigned int N, unsigned int A, unsigned int F, unsigned short uwData)
  270. {
  271.         CC32_DEVICE *dev = (CC32_DEVICE *)handle;
  272.        
  273.         dev->wLastAttributes = 0;
  274.         *pwCC32_ADR(dev->base, N, A, F) = uwData;
  275. }
  276.  
  277. //--------------------------------------------------------------------------------------
  278. // write a long
  279. //
  280. void cc32_write_long_95(void *handle, unsigned int N, unsigned int A, unsigned int F, unsigned long ulData)
  281. {
  282.         CC32_DEVICE *dev = (CC32_DEVICE *)handle;
  283.        
  284.         dev->wLastAttributes = 0;
  285.         *plCC32_ADR(dev->base, N, A, F) = ulData;
  286. }
  287.  
  288. //--------------------------------------------------------------------------------------
  289. // clear the PCIADA status
  290. //
  291. int cc32_poll_error_95(void *handle, char *nTimeout, char *nLam)
  292. {
  293.         CC32_DEVICE *dev = (CC32_DEVICE *)handle;
  294.         int error;
  295.        
  296.     if ((error = getStatus(dev->nHandle, dev->nModuleNumber, nTimeout, nLam)))
  297.                 return error;
  298.                
  299.         if (*nTimeout)  /* clear error */
  300.         {
  301.                 if ((error = clearStatus(dev->nHandle, dev->nModuleNumber)))
  302.                         return error;  
  303.         }
  304.        
  305.         return NO_ERROR;
  306. }
  307.  
  308. //--------------------------------------------------------------------------------------
  309. // read 'len' words or 'UNTIL_NOT_Q' from a address made out of N,A,F
  310. //
  311. int cc32_read_word_buffer_95(void * handle, unsigned int N, unsigned int A, unsigned int F,
  312.                                                                                                                                 unsigned short *pwBuffer, unsigned long *pdwLen)
  313. {
  314.         CC32_DEVICE *dev = (CC32_DEVICE *)handle;
  315.         register unsigned long i = 0;
  316.         unsigned long dwLen = *pdwLen;
  317.         unsigned long *pdwAddress = plCC32_ADR(dev->base, N, A, F);
  318.         register unsigned long dwTempBuffer;
  319.  
  320.         if (dev->wLastAttributes & UNTIL_NOT_Q)
  321.         {
  322.                 do
  323.                 {
  324.                         dwTempBuffer = *pdwAddress;
  325.                         *pwBuffer++ = (unsigned short)dwTempBuffer;
  326.                 } while ((dwTempBuffer & 0x80000000) && (i++ < dwLen));
  327.         }
  328.         else
  329.         {
  330.                 while (i++ < dwLen)
  331.                         *pwBuffer++ = (unsigned short)*pdwAddress;
  332.         }
  333.        
  334.         *pdwLen = --i;
  335.         return 0;
  336. }
  337.  
  338. //--------------------------------------------------------------------------------------
  339. // read 'len' longs or 'UNTIL_NOT_Q' from a address made out of N,A,F, mask 24 bits out
  340. //
  341. int cc32_read_long_buffer_95(void * handle, unsigned int N, unsigned int A, unsigned int F,
  342.                                                                                                                                 unsigned long *pdwBuffer, unsigned long *pdwLen)
  343. {
  344.         CC32_DEVICE *dev = (CC32_DEVICE *)handle;
  345.         register unsigned long i = 0;
  346.         unsigned long dwLen = *pdwLen;
  347.         unsigned long *pdwAddress = plCC32_ADR(dev->base, N, A, F);
  348.         register unsigned long dwTempBuffer;
  349.  
  350.         if (dev->wLastAttributes & UNTIL_NOT_Q)
  351.         {
  352.                 do
  353.                 {
  354.                         dwTempBuffer = *pdwAddress;
  355.                         *pdwBuffer++ = dwTempBuffer & 0x00FFFFFF;
  356.                 } while ((dwTempBuffer & 0x80000000) && (i++ < dwLen));
  357.         }
  358.         else
  359.         {
  360.                 while (i++ < dwLen)
  361.                         *pdwBuffer++ = *pdwAddress & 0x00FFFFFF;
  362.         }
  363.        
  364.         *pdwLen = --i;
  365.         return 0;
  366. }
  367.  
  368. //--------------------------------------------------------------------------------------
  369. // read 'len' longs or 'UNTIL_NOT_Q' from a address made out of N,A,F, without interpretation
  370. //
  371. int cc32_read_long_all_buffer_95(void * handle, unsigned int N, unsigned int A, unsigned int F,
  372.                                                                                                                                 unsigned long *pdwBuffer, unsigned long *pdwLen)
  373. {
  374.         CC32_DEVICE *dev = (CC32_DEVICE *)handle;
  375.         register unsigned long i = 0;
  376.         unsigned long dwLen = *pdwLen;
  377.         unsigned long *pdwAddress = plCC32_ADR(dev->base, N, A, F);
  378.         register unsigned long dwTempBuffer;
  379.  
  380.         if (dev->wLastAttributes & UNTIL_NOT_Q)
  381.         {
  382.                 do
  383.                 {
  384.                         dwTempBuffer = *pdwAddress;
  385.                         *pdwBuffer++ = dwTempBuffer;
  386.                 } while ((dwTempBuffer & 0x80000000) && (i++ < dwLen));
  387.         }
  388.         else
  389.         {
  390.                 while (i++ < dwLen)
  391.                         *pdwBuffer++ = *pdwAddress;
  392.         }
  393.        
  394.         *pdwLen = --i;
  395.         return 0;
  396. }
  397.  
  398. //--------------------------------------------------------------------------------------
  399. // switch UNTIL_NOT_Q or AUTOREAD on or off
  400. //
  401. int cc32_access_switch_95(void *handle, unsigned short uwSwitch)
  402. {
  403.         CC32_DEVICE *dev = (CC32_DEVICE *)handle;
  404.  
  405.         dev->wLastAttributes = uwSwitch;
  406.         return setAccessParameter(dev->nHandle, dev->nModuleNumber, dev->wLastAttributes);
  407. }
  408.  
  409. //--------------------------------------------------------------------------------------
  410. // switch interrupts on
  411. //
  412. int cc32_enable_interrupt_95(void *handle)
  413. {
  414.         return ERROR_INVALID_FUNCTION;
  415. }
  416.  
  417. //--------------------------------------------------------------------------------------
  418. // switch interrupts off
  419. //
  420. int cc32_disable_interrupt_95(void *handle)
  421. {
  422.         return ERROR_INVALID_FUNCTION;
  423. }
  424.  
  425. //--------------------------------------------------------------------------------------
  426. // wait blocking for the next interrupt
  427. //
  428. int cc32_get_interrupt_95(void *handle, unsigned long *dwStatus)
  429. {
  430.         return ERROR_INVALID_FUNCTION;
  431. }
  432.