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

📄 wmauxadc.c

📁 WM9713 audio codec driver for WinCE 5.0
💻 C
📖 第 1 页 / 共 3 页
字号:
        status = WMS_UNSUPPORTED;
        goto error0;
    }

    /*
     * We only have to do anything in streaming mode.
     */
#if WM_STREAM_AUXADC
    {
        WM_DEVICE_CONTEXT   *pDeviceContext = WMHANDLE_TO_DEVICE( hDevice );
        unsigned int        index;
        unsigned int        bucket;
        WM_REGVAL           adcAdr;
    
        /*
         * Protect ourselves from interference.
         */
        if ( !WMLockGlobalData( hDevice ) )
        {
            status = WMS_LOCK_TIMED_OUT;
            goto error0;
        }
    
        /* Touch is a special case */
        if ( WM_ADC_TOUCH == adc )
        {
            if ( !(pDeviceContext->v_pADCData->flags & WM_DRVCTX_AUXADC_TOUCH_STREAMING) )
            {
                /* Nothing to do */
                goto done;
            }
            pDeviceContext->v_pADCData->flags &= ~WM_DRVCTX_AUXADC_TOUCH_STREAMING;
    
            /* Stop the buckets */
            bucket = BUCKET_INDEX_FROM_ADCADR( WM_AUXADC_X_COORD );
            WM_ASSERT( hDevice, bucket < ADC_COUNT );
            pDeviceContext->v_pADCData->activeADCs &= ~(1 << bucket);
    
            bucket = BUCKET_INDEX_FROM_ADCADR( WM_AUXADC_Y_COORD );
            WM_ASSERT( hDevice, bucket < ADC_COUNT );
            pDeviceContext->v_pADCData->activeADCs &= ~(1 << bucket);
        }
        else
        {
            /* Work out the index into our table */
            index = INDEX_FROM_ADCVAL( adc );
            WM_ASSERT( hDevice, index < pDeviceContext->pChipDef->adcCount );
    
            /* Now look up the address */
            adcAdr = pDeviceContext->pChipDef->pAuxADCDetails[index].adcAdr;
            bucket = BUCKET_INDEX_FROM_ADCADR( adcAdr );
            WM_ASSERT( hDevice, bucket < ADC_COUNT );
    
            if ( !(pDeviceContext->v_pADCData->activeADCs & (1 << bucket)) )
            {
                /* Nothing to do */
                goto done;
            }
            pDeviceContext->v_pADCData->activeADCs &= ~(1 << bucket);
            pDeviceContext->v_pADCData->flags &= ~WM_DRVCTX_AUXADC_ADC_STREAMING;
    
            /* Stop the bucket */
            pDeviceContext->v_pADCData->activeADCs &= ~(1 << bucket);
        }
    
        /*
         * If we get here, we've got a change.
         */
        status = private_SwitchStreaming( hDevice );
        if ( WM_ERROR( status ) )
        {
            goto error1;
        }
    
    done:
        /*
         * Let other threads in.
         */
        WMUnlockGlobalData( hDevice );
    }
#endif  /* WM_STREAM_AUXADC */

    return WMS_SUCCESS;

#if WM_STREAM_AUXADC
error1:
    /*
     * Let other threads in.
     */
    WMUnlockGlobalData( hDevice );
#endif /* WM_STREAM_AUXADC */

error0:
    return status;
}

/*-----------------------------------------------------------------------------
 * Function:    WMSampleADC
 *
 * Returns the next sample of the given type.
 *
 * Parameters:
 *      hDevice             handle to the device (from WMOpenDevice)
 *      adc                 One of the WM_AUXADC_TYPE constants.
 *      pValue              Variable to receive the value (between 0 and 0xFFF).
 *                          Set to WM_INVALID_SAMPLE on error.
 *
 * Returns:     WMSTATUS
 *		See WMStatus.h.
 *---------------------------------------------------------------------------*/
WMSTATUS WMSampleADC( WM_DEVICE_HANDLE hDevice,
                        WM_AUXADC_TYPE adc,
                        WM_REGVAL *pValue
                      )
{
    WM_DEVICE_CONTEXT   *pDeviceContext = WMHANDLE_TO_DEVICE( hDevice );
    WMSTATUS            status;
    WM_REGVAL           adcSel;
    WM_REGVAL           adcAdr;
    WM_BOOL             needPenDown = FALSE;
    WM_REGVAL           rawValue;
    unsigned int        index;

    /* Check we've got AUX ADC */
    if ( !WM_IS_AUXADC_SUPPORTED( hDevice ) )
    {
        status = WMS_UNSUPPORTED;
        goto error;
    }

    /*
     * Work out our ADC address.
     * First calculate the index into our table...
     */
    index = INDEX_FROM_ADCVAL( adc );
    if ( index >= pDeviceContext->pChipDef->adcCount )
    {
    	status = WMS_INVALID_PARAMETER;
		goto error;
    }

    /* Now look up the address */
    adcSel = pDeviceContext->pChipDef->pAuxADCDetails[index].adcSel;
    adcAdr = pDeviceContext->pChipDef->pAuxADCDetails[index].adcAdr;
    needPenDown = pDeviceContext->pChipDef->pAuxADCDetails[index].needPenDown;

    if ( WM_AUXADC_INVALID == adcAdr )
    {
        status = WMS_INVALID_PARAMETER;
        goto error;
    }

    /*
     * Get the sample.
     */
#if WM_STREAM_AUXADC
    if ( pDeviceContext->v_pADCData->flags & WM_DRVCTX_AUXADC_STREAMING )
    {
        /*
         * Now sample the ADC.  Note we pass in the ADCADR instead of the
         * ADCSEL because we're checking against the returned data, not
         * requesting a new sample.
         */
        status = private_SampleADC( hDevice, adcAdr, &rawValue );
    }
    else
#endif /* WM_STREAM_AUXADC */
        status = private_PollADC( hDevice, adcSel, &rawValue );

    if ( WM_ERROR( status ) )
    {
        goto error;
    }

    /*
     * Check it's the right ADC.
     */
    if ( (rawValue & WM_AUXADC_MASK) != adcAdr )
    {
        status = WMS_UNEXPECTED_DATA;
        goto error;
    }

    /*
     * Check pen down if we need it.
     */
    if ( needPenDown && !(rawValue & WM_DATA_PENDOWN) )
    {
        status = WMS_NO_PEN_DOWN;
        goto error;
    }

    /*
     * Get the adcAdr sample.
     */
    *pValue = rawValue & WM_DATA_VAL;   // lowest 12 bits

    /*
     * Do any post-processing.
     */
    switch ( adc )
    {
        /*
         * Invert the sample if requested.
         */
#if WM_TOUCH_INVERT_X
        case WM_ADC_X_COORD:
            *pValue = WM_MAX_DATA_VAL - *pValue;
            break;
#endif /* WM_TOUCH_INVERT_X */
#if WM_TOUCH_INVERT_Y
        case WM_ADC_Y_COORD:
            *pValue = WM_MAX_DATA_VAL - *pValue;
            break;
#endif /* WM_TOUCH_INVERT_Y */

            /*
             * BMON has a divide by three to bring it within range of VRef.
             * Note: doing the multiply means we can return values greater
             * than WM_MAX_DATA_VAL.
             */
#if WM_BATTERY_NORMALISE
        case WM_ADC_BMON:
            *pValue *= 3;
            break;
#endif /* WM_BATTERY_NORMALISE */

        default:
            break;
    }

    return WMS_SUCCESS;

error:
    *pValue = WM_INVALID_SAMPLE;
    return status;
}

/*-----------------------------------------------------------------------------
 * Function:    private_PollADC
 *
 * Returns the next raw sample of the given type, using polling mode.
 *
 * Parameters:
 *      hDevice             handle to the device (from WMOpenDevice)
 *      adcSel              The ADCSEL address to pass to the chip (from the chipDef).
 *      pValue              Variable to receive the value (between 0 and 0xFFFF).
 *
 * Returns:     WMSTATUS
 *		See WMStatus.h.
 *---------------------------------------------------------------------------*/
static WMSTATUS private_PollADC( WM_DEVICE_HANDLE hDevice,
                                 WM_REGVAL adcSel,
                                 WM_REGVAL *pValue
                                 )
{
    WMSTATUS            status;
    WM_REGVAL           controlValue = 0;
    WM_REGVAL           controlMask = 0;
    WM_REGVAL           pollBit = WM_TOUCHCTRL_POLL;
    WM_REGTYPE          adcSelReg = WM97_DIGITISER_CONTROL;
    WM_REGVAL           adcSelValue = 0;
    unsigned int        tFail;
    WM_BOOL             isTouch = FALSE;

    /*
     * Make sure the digitiser is powered up.
     */
    status = WMAuxADCPowerUp( hDevice, WM_POWER_AUXADC_DIGITISER );
    if ( WM_ERROR( status ) )
    {
        goto error;
    }

    /*
     * Set delay.
     */
    controlMask = WM_TOUCHCTRL_DEL_MASK;

    /* Select the ADC */
    if ( WM_USES_ADCSEL( hDevice ) )
    {
        if ( WM_ADCSEL_X_COORD == adcSel || WM_ADCSEL_X_COORD == adcSel )
            isTouch = TRUE;
    }
    else
    {
        if ( WM_AUXADC_X_COORD == adcSel || WM_AUXADC_X_COORD == adcSel )
            isTouch = TRUE;
    }
    
    /* Set our delay appropriately */
    if ( isTouch )
        controlValue |= WM_TOUCH_SETTLE_DELAY;
    else
        controlValue |= WM_AUXADC_SETTLE_DELAY;

    /*
     * And write these to the registers.
     * First digitiser control.  Note this includes ADC input select on the
     * WM9705 and WM9712.
     */
    if ( !WM_USES_ADCSEL( hDevice ) )
    {
        controlValue |= WM_TOUCHCTRL_POLL | adcSel;
        controlMask |= WM_TOUCHCTRL_POLL | WM_AUXADC_MASK;
        
        /* The control register is the ADC select */
        adcSelReg = WM97_DIGITISER_CONTROL;
        pollBit = WM_TOUCHCTRL_POLL;
    }
    status = WMSetField( hDevice, WM97_DIGITISER_CONTROL, controlValue, controlMask );
    if ( WM_ERROR( status ) )
    {
        goto error;
    }
    
    /* 
     * Now digitiser ADC input select for any device not yet covered.
     */
    if ( WM_USES_ADCSEL( hDevice ) )
    {
        WM_REGVAL adcSelMask;
        
        adcSelMask = WM_ADCSEL_POLL | WM_ADCSEL_MASK;
        adcSelValue = WM_ADCSEL_POLL | adcSel;
     
    	status = WMSetField( hDevice, WM97_DIGITISER_ADCSEL, adcSelValue, adcSelMask );
    	if ( WM_ERROR( status ) )
    	{
    		goto error;
    	}
        
        /* The control register is the ADC select */
        adcSelReg = WM97_DIGITISER_ADCSEL;
        pollBit = WM_ADCSEL_POLL;
    }
    
    /*
     * Wait for the sample to complete (polling bit will reset itself).
     * If it doesn't complete within a couple of milliseconds, assume
     * something's gone wrong.
     */
    tFail = GetMillisecondTimestamp( hDevice ) + 2;
    do 
    {
        status = WMRead( hDevice, adcSelReg, &adcSelValue );
        if ( WM_ERROR( status ) )
        {
            goto error;
        }

        /* Are we done? */
        if ( !(adcSelValue & pollBit) )
        {
            break;
        }

        /* Let other things have a bit of time */
        WMBeNice( hDevice );
    } while ( GetMillisecondTimestamp( hDevice ) < tFail );

    /* Did we time out? */
    if ( adcSelValue & pollBit )
    {
        status = WMS_NO_DATA;
        goto error;
    }

    /*
     * Now read the value.
     */
	status = WMRead( hDevice, WM97_DIGITISER_DATA, pValue );
    if ( WM_ERROR( status ) )
    {
        goto error;
    }

    /*
     * Power down the digitiser again.  If we've come to this function, we're
     * not streaming, so it's safe to do this.
     */
    status = WMAuxADCPowerDown( hDevice, WM_POWER_AUXADC_DIGITISER );
    if ( WM_ERROR( status ) )
    {
        goto error;
    }

    /*
     * It worked.
     */
    return WMS_SUCCESS;

    /*
     * Error cleanup.
     */
error:
    /*
     * Power down the digitiser again.  If we've come to this function, we're
     * not streaming, so it's safe to do this.
     */
    WMAuxADCPowerDown( hDevice, WM_POWER_AUXADC_DIGITISER );

    return status;
}

#if WM_STREAM_AUXADC
/*-----------------------------------------------------------------------------
 * Function:    private_PrepareBucket
 *
 * Prepares the ADC functionality to handle readings of the appropriate type.
 *
 * Parameters:
 *      hDevice             handle to the device (from WMOpenDevice)
 *      adc                 Which ADC to prepare.
 *
 * Returns:     WMSTATUS
 *		See WMStatus.h
 *---------------------------------------------------------------------------*/
static void private_PrepareBucket( WM_DEVICE_HANDLE hDevice, WM_REGVAL adcAdr )
{
    WM_DEVICE_CONTEXT   *pDeviceContext = WMHANDLE_TO_DEVICE( hDevice );
    unsigned int        bucket;

    bucket = BUCKET_INDEX_FROM_ADCADR( adcAdr );
    WM_ASSERT( hDevice, bucket < ADC_COUNT );

    /*
     * The '05 and '12 can only do one input (other than touch) at a time.
     */
    if ( IS_WM9705_FAMILY( hDevice ) || IS_WM9712_FAMILY( hDevice ) )
    {
        /*
         * Zap the buckets, leaving just the touch.
         */
        pDeviceContext->v_pADCData->activeADCs &= TOUCH_ACTIVE_MASK;
    }
    
    /* Prepare the bucket */
    pDeviceContext->v_pADCData->reading[bucket] = WM_INVALID_SAMPLE;
    pDeviceContext->v_pADCData->lastReading[bucket] = WM_INVALID_SAMPLE;
    pDeviceContext->v_pADCData->activeADCs |= 1 << bucket;
}

/*-----------------------------------------------------------------------------
 * Function:    private_SwitchStreaming
 *
 * Enables or disables streaming and/or coordinate mode according to what has
 * been asked for.
 *
 * Streaming mode only.
 *
 * Parameters:
 *      hDevice             handle to the device (from WMOpenDevice)
 *
 * Returns:     WMSTATUS
 *		See WMStatus.h
 *---------------------------------------------------------------------------*/
static WMSTATUS private_SwitchStreaming( WM_DEVICE_HANDLE hDevice )
{
    WM_DEVICE_CONTEXT   *pDeviceContext = WMHANDLE_TO_DEVICE( hDevice );
    WMSTATUS            status;
    WM_REGVAL           controlVal = 0;
    WM_REGVAL           adcSelVal = 0;
    WM_BOOL             streamTouch;

⌨️ 快捷键说明

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