📄 pdd.c
字号:
BOOL SetPower(UARTPDD *pPdd, CEDEVICE_POWER_STATE dx)
{
BOOL rc = FALSE;
DEBUGMSG(ZONE_FUNCTION, (L"+SetPower\r\n"));
EnterCriticalSection(&pPdd->powerCS);
// Device can't be set to lower power state than external
if (dx < pPdd->externalDX) dx = pPdd->externalDX;
// Update state only when it is different from actual
if (pPdd->currentDX != dx) {
if (D3 == dx) {
gps_1170_reset(pPdd);
RegSetBit(pPdd, XR20M1170REG_IER, BIT4); //Enable Sleep
gps_poweron(pPdd, 0);
}
else if (D0 == dx)
HWStartup(pPdd);
// Update current power state
pPdd->currentDX = dx;
// We changed power state
rc = TRUE;
}
LeaveCriticalSection(&pPdd->powerCS);
DEBUGMSG(ZONE_FUNCTION, (L"-SetPower\r\n"));
return rc;
}
//------------------------------------------------------------------------------
//
// Function: GetSerialObject
//
// This function returns a pointer to a HWOBJ structure, which contains
// the correct function pointers and parameters for the relevant PDD layer's
// hardware interface functions.
//
PHWOBJ GetSerialObject(DWORD dwIndex)
{
PHWOBJ pHWObj;
DEBUGMSG(ZONE_FUNCTION, (L"+GetSerialObject()\r\n"));
// Allocate space for the HWOBJ.
pHWObj = malloc(sizeof(HWOBJ));
if (pHWObj == NULL) goto cleanUp;
// Fill in the HWObj structure
pHWObj->BindFlags = THREAD_AT_OPEN;
pHWObj->dwIntID = 0;
pHWObj->pFuncTbl = &g_pddVTbl;
cleanUp:
DEBUGMSG(ZONE_FUNCTION, (L"-GetSerialObject()\r\n"));
return pHWObj;
}
static void HWStartup(UARTPDD *pPdd)
{
DEBUGMSG(ZONE_FUNCTION, (L"+HWStartup\r\n"));
EnterCriticalSection(&pPdd->hwCS);
gps_poweron(pPdd, 1);
gps_1170_reset(pPdd);
//RegPrintAll(pPdd);
#if 1
/* Clear the interrupt registers. */
(void)RegRead(pPdd, XR20M1170REG_LSR);
(void)RegRead(pPdd, XR20M1170REG_RHR);
(void)RegRead(pPdd, XR20M1170REG_ISR);
(void)RegRead(pPdd, XR20M1170REG_MSR);
#endif
SetWordLength(pPdd, pPdd->dcb.ByteSize);
SetStopBits(pPdd, pPdd->dcb.StopBits);
SetParity(pPdd, pPdd->dcb.Parity);
/* Clear the interrupt registers again. */
#if 1
(void)RegRead(pPdd, XR20M1170REG_LSR);
(void)RegRead(pPdd, XR20M1170REG_RHR);
(void)RegRead(pPdd, XR20M1170REG_ISR);
(void)RegRead(pPdd, XR20M1170REG_MSR);
#endif
RegWrite(pPdd, XR20M1170REG_TCR, UART_TCR_RX_FIFO_TRIG_START_36|UART_TCR_RX_FIFO_TRIG_HALT_52);
RegWrite(pPdd, XR20M1170REG_TLR, 0);
RegWrite(pPdd, XR20M1170REG_MCR, 0xb);
RegWrite(pPdd, XR20M1170REG_IER, pPdd->intrMask);
SetBaudRate(pPdd, pPdd->dcb.BaudRate);
RegWrite(pPdd, XR20M1170REG_FCR, \
UART_FCR_RX_FIFO_TRIG_8 | UART_FCR_TX_FIFO_TRIG_16 |\
UART_FCR_TX_FIFO_CLEAR | UART_FCR_RX_FIFO_CLEAR | UART_FCR_FIFO_EN);
//RegWrite(pPdd, XR20M1170REG_MCR, 0x1b); //BIT4 enable Loopback
//RegPrintAll(pPdd);
LeaveCriticalSection(&pPdd->hwCS);
DEBUGMSG(ZONE_FUNCTION, (L"-HWStartup\r\n"));
}
//------------------------------------------------------------------------------
//
// Function: HWInit
//
// This function initializes a serial device and it returns information about
// it.
//
static PVOID HWInit(ULONG ulContext, PVOID pMdd, PHWOBJ pHWObj)
{
BOOL bRc = FALSE;
UARTPDD *pPdd = NULL;
PHYSICAL_ADDRESS pa;
DWORD irq;
DEBUGMSG(ZONE_OPEN||ZONE_FUNCTION, (L"+HWInit(%s, 0x%08x, 0x%08x\r\n", ulContext, pMdd, pHWObj));
// Allocate SER_INFO structure
pPdd = LocalAlloc(LPTR, sizeof(UARTPDD));
if (pPdd == NULL) goto cleanUp;
// Read device parameters
if (GetDeviceRegistryParams(
(LPCWSTR)ulContext, pPdd, dimof(g_deviceRegParams), g_deviceRegParams
) != ERROR_SUCCESS) {
DEBUGMSG(ZONE_ERROR, (L"ERROR: HWInit: "L"Failed read driver registry parameters\r\n"));
goto cleanUp;
}
// Open GPIO driver
pPdd->hGPIO = GPIOOpen();
if (pPdd->hGPIO == NULL) {
DEBUGMSG(ZONE_ERROR, (L"ERROR: HWInit: "L"Failed open GPIO device driver\r\n"));
goto cleanUp;
}
//init conf register address
pa.QuadPart = OMAP730_CONFIG_REGS_PA;
pPdd->pConfigRegs = (OMAP730_CONFIG_REGS*)MmMapIoSpace(pa, sizeof(OMAP730_CONFIG_REGS), FALSE);
if (pPdd->pConfigRegs == NULL) {
DEBUGMSG(ZONE_ERROR, (L"ERROR: HWInit: "L"Failed map physical memory 0x%08x\r\n", pa.LowPart));
goto cleanUp;
}
//init pin mux of GPIO 79/82/135/167
MASKREG32( &pPdd->pConfigRegs->IO_CONFIG6, 0x0000000E, 0x0000000C ); //GPIO 79
MASKREG32( &pPdd->pConfigRegs->IO_CONFIG6, 0x0000E000, 0x0000C000 ); //GPIO 82
MASKREG32( &pPdd->pConfigRegs->IO_CONFIG9, 0x00000E00, 0x00000D00 ); //GPIO 135
MASKREG32( &pPdd->pConfigRegs->IO_CONFIG13, 0x00F00000, 0x00D00000 ); //GPIO 167, PE disable
//init gpio
GPIOSetMode(pPdd->hGPIO, pPdd->gpio_power, GPIO_DIR_OUTPUT);
GPIOSetMode(pPdd->hGPIO, pPdd->gpio_irq, GPIO_DIR_INPUT|GPIO_INT_HIGH_LOW);
GPIOSetMode(pPdd->hGPIO, pPdd->gpio_download, GPIO_DIR_OUTPUT);
GPIOSetMode(pPdd->hGPIO, pPdd->gpio_reset, GPIO_DIR_OUTPUT);
GPIOSetBit(pPdd->hGPIO, pPdd->gpio_reset);
GPIOClrBit(pPdd->hGPIO, pPdd->gpio_download);
GPIOClrBit(pPdd->hGPIO, pPdd->gpio_power);
irq = GPIOGetIrq(pPdd->hGPIO, pPdd->gpio_irq);
if (!KernelIoControl(IOCTL_HAL_REQUEST_SYSINTR, &irq, sizeof(irq), \
&pPdd->sysIntr,sizeof(pPdd->sysIntr), NULL)) {
DEBUGMSG(ZONE_ERROR, (L"ERROR: HWInit: "L"Failed map GPIO %d interrupt\r\n", irq));
goto cleanUp;
}
// Save it to HW object
pHWObj->dwIntID = pPdd->sysIntr;
// Create sync objects
InitializeCriticalSection(&pPdd->hwCS);
InitializeCriticalSection(&pPdd->txCS);
InitializeCriticalSection(&pPdd->powerCS);
pPdd->txEvent = CreateEvent(0, FALSE, FALSE, NULL);
if (pPdd->txEvent == NULL) {
DEBUGMSG(ZONE_ERROR, (L"ERROR: HWInit: "L"Failed create event\r\n"));
goto cleanUp;
}
// Initialize DCB
pPdd->dcb.DCBlength = sizeof(pPdd->dcb);
pPdd->dcb.BaudRate = 9600;
pPdd->dcb.fBinary = TRUE;
pPdd->dcb.fParity = FALSE;
pPdd->dcb.fOutxCtsFlow = FALSE;
pPdd->dcb.fOutxDsrFlow = FALSE;
pPdd->dcb.fDtrControl = DTR_CONTROL_DISABLE;
pPdd->dcb.fDsrSensitivity = FALSE;
pPdd->dcb.fRtsControl = RTS_CONTROL_DISABLE;
pPdd->dcb.ByteSize = 8;
pPdd->dcb.Parity = 0;
pPdd->dcb.StopBits = ONESTOPBIT;
pPdd->intrMask = UART_IER_LINE|UART_IER_MODEM|UART_IER_RHR;
pPdd->hI2c= I2COpen();
if ( pPdd->hI2c == NULL)
{
DEBUGMSG(ZONE_INIT, (L"ERROR: UARTPDD_Init: "
L"Failed open I2C device \r\n"));
goto cleanUp;
}
if (!I2CSetSlaveAddress(pPdd->hI2c, XR20M1170_ADDR_SIZE, XR20M1170_I2C_ADDR))
{
DEBUGMSG(ZONE_ERROR, (L"ERROR: UARTPDD_Init: "L"Failed to set XR20M1170 I2C Read address\r\n"));
goto cleanUp;
}
// Set device to D3
pPdd->externalDX = D3;
SetPower(pPdd, D3);
// Save MDD context for callback
pPdd->pMdd = pMdd;
// Initialization succeeded
bRc = TRUE;
DEBUGMSG(ZONE_INIT, (L"HWInit: Initialization succeeded\r\n"));
cleanUp:
if (!bRc && pPdd != NULL) {
HWDeinit(pPdd);
pPdd = NULL;
}
DEBUGMSG(ZONE_OPEN||ZONE_FUNCTION, (L"-HWInit(pPdd = 0x%08x)\r\n", pPdd));
return pPdd;
}
//------------------------------------------------------------------------------
//
// Function: HWPostInit
//
// This function is called by the upper layer after hardware independent
// initialization is done (at end of COM_Init).
//
static BOOL HWPostInit(VOID *pvContext)
{
return TRUE;
}
//------------------------------------------------------------------------------
//
// Function: HWDeinit
//
// This function is called by the upper layer to de-initialize the hardware
// when a device driver is unloaded.
//
static BOOL HWDeinit(VOID *pvContext)
{
UARTPDD *pPdd = (UARTPDD*)pvContext;
DEBUGMSG(ZONE_CLOSE||ZONE_FUNCTION, (L"+HWDeinit(0x%08x)\r\n", pvContext));
// Close GPIO
if (pPdd->hGPIO != NULL) GPIOClose(pPdd->hGPIO);
// Unmap CONFIG registers
if (pPdd->pConfigRegs != NULL) {
MmUnmapIoSpace((VOID*)pPdd->pConfigRegs, sizeof(OMAP730_CONFIG_REGS));
}
// Disconnect the interrupt
if (pPdd->sysIntr != 0)
KernelIoControl(IOCTL_HAL_RELEASE_SYSINTR, &pPdd->sysIntr, sizeof(&pPdd->sysIntr),NULL, 0, NULL);
// Close I2C
if (pPdd->hI2c)
I2CClose(pPdd->hI2c);
// Delete sync objects
DeleteCriticalSection(&pPdd->hwCS);
DeleteCriticalSection(&pPdd->txCS);
DeleteCriticalSection(&pPdd->powerCS);
if (pPdd->txEvent != NULL)
CloseHandle(pPdd->txEvent);
// Free driver object
LocalFree(pPdd);
DEBUGMSG(ZONE_CLOSE||ZONE_FUNCTION, (L"-HWDeinit\r\n"));
return TRUE;
}
//------------------------------------------------------------------------------
static BOOL HWOpen(VOID *pvContext)
{
BOOL bRc = FALSE;
UARTPDD *pPdd = (UARTPDD*)pvContext;
DEBUGMSG(ZONE_OPEN||ZONE_FUNCTION, (L"+HWOpen\r\n"));
if (pPdd->open) goto cleanUp;
pPdd->commErrors = 0;
pPdd->overrunCount = 0;
pPdd->flowOffCTS = FALSE;
pPdd->flowOffDSR = FALSE;
pPdd->addTxIntr = FALSE;
pPdd->open = TRUE;
//set hardware to D0
pPdd->externalDX = D0;
SetPower(pPdd, D0);
// Update line & modem status
ReadModemStat(pPdd);
bRc = TRUE;
cleanUp:
DEBUGMSG(ZONE_OPEN||ZONE_FUNCTION, (L"-HWOpen(rc = %d)\r\n", bRc));
return bRc;
}
//------------------------------------------------------------------------------
static ULONG HWClose(VOID *pvContext)
{
ULONG ulRc = -1;
UARTPDD *pPdd = (UARTPDD*)pvContext;
DEBUGMSG(ZONE_CLOSE||ZONE_FUNCTION, (L"+HWClose(0x%08x)\r\n", pvContext));
if (!pPdd->open) goto cleanUp;
// Set hardware to D3
pPdd->externalDX = D3;
SetPower(pPdd, D3);
// We are closed
pPdd->open = FALSE;
ulRc = 0;
cleanUp:
DEBUGMSG(ZONE_CLOSE||ZONE_FUNCTION, (L"-HWClose(%d)\r\n", ulRc));
return ulRc;
}
//------------------------------------------------------------------------------
//
// Function: HWGetInterruptType
//
// This function is called by the upper layer whenever an interrupt occurs.
// The return code is then checked by the MDD to determine which of the four
// interrupt handling routines are to be called.
//
static INTERRUPT_TYPE HWGetInterruptType(VOID *pvContext)
{
UARTPDD *pPdd = (UARTPDD *)pvContext;
INTERRUPT_TYPE type = INTR_NONE;
UCHAR ucIntCause;
DEBUGMSG(ZONE_THREAD, (L"+HWGetInterruptType(0x%08x)\r\n", pvContext));
EnterCriticalSection(&pPdd->hwCS);
ucIntCause=RegRead(pPdd, XR20M1170REG_ISR);
LeaveCriticalSection(&pPdd->hwCS);
if ((ucIntCause & UART_IIR_IT_PENDING) == 0) {
switch (ucIntCause & 0x3F) {
case UART_IIR_THR:
type = INTR_TX;
break;
case UART_IIR_RHR:
case UART_IIR_TO:
type = INTR_RX;
break;
case UART_IIR_MODEM:
case UART_IIR_HW:
type = INTR_MODEM;
break;
case UART_IIR_LINE:
type = INTR_LINE;
break;
}
}
// Add software TX interrupt to resume send
if (pPdd->addTxIntr) {
type |= INTR_TX;
pPdd->addTxIntr = FALSE;
}
//cleanUp:
DEBUGMSG(ZONE_THREAD, (L"-HWGetInterruptType(type = %d, cause = %02x)\r\n",type, ucIntCause));
return type;
}
//------------------------------------------------------------------------------
//
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -