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

📄 wmauxadc.c

📁 pxa270平台 windows mobile 5.2 wm9713 触摸屏+音频驱动
💻 C
📖 第 1 页 / 共 3 页
字号:
    WM_BOOL             streamADC;
    unsigned int        sampleRate = 0;
    WM_REGVAL           conversionRate = 0;
    WM_REGVAL           settleDelay = 0;

    /*
     * Variables for shorthand.
     */
    streamTouch = pDeviceContext->v_pADCData->flags & WM_DRVCTX_AUXADC_TOUCH_STREAMING;
    streamADC = pDeviceContext->v_pADCData->flags & WM_DRVCTX_AUXADC_ADC_STREAMING;

    /*
     * Work out our request.
     */
    adcSelVal = private_GetAdcSelVal( hDevice );

    /* If we've got something, add in the rest to enable streaming */
    if ( 0 != adcSelVal )
    {
        /* Use at least the touch conversion rates if touch is requested. */
        if ( streamTouch )
        {
            sampleRate = WM_TOUCH_SAMPLE_RATE;
            settleDelay = WM_TOUCH_SETTLE_DELAY;
        }
    
        /* An Auxiliary ADC? */
        if ( streamADC && ( 0 != pDeviceContext->v_pADCData->activeADCs ) )
        {
            /*
             * The conversion rate is the faster of the touch panel and the ADC.
             *
             * If we're not using the touch panel, this will currently be 0.
             */
            sampleRate = WM_MAX( sampleRate, WM_DIGITISER_SAMPLE_RATE );
    
            /*
             * The settle delay is the longer of the touch panel and the ADC.
             * Higher number is longer.
             *
             * If we're not using the touch panel, this will currently be 0.
             */
            settleDelay = WM_MAX( settleDelay, WM_AUXADC_SETTLE_DELAY );
        }

        /* Now convert from sample rate to CR setting */
        if ( IS_WM9713_FAMILY( hDevice ) )
        {
            if ( sampleRate > 154 )
            {
                if ( sampleRate > 187 )
                {
                    WM_TRACE( hDevice, ( "WM9713 maximum sample rate is 187.5Hz" ));
                }
                conversionRate = WM9713_TOUCHCTRL_CR_187Hz;
            }
            else if ( sampleRate > 120 )
            {
                conversionRate = WM9713_TOUCHCTRL_CR_154Hz;
            }
            else if ( sampleRate > 94 )
            {
                conversionRate = WM9713_TOUCHCTRL_CR_120Hz;
            }
            else
            {
                conversionRate = WM9713_TOUCHCTRL_CR_94Hz;
            }
        }
        else	/* => WM9705 or WM9712 */
        {
            if ( sampleRate > 375 )
            {
                if ( sampleRate > 750 )
                {
                    WM_TRACE( hDevice, ( "WM9705/WM9712 maximum sample rate is 750Hz" ) );
                }
                conversionRate = WM97_TOUCHCTRL_CR_750Hz;
            }
            else if ( sampleRate > 187 )
            {
                conversionRate = WM97_TOUCHCTRL_CR_375Hz;
            }
            else if ( sampleRate > 94 )
            {
                conversionRate = WM97_TOUCHCTRL_CR_187Hz;
            }
            else
            {
                conversionRate = WM97_TOUCHCTRL_CR_94Hz;
            }
        }

        /*
         * Select and configure continuous mode.
         */
        controlVal |= WM97_TOUCHCTRL_SLEN       /* Slot enable */
                   |  WM97_AUXADC_SLOT          /* Slot selection */
                   |  conversionRate            /* Conversion rate */
                   |  settleDelay;              /* Settling time */

        if ( !(pDeviceContext->v_pADCData->flags & WM_DRVCTX_AUXADC_STREAMING) )
        {
            /*
            * Make sure the digitiser is powered up.
            */
            status = WMAuxADCPowerUp( hDevice, WM_POWER_AUXADC_DIGITISER );
            if ( WM_ERROR( status ) )
            {
                goto error;
            }
        }

        /*
         * Do a poll with the new settings to get things started.
         * Note: it's enough to set the poll bit to kick things off and then
         * switch immediately to continuous mode.  This way the result will
         * come across the slot as normal, but we won't have to wait for our
         * first set of results.
         */
        if ( WM_USES_ADCSEL( hDevice ) )
        {
            adcSelVal |= WM_ADCSEL_POLL;
        }
        else
        {
            controlVal |= WM_TOUCHCTRL_POLL | adcSelVal;
        }
        
        /*
         * Now write our control (and ADC selection on WM9705/12)
         */
        status = WMWrite( hDevice, WM97_DIGITISER_CONTROL, controlVal );
        if ( WM_ERROR( status ) )
        {
            goto error;
        }
        
        /*
         * Write the ADCSEL if separate.
         */
        if ( WM_USES_ADCSEL( hDevice ) )
        {
            status = WMWrite( hDevice, WM97_DIGITISER_ADCSEL, adcSelVal );
            if ( WM_ERROR( status ) )
            {
                goto error;
            }
        }
        /*
         * Now switch to continuous mode.  The poll will complete and send
         * the results across the slot, and the timer will start so we'll
         * get our readings continuously from now on.
         */
        if ( WM_USES_ADCSEL( hDevice ) )
        {
            adcSelVal = (adcSelVal & ~WM_ADCSEL_POLL) | WM_ADCSEL_CTC;
            
            /*
             * Now tell the chip to start the new stream.
             */
            status = WMWrite( hDevice, WM97_DIGITISER_ADCSEL, adcSelVal );
            if ( WM_ERROR( status ) )
            {
                goto error;
            }
        }
        else
        {
            controlVal = (controlVal & ~WM_TOUCHCTRL_POLL) | WM_TOUCHCTRL_CTC;
            
            /*
             * Now tell the chip to start the new stream.
             */
            status = WMWrite( hDevice, WM97_DIGITISER_CONTROL, controlVal );
            if ( WM_ERROR( status ) )
            {
                goto error;
            }
        }
            
        /*
         * We're streaming.
         */
        pDeviceContext->v_pADCData->flags |= WM_DRVCTX_AUXADC_STREAMING;
    }
    else
    {
        /*
         * Tell the chip to stop streaming.
         */
        if ( WM_USES_ADCSEL( hDevice ) )
        {
            status = WMWrite( hDevice, WM97_DIGITISER_ADCSEL, 0 );
        }
        else
        {
            status = WMWrite( hDevice, WM97_DIGITISER_CONTROL, 0 );
        }
        if ( WM_ERROR( status ) )
        {
            goto error;
        }
        
        /*
         * If we're not streaming, power down the digitiser again.
         */
        status = WMAuxADCPowerDown( hDevice, WM_POWER_AUXADC_DIGITISER );
        if ( WM_ERROR( status ) )
        {
            goto error;
        }
        
        /*
         * We're not streaming.
         */
        pDeviceContext->v_pADCData->flags &= ~WM_DRVCTX_AUXADC_STREAMING;
    }

    /*
     * It worked.
     */
    return WMS_SUCCESS;

error:
    /*
     * Return the status we received
     */
    return status;
}

/*-----------------------------------------------------------------------------
 * Function:    private_GetAdcSelVal (streaming mode)
 *
 * Returns the ADCSEL value for the Aux ADC currently selected, appropriate
 * for the device in question (i.e. for WM97_DIGITISER_CONTROL for the WM9712,
 * for WM97_DIGITISER_ADCSEL for the WM9713).
 * 
 * Note: this _doesn't_ turn on continuous mode.
 *
 * Parameters:
 *      hDevice             handle to the device (from WMOpenDevice)
 *
 * Returns:     WM_REGVAL
 *      The ADCSEL value to pass to the ADCSEL sections of the appropriate
 *      register.
 *---------------------------------------------------------------------------*/
static WM_REGVAL private_GetAdcSelVal( WM_DEVICE_HANDLE hDevice )
{
    WM_DEVICE_CONTEXT   *pDeviceContext = WMHANDLE_TO_DEVICE( hDevice );
    WM_REGVAL           adcSelVal = 0;

    if ( WM_USES_ADCSEL( hDevice ) )
    {
        adcSelVal = ADCSEL_FROM_BUCKET_MASK( pDeviceContext->v_pADCData->activeADCs );
    }
    else
    {
        int bit;
        int bitmask;
        int activeADCs = pDeviceContext->v_pADCData->activeADCs;

        /*
         * If we've got touch, turn on coordinate mode, and mask off X and Y
         * from our checks.
         */
        if ( pDeviceContext->v_pADCData->flags & WM_DRVCTX_AUXADC_TOUCH_STREAMING )
        {
            adcSelVal |= WM_TOUCHCTRL_COO;
            activeADCs &= ~TOUCH_ACTIVE_MASK;
        }
            
        /*
         * Run through the bits until we find one which is set.
         * The '05 and '12 can only do one input (other than touch) at a time,
         * so we'll take the first we find (ignoring touch).
         */
        for ( bit = 0; bit < ADC_COUNT; bit++ )
        {
            bitmask = 1U << bit;
            if ( activeADCs & bitmask )
            {
                adcSelVal |= ADCADR_FROM_BUCKET_INDEX( bit );
                break;
            }
        }
    }
    
    /*
     * And return the value we've built up.
     */
    return adcSelVal;
}

/*-----------------------------------------------------------------------------
 * Function:    private_SampleADC (streaming mode)
 *
 * Returns the next raw sample of the given type, using streaming mode.
 *
 * Parameters:
 *      hDevice             handle to the device (from WMOpenDevice)
 *      adcAdr              The ADCADR address to look for (from the chipDef).
 *      pValue              Variable to receive the value (between 0 and 0xFFFF).
 *
 * Returns:     WMSTATUS
 *		See WMStatus.h.
 *---------------------------------------------------------------------------*/
static WMSTATUS private_SampleADC( WM_DEVICE_HANDLE hDevice,
                                   WM_REGVAL adcAdr,
                                   WM_REGVAL *pValue
                                   )
{
    WM_DEVICE_CONTEXT   *pDeviceContext = WMHANDLE_TO_DEVICE( hDevice );
    WMSTATUS            status = WMS_SUCCESS;
    unsigned int        bucket;
    unsigned short      activeFlag;
    int                 sampleCount;

    /*
     * Protect ourselves from interference.
     */
    if ( !WMLockGlobalData( hDevice ) )
    {
        status = WMS_LOCK_TIMED_OUT;
        goto error0;
    }

    /*
     * Work out our bucket.
     */
    bucket = BUCKET_INDEX_FROM_ADCADR( adcAdr );
    WM_ASSERT( hDevice, bucket < ADC_COUNT );
    activeFlag = 1 << bucket;

    /*
     * Wait for something in our bucket.
     */
    sampleCount = 0;
    while ( WM_INVALID_SAMPLE == pDeviceContext->v_pADCData->reading[bucket]
         && pDeviceContext->v_pADCData->activeADCs & activeFlag
         && sampleCount < SAMPLE_CYCLE_COUNT
          )
    {
        status = private_GetADCValue( hDevice );
        if ( WMS_NO_DATA == status )
        {
            MicroSleep( hDevice, SAMPLE_DATA_WAIT );
        }
        else if ( WM_ERROR( status ) )
        {
            goto error1;
        }

        sampleCount++;
    }

    /*
     * Read the value.
     */
    *pValue = pDeviceContext->v_pADCData->reading[bucket];

    if ( WM_INVALID_SAMPLE == *pValue )
    {
        *pValue = pDeviceContext->v_pADCData->lastReading[bucket];
    }
    
    /*
     * If we still haven't got anything, give up.
     */
    if ( WM_INVALID_SAMPLE == *pValue )
    {
        /*
         * Check we're actually reading this ADC.
         */
        if ( !pDeviceContext->v_pADCData->activeADCs & (1 << bucket) )
        {
            status = WMS_AUXADC_INACTIVE;
        }
        else
        {
            status = WMS_NO_DATA;
        }
        goto error1;
    }

    /* 
     * Now we've got something, save it and zap the bucket.
     */
    pDeviceContext->v_pADCData->lastReading[bucket] =
                        pDeviceContext->v_pADCData->reading[bucket];
    pDeviceContext->v_pADCData->reading[bucket] = WM_INVALID_SAMPLE;

    /*
     * Let other threads in.
     */
    WMUnlockGlobalData( hDevice );

    return WMS_SUCCESS;

    /*
     * Failure.
     */
error1:
    WMUnlockGlobalData( hDevice );

error0:
    return status;
}

/*-----------------------------------------------------------------------------
 * Function:    private_GetADCValue (streaming mode)
 *
 * Reads the next sample off the stream and puts it into the appropriate
 * bucket, using streaming mode.
 *
 * Parameters:
 *      hDevice             handle to the device (from WMOpenDevice)
 *
 * Returns:     WMSTATUS
 *		See WMStatus.h.
 *---------------------------------------------------------------------------*/
static WMSTATUS private_GetADCValue( WM_DEVICE_HANDLE hDevice )
{
    WM_DEVICE_CONTEXT   *pDeviceContext = WMHANDLE_TO_DEVICE( hDevice );
    WMSTATUS            status = WMS_SUCCESS;
    unsigned int        bucket;
    WM_REGVAL           adcVal;

    status = WMPlatformReadCTCAuxADC( hDevice, &adcVal );
    if ( WM_ERROR( status ) )
    {
        goto error;
    }

    bucket = BUCKET_INDEX_FROM_ADCADR( adcVal );
    if ( bucket >= ADC_COUNT )
    {
        status = WMS_UNEXPECTED_DATA;
        goto error;
    }

    pDeviceContext->v_pADCData->reading[bucket] = adcVal;

    /*
    WM_TRACE( hDevice, 
              ( "private_SampleADC: received 0x%X (bucket %d, value 0x%X%s)",
                adcVal,
                bucket,
                adcVal & WM_DATA_VAL,
                (adcVal & WM_DATA_PENDOWN) ? ", pen down" : ""
              ));
    */

    return WMS_SUCCESS;

error:
    return status;
}
#endif  /* WM_STREAM_AUXADC */

#endif  /* WM_AUXADC */

/*------------------------------ END OF FILE ---------------------------------*/

⌨️ 快捷键说明

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