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

📄 lh79524_adc_driver.c

📁 LH79524SoftwareLH79524 Software
💻 C
📖 第 1 页 / 共 4 页
字号:
  }
  
  /* Build and save the idle channel step */
  tmp = (ADC_SETTIME(adc_time_2_clock(adccfgptr, tsc_cfg->settle_time)) |
    ADC_INPSEL(ADC_ANALOG_1) |
    ADC_INNSEL(ADC_REFN_VREFN) |
    ADC_REFP_SEL(ADC_REFP_VREF));
  adcregsptr->adcidlehi = tmp;
  
  tmp = (ADC_REFN_SEL(ADC_REFN_VREF) |
    (ADC_FET_AN0_VDDA1K | ADC_FET_AN4_GND));
  adcregsptr->adcidlelo = tmp;
  
  /* for rest of the steps keep settling time same */
  step.settle_time = tsc_cfg->settle_time;
  
  /* Build step 0 - prior to 1st pen-down check*/
  step.inpc = ADC_ANALOG_0;
  step.innc = ADC_REFN_VREFN;
  step.vrefp = pen_detect_p;
  step.vrefn = pen_detect_n;
  step.bias = (ADC_FET_AN0_VDDA | ADC_FET_AN4_GND);
  adc_add_sequence_entry(&step, adccfgptr);
  
  /* Build step 1 - check pen down state prior to coords*/
  step.inpc = ADC_ANALOG_0;
  step.innc = ADC_REFN_VREFN;
  step.vrefp = pen_detect_p;
  step.vrefn = pen_detect_n;
  step.bias = (ADC_FET_AN0_VDDA1K | ADC_FET_AN4_GND);
  adc_add_sequence_entry(&step, adccfgptr);
  
  /* Build step 2,3,4 & 5 - measure x coords*/
  for(tmp = 0; tmp < 4; tmp++)
  {
    step.inpc = ADC_ANALOG_4;
    step.innc = ADC_REFN_VREFN;
    step.vrefp = tsc_cfg->vrefp_x; 
    step.vrefn = tsc_cfg->vrefn_x; 
    step.bias = (ADC_FET_AN0_VDDA | ADC_FET_AN2_VDDA 
      | ADC_FET_AN3_GND | ADC_FET_AN1_GND);
    adc_add_sequence_entry(&step, adccfgptr);
  }
  
  /* Build step 6,7,8 & 9 - measure y coords*/
  for(tmp = 0; tmp < 4; tmp++)
  {
    step.inpc = ADC_ANALOG_4;
    step.innc = ADC_REFN_VREFN;
    step.vrefp = tsc_cfg->vrefp_y; 
    step.vrefn = tsc_cfg->vrefn_y; 
    step.bias = (ADC_FET_AN0_VDDA | ADC_FET_AN1_VDDA 
      | ADC_FET_AN3_GND | ADC_FET_AN2_GND);
    adc_add_sequence_entry(&step, adccfgptr);
  }
  
  /* Build step 10 - prior to last pen-down check*/
  step.inpc = ADC_ANALOG_0;
  step.innc = ADC_REFN_VREFN;
  step.vrefp = pen_detect_p;
  step.vrefn = pen_detect_n;
  step.bias = ADC_FET_AN0_VDDA | ADC_FET_AN4_GND;
  adc_add_sequence_entry(&step, adccfgptr);
  
  /* Build step 11 - prior to last pen-down check*/
  step.inpc = ADC_ANALOG_0;
  step.innc = ADC_REFN_VREFN;
  step.vrefp = pen_detect_p;
  step.vrefn = pen_detect_n;
  step.bias = (ADC_FET_AN0_VDDA1K | ADC_FET_AN3_GND);
  adc_add_sequence_entry(&step, adccfgptr);
  
  /* It is only necessary to turn on the reference buffer if the on-chip
  reference is used as the positive reference for a measurement. If
  an external reference is used (e.g. for ratiometric measurements),
  then the reference buffer can be off (saves power) */
  if(tsc_cfg->vrefp_x != ADC_REFP_VN8)
    adcregsptr->adcpcr |= ADC_REF_ENABLE;
  
  return _NO_ERROR;
}

/***********************************************************************
* 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
*     arg   : On board clock oscillator frequency (XTAL_IN)
*
* Outputs: None
*
* Returns: The pointer to a ADC config structure or 0
*
* Notes: None
*
**********************************************************************/
INT_32 adc_open(INT_32 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 and
    store the ADC clock source frequency */
    adccfg.adc_clk_source = adc_default(adccfg.regptr, (UNS_32)arg,
                                        FALSE);
    
    /* 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, 0, FALSE);
    
    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;
  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 */
      if(adc_set_clock((UNS_32)arg, adccfgptr) == 0)
        status = _ERROR;
      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_BROWN_IRQ_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_BROWN_IRQ_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(adc_time_2_clock(adccfgptr, chcfgptr->settle_time))
        | 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, 0, FALSE);
        
        /* 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 */
        /* 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 */
        status = (INT_32) (adcregsptr->adcmis &

⌨️ 快捷键说明

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