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

📄 lh7a404_adc_driver.c

📁 sharp触摸屏测试代码
💻 C
📖 第 1 页 / 共 3 页
字号:
 *     arg   : Not used
 *
 * Outputs: None
 *
 * Returns: The pointer to a ADC config structure or 0
 *
 * Notes: None
 *
 **********************************************************************/
INT_32 adc_open(void *ipbase,
                INT_32 arg)
{
    INT_32 status = 0;

    if ((adccfg.init == FALSE) && ((ADC_REGS_T *) ipbase == ADC))
    {
        /* Device is valid and not previously initialized */
        adccfg.init = TRUE;

        /* Save and return address of peripheral block */
        adccfg.regptr = (ADC_REGS_T *) ipbase;

        /* Place ADC in a default state */
        adc_default(adccfg.regptr);

        /* Empty ring buffer and set conversion counter to 0 */
        adccfg.rx_head = adccfg.rx_tail = 0;
        adccfg.conv_count = 0;

        /* Clear default callback vector addresses for pendown and
           brownout interrupts */
        adccfg.bro_cbfunc = (PFV) NULL;
        adccfg.pd_cbfunc = (PFV) NULL;

        /* Return pointer to ADC configuration structure */
        status = (INT_32) &adccfg;
    }

    return status;
}

/***********************************************************************
 *
 * Function: adc_close
 *
 * Purpose: Close the ADC
 *
 * Processing:
 *     If init is not TRUE, then return _ERROR to the caller as the
 *     device was not previously opened. Otherwise, disable the ADC
 *     interface and controller by calling adc_default(), and return
 *     _NO_ERROR to the caller.
 *
 * Parameters:
 *     devid: Pointer to ADC config structure
 *
 * Outputs: None
 *
 * Returns: The status of the close operation
 *
 * Notes: None
 *
 **********************************************************************/
STATUS adc_close(INT_32 devid)
{
    ADC_CFG_T *adccfgptr = (ADC_CFG_T *) devid;
    STATUS status = _ERROR;

    if (adccfgptr->init == TRUE)
    {
        /* Restore ADC to a default state */
        adc_default(adccfg.regptr);

        status = _NO_ERROR;
        adccfgptr->init = FALSE;
    }

    return status;
}

/***********************************************************************
 *
 * Function: adc_ioctl
 *
 * Purpose: ADC configuration block
 *
 * Processing:
 *     This function is a large case block. Based on the passed function
 *     and option values, set or get the appropriate ADC parameter.
 *
 * Parameters:
 *     devid: Pointer to ADC config structure
 *     cmd:   ioctl command
 *     arg:   ioctl argument
 *
 * Outputs: None
 *
 * Returns: The status of the ioctl operation
 *
 * Notes: None
 *
 **********************************************************************/
STATUS adc_ioctl(INT_32 devid,
                 INT_32 cmd,
                 INT_32 arg)
{
    ADC_REGS_T *adcregsptr;
    UNS_32 tmp, tmp1, tmp2;
    ADC_CH_CONV_T *chcfgptr;
    ADC_CFG_T *adccfgptr = (ADC_CFG_T *) devid;
    STATUS status = _ERROR;

    if (adccfgptr->init == TRUE)
    {
        status = _NO_ERROR;
        adcregsptr = adccfgptr->regptr;

        switch (cmd)
        {
            case ADC_SET_CLOCK:
                /* Set base speed of ADC clock in Hz */
                /* Try to find best ADC clock at or below desired
                   clock */
                tmp1 = 0;
                tmp2 = 1;
                while ((tmp1 < 7) &&
                    ((CLOCK_MAINOSC / tmp2) > (UNS_32) arg))
                {
                    tmp1++;
                    tmp2 = tmp2 * 2;
                }

                /* Best divider found, use it */
                tmp = adcregsptr->adcpcr & ~ADC_CLKSEL_MASK;
                adcregsptr->adcpcr = (tmp | ADC_CLKSEL_SET(tmp1));
                break;

            case ADC_CLEAR_FIFO:
                /* Clear the ADC sample FIFO */
                while ((adcregsptr->adcfifosts & ADC_FIFO_EMPTY) == 0)
                {
                    tmp = adcregsptr->adcresults;
                }
                break;

            case ADC_ENABLE_IREF:
                /* Enable or disable the internal reference buffer */
                if (arg == 1)
                {
                    adcregsptr->adcpcr |= ADC_REF_ENABLE;
                }
                else
                {
                    adcregsptr->adcpcr &= ~ADC_REF_ENABLE;
                }
                break;

            case ADC_CLEAR_INTS:
                /* Clear pending ADC interrupts */
                adcregsptr->adcic = ((UNS_32) arg &
                    (ADC_EOS_CLR | ADC_PEN_CLR | ADC_BROWNOUT_CLR));
                break;

            case ADC_INT_ENABLE:
                /* Enable ADC interrupts */
                adcregsptr->adcie |= ((UNS_32) arg &
                        (ADC_FIFO_OV_INT | ADC_WATERM_INT |
                        ADC_EOS_INT | ADC_PEN_INT)) | ADC_GLOBAL_INT;
                break;

            case ADC_INT_DISABLE:
                /* Disable ADC interrupts */
                adcregsptr->adcie &= ~((UNS_32) arg &
                    (ADC_FIFO_OV_INT | ADC_WATERM_INT |
                    ADC_EOS_INT | ADC_PEN_INT | ADC_GLOBAL_INT));
                if (adcregsptr->adcie == ADC_GLOBAL_INT)
                {
                    adcregsptr->adcie = 0;
                }                    
                break;

            case ADC_INSTALL_BRO:
                /* Install the brownout interrupt callback function */
                adccfgptr->bro_cbfunc = (PFV) arg;
                break;

            case ADC_INSTALL_PDC:
                /* Install the pendown interrupt callback function */
                adccfgptr->pd_cbfunc = (PFV) arg;
                break;

            case ADC_INSTALL_EOS:
                /* Install the end of sequence interrupt callback
                   function */
                adccfgptr->eos_cbfunc = (PFV) arg;
                break;
                
            case ADC_SET_IDLE_CH:
                /* Configure or reconfigure the ADC inputs used
                   during idle mode */
                chcfgptr = (ADC_CH_CONV_T *) arg;
                tmp = (ADC_SETTIME(chcfgptr->settle_clks) |
                    ADC_INPSEL(chcfgptr->inpc) |
                    ADC_INNSEL(chcfgptr->innc) |
                    ADC_REFP_SEL(chcfgptr->vrefp));
                adcregsptr->adcidlehi = tmp;

                /* Build and save the control bank low word register */
                tmp = (ADC_REFN_SEL(chcfgptr->vrefn) |
                    chcfgptr->bias);
                adcregsptr->adcidlelo = tmp;
                break;

            case ADC_SET_WMLEVEL:
                /* Set ADC FIFO watermark (interrupt trip) level */
                tmp = adcregsptr->adcgencfg & ~ADC_WM_MASK;
                adcregsptr->adcgencfg = (tmp |
                    ADC_WM_SET((UNS_32) arg));
                break;

            case ADC_ADD_CHANNEL:
                /* Add a conversion sequence entry */
                chcfgptr = (ADC_CH_CONV_T *) arg;
                status = adc_add_sequence_entry(chcfgptr, adccfgptr);
                break;

            case ADC_CHG_CHANNEL:
                /* Changes a conversion sequence entry with the passed
                   key argument */
                chcfgptr = (ADC_CH_CONV_T *) arg;
                status = adc_chg_sequence_entry(chcfgptr, adccfgptr);
                break;

            case ADC_START_SAMP:
                /* Starts an ADC sample */
                adcregsptr->adcgencfg |= ADC_SSB_START;
                break;

            case ADC_SET_STATE:
                /* Set sampling state */
                if (arg == ADC_MODE_RESET)
                {
                    /* Reset ADC controller and driver */
                    adc_default(adcregsptr);

                    /* Empty ring buffer and set conversion counter
                       to 0 */
                    adccfgptr->rx_head = adccfgptr->rx_tail = 0;
                    adccfgptr->conv_count = 0;
                }
                else if (arg == ADC_MODE_STOP)
                {
                    /* Stop the ADC controller */
                    tmp = adcregsptr->adcpcr & ~ADC_PWM_MASK;
                    adcregsptr->adcpcr = (tmp | ADC_PWM_ALL_OFF);
                }
                else if (arg == ADC_SW_TRIGGERED)
                {
                    /* ADC mode is polled/sw triggered */
                    /* Disable and clear ADC interrupts */
                    adcregsptr->adcie &= ~((UNS_32) arg &
                        (ADC_FIFO_OV_INT | ADC_WATERM_INT |
                        ADC_EOS_INT | ADC_PEN_INT | ADC_GLOBAL_INT));
                    adcregsptr->adcic = ((UNS_32) arg &
                        (ADC_EOS_CLR | ADC_PEN_CLR | ADC_BROWNOUT_CLR));

                    /* Standby mode  */
                    tmp = adcregsptr->adcpcr & ~ADC_PWM_MASK;
                    adcregsptr->adcpcr = (tmp | ADC_PWM_STANDBY);

                    /* Enable triggered mode  */
                    tmp = adcregsptr->adcgencfg & ~ADC_SSM_MASK;
                    adcregsptr->adcgencfg = (tmp | ADC_SSM_SSB);
                }
                else if (arg == ADC_PENDOWN_TRIGGERED)
                {
                    /* An ADC sequence is started on a pendown
                       detection event */
                    /* Standby mode  */
                    tmp = adcregsptr->adcpcr & ~ADC_PWM_MASK;
                    adcregsptr->adcpcr = (tmp | ADC_PWM_STANDBY);

                    /* Enable pendown triggered mode  */
                    tmp = adcregsptr->adcgencfg & ~ADC_SSM_MASK;
                    adcregsptr->adcgencfg = (tmp | ADC_SSM_PEN);
                }
                else if (arg == ADC_PENDOWN_SW_TRIGGERED)
                {
                    /* An ADC sequence is started on a pendown
                       detection event or software request */
                    /* Standby mode  */
                    tmp = adcregsptr->adcpcr & ~ADC_PWM_MASK;
                    adcregsptr->adcpcr = (tmp | ADC_PWM_STANDBY);

                    /* Enable pendown triggered mode  */
                    tmp = adcregsptr->adcgencfg & ~ADC_SSM_MASK;
                    adcregsptr->adcgencfg = (tmp | ADC_SSM_SSB_PEN);
                }
                else if (arg == ADC_CONTINUOUS)
                {
                    /* Place ADC in run mode */
                    tmp = adcregsptr->adcpcr & ~ADC_PWM_MASK;
                    adcregsptr->adcpcr = (tmp | ADC_PWM_RUN);

                    /* Continuous sampling */
                    tmp = adcregsptr->adcgencfg & ~ADC_SSM_MASK;
                    adcregsptr->adcgencfg = (tmp | ADC_SSM_CONT);
                }
                else
                {
                    /* Unknown mode */
                    status = SMA_BAD_PARAMS;
                }
                break;                

            case ADC_GET_STATUS:
                switch (arg)
                {
                    case ADC_RAWINT_ST:
                        /* Return raw interrupt statuses */
                        status = (INT_32) (adcregsptr->adcrawint &
                            (ADC_FIFO_OV_IRQ | ADC_WATERM_IRQ |
                            ADC_EOS_IRQ |ADC_PEN_IRQ |
                            ADC_BROWNOUT_IRQ));
                        break;

                    case ADC_INT_ST:
                        /* Return pending (enabled) interrupt
                           statuses */

⌨️ 快捷键说明

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