📄 dodmabm.c
字号:
case IDM_RUN :
// Step 1: Device open
ErrCde = DRV_DeviceOpen(dwDeviceNum, (LONG far *)&DriverHandle);
if (ErrCde != SUCCESS)
{
DRV_GetErrorMessage(ErrCde,(LPSTR)szErrMsg);
MessageBox(hWnd,(LPCSTR)szErrMsg,"Device Open",MB_OK);
return 0;
}
// Step 2: Get device features
ptDevFeatures.buffer = (LPDEVFEATURES)&DevFeatures;
ptDevFeatures.size = sizeof(DEVFEATURES);
if ((ErrCde = DRV_DeviceGetFeatures(DriverHandle,
(LPT_DeviceGetFeatures)&ptDevFeatures)) != SUCCESS)
{
DRV_GetErrorMessage(ErrCde,(LPSTR)szErrMsg);
MessageBox(hWnd,(LPCSTR)szErrMsg,"Driver Message",MB_OK);
DRV_DeviceClose((LONG far *)&DriverHandle);
return 0;
}
// Step 3: Allocate memory for Fast DI data
//********Version 2.0B*******************
// As with DMA transfers, it's better to start the buffer at
// page boundary(4096 Bytes). If the buffers used for the
// DMA operation is aligned on addresses of page boundary, user
// can get exact page change event(just set the Count of
// PT_EnableEvent to 2048, it means 1 page). Once Interrupt
// event occurs, it means 2048 samples(4096 byes) are available.
//
// It is why we changed the memory allocation policy from
// Solution A to solution B at Version 2.0B.
//
// At the same time, the buffer that receives the samples must
// be a multiple of 4096 bypes(2048 samples). In cycle mode, if
// you are interested in buffer change event, the minimal buffer
// is 8192 bytes(4096 samples).
//****************************************
//*************** 2.0B note *********************
// Device driver's ReadFile will Error(System resource insufficient
// when use GlobalAlloc function to allocate more than 16M byte memory.
// So we use VirtualAlloc, but not test in Win9x platform.
dwUserBufferSize = (DWORD)(Mega * pow((double)2, (double)gdwUserBufferSize));
/*
// Solution A:
if((hUserBuf = GlobalAlloc(GPTR,
dwUserBufferSize )) == 0)
{
MessageBox(hWnd,"Not enough memory for buffer ",
"High Speed",MB_OK);
DRV_DeviceClose((LONG far *)&DriverHandle);
return 0;
}
*/
// Solution B:
// Win9x seems don't support the routine well.
// so it's recommended only to use it at WinNT/2K.
hUserBuf = VirtualAlloc( NULL, // region to reserve or commit
dwUserBufferSize, // size of region
MEM_COMMIT|MEM_RESERVE, // type of allocation
PAGE_READWRITE ); // type of access protection
if ( NULL==hUserBuf )
{
MessageBox( hWnd, "Not enough memory for buffer", "High Speed",MB_OK );
DRV_DeviceClose((LONG *)&DriverHandle);
return 0;
}
// End of solution B.
// Step 4: Enable event feature
ptEnableEvent.Enabled = 1;
ptEnableEvent.Count = 1;
ptEnableEvent.EventType = ADS_EVT_DO_UNDERRUN; // Overrun event
ErrCde = DRV_EnableEvent(DriverHandle, &ptEnableEvent);
ptEnableEvent.EventType = ADS_EVT_DO_LOBUFTRANS; // Low buffer transfered event
ErrCde = DRV_EnableEvent(DriverHandle, &ptEnableEvent);
ptEnableEvent.EventType = ADS_EVT_DO_HIBUFTRANS; // High buffer transfered event.
ErrCde = DRV_EnableEvent(DriverHandle, &ptEnableEvent);
ptEnableEvent.EventType = ADS_EVT_DO_TERMINATED; // Fast DI function terminated
ErrCde = DRV_EnableEvent(DriverHandle, &ptEnableEvent);
if (ErrCde != 0)
{
DRV_GetErrorMessage(ErrCde,(LPSTR)szErrMsg);
MessageBox(hWnd,(LPCSTR)szErrMsg,"Driver Message",MB_OK);
// GlobalFree( hUserBuf );
// Decommit first, then release the memory
VirtualFree( hUserBuf, dwUserBufferSize, MEM_DECOMMIT );
VirtualFree( hUserBuf, 0, MEM_RELEASE);
DRV_DeviceClose((LONG far *)&DriverHandle);
return 0;
}
// 32DI(0)/32DO(1)/ 16 DIO(2) / 8DIO(3)
switch( gdwDataWidth )
{
case 3:
for ( i = 0 ; i < dwUserBufferSize; i++)
{
((PUCHAR)hUserBuf)[i] = (BYTE)gdwDigitalOut;
}
dwCount = dwUserBufferSize;
break;
case 2:
for ( i = 0 ; i < dwUserBufferSize/2; i++)
{
((PUSHORT)hUserBuf)[i] = (USHORT) gdwDigitalOut;
}
dwCount = dwUserBufferSize/2;
break;
default:
for ( i = 0 ; i < dwUserBufferSize/4; i++)
{
((PULONG)hUserBuf)[i] = (ULONG)gdwDigitalOut;
}
dwCount = dwUserBufferSize/4;
break;
}
ErrCde = DRV_DeviceSetProperty(DriverHandle, CFG_DoOperationMode, &gdwOperationMode, sizeof(DWORD));
ErrCde = DRV_DeviceSetProperty(DriverHandle, CFG_CounterCountValue, &gdwCounterValue, 3*sizeof(DWORD));
ErrCde = DRV_DeviceSetProperty(DriverHandle, CFG_DioFdioDirection, &gdwDataWidth, sizeof(DWORD));
ErrCde = DRV_DeviceSetProperty(DriverHandle, CFG_DoStartMethod, &gdwDOStartMode, sizeof(DWORD));
ErrCde = DRV_DeviceSetProperty(DriverHandle, CFG_DoStopMethod, &gdwDOStopMode, sizeof(DWORD));
ErrCde = DRV_DeviceSetProperty(DriverHandle, CFG_DoPacerSource, &gdwDOTriggerSource, sizeof(DWORD));
if( BD_MIC3755 == gdwBoardId )
{
ErrCde = DRV_DeviceSetProperty(DriverHandle, CFG_DoTransferRequestMode, &gdwDmaMode, sizeof(DWORD));
}
if (ErrCde != 0)
{
DRV_GetErrorMessage(ErrCde,(LPSTR)szErrMsg);
MessageBox(hWnd,(LPCSTR)szErrMsg,"Driver Message",MB_OK);
// GlobalFree( hUserBuf );
// Decommit first, then release the memory
VirtualFree( hUserBuf, dwUserBufferSize, MEM_DECOMMIT );
VirtualFree( hUserBuf, 0, MEM_RELEASE);
DRV_DeviceClose((LONG far *)&DriverHandle);
return 0;
}
// Step 5: Start fast DO
ErrCde = DRV_FDOStart(
DriverHandle, //Device handle
gdwCyclicMode, //Cyclic(1)/non cyclic
dwCount, //Data counts
hUserBuf ); //Data buffer.
if (ErrCde != 0)
{
DRV_GetErrorMessage(ErrCde,(LPSTR)szErrMsg);
MessageBox(hWnd,(LPCSTR)szErrMsg,"Driver Message",MB_OK);
// GlobalFree( hUserBuf );
// Decommit first, then release the memory
VirtualFree( hUserBuf, dwUserBufferSize, MEM_DECOMMIT );
VirtualFree( hUserBuf, 0, MEM_RELEASE);
DRV_DeviceClose((LONG far *)&DriverHandle);
return 0;
}
hThreadHandle = CreateThread(0, 0,
(LPTHREAD_START_ROUTINE) UserThread,
0, 0, (LPDWORD)&dwThreadID);
bThreadloop = TRUE;
Sleep(0);
EnableMenuItem(hMenu, IDM_RUN, MF_DISABLED | MF_BYCOMMAND);
// Enable stop and status buttons
if( gdwCyclicMode )
{
EnableWindow( hwndStatusButton, TRUE );
EnableWindow( hwndStopButton, TRUE );
}
else
{
EnableWindow( hwndStatusButton, FALSE );
EnableWindow( hwndStopButton, TRUE );
}
return 0;
//end IDM_RUN
case IDC_STOPBUTTON:
{
//BOOL bflag = TRUE;
// Close thread
//bThreadloop = FALSE;
//Sleep(100);
ErrCde = DRV_FDOStop(DriverHandle);
if (ErrCde != 0)
{
DRV_GetErrorMessage(ErrCde,(LPSTR)szErrMsg);
MessageBox(hWnd,(LPCSTR)szErrMsg,"Driver Error",MB_OK);
return 0;
}
// stop fdo function
/*adTerminateEvent();
EnableWindow(hwndStopButton, FALSE);
EnableWindow(hwndStatusButton, FALSE);
// Step 3: Free buffer
// GlobalFree(hUserBuf);
// Decommit first, then release the memory
VirtualFree( hUserBuf, (DWORD)(Mega * pow((double)2, (double)gdwUserBufferSize)), MEM_DECOMMIT );
VirtualFree( hUserBuf, 0, MEM_RELEASE);
// Step 4: Close driver
if ( DriverHandle )
{
DRV_DeviceClose((LONG far *)&DriverHandle);
}
EnableMenuItem(hMenu, IDM_RUN, MF_ENABLED | MF_BYCOMMAND);
*/
return 0;
}
case IDC_STATUSBUTTON:
{
ErrCde = DRV_FDOCheck( DriverHandle, &dwFdoStatus, &dwRetrieved);
// Display the status of the A/D conversion
sprintf(szDest, "Cyclic Counts: %d\n", gdwDOBufferChangeCounter / 2);
if ( dwFdoStatus & 0x1 ) // Running
{
strcpy(szTemp, "Running\n");
}
else // Stopped
{
strcpy(szTemp, "FDI: Stopped\n");
}
strcat(szDest, szTemp);
dwUserBufferSize = (DWORD)(Mega * pow((double)2, (double)gdwUserBufferSize));
// 32DI(0)/32DO(1)/ 16 DIO(2) / 8DIO(3)
switch( gdwDataWidth )
{
case 3:
dwCount = dwUserBufferSize;
break;
case 2:
dwCount = dwUserBufferSize / 2;
break;
default:
dwCount = dwUserBufferSize / 4;
break;
}
ratio = 100.0 * dwRetrieved / dwCount;
szStr = fcvt((double)ratio, 0, &dec, &sign);
strcat(szDest, "Finish: ");
strcat(szDest, szStr);
strcat(szDest, "%...");
MessageBox(hWnd,(LPCSTR)szDest, "Check Status", MB_OK);
}
return 0;
}
case WM_CLOSE:
if( IsWindowEnabled(hwndStopButton))
{
MessageBox(hWnd,"The program is running, please push the stop button to stop. ",
"Close", MB_ICONEXCLAMATION | MB_ICONWARNING);
return 0;
}
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return (DefWindowProc(hWnd, message, wParam, lParam));
}
return ((LONG)NULL);
}
//------------------------------------------------------------------
void UserThread()
{
USHORT usEventType;
LONG ErrCde;
gdwDOBufferChangeCounter = 0;
gdwDOUnderRunCounter = 0;
gdwDOTerminateCounter = 0;
hdc = GetDC( hWnd );
GetClientRect( hWnd, &rect );
InvalidateRect( hWnd, NULL, TRUE );
UpdateWindow( hWnd );
while(bThreadloop)
{
// Check message
ptCheckEvent.EventType = &usEventType;
ptCheckEvent.Milliseconds = gulOverrunTime;
bThreadflag = TRUE;
ErrCde = DRV_CheckEvent(DriverHandle, (LPT_CheckEvent)&ptCheckEvent);
if ( usEventType == ADS_EVT_DO_LOBUFTRANS ) // Driver finish the fill low buffer data
{
DRV_ClearFlag( DriverHandle, ADS_EVT_DO_UNDERRUN);
gdwDOBufferChangeCounter++;
}
else if( usEventType == ADS_EVT_DO_HIBUFTRANS )
{
DRV_ClearFlag( DriverHandle, ADS_EVT_DO_UNDERRUN);
gdwDOBufferChangeCounter++;
}
else if ( usEventType == ADS_EVT_DO_TERMINATED )
{
gdwDOTerminateCounter++;
bThreadloop = FALSE; // Stop the thread
bThreadflag = FALSE;
adTerminateEvent();
EnableWindow(hwndStopButton, FALSE);
EnableWindow(hwndStatusButton, FALSE);
}
else if ( usEventType == ADS_EVT_DO_UNDERRUN )
{
DRV_ClearFlag( DriverHandle, ADS_EVT_DO_UNDERRUN);
gdwDOUnderRunCounter++;
}
bThreadflag = FALSE;
sprintf( szCounter, "Buffer Change Count = %4d\n", gdwDOBufferChangeCounter );
TextOut( hdc, 300, 50, szCounter, 26 );
sprintf( szCounter, "Underrun Count = %4d\n", gdwDOUnderRunCounter );
TextOut( hdc, 300, 70, szCounter, 21 );
sprintf( szCounter, "Terminate Count = %4d\n",gdwDOTerminateCounter );
TextOut( hdc, 300, 90, szCounter, 22 );
UpdateWindow( hWnd );
}
bThreadflag = FALSE;
ReleaseDC( hWnd, hdc );
/*
GetExitCodeThread(
hThreadHandle, // handle to the thread
&dwExitCode ); // termination status
TerminateThread( hThreadHandle, dwExitCode );
*/
}
//-----------------------------------------------------------------------------
void adTerminateEvent()
{
bThreadloop = FALSE;
bThreadflag = FALSE;
ErrCde = DRV_FDOStop(DriverHandle);
if (ErrCde != 0)
{
DRV_GetErrorMessage(ErrCde,(LPSTR)szErrMsg);
MessageBox(hWnd,(LPCSTR)szErrMsg,"Driver Error",MB_OK);
return ;
}
//
// Disable open Event
//
ptEnableEvent.Enabled = 0;
ptEnableEvent.EventType = ADS_EVT_DO_UNDERRUN; // Overrun event
DRV_EnableEvent(DriverHandle, &ptEnableEvent);
ptEnableEvent.EventType = ADS_EVT_DO_LOBUFTRANS; // Low buffer transfered event
DRV_EnableEvent(DriverHandle, &ptEnableEvent);
ptEnableEvent.EventType = ADS_EVT_DO_HIBUFTRANS; // High buffer transfered event.
DRV_EnableEvent(DriverHandle, &ptEnableEvent);
ptEnableEvent.EventType = ADS_EVT_DO_TERMINATED; // Fast DO function terminated
DRV_EnableEvent(DriverHandle, &ptEnableEvent);
// GetExitCodeThread(hThreadHandle,&ExitCode);
// if(ExitCode==STILL_ACTIVE)
// TerminateThread(hThreadHandle,ExitCode);
if (ErrCde != 0)
{
DRV_GetErrorMessage(ErrCde,(LPSTR)szErrMsg);
MessageBox(hWnd,(LPCSTR)szErrMsg,"Driver Error",MB_OK);
return ;
}
// Free buffer
// GlobalFree(hUserBuf);
// Decommit first, then release the memory
VirtualFree( hUserBuf, (DWORD)(Mega * pow((double)2, (double)gdwUserBufferSize)), MEM_DECOMMIT );
VirtualFree( hUserBuf, 0, MEM_RELEASE);
/*
GetExitCodeThread(
hThreadHandle, // handle to the thread
&dwExitCode ); // termination status
TerminateThread( hThreadHandle, dwExitCode );
*/
// Close driver
if ( DriverHandle )
{
DRV_DeviceClose((LONG far *)&DriverHandle);
}
EnableMenuItem(hMenu, IDM_RUN, MF_ENABLED | MF_BYCOMMAND);
return;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -