diff options
Diffstat (limited to 'Sensors/SimpleDeviceOrientationSensor/hardwaresimulator.cpp')
| -rw-r--r-- | Sensors/SimpleDeviceOrientationSensor/hardwaresimulator.cpp | 248 |
1 files changed, 248 insertions, 0 deletions
diff --git a/Sensors/SimpleDeviceOrientationSensor/hardwaresimulator.cpp b/Sensors/SimpleDeviceOrientationSensor/hardwaresimulator.cpp new file mode 100644 index 00000000..759338cd --- /dev/null +++ b/Sensors/SimpleDeviceOrientationSensor/hardwaresimulator.cpp @@ -0,0 +1,248 @@ +//Copyright (C) Microsoft Corporation, All Rights Reserved. +// +//Abstract: +// +// This module contains the implementation of the simple device orientation sensor sample +// hardware simulator. +// +//Environment: +// +// Windows User-Mode Driver Framework (UMDF) + +#include "HardwareSimulator.h" + +#include "HardwareSimulator.tmh" + +// Simulated device orientations +const ABI::Windows::Devices::Sensors::SimpleOrientation OrientationData[] = { + ABI::Windows::Devices::Sensors::SimpleOrientation::SimpleOrientation_Facedown, + ABI::Windows::Devices::Sensors::SimpleOrientation::SimpleOrientation_NotRotated, + ABI::Windows::Devices::Sensors::SimpleOrientation::SimpleOrientation_Faceup, + ABI::Windows::Devices::Sensors::SimpleOrientation::SimpleOrientation_Rotated90DegreesCounterclockwise, + ABI::Windows::Devices::Sensors::SimpleOrientation::SimpleOrientation_Facedown, + ABI::Windows::Devices::Sensors::SimpleOrientation::SimpleOrientation_Rotated180DegreesCounterclockwise, + ABI::Windows::Devices::Sensors::SimpleOrientation::SimpleOrientation_Faceup, + ABI::Windows::Devices::Sensors::SimpleOrientation::SimpleOrientation_Rotated270DegreesCounterclockwise +}; + +HardwareSimulator::_HardwareSimulator() : + m_Index(0), + m_Lock(NULL), + m_State(SimulatorState_NotInitialized), + m_SimulatorInstance(NULL), + m_Timer(NULL) +{ +} + +HardwareSimulator::~_HardwareSimulator() +{ +} + +// This static routine performs simulator initialization. The routine creates a +// timer object that periodically updates the m_Index location +// Returns an NTSTATUS code +NTSTATUS HardwareSimulator::Initialize( + _In_ WDFDEVICE Device, // WDF device representing the sensor + _Out_ WDFOBJECT *SimulatorInstance) // Instance of the WDF object for the simulator +{ + PHardwareSimulator pSimulator = nullptr; + NTSTATUS Status = STATUS_SUCCESS; + WDF_OBJECT_ATTRIBUTES HardwareSimulatorAttributes = {}; + + SENSOR_FunctionEnter(); + + // Create WDFOBJECT for the hardware simulator + WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&HardwareSimulatorAttributes, HardwareSimulator); + HardwareSimulatorAttributes.ParentObject = Device; + + Status = WdfObjectCreate(&HardwareSimulatorAttributes, SimulatorInstance); + if (!NT_SUCCESS(Status)) + { + TraceError("SDOS %!FUNC! WdfObjectCreate failed %!STATUS!", Status); + goto Exit; + } + + pSimulator = GetHardwareSimulatorContextFromInstance(*SimulatorInstance); + if (nullptr == pSimulator) + { + Status = STATUS_INSUFFICIENT_RESOURCES; + TraceError("SDOS %!FUNC! GetHardwareSimulatorContextFromInstance failed %!STATUS!", Status); + goto Exit; + } + + pSimulator->InitializeInternal(*SimulatorInstance); + +Exit: + + SENSOR_FunctionExit(Status); + + return Status; +} + +// Internal routine to perform simulator initialization +// Returns an NTSTATUS code +NTSTATUS HardwareSimulator::InitializeInternal( + _In_ WDFOBJECT SimulatorInstance) // Instance of the WDF object for the simulator +{ + NTSTATUS Status = STATUS_SUCCESS; + WDF_OBJECT_ATTRIBUTES TimerAttributes = {}; + WDF_TIMER_CONFIG TimerConfig = {}; + + SENSOR_FunctionEnter(); + + // Only initialize the simulator if it is in the "not initialized" state + if (SimulatorState_NotInitialized == m_State) + { + // Create Lock + Status = WdfWaitLockCreate(WDF_NO_OBJECT_ATTRIBUTES, &m_Lock); + if (!NT_SUCCESS(Status)) + { + m_Lock = NULL; + + TraceError("SDOS %!FUNC! WdfWaitLockCreate failed %!STATUS!", Status); + goto Exit; + } + + // Create a timer object for simulation updates + WDF_TIMER_CONFIG_INIT(&TimerConfig, HardwareSimulator::OnTimerExpire); + WDF_OBJECT_ATTRIBUTES_INIT(&TimerAttributes); + TimerAttributes.ParentObject = SimulatorInstance; + TimerAttributes.ExecutionLevel = WdfExecutionLevelPassive; + + Status = WdfTimerCreate(&TimerConfig, &TimerAttributes, &m_Timer); + if (!NT_SUCCESS(Status)) + { + m_Timer = NULL; + + TraceError("SDOS %!FUNC! WdfTimerCreate failed %!STATUS!", Status); + goto Exit; + } + + // Set the simulator state to "initialized" + m_State = SimulatorState_Initialized; + m_SimulatorInstance = SimulatorInstance; + } + +Exit: + if (!NT_SUCCESS(Status) && NULL != m_Lock) + { + WdfObjectDelete(m_Lock); + m_Lock = NULL; + } + + SENSOR_FunctionExit(Status); + + return Status; +} + +// This routine perform a simulator cleanup +// Returns an NTSTATUS code +NTSTATUS HardwareSimulator::Cleanup() +{ + NTSTATUS status = STATUS_SUCCESS; + + if (SimulatorState_Started == m_State) + { + Stop(); + } + + // Delete lock + if (NULL != m_Lock) + { + WdfObjectDelete(m_Lock); + m_Lock = NULL; + } + + // Set the simulator state to "not initialized" + m_State = SimulatorState_NotInitialized; + + return status; +} + +// This routine starts the simulator +// Returns an NTSTATUS code +NTSTATUS HardwareSimulator::Start() +{ + NTSTATUS status = STATUS_SUCCESS; + + SENSOR_FunctionEnter(); + + if (SimulatorState_Initialized == m_State) + { + WdfTimerStart(m_Timer, WDF_REL_TIMEOUT_IN_MS(HardwareSimulator_HardwareInterval)); + m_State = SimulatorState_Started; + } + + SENSOR_FunctionExit(status); + + return status; +} + +// This routine stops the simulator +// Returns an NTSTATUS code +NTSTATUS HardwareSimulator::Stop() +{ + NTSTATUS status = STATUS_SUCCESS; + + SENSOR_FunctionEnter(); + + if (SimulatorState_Started == m_State) + { + WdfTimerStop(m_Timer, TRUE); + m_State = SimulatorState_Initialized; + } + + SENSOR_FunctionExit(status); + + return status; +} + +// This callback is called when the simulator wait time has expired and the simulator +// is ready to switch to the next sample. The callback updates the sample index and +// schedules the next wake up time. +VOID HardwareSimulator::OnTimerExpire( + _In_ WDFTIMER Timer) // WDF timer object +{ + HardwareSimulator *pSimulator = nullptr; + NTSTATUS Status = STATUS_SUCCESS; + + SENSOR_FunctionEnter(); + + pSimulator = GetHardwareSimulatorContextFromInstance(WdfTimerGetParentObject(Timer)); + if (nullptr == pSimulator) + { + Status = STATUS_INSUFFICIENT_RESOURCES; + TraceError("SDOS %!FUNC! GetHardwareSimulatorContextFromInstance failed %!STATUS!", Status); + } + + if (NT_SUCCESS(Status)) + { + // Increment the sample index, roll over if the index reach the end of the array + WdfWaitLockAcquire(pSimulator->m_Lock, NULL); + pSimulator->m_Index++; + pSimulator->m_Index %= ARRAYSIZE(OrientationData); + WdfWaitLockRelease(pSimulator->m_Lock); + + WdfTimerStart(pSimulator->m_Timer, WDF_REL_TIMEOUT_IN_MS(HardwareSimulator_HardwareInterval)); + } + + SENSOR_FunctionExit(Status); +} + +// This routine returns the current sample from the driver at the current m_Index location. +// Returns one of the ABI::Windows::Devices::Sensors::SimpleOrientation enum values. +ABI::Windows::Devices::Sensors::SimpleOrientation HardwareSimulator::GetOrientation() +{ + ABI::Windows::Devices::Sensors::SimpleOrientation Sample = ABI::Windows::Devices::Sensors::SimpleOrientation::SimpleOrientation_Faceup; + NTSTATUS Status = STATUS_SUCCESS; + + SENSOR_FunctionEnter(); + + WdfWaitLockAcquire(m_Lock, NULL); + Sample = OrientationData[m_Index]; + WdfWaitLockRelease(m_Lock); + + SENSOR_FunctionExit(Status); + + return Sample; +}
\ No newline at end of file |
