Subversion Repositories f9daq

Rev

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

  1. //-------------------------------------------------------------------------------------------
  2. // pcivme_ni_NT.c - a ni labview dll skeleton for the ARW pcivme interface, winNT
  3. //
  4. // (c) 1999-2004 ARW Elektronik, Germany
  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. // $Log: pcivme_ni_NT.c,v $
  15. // Revision 1.2  2004/07/24 07:47:00  klaus
  16. // Update copyright to 2004
  17. //
  18. // Revision 1.1.1.1  2003/11/14 23:17:18  klaus
  19. // First put into repository
  20. //
  21. // Revision 1.4  2002/10/27 21:32:35  klaus
  22. // compatibility improved
  23. //
  24. // Revision 1.3  2002/10/27 19:22:58  klaus
  25. // backward compatibilty problem for 2 Gbyte limit solved
  26. //
  27. // Revision 1.2  2002/10/27 17:05:33  klaus
  28. // CVS log added, file addressing bug > 2 Gbtye circumvent
  29. //
  30. // what                                                              who    when
  31. // first steps                                                       AR     07.11.1999
  32. //
  33.  
  34. //-------------------------------------------------------------------------------------------
  35. // INCLUDES
  36. //
  37. #include <windows.h>
  38. #include <winioctl.h>
  39. #include <pcivme.h>    // header for win-NT
  40. #include <vic.h>
  41. #include <vme.h>
  42. #include <pcivme_ni_NT.h>
  43. #include <Klist.h>
  44.  
  45. #include <stdio.h>
  46. FILE *vmefp;
  47. //-------------------------------------------------------------------------------------------
  48. // DEFINES
  49. //
  50. #define DEFDEVICENAME "\\\\.\\PCIVME:\\VMEMMxx"
  51. #define LIMIT_2GBYTE  0x80000000       // 2 GByte addressing limit of WINNT ...
  52.  
  53. //-------------------------------------------------------------------------------------------
  54. // TYPEDEFS
  55. //
  56. typedef struct // a element associated to a open path (between VMEinit and VMEclose)
  57. {
  58.         HANDLE                                  nHandle;
  59.         PCIVME_ACCESS_COMMAND   access;
  60. } OPEN_PATH;
  61.  
  62. //-------------------------------------------------------------------------------------------
  63. // LOCALS
  64. //
  65. // user initialisation table for pcivme
  66. static PCIVME_INIT_COMMAND sUserInitStruct   = {2, {{STOP, WORD_ACCESS, 0,    0}}};            
  67. // user deinitialisation table
  68. static PCIVME_INIT_COMMAND sUserDeInitStruct = {2, {{STOP, WORD_ACCESS, 0,    0}}};
  69.  
  70. // the list of Path specific data (a element lives between VMEinit and VMEclose)
  71. static LIST liPathList          = (LIST)NULL;
  72.  
  73. //-------------------------------------------------------------------------------------------
  74. // EXTERNALS
  75. //
  76.  
  77. //-------------------------------------------------------------------------------------------
  78. // GLOBALS
  79. //
  80.  
  81. //-------------------------------------------------------------------------------------------
  82. // FUNCTIONS
  83. //
  84. // not only delete a element - even remove the whole list if it is empty
  85. static void removeListElement(OPEN_PATH *open_path)
  86. {
  87.         List_Delete((LPVOID)open_path);
  88.  
  89.         // remove the list if the last item was deleted ----
  90.         if ((liPathList != NULL) && (List_IsEmpty(liPathList) == TRUE))
  91.         {
  92.                 List_Destroy(&liPathList);
  93.                 liPathList = (LIST)NULL;
  94.         }
  95. }
  96.  
  97. //-------------------------------------------------------------------------
  98. // create a DeviceName out of cszDeviceName and nIfcNum
  99. static char *DeviceName(const char *cszDeviceName, int nIfcNum)
  100. {
  101.         static char buffer[255];
  102.         char *ptr = buffer;
  103.  
  104.         if (cszDeviceName == NULL)
  105.                 strcpy_s(buffer, 255 , DEFDEVICENAME);
  106.         else
  107.                 strcpy_s(buffer, 255 , cszDeviceName);
  108.  
  109.         while (*ptr) ptr++;
  110.        
  111.         do
  112.         {
  113.                 ptr--;
  114.         } while (*ptr != 'M');
  115.  
  116.         ptr++;
  117.        
  118.         if (nIfcNum >= 10)
  119.         {
  120.                 *ptr++   = '1';
  121.                 nIfcNum -= 10;
  122.         }
  123.  
  124.         *ptr++ = '0' + nIfcNum;
  125.         *ptr = 0;
  126.  
  127.     return buffer;
  128. }
  129.  
  130. int VMEinitNT(const char *cszDeviceName, unsigned short nVMEMM, unsigned char ubAddressModifier, int *pnHandle)
  131. {
  132.         OPEN_PATH *open_path;
  133.         DWORD   DIOC_count;                     // count of returned bytes of DeviceIoControl
  134.         DWORD   result = 0;
  135.         vmefp = fopen("pcivme_ni.log","w");
  136.         fprintf(vmefp, "VMEinitNT\n");
  137.         if (liPathList == NULL)         // create a list to hold the paths and its variables
  138.         {
  139.                 liPathList = List_Create();
  140.                 if (liPathList == (LIST)NULL)
  141.                         return GetLastError();
  142.         }
  143.        
  144.         open_path = (OPEN_PATH *)List_NewFirst(liPathList, sizeof(OPEN_PATH));
  145.  
  146.         *pnHandle = -1;
  147.  
  148.     if ((open_path->nHandle = CreateFile(
  149.                                                 DeviceName(cszDeviceName, nVMEMM),
  150.                                                 GENERIC_READ | GENERIC_WRITE,
  151.                                                 0,
  152.                                                 NULL,
  153.                                                 OPEN_EXISTING,
  154.                                                 FILE_ATTRIBUTE_NORMAL,
  155.                                                 NULL)) != ((HANDLE)-1))
  156.         {
  157.                 // init hardware (only one time after the first init it works OK)
  158.                 result = DeviceIoControl(open_path->nHandle,
  159.                                                 PCIVME_INIT_HARDWARE,
  160.                                                 &sUserInitStruct,
  161.                                                 (DWORD)sizeof(sUserInitStruct),
  162.                                                 NULL,
  163.                                                 (DWORD)0,
  164.                                                 &DIOC_count,
  165.                                                 NULL);
  166.  
  167.                 // set the current access parameters ------------------
  168.                 open_path->access.bAddressModifier      = ubAddressModifier;
  169.                 open_path->access.bAccessType           =
  170.                 open_path->access.bIncrement            = BYTE_ACCESS;
  171.                 open_path->access.dwAccessBase  = 0;
  172.  
  173.                 result = DeviceIoControl(open_path->nHandle,
  174.                                                 PCIVME_SET_ACCESS_PARA,
  175.                                                 &open_path->access,
  176.                                                 (DWORD)sizeof(open_path->access),
  177.                                                 NULL,
  178.                                                 0,
  179.                                                 &DIOC_count,
  180.                                                 NULL); 
  181.                
  182.  
  183.                 if (!result)
  184.                 {
  185.                        
  186.                         result = GetLastError();
  187.                         fprintf(vmefp, "DeviceIoControl result=%d\n", result);
  188.                         fclose(vmefp);
  189.                         CloseHandle(open_path->nHandle);
  190.                         removeListElement(open_path);
  191.                         return result;
  192.                 }
  193.  
  194.                 *pnHandle    = (int)open_path;
  195.  
  196.                 return 0;
  197.         }
  198.         else
  199.         {
  200.                
  201.                 result = GetLastError();
  202.                 fprintf(vmefp, "CreateFile error  result=%d %s\n", result, DeviceName(cszDeviceName, nVMEMM));
  203.                 fclose(vmefp);
  204.                 removeListElement(open_path);
  205.                 return result;
  206.         }
  207. }
  208.  
  209. int VMEreadNT(int nHandle, unsigned long ulAddress, unsigned char ubAccessWidth, unsigned long ulElementCount, void *pvBuffer)
  210. {
  211.         DWORD    DIOC_count;     // count of returned bytes of DeviceIoControl
  212.         unsigned long ulNumberOfBytes = ulElementCount * ubAccessWidth;
  213.         unsigned long bytesRead;
  214.         OPEN_PATH *open_path = (OPEN_PATH *)nHandle;
  215.  
  216.         if (nHandle == -1) return ERROR_PATH_NOT_FOUND;
  217.  
  218.         // set the current access parameters ------------------
  219.         open_path->access.bAccessType                   =
  220.         open_path->access.bIncrement                    = ubAccessWidth;
  221.  
  222.         // take care of only 2 Gbyte addressing capabilities of WINNT ...
  223.         if (ulAddress >= LIMIT_2GBYTE)
  224.         {
  225.                 ulAddress -= LIMIT_2GBYTE;
  226.                 open_path->access.dwAccessBase = LIMIT_2GBYTE;
  227.         }
  228.         else
  229.                 open_path->access.dwAccessBase = 0;
  230.  
  231.         if (!DeviceIoControl(open_path->nHandle,
  232.                                                 PCIVME_SET_ACCESS_PARA,
  233.                                                 &open_path->access,
  234.                                                 (DWORD)sizeof(open_path->access),
  235.                                                 NULL,
  236.                                                 0,
  237.                                                 &DIOC_count,
  238.                                                 NULL))   
  239.                 return GetLastError();
  240.  
  241.         SetFilePointer(open_path->nHandle, ulAddress, NULL, FILE_BEGIN);
  242.  
  243.         if (!ReadFile(open_path->nHandle, pvBuffer, ulNumberOfBytes, &bytesRead, NULL))
  244.                 return GetLastError();
  245.  
  246.         return 0;
  247. }
  248.  
  249. int VMEwriteNT(int nHandle, unsigned long ulAddress, unsigned char ubAccessWidth, unsigned long ulElementCount, void *pvBuffer)
  250. {
  251.         DWORD    DIOC_count;     // count of returned bytes of DeviceIoControl
  252.         unsigned long ulNumberOfBytes = ulElementCount * ubAccessWidth;
  253.         unsigned long bytesRead;
  254.         OPEN_PATH *open_path = (OPEN_PATH *)nHandle;
  255.  
  256.         if (nHandle == -1) return ERROR_PATH_NOT_FOUND;
  257.  
  258.         // set the current access parameters ------------------
  259.         open_path->access.bAccessType    =
  260.         open_path->access.bIncrement     = ubAccessWidth;
  261.  
  262.         // take care of only 2 Gbyte addressing capabilities of WINNT ...
  263.         if (ulAddress >= LIMIT_2GBYTE)
  264.         {
  265.                 ulAddress -= LIMIT_2GBYTE;
  266.                 open_path->access.dwAccessBase = LIMIT_2GBYTE;
  267.         }
  268.         else
  269.                 open_path->access.dwAccessBase = 0;
  270.  
  271.         if (!DeviceIoControl(open_path->nHandle,
  272.                                                         PCIVME_SET_ACCESS_PARA,
  273.                                                         &open_path->access,
  274.                                                         (DWORD)sizeof(open_path->access),
  275.                                                         NULL,
  276.                                                         0,
  277.                                                         &DIOC_count,
  278.                                                         NULL))   
  279.                 return GetLastError();
  280.  
  281.         SetFilePointer(open_path->nHandle, ulAddress, NULL, FILE_BEGIN);
  282.  
  283.         if (!WriteFile(open_path->nHandle, pvBuffer, ulNumberOfBytes, &bytesRead, NULL))
  284.                 return GetLastError();
  285.  
  286.         return 0;
  287. }
  288.  
  289. int VMEaccessVICNT(int nHandle, unsigned char ubAccessMode, unsigned short uwAddress, unsigned char *ubContent)
  290. {
  291.         DWORD    DIOC_count;     // count of returned bytes of DeviceIoControl
  292.         OPEN_PATH *open_path = (OPEN_PATH *)nHandle;
  293.         PCIVME_VIC68A_ACTION   sAction;    // structure to access vic chip
  294.         DWORD                  result;
  295.  
  296.         if (nHandle == -1) return ERROR_PATH_NOT_FOUND;
  297.  
  298.         sAction.wRegisterAddress = uwAddress;
  299.         sAction.wAccessMode      = ubAccessMode;
  300.         sAction.bContent         = *ubContent;
  301.  
  302.         result = DeviceIoControl(open_path->nHandle, PCIVME_ACCESS_VIC68A,
  303.                                          &sAction, sizeof(sAction), &sAction,
  304.                                                         sizeof(sAction), &DIOC_count, NULL);     
  305.  
  306.         *ubContent = sAction.bContent;
  307.  
  308.         if (!result)
  309.                 return GetLastError();
  310.         else
  311.                 return 0;
  312. }
  313.  
  314. int VMEresetNT(int nHandle)
  315. {
  316.         DWORD    DIOC_count;     // count of returned bytes of DeviceIoControl
  317.         OPEN_PATH *open_path = (OPEN_PATH *)nHandle;
  318.         DWORD   result;
  319.         PCIVME_RESET_COMMAND reset_command;
  320.         PCIVME_RESET_RESULT  reset_result;
  321.  
  322.         if (nHandle == -1) return ERROR_PATH_NOT_FOUND;
  323.  
  324.         reset_command.wCommand = VME_RESET_CMD;
  325.         reset_result.wResult   = 0;
  326.         result = DeviceIoControl(open_path->nHandle, PCIVME_RESET,
  327.                 &reset_command, sizeof(reset_command),
  328.                                 &reset_result,  sizeof(reset_result),
  329.                                    &DIOC_count, NULL);   
  330.  
  331.         if (!result)
  332.                 return GetLastError();
  333.         else
  334.         {
  335.                 result = 1;
  336.  
  337.                 while (reset_result.wResult && result)
  338.                 {
  339.                         reset_command.wCommand = POLL_RESET_CMD;
  340.                         result = DeviceIoControl(open_path->nHandle, PCIVME_RESET,
  341.                                                 &reset_command, sizeof(reset_command),
  342.                                                 &reset_result,  sizeof(reset_result),
  343.                                                         &DIOC_count, NULL);      
  344.                         Sleep(10);
  345.                 }
  346.         }
  347.  
  348.         if (!result)
  349.                 return GetLastError();
  350.         else
  351.                 return 0;
  352. }
  353.  
  354. int VMETASNT(int nHandle, unsigned long ulAddress, unsigned char *ubResult)
  355. {
  356.         DWORD    DIOC_count;     // count of returned bytes of DeviceIoControl
  357.         OPEN_PATH *open_path = (OPEN_PATH *)nHandle;
  358.         PCIVME_TAS_STRUCT      sTAS;       // structure to do a Test and Set
  359.         DWORD                  result;
  360.  
  361.         if (nHandle == -1) return ERROR_PATH_NOT_FOUND;
  362.  
  363.         sTAS.wModifier        = open_path->access.bAddressModifier;
  364.         sTAS.dwAddress        = ulAddress;
  365.         sTAS.bContent         = 0x80;
  366.  
  367.         result = DeviceIoControl(open_path->nHandle, PCIVME_TAS,
  368.                                          &sTAS, (DWORD)sizeof(sTAS), &sTAS,
  369.                                                         (DWORD)sizeof(sTAS), &DIOC_count, NULL);
  370.  
  371.         *ubResult = sTAS.bContent;
  372.  
  373.         if (!result)
  374.                 return GetLastError();
  375.         else
  376.                 return 0;
  377. }
  378.  
  379. int VMEinterruptNT(int nHandle, unsigned char *ubVector)
  380. {
  381. //      DWORD    DIOC_count;     // count of returned bytes of DeviceIoControl
  382.         OPEN_PATH *open_path = (OPEN_PATH *)nHandle;
  383.  
  384.         if (nHandle == -1) return ERROR_PATH_NOT_FOUND;
  385.  
  386.         return 0;
  387. }
  388.  
  389. int VMEsysfailGetNT(int nHandle, BOOLEAN *bResult)
  390. {
  391.         DWORD    DIOC_count;     // count of returned bytes of DeviceIoControl
  392.         OPEN_PATH *open_path = (OPEN_PATH *)nHandle;
  393.         PCIVME_VIC68A_ACTION   sAction;    // structure to access vic chip
  394.         DWORD result;
  395.  
  396.         if (nHandle == -1) return ERROR_PATH_NOT_FOUND;
  397.  
  398.         sAction.wRegisterAddress = EGICR;
  399.         sAction.wAccessMode      = VIC68A_READ;
  400.         sAction.bContent         = 0;
  401.  
  402.         result = DeviceIoControl(open_path->nHandle, PCIVME_ACCESS_VIC68A,
  403.                                          &sAction, sizeof(sAction), &sAction,
  404.                                                         sizeof(sAction), &DIOC_count, NULL);     
  405.  
  406.  
  407.         *bResult = (sAction.bContent & 0x08) ? FALSE : TRUE;
  408.  
  409.         if (!result)
  410.                 return GetLastError();
  411.         else
  412.                 return 0;
  413. }
  414.  
  415. int VMEsysfailSetNT(int nHandle, BOOLEAN bForce)
  416. {
  417.         DWORD    DIOC_count;     // count of returned bytes of DeviceIoControl
  418.         OPEN_PATH *open_path = (OPEN_PATH *)nHandle;
  419.         PCIVME_VIC68A_ACTION   sAction;    // structure to access vic chip
  420.         DWORD result;
  421.  
  422.         if (nHandle == -1) return ERROR_PATH_NOT_FOUND;
  423.  
  424.         sAction.wRegisterAddress = ICR7;
  425.         sAction.wAccessMode      = (bForce == TRUE) ? VIC68A_AND : VIC68A_OR;
  426.         sAction.bContent         = (bForce == TRUE) ? 0x3F               : 0x80;
  427.  
  428.         result = DeviceIoControl(open_path->nHandle, PCIVME_ACCESS_VIC68A,
  429.                                          &sAction, (DWORD)sizeof(sAction), &sAction,
  430.                                                         (DWORD)sizeof(sAction), &DIOC_count, NULL);
  431.         if (!result)
  432.                 return GetLastError();
  433.         else
  434.                 return 0;
  435. }
  436.  
  437. int VMEcloseNT(int nHandle)
  438. {
  439.         DWORD    DIOC_count;     // count of returned bytes of DeviceIoControl
  440.         OPEN_PATH *open_path = (OPEN_PATH *)nHandle;
  441.  
  442.         if (nHandle == -1) return ERROR_PATH_NOT_FOUND;
  443.  
  444.         DeviceIoControl(open_path->nHandle,
  445.                                                 PCIVME_DEINIT_HARDWARE,
  446.                                                 &sUserDeInitStruct,
  447.                                                 (DWORD)sizeof(sUserDeInitStruct),
  448.                                                 NULL,
  449.                                                 0,
  450.                                                 &DIOC_count,
  451.                                                 NULL);   
  452.  
  453.         CloseHandle(open_path->nHandle);
  454.         removeListElement(open_path);
  455.  
  456.         return 0;
  457. }
  458.  
  459.