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

📄 lh7a404_adc_driver.c

📁 sharp触摸屏测试代码
💻 C
📖 第 1 页 / 共 3 页
字号:
/***********************************************************************
 * $Workfile:   lh7a404_adc_driver.c  $
 * $Revision:   1.0  $
 * $Author:   WellsK  $
 * $Date:   Oct 15 2003 17:24:44  $
 *
 * Project: LH7A404 ADC driver
 *
 * Description:
 *     This file contains driver support for the ADC module on the
 *     LH7A404
 *
 * Notes:
 *     The number of different configurations supported by the ADC
 *     is beyond the scope of this driver. This driver provides the
 *     following basic functions:
 *         Sequenced analog to digital conversions (polled, interrupt)
 *         Touchscreen conversions (polled, interrupt)
 *         Pendown state detect to touchscreen conversions (interrupt)
 *         Brownout interrupt handling (interrupt only)
 *         ADC status polling and general configuration
 *
 * Revision History:
 * $Log:   //smaicnt2/pvcs/VM/sharpmcu/archives/sharpmcu/software/csps/lh7a404/source/lh7a404_adc_driver.c-arc  $
 * 
 *    Rev 1.0   Oct 15 2003 17:24:44   WellsK
 * Initial revision.
 * 
 *
 ***********************************************************************
 * SHARP MICROELECTRONICS OF THE AMERICAS MAKES NO REPRESENTATION
 * OR WARRANTIES WITH RESPECT TO THE PERFORMANCE OF THIS SOFTWARE,
 * AND SPECIFICALLY DISCLAIMS ANY RESPONSIBILITY FOR ANY DAMAGES, 
 * SPECIAL OR CONSEQUENTIAL, CONNECTED WITH THE USE OF THIS SOFTWARE.
 *
 * SHARP MICROELECTRONICS OF THE AMERICAS PROVIDES THIS SOFTWARE SOLELY 
 * FOR THE PURPOSE OF SOFTWARE DEVELOPMENT INCORPORATING THE USE OF A 
 * SHARP MICROCONTROLLER OR SYSTEM-ON-CHIP PRODUCT. USE OF THIS SOURCE
 * FILE IMPLIES ACCEPTANCE OF THESE CONDITIONS.
 *
 * COPYRIGHT (C) 2001 SHARP MICROELECTRONICS OF THE AMERICAS, INC.
 *     CAMAS, WA
 **********************************************************************/

#include "lh7a404_adc_driver.h"
#include "lh7a404_csc_driver.h"

/***********************************************************************
 * ADC driver private data and types
 **********************************************************************/

/* Size of the ADC receive ring buffer */
#define ADC_RING_BUFSIZE 64

/* Function prototype used for polled and interrupt driven reads */
typedef INT_32 (*ADC_RFUNC_T) (void *, void *, INT_32);

/* ADC device configuration structure type */
typedef struct
{
    BOOL_32 init;       /* Device initialized flag */
    ADC_REGS_T *regptr; /* Pointer to ADC registers */
    UNS_16 rx[ADC_RING_BUFSIZE];  /* ADC data ring buffer */
    INT_32 rx_head;     /* ADC ring buffer head index */
    INT_32 rx_tail;     /* ADC ring buffer tail index */
    UNS_16 conv_count;  /* Number of conversions to perform */
    PFV bro_cbfunc;     /* Brown interrupt callback function */
    PFV pd_cbfunc;      /* Pendown interrupt completion callback
                           function */
    PFV eos_cbfunc;     /* End of sequence interrupt callback
                           function */
} ADC_CFG_T;

/* ADC device configuration structure */
STATIC ADC_CFG_T adccfg;

/***********************************************************************
 * ADC driver public functions
 **********************************************************************/

/***********************************************************************
 *
 * Function: adc_default
 *
 * Purpose: Places the ADC interface and controller in a default state
 *
 * Processing:
 *     Disable ADC interrupts, set ADC power control to off (idle) with
 *     maximum clock divider and 1 conversion, set general configuration
 *     to continuous conversion mode. Set up each MUX input to maximum
 *     clock with default references. Set up idle high and low control
 *     words. Clear the ADC FIFO and clear any latched interrupts.
 *
 * Parameters:
 *     adcregs: Pointer to an ADC register set
 *
 * Outputs: None
 *
 * Returns: Nothing
 *
 * Notes: None
 *
 **********************************************************************/
STATIC void adc_default(ADC_REGS_T *adcregs)
{
    INT_32 idx;

    /* Setup default state of ADC as idle, with all channels set up
       in a safe configuration, and all interrupts masked */
    /* Mask all interrupts */
    adcregs->adcie = 0;

    /* Setup mode as disabled, 1 conversion in a sequence, and
       maximum ADC clock divider */
    adcregs->adcpcr = (ADC_NOC_SET(1) | ADC_PWM_ALL_OFF |
        ADC_CLKSEL_DIV128);

    /* Set conversion mode to continuous with a single FIFO entry
       watermark level */
    adcregs->adcgencfg = (ADC_SSM_SSB | ADC_WM_SET(1));

    /* Set up each control bank register to use a linear analog
       input mapped array with maximum settling time */
    for (idx = 0; idx <= 15; idx++)
    {
        /* High control word */
        adcregs->adchicl[idx] = (ADC_SETTIME(0X1FF) |
            ADC_INPSEL(idx) | ADC_INM_GND | ADC_REF_VREFP);

        /* Low control word */
        adcregs->adclocl[idx] = ADC_REF_VREFN;
    }

    /* Setup idle mode high and low words using analog input 0
       as the default idle input */
    adcregs->adcidlehi = (ADC_SETTIME(0X1FF) | ADC_INP_AN0 |
        ADC_INM_GND | ADC_REF_VREFP);
    adcregs->adcidlelo = ADC_REF_VREFP;

    /* Make sure the FIFO is clear */
    while ((adcregs->adcfifosts & ADC_FIFO_EMPTY) == 0)
    {
        idx = (INT_32) adcregs->adcresults;
    }
    
    /* Clear pending ADC interrupts */
    adcregs->adcic = (ADC_EOS_CLR | ADC_PEN_CLR | ADC_BROWNOUT_CLR);
}

/***********************************************************************
 *
 * Function: adc_add_sequence_entry
 *
 * Purpose: Adds a new sample entry to the sequence list
 *
 * Processing:
 *     If the number of existing conversion sequence entries is greater
 *     than 16, then return _ERROR to the caller. Otherwise, generate
 *     the high and low sequence control words and place them into the
 *     the sequence register array indexed by conv_count. Set status to
 *     conv_count and increment conv_count by one. Return conv_count to
 *     the caller.
 *
 * Parameters:
 *     adc_ch_cfgptr: Pointer to a channel configuration structure
 *     adccfgptr:     Pointer to ADC config structure
 *
 * Outputs: None
 *
 * Returns: A key to the new sequence entry (0 to 15)
 *
 * Notes: None
 *
 **********************************************************************/
STATIC STATUS adc_add_sequence_entry(ADC_CH_CONV_T *adc_ch_cfgptr,
                              ADC_CFG_T *adccfgptr)
{
    UNS_32 tmphi, tmplo;
    STATUS status = _ERROR;

    /* Limit conversion count to 16 conversions */
    if (adccfgptr->conv_count < 16)
    {
        /* Build the high and low control words based on the passed
           channel configuration values */
        tmphi = (ADC_SETTIME(adc_ch_cfgptr->settle_clks) |
            ADC_INPSEL(adc_ch_cfgptr->inpc) |
            ADC_INNSEL(adc_ch_cfgptr->innc) |
            ADC_REFP_SEL(adc_ch_cfgptr->vrefp));

        /* Build and save the control bank low word register */
        tmplo = (ADC_REFN_SEL(adc_ch_cfgptr->vrefn) |adc_ch_cfgptr->bias);

        /* Write registers */
        adccfgptr->regptr->adchicl[adccfgptr->conv_count] = tmphi;
        adccfgptr->regptr->adclocl[adccfgptr->conv_count] = tmplo;

        /* Update the number of conversions in the sequence */
        tmphi = adccfgptr->regptr->adcpcr & ~ADC_NOC_MASK;
        adccfgptr->regptr->adcpcr = (tmphi | adccfgptr->conv_count);

        /* Save key return value */
        status = (STATUS) adccfgptr->conv_count;

        /* Increment conversion count value */
        adccfgptr->conv_count++;
    }

    return status;
}

/***********************************************************************
 *
 * Function: adc_chg_sequence_entry
 *
 * Purpose: Change an existing sequence entry
 *
 * Processing:
 *     If the sequence key (in the ADC_CH_CONV_T structure) is not
 *     within the limits of the converion list, return _ERROR to the
 *     caller. Otherwise, generate the new high and low configuration
 *     words for the channel indicated by the sequence key and update
 *     the registers in the ADC for that channel. Return _NO_ERROR to
 *     the caller.
 *
 * Parameters:
 *     adc_ch_cfgptr: Pointer to a channel configuration structure
 *     adccfgptr:     Pointer to ADC config structure
 *
 * Outputs: None
 *
 * Returns: _ERROR is the sequence key is invalid, otherwise _NO_ERROR.
 *
 * Notes: None
 *
 **********************************************************************/
STATIC STATUS adc_chg_sequence_entry(ADC_CH_CONV_T *adc_ch_cfgptr,
                              ADC_CFG_T *adccfgptr)
{
    UNS_32 tmphi, tmplo;
    STATUS status = _ERROR;

    /* Make sure the passed sequence entry is valid */
    if (adc_ch_cfgptr->chkey <= adccfgptr->conv_count)
    {
        /* Key is valid */
        
        /* Build the high and low control words based on the passed
           channel configuration values */
        tmphi = (ADC_SETTIME(adc_ch_cfgptr->settle_clks) |
            ADC_INPSEL(adc_ch_cfgptr->inpc) |
            ADC_INNSEL(adc_ch_cfgptr->innc) |
            ADC_REFP_SEL(adc_ch_cfgptr->vrefp));

        /* Build and save the control bank low word register */
        tmplo = (ADC_REFN_SEL(adc_ch_cfgptr->vrefn) |
            adc_ch_cfgptr->bias);

        /* Write registers */
        adccfgptr->regptr->adchicl[adc_ch_cfgptr->chkey] = tmphi;
        adccfgptr->regptr->adclocl[adc_ch_cfgptr->chkey] = tmplo;

        status = _NO_ERROR;
    }
    
    return status;
}

/***********************************************************************
 *
 * Function: adc_ring_fill
 *
 * Purpose: Move data from the ADC FIFO to the driver ring buffer
 *
 * Processing:
 *     While the ADC FIFO is not empty, copy an entry from the ADC
 *     FIFO into the ADC driver ring buffer. Increment the ring buffer
 *     head pointer. If it exceeds the ring buffer size, reset the
 *     head pointer to 0.
 *
 * Parameters:
 *     adccfgptr: Pointer to ADC config structure
 *
 * Outputs: None
 *
 * Returns: Nothing
 *
 * Notes: None
 *
 **********************************************************************/
STATIC void adc_ring_fill(ADC_CFG_T *adccfgptr)
{
    ADC_REGS_T *adcregsptr = (ADC_REGS_T *) adccfgptr->regptr;

    /* Continue stuffing the receive ring FIFO until the receive
       FIFO is empty */
    while ((adcregsptr->adcfifosts & ADC_FIFO_EMPTY) == 0)
    {
        adccfgptr->rx[adccfgptr->rx_head] =
            (UNS_16) adcregsptr->adcresults;

        /* Increment receive ring buffer head pointer */
        adccfgptr->rx_head++;
        if (adccfgptr->rx_head >= ADC_RING_BUFSIZE)
        {
            adccfgptr->rx_head = 0;
        }
    }
}

/***********************************************************************
 * ADC driver public functions
 **********************************************************************/

/***********************************************************************
 *
 * Function: adc_open
 *
 * Purpose: Open the ADC
 *
 * Processing:
 *     If init is not FALSE, return 0x00000000 to the caller. Otherwise,
 *     set init to TRUE, save the ADC peripheral register set address,
 *     and initialize the ADC interface and controller to a default
 *     state by calling adc_default(), and return a pointer to the ADC
 *     config structure to the caller.
 *
 * Parameters:
 *     ipbase: ADC descriptor device address

⌨️ 快捷键说明

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