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

📄 pdd.c

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