Periodic WdfTimer() fires only once

Hi. I’m trying to use a ~2ms periodic, DISPATCH-level timer in a KMDF driver. Code Below:

#define TIMEOUTPERIOD WDF_ABS_TIMEOUT_IN_MS(2)
.
.
    WDF_TIMER_CONFIG  timerConfigPeriodic;
    WDF_OBJECT_ATTRIBUTES  timerAttributes;

    // Create HR position reporting, DISPATCH-level timer
    WDF_TIMER_CONFIG_INIT_PERIODIC(&timerConfigPeriodic, SyncStreamController::sTimerFunc, TIMEOUTPERIOD);
    timerConfigPeriodic.UseHighResolutionTimer = WdfTrue;
    timerConfigPeriodic.AutomaticSerialization = FALSE;

    WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&timerAttributes, SSCTIMERCONTEXT);   // Create enough context to store this* and a UINT64
    timerAttributes.ParentObject = mWdfDevice;
    timerAttributes.ExecutionLevel = WdfExecutionLevelDispatch;

    status = WdfTimerCreate(&timerConfigPeriodic, &timerAttributes, &m_PositionTimer);
    if (!NT_SUCCESS(status))
    {
        TraceError("SyncStreamController::init - WdfTimerCreate(m_PositionTimer) Failed!!  status:0x%llx", status);
    }
    *(StreamingWatchdogContext(m_PositionTimer)) = { this, UINT64(STREAMPOS_SIG) };  // Stash this away for use by the timer routine
.
.
.
SetPositionTimer(TIMEOUTPERIOD);
.
.
.
void SetPositionTimer(LONGLONG period)
{
    BOOL b = FALSE;
    
    if (period == 0)
    {
       b = WdfTimerStop(m_PositionTimer, FALSE);
    }
    else
    {
        b = WdfTimerStart(m_PositionTimer, -period);
    }
    TraceVerbose(TRACEFLG_AUDIOCALLBACKS, "+++ SetPositionTimer(%lld) :%d ---", period, b);
}

The timer fires once, about 4ms later, and NEVER again. Changing the timeout to a larger value, say 20ms makes NO difference. The framework logs report nothing.

Any help is greatly appreciated!

-wade

#define TIMEOUTPERIOD WDF_ABS_TIMEOUT_IN_MS(2)
That is a 64 bit value that represents the time 1.1.1600:0:0:0.2 instead you want #define TIMEOUTPERIOD 2000

As Mark said you have a mismatch of data type for the period parameter to WDF_TIMER_CONFIG_INIT_PERIODIC.
According to the documentation, period is a time 32-bit value in milliseconds.

The macro WDF_ABS_TIMEOUT_IN_MS(2) returns a 64-bit system time (100-ns intervals) per the documentation

Right. In the WDM timer APIs, an “absolute” timeout refers to matching the literal value of the system clock. This is only useful if you read the current clock and add your timeout value to it. A “relative” timeout (specified as a negative number) refers to a time “from now”. The system adds your value to the system clock to get the wake up time.

Neither of those are used in WDF_TIMER_CONFIG_INIT_PERIODIC, which uses plain, ordinary milliseconds. Documentation is a good thing.

Actually #define TIMEOUTPERIOD 2 if you want 2ms

Thanks guys! RTFM - sheesh.