📄 pdd.c
字号:
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
//
// Use of this source code is subject to the terms of the Microsoft end-user
// license agreement (EULA) under which you licensed this SOFTWARE PRODUCT.
// If you did not accept the terms of the EULA, you are not authorized to use
// this source code. For a copy of the EULA, please see the LICENSE.RTF on your
// install media.
//
//------------------------------------------------------------------------------
//
// Portions Copyright (c) Texas Instruments. All rights reserved.
//
//------------------------------------------------------------------------------
//
// File: pdd.c
//
// This file implements PDD for OMAP730 serial port.
//
#include <windows.h>
#include <ceddk.h>
#include <ddkreg.h>
#define USE_NEW_SERIAL_MODEL
#include <serhw.h>
#include <serdbg.h>
#include <omap730.h>
#include <ceddkex.h>
#include <Pegdser.h>
#include <i2c.h>
#include <gpio.h>
#include <debugtrace.h>
#include "pdd.h"
#if 0
#undef DEBUGMSG
#define DEBUGMSG(cond, printf_exp) RETAILMSG(1, printf_exp)
#endif
//------------------------------------------------------------------------------
// Global variables
static const GUID DEVICE_IFC_GPIO_GUID;
const GUID DEVICE_IFC_I2C_GUID;
//------------------------------------------------------------------------------
// Device registry parameters
static const DEVICE_REGISTRY_PARAM g_deviceRegParams[] = {
{
L"PowerGPIO", PARAM_DWORD, FALSE, offset(UARTPDD, gpio_power),
fieldsize(UARTPDD, gpio_power), (VOID*)79
}, {
L"IrqGPIO", PARAM_DWORD, FALSE, offset(UARTPDD, gpio_irq),
fieldsize(UARTPDD, gpio_irq), (VOID*)82
}, {
L"DownloadGPIO", PARAM_DWORD, FALSE, offset(UARTPDD, gpio_download),
fieldsize(UARTPDD, gpio_download), (VOID*)135
}, {
L"ResetGPIO", PARAM_DWORD, FALSE, offset(UARTPDD, gpio_reset),
fieldsize(UARTPDD, gpio_reset), (VOID*)167
}, {
L"Index", PARAM_DWORD, FALSE, offset(UARTPDD, index),
fieldsize(UARTPDD, index), (VOID*)-1
}, {
L"HWMode", PARAM_DWORD, FALSE, offset(UARTPDD, hwMode),
fieldsize(UARTPDD, hwMode), (VOID*)FALSE
}, {
L"Frequency", PARAM_DWORD, FALSE, offset(UARTPDD, frequency),
fieldsize(UARTPDD, frequency), (VOID*)12000000
/* }, {
L"WakeChar", PARAM_DWORD, FALSE, offset(UARTPDD, wakeUpChar),
fieldsize(UARTPDD, wakeUpChar), (VOID*)0x32 */
}, {
L"RxBuffer", PARAM_DWORD, FALSE, offset(UARTPDD, rxBufferSize),
fieldsize(UARTPDD, rxBufferSize), (VOID*)8192
/* }, {
L"HWTimeout", PARAM_DWORD, FALSE, offset(UARTPDD, hwTimeout),
fieldsize(UARTPDD, hwTimeout), (VOID*)100 */
}
};
/*
meaning of the pair:
first: the subaddress (physical offset<<3) of the register
second: the access constraint:
10: no constraint
20: lcr[7] == 0
30: lcr == 0xbf
40: lcr <> 0xbf
50: lcr[7] == 1 , lcr <> 0xbf, efr[4] = 1
60: lcr[7] == 1 , lcr <> 0xbf,
70: lcr <> 0xbf, and (efr[4] == 0 or efr[4] =1, mcr[2] = 0)
80: lcr <> 0xbf, and (efr[4] = 1, mcr[2] = 1)
90: lcr[7] == 0, efr[4] =1 (for ier bit 4-7)
third: 1: readonly
2: writeonly
3: read/write
*/
static const int reg_info[27][3] = {
{0x0, 20, 1}, //RHR
{0x0, 20, 2}, //THR
{0x0, 60, 3}, //DLL
{0x8, 60, 3}, //DLM
{0x10, 50, 3}, //DLD
{0x8, 90, 3}, //IER
{0x10, 20, 1}, //ISR
{0x10, 20, 2}, //FCR
{0x18, 10, 3}, //LCR
{0x20, 40, 3}, //MCR
{0x28, 40, 1}, //LSR
{0x30, 70, 1}, //MSR
{0x38, 70, 3}, //SPR
{0x30, 80, 3}, //TCR
{0x38, 80, 3}, //TLR
{0x40, 20, 1}, //TXLVL
{0x48, 20, 1}, //RXLVL
{0x50, 20, 3}, //IODir
{0x58, 20, 3}, //IOState
{0x60, 20, 3}, //IOIntEna
{0x70, 20, 3}, //IOControl
{0x78, 20, 3}, //EFCR
{0x10, 30, 3}, //EFR
{0x20, 30, 3}, //Xon1
{0x28, 30, 3}, //Xon2
{0x30, 30, 3}, //Xoff1
{0x38, 30, 3}, //Xoff2
};
#if 0
static BOOL RegPrintAll(UARTPDD *pPdd)
{
NKDbgPrintfW(_T("+RegPrintAll====================================\r\n"));
{
int i;
PHYSICAL_ADDRESS pa;
OMAP730_GPIO_REGS * pGPIORegs;
for (i=0; i<=5; i++)
{
pa.QuadPart = 0xFFFBC000 + 0x800 * i;
pGPIORegs = MmMapIoSpace(pa, sizeof(OMAP730_GPIO_REGS), FALSE);
NKDbgPrintfW(_T("DATA_INPUT[%d]:0x%x\r\n"), i+1, INREG32(&pGPIORegs->DATAIN));
NKDbgPrintfW(_T("DATA_OUTPUT[%d]:0x%x\r\n"), i+1, INREG32(&pGPIORegs->DATAOUT));
NKDbgPrintfW(_T("DIR_CONTROL[%d]:0x%x\r\n"), i+1, INREG32(&pGPIORegs->DATADIR));
NKDbgPrintfW(_T("INT_CONTROL[%d]:0x%x\r\n"), i+1, INREG32(&pGPIORegs->INTEDGE));
NKDbgPrintfW(_T("INT_MASK[%d]:0x%x\r\n"), i+1, INREG32(&pGPIORegs->INTMASK));
NKDbgPrintfW(_T("INT_STAT[%d]:0x%x\r\n"), i+1, INREG32(&pGPIORegs->INTSTAT));
MmUnmapIoSpace((VOID*)pGPIORegs, sizeof(OMAP730_GPIO_REGS));
NKDbgPrintfW(_T("====================================\r\n"));
}
}
NKDbgPrintfW(_T("conf6:0x%x\r\n"), INREG32(&pPdd->pConfigRegs->IO_CONFIG6));
NKDbgPrintfW(_T("conf9:0x%x\r\n"), INREG32(&pPdd->pConfigRegs->IO_CONFIG9));
NKDbgPrintfW(_T("conf13:0x%x\r\n"), INREG32(&pPdd->pConfigRegs->IO_CONFIG13));
NKDbgPrintfW(_T("====================================\r\n"));
{
int i;
UCHAR the_reg;
for (i=0; i<27; i++)
{
if ((reg_info[i][2] & 0x1) == 1) {
the_reg = RegRead(pPdd, i);
//NKDbgPrintfW(_T("Reg%d, Value:0x%x\r\n"), i, the_reg);
//NKDbgPrintfW(_T("%x\r\n"), the_reg);
}
{
// FILE *flt;
// flt= fopen("\\My Documents\\debug_gps.txt","a+");
// fprintf(flt,"Reg%d, Value:%x\r\n", i, the_reg);// write files
// fclose(flt);
}
}
}
NKDbgPrintfW(_T("-RegPrintAll====================================\r\n"));
return TRUE;
}
#endif
static void RegSetBit(UARTPDD *pPdd, UCHAR regaddr, UCHAR bit)
{
UCHAR lcr_reg;
UCHAR efr_reg;
UCHAR mcr_reg;
UCHAR the_reg;
if((reg_info[regaddr][2] & 0x2) == 0)
DEBUGMSG(ZONE_ERROR, (L"RegSetBit: Reg not writeable\r\n"));
DEBUGMSG(ZONE_FUNCTION, (L"RegSetBit(%d), bit: %d\r\n",regaddr, bit));
EnterConstraint(pPdd, regaddr, &lcr_reg, &efr_reg, &mcr_reg);
the_reg = I2c_ReadReg(pPdd, reg_info[regaddr][0]);
I2c_WriteReg(pPdd, reg_info[regaddr][0], the_reg | bit);
ExitConstraint(pPdd, regaddr, lcr_reg, efr_reg, mcr_reg);
}
static void RegClrBit(UARTPDD *pPdd, UCHAR regaddr, UCHAR bit)
{
UCHAR lcr_reg;
UCHAR efr_reg;
UCHAR mcr_reg;
UCHAR the_reg;
if((reg_info[regaddr][2] & 0x2) == 0)
DEBUGMSG(ZONE_ERROR, (L"RegClrBit: Reg not writeable\r\n"));
DEBUGMSG(ZONE_FUNCTION, (L"RegClrBit(%d), bit: %d\r\n", regaddr, bit));
EnterConstraint(pPdd, regaddr, &lcr_reg, &efr_reg, &mcr_reg);
the_reg = I2c_ReadReg(pPdd, reg_info[regaddr][0]);
I2c_WriteReg(pPdd, reg_info[regaddr][0], the_reg & ~bit);
ExitConstraint(pPdd, regaddr, lcr_reg, efr_reg, mcr_reg);
}
static void RegWrite(UARTPDD *pPdd, UCHAR regaddr, UCHAR data)
{
UCHAR lcr_reg;
UCHAR efr_reg;
UCHAR mcr_reg;
if((reg_info[regaddr][2] & 0x2) == 0)
DEBUGMSG(ZONE_ERROR, (L"RegWrite: Reg not writeable\r\n"));
//DEBUGMSG(ZONE_FUNCTION, (L"RegWrite(%d), value: %x\r\n", regaddr, data));
EnterConstraint(pPdd, regaddr, &lcr_reg, &efr_reg, &mcr_reg);
I2c_WriteReg(pPdd, reg_info[regaddr][0], data);
ExitConstraint(pPdd, regaddr, lcr_reg, efr_reg, mcr_reg);
}
static UCHAR RegRead(UARTPDD *pPdd, UCHAR regaddr)
{
UCHAR lcr_reg;
UCHAR efr_reg;
UCHAR mcr_reg;
UCHAR res;
if((reg_info[regaddr][2] & 0x1) == 0)
DEBUGMSG(ZONE_ERROR, (L"RegRead: Reg not readable\r\n"));
EnterConstraint(pPdd, regaddr, &lcr_reg, &efr_reg, &mcr_reg);
res = I2c_ReadReg(pPdd, reg_info[regaddr][0]);
ExitConstraint(pPdd, regaddr, lcr_reg, efr_reg, mcr_reg);
//DEBUGMSG(ZONE_FUNCTION, (L"RegRead(%d), value: %x\r\n", regaddr, res));
return res;
}
static void EnterConstraint(UARTPDD *pPdd, UCHAR regaddr, UCHAR *plcr_reg, UCHAR *pefr_reg, UCHAR *pmcr_reg)
{
switch (reg_info[regaddr][1]) {
//10: no contraint
case 20://20: lcr[7] == 0
*plcr_reg = I2c_ReadReg(pPdd, reg_info[XR20M1170REG_LCR][0]);
if (*plcr_reg & BIT7)
I2c_WriteReg(pPdd, reg_info[XR20M1170REG_LCR][0], *plcr_reg & ~BIT7);
break;
case 30://30: lcr == 0xbf
*plcr_reg = I2c_ReadReg(pPdd, reg_info[XR20M1170REG_LCR][0]);
if (*plcr_reg != 0xbf)
I2c_WriteReg(pPdd, reg_info[XR20M1170REG_LCR][0], 0xbf);
break;
case 40://40: lcr <> 0xbf
*plcr_reg = I2c_ReadReg(pPdd, reg_info[XR20M1170REG_LCR][0]);
if (*plcr_reg == 0xbf)
I2c_WriteReg(pPdd, reg_info[XR20M1170REG_LCR][0], *plcr_reg & ~BIT7);
break;
case 50://50: lcr[7] == 1 , lcr <> 0xbf, efr[4] = 1
*plcr_reg = I2c_ReadReg(pPdd, reg_info[XR20M1170REG_LCR][0]);
if (*plcr_reg != 0xbf)
I2c_WriteReg(pPdd, reg_info[XR20M1170REG_LCR][0], 0xbf);
*pefr_reg = I2c_ReadReg(pPdd, reg_info[XR20M1170REG_EFR][0]);
if ((*pefr_reg & BIT4 ) == 0)
I2c_WriteReg(pPdd, reg_info[XR20M1170REG_EFR][0], *pefr_reg | BIT4);
if ((*plcr_reg == 0xbf) || ((*plcr_reg & BIT7) == 0))
I2c_WriteReg(pPdd, reg_info[XR20M1170REG_LCR][0], (*plcr_reg | BIT7) & ~BIT0);
else
I2c_WriteReg(pPdd, reg_info[XR20M1170REG_LCR][0], *plcr_reg);
break;
case 60://60: lcr[7] == 1 , lcr <> 0xbf,
*plcr_reg = I2c_ReadReg(pPdd, reg_info[XR20M1170REG_LCR][0]);
if ((*plcr_reg == 0xbf) || ((*plcr_reg & BIT7) == 0))
I2c_WriteReg(pPdd, reg_info[XR20M1170REG_LCR][0], (*plcr_reg | BIT7) & ~BIT0);
break;
case 70://lcr <> 0xbf, and (efr[4] == 0 or efr[4] =1, mcr[2] = 0)
*plcr_reg = I2c_ReadReg(pPdd, reg_info[XR20M1170REG_LCR][0]);
if (*plcr_reg == 0xBF) {
*pefr_reg = I2c_ReadReg(pPdd, reg_info[XR20M1170REG_EFR][0]);
I2c_WriteReg(pPdd, reg_info[XR20M1170REG_LCR][0], *plcr_reg & ~BIT0);
*pmcr_reg = I2c_ReadReg(pPdd, reg_info[XR20M1170REG_MCR][0]);
if ((*pefr_reg & BIT4) && (*pmcr_reg & BIT2))
I2c_WriteReg(pPdd, reg_info[XR20M1170REG_MCR][0], *pmcr_reg & ~BIT2);
} else {
*pmcr_reg = I2c_ReadReg(pPdd, reg_info[XR20M1170REG_MCR][0]);
I2c_WriteReg(pPdd, reg_info[XR20M1170REG_LCR][0], 0xBF);
*pefr_reg = I2c_ReadReg(pPdd, reg_info[XR20M1170REG_EFR][0]);
if ((*pefr_reg & BIT4) && (*pmcr_reg & BIT2))
I2c_WriteReg(pPdd, reg_info[XR20M1170REG_EFR][0], *pefr_reg & ~BIT4);
I2c_WriteReg(pPdd, reg_info[XR20M1170REG_LCR][0], *plcr_reg);
}
break;
case 80: //lcr <> 0xbf, and (efr[4] = 1, mcr[2] = 1)
*plcr_reg = I2c_ReadReg(pPdd, reg_info[XR20M1170REG_LCR][0]);
if (*plcr_reg != 0xBF)
I2c_WriteReg(pPdd, reg_info[XR20M1170REG_LCR][0], 0xBF);
*pefr_reg = I2c_ReadReg(pPdd, reg_info[XR20M1170REG_EFR][0]);
if ((*pefr_reg & BIT4) == 0)
I2c_WriteReg(pPdd, reg_info[XR20M1170REG_EFR][0], *pefr_reg | BIT4);
I2c_WriteReg(pPdd, reg_info[XR20M1170REG_LCR][0], *plcr_reg & ~BIT0);
*pmcr_reg = I2c_ReadReg(pPdd, reg_info[XR20M1170REG_MCR][0]);
if ((*pmcr_reg & BIT2) == 0)
I2c_WriteReg(pPdd, reg_info[XR20M1170REG_MCR][0], *pmcr_reg | BIT2);
break;
case 90: //90: lcr[7] == 0, eft[4] =1
*plcr_reg = I2c_ReadReg(pPdd, reg_info[XR20M1170REG_LCR][0]);
if (*plcr_reg != 0xBF)
I2c_WriteReg(pPdd, reg_info[XR20M1170REG_LCR][0], 0xBF);
*pefr_reg = I2c_ReadReg(pPdd, reg_info[XR20M1170REG_EFR][0]);
if ((*pefr_reg & BIT4) == 0)
I2c_WriteReg(pPdd, reg_info[XR20M1170REG_EFR][0], *pefr_reg | BIT4);
I2c_WriteReg(pPdd, reg_info[XR20M1170REG_LCR][0], *plcr_reg & ~BIT7);
break;
}
}
static void ExitConstraint(UARTPDD *pPdd, UCHAR regaddr, UCHAR lcr_reg, UCHAR efr_reg, UCHAR mcr_reg)
{
//restore
switch (reg_info[regaddr][1]) {
//10: no contraint
case 20://20: lcr[7] == 0
if (lcr_reg & BIT7)
I2c_WriteReg(pPdd, reg_info[XR20M1170REG_LCR][0], lcr_reg);
break;
case 30://30: lcr == 0xbf
if (lcr_reg != 0xbf)
I2c_WriteReg(pPdd, reg_info[XR20M1170REG_LCR][0], lcr_reg);
break;
case 40://40: lcr <> 0xbf
if (lcr_reg == 0xbf)
I2c_WriteReg(pPdd, reg_info[XR20M1170REG_LCR][0], lcr_reg);
break;
case 50://50: lcr[7] == 1 , lcr <> 0xbf, efr[4] = 1
if ((efr_reg & BIT4 ) == 0) {
I2c_WriteReg(pPdd, reg_info[XR20M1170REG_LCR][0], 0xbf);
I2c_WriteReg(pPdd, reg_info[XR20M1170REG_EFR][0], efr_reg);
}
I2c_WriteReg(pPdd, reg_info[XR20M1170REG_LCR][0], lcr_reg);
break;
case 60://60: lcr[7] == 1 , lcr <> 0xbf,
if ((lcr_reg == 0xbf) || ((lcr_reg & BIT7) == 0))
I2c_WriteReg(pPdd, reg_info[XR20M1170REG_LCR][0], lcr_reg);
break;
case 70://lcr <> 0xbf, and (efr[4] == 0 or efr[4] =1, mcr[2] = 0)
if (lcr_reg == 0xBF) {
if ((efr_reg & BIT4) && (mcr_reg & BIT2))
I2c_WriteReg(pPdd, reg_info[XR20M1170REG_MCR][0], mcr_reg);
I2c_WriteReg(pPdd, reg_info[XR20M1170REG_LCR][0], lcr_reg);
} else if ((efr_reg & BIT4) && (mcr_reg & BIT2)) {
I2c_WriteReg(pPdd, reg_info[XR20M1170REG_LCR][0], 0xBF);
I2c_WriteReg(pPdd, reg_info[XR20M1170REG_EFR][0], efr_reg);
I2c_WriteReg(pPdd, reg_info[XR20M1170REG_LCR][0], lcr_reg);
}
break;
case 80://lcr <> 0xbf, and (efr[4] = 1, mcr[2] = 1)
if ((mcr_reg & BIT2) == 0)
I2c_WriteReg(pPdd, reg_info[XR20M1170REG_MCR][0], mcr_reg);
I2c_WriteReg(pPdd, reg_info[XR20M1170REG_LCR][0], 0xBF);
if ((efr_reg & BIT4) == 0)
I2c_WriteReg(pPdd, reg_info[XR20M1170REG_EFR][0], efr_reg);
if (lcr_reg != 0xBF)
I2c_WriteReg(pPdd, reg_info[XR20M1170REG_LCR][0], lcr_reg);
break;
case 90: //90: lcr[7] == 0, eft[4] =1 (for ier bit 4-7)
if ((efr_reg & BIT4) == 0) {
I2c_WriteReg(pPdd, reg_info[XR20M1170REG_LCR][0], 0xBF);
I2c_WriteReg(pPdd, reg_info[XR20M1170REG_EFR][0], efr_reg);
}
I2c_WriteReg(pPdd, reg_info[XR20M1170REG_LCR][0], lcr_reg);
break;
}
}
static BOOL I2c_WriteReg(UARTPDD *pPdd, UCHAR regaddr, UCHAR data)
{
UCHAR udata[2];
BOOL m_I2CError = I2C_ERROR;
//NKDbgPrintfW(_T("I2c_WriteReg: Reg%d, Value:0x%x\r\n"), regaddr/8, data);
udata[0] = regaddr;
udata[1] = data;
if (I2CWrite(pPdd->hI2c, udata, 2) != 2)
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -