📄 gpio.cpp
字号:
/*******************************************************************************
*
* G p s G p i o D e v i c e D r i v e r
*
* Areas are are:
* 1) Initialization and deinit.
* 2) Interrupts
* 3) Data Transfers
* 4) GLL and HAL process model
* 5) Possible extensions.
*
******************************************************************************/
#include "stdafx.h"
#include <winioctl.h>
#include <windows.h>
#include <pkfuncs.h>
#include <ceddk.h> // TODO: can only be used from Platform Builder?
// ... except I patched in a kludge for <pkfuncs.h> and IsInPwrHdlr()
// #define IsInPwrHdlr() (0 != PUserKData[PWR_FLAG_OFFSET])
#include "gpioHardware.h"
#include "spiIoctl.h"
#include "gpioDriver.h"
#include "gpsDeviceDriver.h"
#include "cust_debug.h"
//#include "cust_hw_gpio.h"
#include "oalintr.h"
#include "wit_gpiomap.h"
#include "xllp_ost.h"
#include "bulverde_gpio.h"
#include <Mmsystem.h>
#define GPIO_EXPORT extern "C" __declspec(dllexport)
GPIO_EXPORT void GCO_PowerDown(DWORD hDeviceContext);
//using namespace SSP;
GPIO_EXPORT BOOL
GCO_IOControl(DWORD hOpenContext, DWORD dwCode,
PBYTE pBufIn, DWORD dwLenIn,
PBYTE pBufOut, DWORD dwLenOut,
PDWORD pdwActualOut);
#define GPS_GPIO_VERSION_MAJOR 2
#define GPS_GPIO_VERSION_MINOR 17
//
// GOAL: Create a GPIO-only device driver from v2.17 of the SPI code.
// Options: Enable debugs
// 1-GPIO control.
// Changes:
// Remove SPI code.
// Create a project file for GpsGpioBulverde.dll
// RESULTS:
// ..
#define T_LABEL_MACRO(maj,min) _T("#@(#)GpsGpioBulverde ") \
_T(#maj) _T(".") \
_T(#min) _T(" built ") \
_T(__DATE__) _T(" ") \
_T(__TIME__)
#define LABEL_MACRO(maj,min) "#@(#)GpsGpioBulverde " #maj "." #min \
" built " __DATE__ " " __TIME__
#define T_GPS_LABEL(maj,min) T_LABEL_MACRO(maj,min)
#define GPS_LABEL(maj,min) LABEL_MACRO(maj,min)
static const TCHAR t_driverLabel[] = {T_GPS_LABEL(GPS_GPIO_VERSION_MAJOR,GPS_GPIO_VERSION_MINOR)};
const char driverLabel[] = { GPS_LABEL(GPS_GPIO_VERSION_MAJOR,GPS_GPIO_VERSION_MINOR)};
const char* pDriverLabel = driverLabel;
//-----------------------------------------------------------------------------
// Globals.
//----------------------------------------------------------------------------
#define CACHED_TO_UNCACHED_OFFSET 0x20000000
#define GPIO_OFFSET 0x00E00000
#define PERIF_BASE_C_VIRTUAL 0x8C000000
#define PERIF_BASE_U_VIRTUAL (PERIF_BASE_C_VIRTUAL + CACHED_TO_UNCACHED_OFFSET)
#define GPIO_BASE_U_VIRTUAL (PERIF_BASE_U_VIRTUAL + GPIO_OFFSET)
volatile XLLP_GPIO_T* v_pGPIORegs = (XLLP_GPIO_T *)GPIO_BASE_U_VIRTUAL;
//-----------------------------------------------------------------------------
// Forward declarations - provided by this device driver.
//-----------------------------------------------------------------------------
static BOOL GPIO_AllocReg(GPIO_DEVICE_CONTEXT* pDev);
GPIO_EXPORT BOOL GPIO_Deinit(DWORD hDeviceContext);
//----------------------------------------------------------------------------//// glFormatTime()////----------------------------------------------------------------------------const TCHAR* glFormatTime(void){ static TCHAR timeString[80]; SYSTEMTIME t; GetLocalTime(&t); wsprintf(timeString, _T("%02d/%02d/%02d %02d:%02d:%02d"), t.wMonth, t.wDay, t.wYear % 100, t.wHour, t.wMinute, t.wSecond); return timeString;}
void glReportTime(void){ NKDbgPrintfW(TEXT("%s %lu "), glFormatTime(), GetTickCount());}
// ISSUE: TODO:
// How to connect the device power-down and power-up to a restart
// of the HABI? This would seem to require a new HABI feature.
/*******************************************************************************
********************************************************************************
**
** Device Driver Public Entry Points.
**
** These subroutines satisfy the requirements of the Microsoft
** device driver interface.
**
** The prefix is "GCO_" for "GPS Control Output".
**
********************************************************************************
*******************************************************************************/
//-----------------------------------------------------------------------------
//
// GPO_Init()
//
// Init access to the hardware.
// Init access to the ISR.
// Init the ring buffers.
// Resume control of the GPIO.
//
//-----------------------------------------------------------------------------
#ifdef GCO_DONE_INTERRUPT // Use ISR to detect the GPIO done
HANDLE ghRxDone = 0;
#endif
GPIO_EXPORT DWORD
GCO_Init(LPCTSTR pContext, LPCVOID lpvBusContext)
{
GL_ERROR((TEXT("GCO_Init()/%d %s\n\r"), __LINE__,
t_driverLabel, driverLabel));
// allocate our device context
GPIO_DEVICE_CONTEXT* pDev = (GPIO_DEVICE_CONTEXT *)malloc(sizeof(GPIO_DEVICE_CONTEXT));
pDev->ctor(1);
//-------------------------------------------------------------------------
// GPIO Configuration
//
// Set the Bulverde GPIO to drive the various GPIOs configured
// in gpioHardware.h
//
// You can see the Bulverde CPU Spec. 3-100 to learn about the GPIOs.
//
//-------------------------------------------------------------------------
#ifdef GPS_GPIO_RESET_EXISTS
v_pGPIORegs->GPSR_RESET = GPS_GPIO_RESET_EXISTS;
v_pGPIORegs->GPDR_RESET |= GPS_GPIO_RESET_EXISTS;
GL_PRINT((MSG("GPS Reset Enable!! 0x%x\r\n"),GPS_GPIO_RESET_EXISTS));
Sleep(1);
#endif
#ifdef GPS_GPIO_POWER_EXISTS
v_pGPIORegs->GPSR_POWER = GPS_GPIO_POWER_EXISTS;
v_pGPIORegs->GPDR_POWER |= GPS_GPIO_POWER_EXISTS;
GL_PRINT((MSG("GPS Power Enable!! 0x%x\r\n"),GPS_GPIO_POWER_EXISTS));
Sleep(1);
#endif
#ifdef GPS_GPIO_STANDBY_EXISTS
v_pGPIORegs->GPSR_STANDBY = GPS_GPIO_STANDBY_EXISTS;
v_pGPIORegs->GPDR_STANDBY |= GPS_GPIO_STANDBY_EXISTS;
GL_PRINT((MSG("GPS Power Enable!! 0x%x\r\n"),GPS_GPIO_STANDBY_EXISTS));
#endif
return (DWORD)pDev;
}
//-----------------------------------------------------------------------------
//
// GCO_Deinit()
//
// Set the GPIO to the lowest GPS power level.
// Set the GPIO to the lowest GPIO power level.
// Set the GPIO to the lowest GPIO power level.
// Deinit the ring buffers.
// Deinit access to the ISR.
// Deinit access to the hardware.
//
//-----------------------------------------------------------------------------
GPIO_EXPORT BOOL
GCO_Deinit(DWORD hDeviceContext)
{
GL_PRINT((MSG("GCO_Deinit(0x%x)/%d\n\r"),hDeviceContext,__LINE__));
GPIO_DEVICE_CONTEXT* pDev = getGpioDeviceContext(hDeviceContext);
if (pDev->v_pGPIORegs)
{
pDev->v_pGPIORegs = NULL;
}
if (pDev->v_pGPIORegs)
{
pDev->v_pGPIORegs = NULL;
}
free(pDev);
GL_PRINT((MSG("GCO_Deinit()/%d\n\r"),__LINE__));
return TRUE;
}
//-----------------------------------------------------------------------------
//
// GCO_Open()
//
// Don't touch GPIO.
//
//-----------------------------------------------------------------------------
GPIO_EXPORT DWORD
GCO_Open(DWORD hDeviceContext, DWORD AccessCode, DWORD ShareMode)
{
GL_ERROR((TEXT("GCO_Open()/%d %s\n\r"), __LINE__, t_driverLabel));
GPIO_DEVICE_CONTEXT* pDev = getGpioDeviceContext(hDeviceContext);
pDev->mbSignaledPower = false;
pDev->mbClosed = false;
return (DWORD)pDev;
}
//-----------------------------------------------------------------------------
//
// GCO_Close()
//
// Flush the ring buffers.
//
//-----------------------------------------------------------------------------
GPIO_EXPORT BOOL
GCO_Close(DWORD hOpenContext)
{
// Use GL_PRINT normally
// GL_PRINT((TEXT("GCO_Close()/%d %s\n\r"), __LINE__, t_driverLabel));
// Use GL_ERROR during bring-up.
GL_ERROR((TEXT("GCO_Close()/%d %s\n\r"), __LINE__, t_driverLabel));
GCO_PowerDown(hOpenContext);
return TRUE;
}
//-----------------------------------------------------------------------------
//
// GCO_PowerUp()
//
//-----------------------------------------------------------------------------
GPIO_EXPORT void
GCO_PowerUp(DWORD hDeviceContext)
{
GL_ERROR((TEXT("GCO_PowerUp()/%d\n\r"),__LINE__));
}
//-----------------------------------------------------------------------------
//
// GCO_PowerDown()
//
// Touch GPIO - set it to the lowest power consumption state.
// ISSUE - how to tell the HABI to restart?
//
//-----------------------------------------------------------------------------
GPIO_EXPORT void
GCO_PowerDown(DWORD hDeviceContext)
{
GPIO_DEVICE_CONTEXT* pDev = getGpioDeviceContext(hDeviceContext);
GPS_GPIO_CONTROL control;
control.value = 0;
#ifdef GPS_GPIO_STANDBY_EXISTS // {
// Clear nSTANDBY/POWERON to cause Mantaray/Hammerhead to go into
// low power standby mode.
control.id = GPS_GPIO_STANDBY;
GCO_IOControl(hDeviceContext, GPS_IOCTL_CHIPSET_CONTROL,
reinterpret_cast<const PBYTE> (&control), sizeof(control),
0,0,0);
#endif // } GPS_GPIO_STANDBY_EXISTS
#ifdef GPS_GPIO_POWER_EXISTS // {
// Clear POWER to turn off Mantaray/Hammerhead VDD_CORE power supply.
control.id = GPS_GPIO_POWER;
GCO_IOControl(hDeviceContext, GPS_IOCTL_CHIPSET_CONTROL,
reinterpret_cast<const PBYTE> (&control), sizeof(control),
0,0,0);
#endif // } GPS_GPIO_POWER_EXISTS
pDev->mbClosed = true;
GL_ERROR((TEXT("GCO_PowerDown()/%d\n\r"),__LINE__));
}
//-----------------------------------------------------------------------------
//
// GCO_Read()
//
// Read data from the queue.
// If we had a power-down/up, then return ERROR_PWR_INT.
//
//-----------------------------------------------------------------------------
GPIO_EXPORT DWORD
GCO_Read(DWORD hOpenContext, LPVOID pBuf, DWORD Count)
{
GPIO_DEVICE_CONTEXT* pGpio = getGpioDeviceContext(hOpenContext);
GL_PRINT((MSG("GCO_Read(%d)/%d %d %d {\n\r"),
Count,__LINE__,pGpio->mbClosed,pGpio->mbIsrAllow));
if (pGpio->mbClosed)
{
GL_ERROR((TEXT("GCO_Read()/%d Signal Power %d\n\r"),
__LINE__, pGpio->mbSignaledPower));
if (!pGpio->mbSignaledPower)
{
// This code to send the error result only once isn't needed:
pGpio->mbSignaledPower = true;
// For safety, always return the power interrupted error code
// until the next close/open cycle.
}
SetLastError(ERROR_PWRINT);
return -1;
}
SetLastError(0);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -