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