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

📄 bsptouch.cpp

📁 IMX31开发板触摸屏驱动程序
💻 CPP
📖 第 1 页 / 共 2 页
字号:
// Returns:
//      TRUE if successful, FALSE otherwise.
//
//-----------------------------------------------------------------------------
static BOOL BSPTouchAlloc(void)
{
    BOOL rc = FALSE;

    PHYSICAL_ADDRESS phyAddr;

    DEBUGMSG(ZONE_FUNCTION, (TEXT("+%s()\r\n"), __WFUNCTION__));

    phyAddr.QuadPart = CSP_BASE_REG_PA_EPIT2;

    // Map peripheral physical address to virtual address
    g_pEPIT = (PCSP_EPIT_REG) MmMapIoSpace(phyAddr, sizeof(CSP_EPIT_REG),
       FALSE);

    // Check if virtual mapping failed
    if (g_pEPIT == NULL)
    {
        DEBUGMSG(ZONE_ERROR,
            (_T("BSPTouchTimerAlloc:  MmMapIoSpace failed!\r\n")));
        goto cleanUp;
    }

    rc = TRUE;

cleanUp:
    if (!rc) BSPTouchDealloc();

    DEBUGMSG(ZONE_FUNCTION, (TEXT("-%s()\r\n"), __WFUNCTION__));
    
    return rc;
}


//-----------------------------------------------------------------------------
//
// Function: BSPTouchDeinit
//
// Deinitializes the BSP-specific interfaces and data structures for 
// touch support
//
// Parameters:
//      None.
//
// Returns:
//      None.
//
//-----------------------------------------------------------------------------
void BSPTouchDeinit(void)
{
    HANDLE hEvent;

    DEBUGMSG(ZONE_FUNCTION, (TEXT("-%s()\r\n"), __WFUNCTION__));

    // Disable timer
    if (g_pEPIT != NULL) BSPTouchTimerDisable();

    // Deinitialize PMIC touch interface
    PmicTouchDeinit();

    // If interrupt has been registered with OAL
    if (gIntrTouch != SYSINTR_UNDEFINED)
    {
        InterruptDone( gIntrTouch );
        InterruptDisable( gIntrTouch );
        KernelIoControl(IOCTL_HAL_RELEASE_SYSINTR, &gIntrTouch, sizeof(gIntrTouch), NULL, 0, NULL);
        gIntrTouch = SYSINTR_UNDEFINED;

        // If the touch panel was hijacked from GWES during CETK testing, 
        // restore the GWES bindings to the OAL
        if (gTouchEventName == gEventNameAlt)
        {
            gTouchEventName = gEventNamePri;

            // Reenable panel
            PmicTouchInit();

            // Obtain SYSINTR values from the OAL for the touch interrupts.
            // InterruptInitialize is called within MDD
            KernelIoControl(IOCTL_HAL_REQUEST_SYSINTR, &gTouchTimerIrq,
                sizeof(gTouchTimerIrq), &gIntrTouch, sizeof(gIntrTouch), NULL);

            hEvent = CreateEvent( NULL, FALSE, FALSE, gTouchEventName);

            InterruptInitialize(gIntrTouch, hEvent, NULL, 0);

            CloseHandle(hEvent);
        
            hEvent = NULL;
            gIntrTouch = SYSINTR_UNDEFINED;
        }
    }

    // Deallocate touch data structures
    BSPTouchDealloc();
    
    DEBUGMSG(ZONE_FUNCTION, (TEXT("-%s()\r\n"), __WFUNCTION__));
}


//-----------------------------------------------------------------------------
//
// Function: BSPTouchAttach
//
// The function performs BSP-specific attachment allocations and assignments.
//
// Parameters:
//      None.
//
// Returns:
//      Handle to an event that will be used by the touch MDD for interrupt
//      registration.
//
//-----------------------------------------------------------------------------
extern "C" HANDLE BSPTouchAttach(void)
{
    gTouchEventName = gEventNamePri;

    // Determine if touch is already to attached (i.e. to GWES) and
    // we are trying to hijack the interrupt signaling (i.e. for TUX)
    if (KernelIoControl(IOCTL_HAL_IRQ2SYSINTR, &gTouchTimerIrq,
        sizeof(gTouchTimerIrq), &gIntrTouch, sizeof(gIntrTouch), NULL))
    {
        // If panel interrupt registered to another process
        if (gIntrTouch != SYSINTR_UNDEFINED)
        {
            InterruptDone( gIntrTouch );
            InterruptDisable( gIntrTouch );
            KernelIoControl(IOCTL_HAL_RELEASE_SYSINTR, &gIntrTouch, sizeof(gIntrTouch), NULL, 0, NULL);
            gIntrTouch = SYSINTR_UNDEFINED;
            gTouchEventName = gEventNameAlt;
        }
    }

    return CreateEvent(NULL, FALSE, FALSE, gTouchEventName);
}


//-----------------------------------------------------------------------------
//
// Function: BSPTouchInit
//
// Initializes BSP-specific interfaces and data structures for touch support
//
// Parameters:
//      dwIntervalMsec
//          [in] Specifies the interval in msec to be used for generating
//          a periodic timer interrupt.  This interval sets the sample
//          rate of the touch driver.
//
// Returns:
//      TRUE indicates success. FALSE indicates failure.
//
//-----------------------------------------------------------------------------
BOOL BSPTouchInit(DWORD dwIntervalMsec)
{
    BOOL rc = FALSE;

    DEBUGMSG(ZONE_FUNCTION, (TEXT("+%s()\r\n"), __WFUNCTION__));

    // Allocate touch data structures
    if (!BSPTouchAlloc())
    {
        ERRORMSG(TRUE, (_T("BSPTouchInit:  BSPTouchAlloc failed\r\n")));
        goto cleanUp;
    }

    // Obtain SYSINTR values from the OAL for the touch interrupts.
    // InterruptInitialize is called within MDD
    if (!KernelIoControl(IOCTL_HAL_REQUEST_SYSINTR, &gTouchTimerIrq,
        sizeof(gTouchTimerIrq), &gIntrTouch, sizeof(gIntrTouch), NULL))
    {
        ERRORMSG(TRUE, (_T("BSPTouchInit: Failed to request the touch sysintr.\r\n")));
        gIntrTouch = SYSINTR_UNDEFINED;
        goto cleanUp;
    }

    // Initialize touch controller on PMIC
    if (PmicTouchInit() != PMIC_SUCCESS)
    {
        ERRORMSG(TRUE, (_T("BSPTouchInit:  PmicTouchInit failed\r\n")));
        goto cleanUp;
    }

    // Initialize the touch timer
    if (!BSPTouchTimerInit(dwIntervalMsec))
    {
        ERRORMSG(TRUE, (_T("BSPTouchInit:  BSPTouchTimerInit failed\r\n")));
        goto cleanUp;
    }

    rc = TRUE;

cleanUp:
    if (!rc) BSPTouchDeinit();

    DEBUGMSG(ZONE_FUNCTION, (TEXT("-%s()\r\n"), __WFUNCTION__));

    return rc;
}


//-----------------------------------------------------------------------------
//
// Function: BSPTouchGetSample
//
// This function is used to get touch screen samples from the ADS7843
// touch screen controller.
//
// Parameters:
//      x
//          [out] Points to x sample coordinate.
//
//      y
//          [out] Points to y sample coordinate.
//
// Returns:
//      Current touch panel status as TOUCH_PANEL_SAMPLE_FLAGS type.
//
//-----------------------------------------------------------------------------
TOUCH_PANEL_SAMPLE_FLAGS BSPTouchGetSample(INT *x, INT *y)
{
    UINT16 adc_x[3], adc_y[3];
    INT32 d0, d1, d2;
    static UINT16 hys_x[2];
    static UINT16 hys_y[2];
    static UINT32 hysIndex;
    static BOOL bPenDown = FALSE;

    TOUCH_PANEL_SAMPLE_FLAGS StateFlags = TouchSampleDownFlag;

    DEBUGMSG(ZONE_FUNCTION, (TEXT("+%s()\r\n"), __WFUNCTION__));

    // Request touch samples from PMIC
    if (PmicADCTouchRead(adc_x, adc_y) != PMIC_SUCCESS)
    {
        // Tell upper layers to ignore this attempt and
        // clear the TouchSampleDownFlag
        StateFlags = TouchSampleIgnore;
        goto cleanUp;
    }

    // Check for pen up condition
    for (int i=0; i<3; i++)
    {
        if ((adc_x[i] >= ADC_SAMPLE_MAX_VALUE) || (adc_y[i] >= ADC_SAMPLE_MAX_VALUE))
        {
            // Tell upper layers to ignore this attempt and
            // clear the TouchSampleDownFlag
            StateFlags = TouchSampleIgnore;
            goto cleanUp;
        }
    }

    // Calculate absolute differences between x-coordinate samples
    d0 = ABS(adc_x[0] - adc_x[1]);
    d1 = ABS(adc_x[1] - adc_x[2]);
    d2 = ABS(adc_x[0] - adc_x[2]);

    // Reject the samples if the spread is too large
    if ((d0 > DELTA_X_COORD_VARIANCE) || (d1 > DELTA_X_COORD_VARIANCE) ||
        (d2 > DELTA_X_COORD_VARIANCE))
    {
        StateFlags |= TouchSampleIgnore;
        goto cleanUp;    
    }
    
    // Pick the two samples closest together
    if (d0 < d1)
    {
        if (d0 < d2)
        {   
            // Sample 0 & 1 closest together
            *x = adc_x[0] + adc_x[1];
        }
        else
        {
            // Sample 0 & 2 closest together
            *x = adc_x[0] + adc_x[2];
        }
    }
    else
    {
        if (d1 < d2)
        {   
            // Sample 1 & 2 closest together
            *x = adc_x[1] + adc_x[2];
        }
        else
        {
            // Sample 0 & 2 closest together
            *x = adc_x[0] + adc_x[2];
        }
    }

    // Calculate absolute differences between y-coordinate samples
    d0 = ABS(adc_y[0] - adc_y[1]);
    d1 = ABS(adc_y[1] - adc_y[2]);
    d2 = ABS(adc_y[0] - adc_y[2]);

    if ((d0 > DELTA_Y_COORD_VARIANCE) || (d1 > DELTA_Y_COORD_VARIANCE) ||
        (d2 > DELTA_Y_COORD_VARIANCE))
    {
        StateFlags |= TouchSampleIgnore;
        goto cleanUp;    
    }
    
    // Pick the two samples closest together
    if (d0 < d1)
    {
        if (d0 < d2)
        {   
            // Sample 0 & 1 closest together
            *y = adc_y[0] + adc_y[1];
        }
        else
        {
            // Sample 0 & 2 closest together
            *y = adc_y[0] + adc_y[2];
        }
    }
    else
    {
        if (d1 < d2)
        {   
            // Sample 1 & 2 closest together
            *y = adc_y[1] + adc_y[2];
        }
        else
        {
            // Sample 0 & 2 closest together
            *y = adc_y[0] + adc_y[2];
        }
    }

    if (!bPenDown)
    {
        bPenDown = TRUE;

        // Prime the hysteresis buffers with average of two
        // best samples from ADC
        *x = *x >> 1;
        *y = *y >> 1;
        hys_x[0] = hys_x[1] = *x;
        hys_y[0] = hys_y[1] = *y;
    }
    else
    {
        // Implement noise rejection since transition to pen up
        // condition often gives us a spike in samples
        if (ABS(*x - (hys_x[0] + hys_x[1])) > (DELTA_X_COORD_VARIANCE*8))
        {
            StateFlags |= TouchSampleIgnore;
            goto cleanUp;    
        }
    
        if (ABS(*y - (hys_y[0] + hys_y[1])) > (DELTA_Y_COORD_VARIANCE*8))
        {
            StateFlags |= TouchSampleIgnore;
            goto cleanUp;    
        }
                
        // Average two best samples from ADC with samples
        // from hysteresis buffer
        *x = (hys_x[0] + hys_x[1] + *x) >> 2;
        *y = (hys_y[0] + hys_y[1] + *y) >> 2;

        // Replace an entry in hysteresis buffer
        hys_x[hysIndex & 0x1] = *x;
        hys_y[hysIndex & 0x1] = *y;

        hysIndex++;
    }

    // Tell upper layers that this attempt was valid
    StateFlags |= TouchSampleValidFlag;
        

cleanUp:

    // If we need to look for next pen down event
    if (!(StateFlags & TouchSampleDownFlag))
    {
        // Place touch controller back in standby mode
        if (PmicADCTouchStandby(true) != PMIC_SUCCESS)
        {
            ERRORMSG(1, (_T("PmicTouchStandby failed\r\n")));
        }

        // Make sure pen down interrupt is unmasked
        if (PmicInterruptHandlingComplete(PMIC_MC13783_INT_TSI) != PMIC_SUCCESS)
        {
            ERRORMSG(1, (_T("PmicInterruptHandlingComplete failed\r\n")));
        }

        bPenDown = FALSE;
    }        

    DEBUGMSG(ZONE_FUNCTION, (TEXT("-%s()\r\n"), __WFUNCTION__));

    return StateFlags;
}


//-----------------------------------------------------------------------------
//
// Function: BSPTouchPowerHandler
//
// DESCRIPTION:
//      This function enable and disable the PEN_IRQ, the function
//      also disable timer during power down
//
// Parameters:
//      boff - TRUE  : power down
//           - FALSE : power up
//
// Returns:
//      None.
//
//-----------------------------------------------------------------------------
void BSPTouchPowerHandler(BOOL boff)
{
    DEBUGMSG(ZONE_FUNCTION, (TEXT("+%s()\r\n"), __WFUNCTION__));

    if (boff)
    {
    }
    else
    {
    }

    DEBUGMSG(ZONE_FUNCTION, (TEXT("-%s()\r\n"), __WFUNCTION__));
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -