633 lines
17 KiB
C++
633 lines
17 KiB
C++
//==========================================================================;
|
|
//
|
|
//
|
|
// Gpio.cpp
|
|
// Gpio Class implementation
|
|
// Based on code from ATI Technologies Inc. Copyright (c) 1996 - 1997
|
|
//
|
|
// ATIConfg.CPP
|
|
// WDM MiniDrivers development.
|
|
// ATIHwConfiguration class implementation.
|
|
// Copyright (c) 1996 - 1997 ATI Technologies Inc. All Rights Reserved.
|
|
//
|
|
//==========================================================================;
|
|
|
|
extern "C"
|
|
{
|
|
#include <wdm.h>
|
|
}
|
|
|
|
#include <unknown.h>
|
|
#include "ks.h"
|
|
#include "ksmedia.h"
|
|
#include <ksdebug.h>
|
|
#include "gpio.h"
|
|
#include "wdmdebug.h"
|
|
|
|
//$REVIEW - Let's find a way to get the proper module name into this
|
|
//
|
|
#define MODULENAME "PhilTune"
|
|
#define MODULENAMEUNICODE L"PhilTune"
|
|
|
|
#define STR_MODULENAME MODULENAME
|
|
|
|
#define ENSURE do
|
|
#define END_ENSURE while( FALSE)
|
|
#define FAIL break
|
|
|
|
|
|
|
|
|
|
/*^^*
|
|
* CGpio()
|
|
* Purpose : CGpio Class constructor
|
|
* Determines I2CExpander address and all possible hardware IDs and addresses
|
|
*
|
|
* Inputs : PDEVICE_OBJECT pDeviceObject : pointer to the creator DeviceObject
|
|
* CI2CScript * pCScript : pointer to the I2CScript class object
|
|
* PUINT puiError : pointer to return Error code
|
|
*
|
|
* Outputs : none
|
|
* Author : IKLEBANOV
|
|
*^^*/
|
|
CGpio::CGpio( PDEVICE_OBJECT pDeviceObject, NTSTATUS * pStatus)
|
|
{
|
|
*pStatus = STATUS_SUCCESS;
|
|
|
|
ENSURE
|
|
{
|
|
m_gpioProviderInterface.gpioOpen = NULL;
|
|
m_gpioProviderInterface.gpioAccess = NULL;
|
|
m_pdoDriver = NULL;
|
|
|
|
|
|
if( InitializeAttachGPIOProvider( &m_gpioProviderInterface, pDeviceObject))
|
|
{
|
|
// There was no error to get GPIOInterface from the MiniVDD
|
|
//
|
|
m_pdoDriver = pDeviceObject;
|
|
}
|
|
else
|
|
{
|
|
* pStatus = STATUS_NOINTERFACE;
|
|
FAIL;
|
|
}
|
|
|
|
} END_ENSURE;
|
|
|
|
_DbgPrintF( DEBUGLVL_VERBOSE, ( "CGPio:CGpio() Status=%x\n", * pStatus));
|
|
}
|
|
|
|
|
|
|
|
|
|
/*^^*
|
|
* GPIOIoSynchCompletionRoutine()
|
|
* Purpose : This routine is for use with synchronous IRP processing.
|
|
* All it does is signal an event, so the driver knows it and can continue.
|
|
*
|
|
* Inputs : PDEVICE_OBJECT DriverObject : Pointer to driver object created by system
|
|
* PIRP pIrp : Irp that just completed
|
|
* PVOID Event : Event we'll signal to say Irp is done
|
|
*
|
|
* Outputs : none
|
|
* Author : IKLEBANOV
|
|
*^^*/
|
|
extern "C"
|
|
NTSTATUS GPIOIoSynchCompletionRoutine( IN PDEVICE_OBJECT pDeviceObject,
|
|
IN PIRP pIrp,
|
|
IN PVOID Event)
|
|
{
|
|
|
|
KeSetEvent(( PKEVENT)Event, 0, FALSE);
|
|
return( STATUS_MORE_PROCESSING_REQUIRED);
|
|
}
|
|
|
|
|
|
|
|
/*^^*
|
|
* InitializeAttachGPIOProvider()
|
|
* Purpose : determines the pointer to the parent GPIO Provider interface
|
|
* This function will be called at Low priority
|
|
*
|
|
* Inputs : GPIOINTERFACE * pGPIOInterface : pointer to the Interface to be filled in
|
|
* PDEVICE_OBJECT pDeviceObject : MiniDriver device object, which is a child of GPIO Master
|
|
*
|
|
* Outputs : BOOL - returns TRUE, if the interface was found
|
|
* Author : IKLEBANOV
|
|
*^^*/
|
|
BOOL CGpio::InitializeAttachGPIOProvider( GPIOINTERFACE * pGPIOInterface, PDEVICE_OBJECT pDeviceObject)
|
|
{
|
|
BOOL bResult;
|
|
|
|
// Find the GPIO provider
|
|
bResult = LocateAttachGPIOProvider( pGPIOInterface, pDeviceObject, IRP_MJ_PNP);
|
|
if(( pGPIOInterface->gpioOpen == NULL) || ( pGPIOInterface->gpioAccess == NULL))
|
|
{
|
|
// TRAP;
|
|
_DbgPrintF( DEBUGLVL_ERROR,
|
|
( "CGpio(): GPIO interface has NULL pointers\n")
|
|
);
|
|
bResult = FALSE;
|
|
}
|
|
|
|
return( bResult);
|
|
}
|
|
|
|
|
|
|
|
/*^^*
|
|
* LocateAttachGPIOProvider()
|
|
* Purpose : gets the pointer to the parent GPIO Provider interface
|
|
* This function will be called at Low priority
|
|
*
|
|
* Inputs : GPIOINTERFACE * pGPIOInterface : pointer to the Interface to be filled in
|
|
* PDEVICE_OBJECT pDeviceObject : MiniDriver device object, which is a child of I2C Master
|
|
* int nIrpMajorFunction : IRP major function to query the GPIO Interface
|
|
*
|
|
* Outputs : BOOL - returns TRUE, if the interface was found
|
|
* Author : IKLEBANOV
|
|
*^^*/
|
|
BOOL CGpio::LocateAttachGPIOProvider( GPIOINTERFACE * pGPIOInterface, PDEVICE_OBJECT pDeviceObject, int nIrpMajorFunction)
|
|
{
|
|
PIRP pIrp;
|
|
BOOL bResult = FALSE;
|
|
|
|
ENSURE
|
|
{
|
|
PIO_STACK_LOCATION pNextStack;
|
|
NTSTATUS ntStatus;
|
|
KEVENT Event;
|
|
|
|
|
|
pIrp = IoAllocateIrp( pDeviceObject->StackSize, FALSE);
|
|
if( pIrp == NULL)
|
|
{
|
|
// TRAP;
|
|
_DbgPrintF( DEBUGLVL_ERROR, ("CGpio(): can not allocate IRP\n"));
|
|
FAIL;
|
|
}
|
|
|
|
pNextStack = IoGetNextIrpStackLocation( pIrp);
|
|
if( pNextStack == NULL)
|
|
{
|
|
// TRAP;
|
|
_DbgPrintF( DEBUGLVL_ERROR,
|
|
("CATIHwConfig(): can not allocate NextStack\n")
|
|
);
|
|
FAIL;
|
|
}
|
|
|
|
//$REVIEW - Should change function decl to make nIrpMajorFunction be UCHAR - TCP
|
|
pNextStack->MajorFunction = (UCHAR) nIrpMajorFunction;
|
|
pNextStack->MinorFunction = IRP_MN_QUERY_INTERFACE;
|
|
KeInitializeEvent( &Event, NotificationEvent, FALSE);
|
|
|
|
IoSetCompletionRoutine( pIrp,
|
|
GPIOIoSynchCompletionRoutine,
|
|
&Event, TRUE, TRUE, TRUE);
|
|
|
|
pNextStack->Parameters.QueryInterface.InterfaceType = ( struct _GUID *)&GUID_GPIO_INTERFACE;
|
|
pNextStack->Parameters.QueryInterface.Size = sizeof( GPIOINTERFACE);
|
|
pNextStack->Parameters.QueryInterface.Version = 1;
|
|
pNextStack->Parameters.QueryInterface.Interface = ( PINTERFACE)pGPIOInterface;
|
|
pNextStack->Parameters.QueryInterface.InterfaceSpecificData = NULL;
|
|
|
|
ntStatus = IoCallDriver( pDeviceObject, pIrp);
|
|
|
|
if( ntStatus == STATUS_PENDING)
|
|
KeWaitForSingleObject( &Event,
|
|
Suspended, KernelMode, FALSE, NULL);
|
|
if(( pGPIOInterface->gpioOpen == NULL) || ( pGPIOInterface->gpioAccess == NULL))
|
|
{
|
|
_DbgPrintF( DEBUGLVL_ERROR,
|
|
( "CATIHwConfig(): GPIO interface has NULL pointers\n")
|
|
);
|
|
FAIL;
|
|
}
|
|
bResult = TRUE;
|
|
|
|
} END_ENSURE;
|
|
|
|
if( pIrp != NULL)
|
|
IoFreeIrp( pIrp);
|
|
|
|
return( bResult);
|
|
}
|
|
|
|
|
|
|
|
/*^^*
|
|
* QueryGPIOProvider()
|
|
* Purpose : queries the GPIOProvider for the pins supported and private interfaces
|
|
*
|
|
* Inputs : PGPIOControl pgpioAccessBlock : pointer to GPIO control structure
|
|
*
|
|
* Outputs : BOOL : retunrs TRUE, if the query function was carried on successfully
|
|
* Author : IKLEBANOV
|
|
*^^*/
|
|
BOOL CGpio::QueryGPIOProvider( PGPIOControl pgpioAccessBlock)
|
|
{
|
|
|
|
ENSURE
|
|
{
|
|
if(( m_gpioProviderInterface.gpioOpen == NULL) ||
|
|
( m_gpioProviderInterface.gpioAccess == NULL) ||
|
|
( m_pdoDriver == NULL))
|
|
FAIL;
|
|
|
|
pgpioAccessBlock->Status = GPIO_STATUS_NOERROR;
|
|
pgpioAccessBlock->Command = GPIO_COMMAND_QUERY;
|
|
pgpioAccessBlock->AsynchCompleteCallback = NULL;
|
|
|
|
if(( !NT_SUCCESS( m_gpioProviderInterface.gpioOpen( m_pdoDriver, TRUE, pgpioAccessBlock))) ||
|
|
( pgpioAccessBlock->Status != GPIO_STATUS_NOERROR))
|
|
FAIL;
|
|
|
|
return( TRUE);
|
|
|
|
} END_ENSURE;
|
|
|
|
return( FALSE);
|
|
}
|
|
|
|
|
|
|
|
/*^^*
|
|
* LockGPIOProviderEx()
|
|
* Purpose : locks the GPIOProvider for exclusive use
|
|
*
|
|
* Inputs : PGPIOControl pgpioAccessBlock : pointer to GPIO control structure
|
|
*
|
|
* Outputs : BOOL : retunrs TRUE, if the GPIOProvider is locked
|
|
* Author : IKLEBANOV
|
|
*^^*/
|
|
BOOL CGpio::LockGPIOProviderEx( PGPIOControl pgpioAccessBlock)
|
|
{
|
|
NTSTATUS ntStatus;
|
|
LARGE_INTEGER liStartTime, liCurrentTime;
|
|
|
|
KeQuerySystemTime( &liStartTime);
|
|
|
|
ENSURE
|
|
{
|
|
if(( m_gpioProviderInterface.gpioOpen == NULL) ||
|
|
( m_gpioProviderInterface.gpioAccess == NULL) ||
|
|
( m_pdoDriver == NULL))
|
|
FAIL;
|
|
|
|
pgpioAccessBlock->Status = GPIO_STATUS_NOERROR;
|
|
pgpioAccessBlock->Command = GPIO_COMMAND_OPEN_PINS;
|
|
|
|
while( TRUE)
|
|
{
|
|
KeQuerySystemTime( &liCurrentTime);
|
|
|
|
if(( liCurrentTime.QuadPart - liStartTime.QuadPart) >= GPIO_TIMELIMIT_OPENPROVIDER)
|
|
{
|
|
// time has expired for attempting to lock GPIO provider
|
|
return (FALSE);
|
|
}
|
|
|
|
ntStatus = m_gpioProviderInterface.gpioOpen( m_pdoDriver, TRUE, pgpioAccessBlock);
|
|
|
|
if(( NT_SUCCESS( ntStatus)) && ( pgpioAccessBlock->Status == GPIO_STATUS_NOERROR))
|
|
break;
|
|
}
|
|
|
|
// the GPIO Provider has granted access - save dwCookie for further use
|
|
m_dwGPIOAccessKey = pgpioAccessBlock->dwCookie;
|
|
|
|
return( TRUE);
|
|
|
|
} END_ENSURE;
|
|
|
|
return( FALSE);
|
|
}
|
|
|
|
|
|
|
|
/*^^*
|
|
* ReleaseGPIOProvider()
|
|
* Purpose : releases the GPIOProvider for other clients' use
|
|
*
|
|
* Inputs : PGPIOControl pgpioAccessBlock : pointer to a composed GPIO access block
|
|
*
|
|
* Outputs : BOOL : retunrs TRUE, if the GPIOProvider is released
|
|
* Author : IKLEBANOV
|
|
*^^*/
|
|
BOOL CGpio::ReleaseGPIOProvider( PGPIOControl pgpioAccessBlock)
|
|
{
|
|
NTSTATUS ntStatus;
|
|
|
|
ENSURE
|
|
{
|
|
if(( m_gpioProviderInterface.gpioOpen == NULL) ||
|
|
( m_gpioProviderInterface.gpioAccess == NULL) ||
|
|
( m_pdoDriver == NULL))
|
|
FAIL;
|
|
|
|
pgpioAccessBlock->Status = GPIO_STATUS_NOERROR;
|
|
pgpioAccessBlock->Command = GPIO_COMMAND_CLOSE_PINS;
|
|
pgpioAccessBlock->dwCookie = m_dwGPIOAccessKey;
|
|
|
|
ntStatus = m_gpioProviderInterface.gpioOpen( m_pdoDriver, FALSE, pgpioAccessBlock);
|
|
|
|
if( !NT_SUCCESS( ntStatus))
|
|
{
|
|
_DbgPrintF( DEBUGLVL_ERROR,
|
|
( "CGpio: ReleaseGPIOProvider() NTSTATUS = %x\n",
|
|
ntStatus)
|
|
);
|
|
FAIL;
|
|
}
|
|
|
|
if( pgpioAccessBlock->Status != GPIO_STATUS_NOERROR)
|
|
{
|
|
_DbgPrintF( DEBUGLVL_ERROR,
|
|
( "CGpio: ReleaseGPIOProvider() Status = %x\n",
|
|
pgpioAccessBlock->Status)
|
|
);
|
|
FAIL;
|
|
}
|
|
|
|
m_dwGPIOAccessKey = 0;
|
|
return ( TRUE);
|
|
|
|
} END_ENSURE;
|
|
|
|
return( FALSE);
|
|
}
|
|
|
|
|
|
|
|
/*^^*
|
|
* AccessGPIOProvider()
|
|
* Purpose : provide synchronous type of access to GPIOProvider
|
|
*
|
|
* Inputs : PDEVICE_OBJECT pdoDriver : pointer to the client's device object
|
|
* PGPIOControl pgpioAccessBlock : pointer to a composed GPIO access block
|
|
*
|
|
* Outputs : BOOL, TRUE if acsepted by the GPIO Provider
|
|
*
|
|
* Author : IKLEBANOV
|
|
*^^*/
|
|
//BOOL CGpio::AccessGPIOProvider( PDEVICE_OBJECT pdoClient, PGPIOControl pgpioAccessBlock)
|
|
BOOL CGpio::AccessGPIOProvider( PGPIOControl pgpioAccessBlock)
|
|
|
|
{
|
|
NTSTATUS ntStatus;
|
|
|
|
ENSURE
|
|
{
|
|
|
|
if(( m_gpioProviderInterface.gpioOpen == NULL) ||
|
|
( m_gpioProviderInterface.gpioAccess == NULL) ||
|
|
( m_pdoDriver == NULL))
|
|
FAIL;
|
|
|
|
|
|
//ntStatus = m_gpioProviderInterface.gpioAccess( pdoClient, pgpioAccessBlock);
|
|
ntStatus = m_gpioProviderInterface.gpioAccess( m_pdoDriver, pgpioAccessBlock);
|
|
|
|
if( !NT_SUCCESS( ntStatus))
|
|
{
|
|
_DbgPrintF( DEBUGLVL_ERROR,
|
|
( "CGpio: AccessGPIOProvider() NTSTATUS = %x\n",
|
|
ntStatus)
|
|
);
|
|
FAIL;
|
|
}
|
|
|
|
if( pgpioAccessBlock->Status != GPIO_STATUS_NOERROR)
|
|
{
|
|
_DbgPrintF( DEBUGLVL_ERROR,
|
|
( "CGpio: AccessGPIOProvider() Status = %x\n",
|
|
pgpioAccessBlock->Status)
|
|
);
|
|
FAIL;
|
|
}
|
|
|
|
return TRUE;
|
|
|
|
} END_ENSURE;
|
|
|
|
return( FALSE);
|
|
}
|
|
|
|
/*
|
|
* WriteGPIO()
|
|
* Purpose : write to GPIO
|
|
*
|
|
* Inputs : PDEVICE_OBJECT pdoDriver : pointer to the client's device object
|
|
* PGPIOControl pgpioAccessBlock : pointer to a composed GPIO access block
|
|
*
|
|
* Outputs : BOOL, TRUE if write succeeds
|
|
*
|
|
* Author : MM
|
|
*
|
|
*/
|
|
BOOL CGpio::WriteGPIO(PGPIOControl pgpioAccessBlock)
|
|
{
|
|
|
|
ENSURE
|
|
{
|
|
// Put cookie value in the structure
|
|
pgpioAccessBlock->dwCookie = m_dwGPIOAccessKey;
|
|
pgpioAccessBlock->Command = GPIO_COMMAND_WRITE_BUFFER;
|
|
pgpioAccessBlock->Flags = GPIO_FLAGS_BYTE;
|
|
pgpioAccessBlock->nBytes = 1;
|
|
pgpioAccessBlock->nBufferSize = 1;
|
|
|
|
// Put cookie value in the structure
|
|
pgpioAccessBlock->dwCookie = m_dwGPIOAccessKey;
|
|
|
|
if (AccessGPIOProvider(pgpioAccessBlock) == FALSE)
|
|
{
|
|
_DbgPrintF( DEBUGLVL_ERROR, ("CGpio: GPIO Write Error\n"));
|
|
FAIL;
|
|
}
|
|
|
|
return TRUE;
|
|
|
|
} END_ENSURE;
|
|
|
|
return( FALSE);
|
|
}
|
|
|
|
/*
|
|
* ReadGPIO()
|
|
* Purpose : Read From GPIO
|
|
*
|
|
* Inputs : PDEVICE_OBJECT pdoDriver : pointer to the client's device object
|
|
* PGPIOControl pgpioAccessBlock : pointer to a composed GPIO access block
|
|
*
|
|
* Outputs : BOOL, TRUE if write succeeds
|
|
*
|
|
* Author : MM
|
|
*
|
|
*/
|
|
BOOL CGpio::ReadGPIO(PGPIOControl pgpioAccessBlock)
|
|
{
|
|
|
|
ENSURE
|
|
{
|
|
// Put cookie value in the structure
|
|
pgpioAccessBlock->dwCookie = m_dwGPIOAccessKey;
|
|
pgpioAccessBlock->Command = GPIO_COMMAND_READ_BUFFER;
|
|
pgpioAccessBlock->Flags = GPIO_FLAGS_BYTE;
|
|
pgpioAccessBlock->nBytes = 1;
|
|
pgpioAccessBlock->nBufferSize = 1;
|
|
|
|
// Put cookie value in the structure
|
|
pgpioAccessBlock->dwCookie = m_dwGPIOAccessKey;
|
|
|
|
if (AccessGPIOProvider(pgpioAccessBlock) == FALSE)
|
|
{
|
|
_DbgPrintF( DEBUGLVL_ERROR, ("CGpio: GPIO Read Error\n"));
|
|
FAIL;
|
|
}
|
|
else
|
|
_DbgPrintF( DEBUGLVL_BLAB, ("CGpio: GPIO Read OK\n"));
|
|
|
|
return TRUE;
|
|
|
|
} END_ENSURE;
|
|
|
|
return( FALSE);
|
|
}
|
|
|
|
|
|
/* WriteGPIO()
|
|
* Purpose : write to GPIO
|
|
*
|
|
* Inputs : UCHAR *p_uchPin : the pin number
|
|
* UCHAR *p_uchValue : the pin value
|
|
*
|
|
* Outputs : BOOL, TRUE if write succeeds
|
|
*
|
|
* Author : MM
|
|
*
|
|
*/
|
|
BOOL CGpio::WriteGPIO(UCHAR *p_uchPin,UCHAR *p_uchValue )
|
|
{
|
|
GPIOControl gpioAccessBlock;
|
|
BOOL bResult = FALSE;
|
|
|
|
ENSURE
|
|
{
|
|
// Put cookie value in the structure
|
|
|
|
gpioAccessBlock.Flags = GPIO_FLAGS_BYTE;
|
|
gpioAccessBlock.nBytes = 1;
|
|
gpioAccessBlock.nBufferSize = 1;
|
|
gpioAccessBlock.AsynchCompleteCallback = NULL;
|
|
|
|
int counter = 0;
|
|
LARGE_INTEGER liTime;
|
|
// Somewhat arbitrary max of 1 second.
|
|
while (!LockGPIOProviderEx( &gpioAccessBlock))
|
|
{
|
|
if (counter++ >= 100)
|
|
{
|
|
_DbgPrintF( DEBUGLVL_ERROR,("PhilTune: unable to lock GPIOProvider\n"));
|
|
FAIL;
|
|
}
|
|
|
|
liTime.QuadPart = 100000;
|
|
KeDelayExecutionThread(KernelMode, FALSE, &liTime); // = 10 milliseconds
|
|
} // try to get GPIO Provider
|
|
|
|
|
|
gpioAccessBlock.Command = GPIO_COMMAND_WRITE_BUFFER;
|
|
gpioAccessBlock.Pins = p_uchPin;
|
|
// Put cookie value in the structure
|
|
gpioAccessBlock.dwCookie = m_dwGPIOAccessKey;
|
|
gpioAccessBlock.Buffer = p_uchValue;
|
|
|
|
if (AccessGPIOProvider(&gpioAccessBlock) == FALSE)
|
|
{
|
|
_DbgPrintF( DEBUGLVL_ERROR,("CGpio: GPIO Write Error\n"));
|
|
FAIL;
|
|
}
|
|
|
|
bResult = TRUE;
|
|
|
|
} END_ENSURE;
|
|
|
|
ReleaseGPIOProvider(&gpioAccessBlock);
|
|
return bResult;
|
|
}
|
|
|
|
/*
|
|
* ReadGPIO()
|
|
* Purpose : Read From GPIO
|
|
*
|
|
* Inputs : UCHAR *p_uchPin : the pin number
|
|
* UCHAR *p_uchValue : the pin value
|
|
*
|
|
* Outputs : BOOL, TRUE if write succeeds
|
|
*
|
|
* Author : MM
|
|
*
|
|
*/
|
|
BOOL CGpio::ReadGPIO(UCHAR *p_uchPin,UCHAR *p_uchValue )
|
|
{
|
|
GPIOControl gpioAccessBlock;
|
|
BOOL bResult = FALSE;
|
|
|
|
ENSURE
|
|
{
|
|
// Put cookie value in the structure
|
|
gpioAccessBlock.Flags = GPIO_FLAGS_BYTE;
|
|
gpioAccessBlock.nBytes = 1;
|
|
gpioAccessBlock.nBufferSize = 1;
|
|
gpioAccessBlock.AsynchCompleteCallback = NULL;
|
|
|
|
int counter = 0;
|
|
LARGE_INTEGER liTime;
|
|
// Somewhat arbitrary max of 1 second.
|
|
while (!LockGPIOProviderEx( &gpioAccessBlock))
|
|
{
|
|
if (counter++ >= 100)
|
|
{
|
|
_DbgPrintF( DEBUGLVL_ERROR,("PhilTune: unable to lock GPIOProvider"));
|
|
FAIL;
|
|
}
|
|
|
|
liTime.QuadPart = 100000;
|
|
KeDelayExecutionThread(KernelMode, FALSE, &liTime); // = 10 milliseconds
|
|
} // try to get GPIO Provider
|
|
|
|
gpioAccessBlock.Command = GPIO_COMMAND_READ_BUFFER;
|
|
gpioAccessBlock.Pins = p_uchPin;
|
|
// Put cookie value in the structure
|
|
gpioAccessBlock.dwCookie = m_dwGPIOAccessKey;
|
|
gpioAccessBlock.Buffer = p_uchValue;
|
|
|
|
if (AccessGPIOProvider(&gpioAccessBlock) == FALSE)
|
|
{
|
|
_DbgPrintF( DEBUGLVL_ERROR,("CGpio: GPIO Read Error\n"));
|
|
FAIL;
|
|
}
|
|
else
|
|
{
|
|
_DbgPrintF( DEBUGLVL_TERSE,("CGpio: GPIO Read OK\n"));
|
|
}
|
|
|
|
bResult = TRUE;
|
|
|
|
} END_ENSURE;
|
|
|
|
ReleaseGPIOProvider(&gpioAccessBlock);
|
|
return bResult;
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|