⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pdd.c

📁 Exar 公司 M1170 芯片 (i2c 转 串口)的 驱动
💻 C
📖 第 1 页 / 共 5 页
字号:
//
// 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 + -