AIOWDG

General Notes

Numbering Cards

Most AIOWDG functions take a signed 32-bit integer CardNum. Usually, CardNum = 0 because there's only one watchdog card in the system. You can simply use WDGPet(0); to pet the only watchdog card installed, and such. If, however, you have multiple watchdog cards in the system, see the Multi-Card Functions below.

Error Codes And Other Return Values

Most functions return a UInt32 error code. On a success, this will be zero (= ERROR_SUCCESS). On a failure, it will be nonzero, and equal to some other Windows error code. See WinError.h for details; if your IDE doesn't provide Windows error codes, you can find WinError.h readily on the Web.

A few multi-card functions return an SInt32 number, which is a card number (or, technically, comparable to card numbers).

Export & Import

AIOWDG's functions are similar to — but not the same as — their equivalents in AIOWDM. All of these functions are exported three times:

Basic Watchdog Functions

In general, you'll want to call WDGInit(), WDGSetTimeout(), then WDGStart() at initialization, call WDGPet() periodically during operation, then call WDGStop() at deinitialization. During watchdog timing, you must "pet" often enough, or the watchdog will "growl", and then if it still isn't pet, "bark".

UInt32 WDGInit(SInt32 CardNum);

As in AIOWDM, this initializes watchdog operation.

UInt32 WDGSetTimeout(SInt32 CardNum, Double *pMilliseconds);

Sets how often the watchdog must be pet. It's best to leave some margin for error; for example, if you plan to pet every 10 seconds, you could specify a timeout of 11,000 milliseconds.

UInt32 WDGStart(SInt32 CardNum);

Starts the watchdog timing. After this, until WDGStop(), the watchdog must be pet.

UInt32 WDGStop(SInt32 CardNum);

Stops the watchdog timing.

UInt32 WDGPet(SInt32 CardNum);

Pets the watchdog.

Advanced Watchdog Functions

UInt32 WDGSetResetDuration(SInt32 CardNum, Double *pMilliseconds);

Sets how long the watchdog will hold the reset, once it barks. However, if the watchdog itself loses power when it barks, this duration is largely irrelevant.

UInt32 WDGReadTemp(SInt32 CardNum, Double *TempF);

Reads the thermometer on the watchdog card, if installed.

UInt32 WDGReadStatus(SInt32 CardNum, UInt32 *StatusByte);

Reads the watchdog's status, expressed in the form of a PCI-WDG-CSM status byte.

UInt32 EmergencyReboot();

Intended for use in WaitForWDG worker threads, to initiate a "hard" reboot command.

UInt32 WaitForWDG(SInt32 CardNum);

Does not return until aborted, or the watchdog growls. If the process being monitored is not entirely locked up, this can be used to interrupt the process and return to normal petting operation. This is intended to be called from a high-priority worker thread; that way, the thread consumes no CPU while waiting, but once there's a growl, the thread comes out of the wait even if normal-priority threads are hogging the CPU. If aborted, returns ERROR_OPERATION_ABORTED instead of ERROR_SUCCESS.

UInt32 AbortWDGRequest(SInt32 CardNum);

Aborts a waiting WaitForWDG() call. Intended for use during deinitialization.

UInt32 WDGHandleIRQ(SInt32 CardNum, UInt32 Action);

Launches its own thread to call WaitForWDG(), then responds with the indicated action. Action codes are the same as for AIOWDM.

UInt32 WaitForCOS(SInt32 CardNum, UInt8 *pDIData);

Does not return until aborted, or a change-of-state(COS) event occurs. This is intended to be called from a worker thread; that way, the thread consumes no CPU while waiting. If aborted, returns ERROR_OPERATION_ABORTED instead of ERROR_SUCCESS.

UInt32 WaitForCOSMulti(SInt32 CardNum, SInt32 *pTimestamp, SInt32 DISize, UInt8 *pDIData, Double *pAIData);

Like WaitForCOS(), except it also provides a timestamp and the digital and analog readings at the time of the COS event.

UInt32 AbortCOSRequest(SInt32 CardNum);

Aborts a waiting WaitForCOS() call. Intended for use during deinitialization.

UInt32 ReadTimestamp(SInt32 CardNum, UInt16 *pTimestamp);

Reads the current timestamp. Intended for use in interpreting the timestamps returned by WaitForCOSMulti().

DIO And ADC Functions

UInt32 DI_ReadAll(SInt32 CardNum, UInt8 *pDIData);

Reads all the digital inputs into the provided buffer. Each bit corresponds to a single input; see the sample for details. This also resets the digital input latches.

UInt32 DI_Read1(SInt32 CardNum, UInt8 BitIndex, Bool32 *pBitValue);

Reads the specified digital input into the provided variable. This also resets the digital input latches.

UInt32 DI_ReadLatched(SInt32 CardNum, UInt8 *pDIRisen, UInt8 *pDIFallen);

Reads the digital input latches into the provided buffers, and resets the latches. *pDIRisen indicates which digital inputs have had a rising edge since last reset, while *pDIFallen does the same for falling edges.

UInt32 DI_PeekAll(SInt32 CardNum, UInt8 *pDIData);

Like DI_ReadAll(), except it doesn't reset the latches.

UInt32 DI_Peek1(SInt32 CardNum, UInt8 BitIndex, Bool32 *pBitValue);

Like DI_Read1(), except it doesn't reset the latches.

UInt32 DI_SetDebounceAll(SInt32 CardNum, UInt8 TimeMS);

Sets a debouncing time constant for all the digital inputs. If the signals have high-frequency noise, this can be used to ignore it. This applies to all uses of the digital inputs, including reading, latching, and COS events.

UInt32 DI_SetDebounce1(SInt32 CardNum, UInt8 BitIndex, UInt8 TimeMS);

Sets a debouncing time constant for the specified digital input.

UInt32 DI_SetDebounceSome(SInt32 CardNum, UInt8 BitMask, UInt8 TimeMS);

Sets a debouncing time constant for the specified digital inputs. Each digital input whose bit is set in the bit mask will get the provided time constant.

UInt32 DO_WriteAll(SInt32 CardNum, UInt8 DOData);

Writes to all the digital outputs. Each bit corresponds to a single output; see the sample for details.

UInt32 DO_Write1(SInt32 CardNum, UInt8 BitIndex, Bool32 BitValue);

Writes to the specified digital output.

UInt32 AI_ReadAll(SInt32 CardNum, Double *pAIData);

Reads all the analog inputs into the provided buffer. The pointer should point to the first of an array of IEEE double-precision floating-point entries.

UInt32 AI_Read1(SInt32 CardNum, UInt8 ChannelIndex, Double *pAIData);

Reads the specified analog input into the provided variable.

Multi-Card Functions

If you have multiple AIOWDG cards in the system, you can use these functions to identify them. Here's an example, recognizing the cards by their serial numbers:


	NumCards = GetNumCards();
	for ( ThisCard = 0; ThisCard < NumCards; ++ThisCard )
	{
		Err = QuerySerialNumber(ThisCard, @ThisSN);
		if ( Err == ERROR_SUCCESS )
			for ( I = 0; I < WDGOb.Length(); ++I )
				if ( ThisSN == WDGOb[I].SN )
				{
					WDGOb[I].CardNum = ThisCard;
					break;
				}
	}

SInt32 GetNumCards();

Returns how many cards are installed. The cards will be numbered from 0 to GetNumCards()-1. For example, if GetNumCards() returns 4, then those four cards are numbered 0, 1, 2, and 3. You can then query them, notably their serial numbers, to determine which is which.

UInt32 QueryCardID(SInt32 CardNum, UInt32 *pDeviceID);

Reads the card's ID into the provided variable. This can be used to tell a PCIe-WDG-CSMA from a PCIe-WDG-CSM.

UInt32 QueryCardName(SInt32 CardNum, UInt32 *pNameSize, Char8 *pName);

Reads the card's "friendly name" string into the provided buffer. *pNameSize should contain the length of the buffer when called, and upon return will contain the length of the string read into the buffer.

UInt32 QuerySerialNumber(SInt32 CardNum, SInt64 *pSerialNumber);

Reads the card's internal software serial number into the provided variable. This can be used to tell each individual card apart, but may be too specific — it doesn't support drop-in replacement with another card of the exact same model.

UInt32 QueryCardInfo(SInt32 CardNum, UInt32 *pDeviceID, UInt32 *pBase, UInt32 *pNameSize, Char8 *pName);

Like QueryCardID() and QueryCardName(), in a single call. The "base address" provided is not meaningful. Intended for easy conversion from AIOWDM.

UInt32 AIOWDG_CloseDevice(SInt32 CardNum);

Closes the internal handles to the card. AIOWDG.dll will close all handles upon exit, so this is strictly optional in current driver versions.

SInt32 GetDeviceBySerialNumber(SInt64 *pSerialNumber);

Returns the CardNum of the card with the specified serial number, or -1 if there is no such card.