/** * \brief Write configuration to ADC module * * Disables the ADC and flushes its pipeline before writing the specified * configuration and factory calibration value to it. If the ADC was enabled * upon entry of the function, it is enabled upon function return. * * \param adc Pointer to ADC module. * \param conf Pointer to ADC module configuration. */ void adc_write_configuration(ADC_t *adc, const struct adc_config *conf) { uint16_t cal; uint8_t enable; irqflags_t flags; #ifdef ADCA if ((uintptr_t)adc == (uintptr_t)&ADCA) { cal = adc_get_calibration_data(ADC_CAL_ADCA); } else #endif { Assert(0); return; } flags = cpu_irq_save(); adc_enable_clock(adc); enable = adc->CTRLA & ADC_ENABLE_bm; adc->CTRLA = ADC_FLUSH_bm; adc->CAL = cal; adc->CMP = conf->cmp; adc->REFCTRL = conf->refctrl; adc->PRESCALER = conf->prescaler; adc->EVCTRL = conf->evctrl; adc->CTRLB = conf->ctrlb; adc->SAMPCTRL = conf->sampctrl; adc->CTRLA = enable; adc_disable_clock(adc); cpu_irq_restore(flags); }
/** * \brief Read configuration from ADC channel * * Reads out the current configuration from the ADC channel to the specified * buffer. * * \param adc Pointer to ADC module. * \param ch_mask Mask of ADC channel(s): * \arg \c ADC_CHn , where \c n specifies the channel. (Only a single channel * can be given in mask) * \param ch_conf Pointer to ADC channel configuration. */ void adcch_read_configuration(ADC_t *adc, uint8_t ch_mask, struct adc_channel_config *ch_conf) { ADC_CH_t *adc_ch; irqflags_t flags; adc_ch = adc_get_channel(adc, ch_mask); flags = cpu_irq_save(); adc_enable_clock(adc); ch_conf->ctrl = adc_ch->CTRL; ch_conf->intctrl = adc_ch->INTCTRL; ch_conf->muxctrl = adc_ch->MUXCTRL; ch_conf->scan = adc_ch->SCAN; ch_conf->corrctrl = adc_ch->CORRCTRL; ch_conf->offsetcorr0 = adc_ch->OFFSETCORR0; ch_conf->offsetcorr1 = adc_ch->OFFSETCORR1; ch_conf->gaincorr0 = adc_ch->GAINCORR0; ch_conf->gaincorr1 = adc_ch->GAINCORR1; ch_conf->avgctrl = adc_ch->AVGCTRL; adc_disable_clock(adc); cpu_irq_restore(flags); }
/** * \brief Enable ADC * * Enables the ADC and locks IDLE mode for the sleep manager. * * \param adc Pointer to ADC module * * \note To ensure accurate conversions, please wait for at least * the specified start-up time between enabling the ADC module, and starting * a conversion. For most XMEGA devices the start-up time is specified * to be a maximum of 24 ADC clock cycles. Please verify the start-up time for * the device in use. */ void adc_enable(ADC_t *adc) { irqflags_t flags = cpu_irq_save(); adc_enable_clock(adc); adc->CTRLA |= ADC_ENABLE_bm; cpu_irq_restore(flags); sleepmgr_lock_mode(SLEEPMGR_IDLE); }
/** * \brief Read configuration from ADC module * * Reads out the current configuration of the ADC module to the specified * buffer. * * \param adc Pointer to ADC module. * \param conf Pointer to ADC module configuration. */ void adc_read_configuration(ADC_t *adc, struct adc_config *conf) { irqflags_t flags = cpu_irq_save(); adc_enable_clock(adc); conf->cmp = adc->CMP; conf->refctrl = adc->REFCTRL; conf->prescaler = adc->PRESCALER; conf->evctrl = adc->EVCTRL; conf->ctrlb = adc->CTRLB; conf->sampctrl = adc->SAMPCTRL; adc_disable_clock(adc); cpu_irq_restore(flags); }
/** * \brief Write configuration to ADC channel * * Writes the specified configuration to the ADC channel. * * \param adc Pointer to ADC module. * \param ch_mask Mask of ADC channel(s): * \arg \c ADC_CHn , where \c n specifies the channel. (Only a single channel * can be given in mask) * \param ch_conf Pointer to ADC channel configuration. * * \note The specified ADC's callback function must be set before this function * is called if callbacks are enabled and interrupts are enabled in the * channel configuration. */ void adcch_write_configuration(ADC_t *adc, uint8_t ch_mask, const struct adc_channel_config *ch_conf) { ADC_CH_tmpfix_t *adc_ch; irqflags_t flags; adc_ch = adc_get_channel(adc, ch_mask); flags = cpu_irq_save(); #if defined(CONFIG_ADC_CALLBACK_ENABLE) && defined(_ASSERT_ENABLE_) if ((adc_ch->INTCTRL & ADC_CH_INTLVL_gm) != ADC_CH_INTLVL_OFF_gc) { # ifdef ADCA if ((uintptr_t)adc == (uintptr_t)&ADCA) { Assert(adca_callback); } else # endif # ifdef ADCB if ((uintptr_t)adc == (uintptr_t)&ADCB) { Assert(adcb_callback); } else # endif { Assert(0); return; } } #endif adc_enable_clock(adc); adc_ch->CTRL = ch_conf->ctrl; adc_ch->INTCTRL = ch_conf->intctrl; adc_ch->MUXCTRL = ch_conf->muxctrl; #if CONFIG_ADC_VERSION == 2 if (ch_mask & ADC_CH0) { /* USB devices has channel scan available on ADC channel 0 */ adc_ch->SCAN = ch_conf->scan; } #endif adc_disable_clock(adc); cpu_irq_restore(flags); }
/** * \brief Write configuration to ADC channel * * Writes the specified configuration to the ADC channel. * * \param adc Pointer to ADC module. * \param ch_mask Mask of ADC channel(s): * \arg \c ADC_CHn , where \c n specifies the channel. (Only a single channel * can be given in mask) * \param ch_conf Pointer to ADC channel configuration. * * \note The specified ADC's callback function must be set before this function * is called if callbacks are enabled and interrupts are enabled in the * channel configuration. */ void adcch_write_configuration(ADC_t *adc, uint8_t ch_mask, const struct adc_channel_config *ch_conf) { ADC_CH_t *adc_ch; irqflags_t flags; adc_ch = adc_get_channel(adc, ch_mask); flags = cpu_irq_save(); #if defined(CONFIG_ADC_CALLBACK_ENABLE) && defined(_ASSERT_ENABLE_) if ((adc_ch->INTCTRL & ADC_CH_INTLVL_gm) != ADC_CH_INTLVL_OFF_gc) { # ifdef ADCA if ((uintptr_t)adc == (uintptr_t)&ADCA) { Assert(adca_callback); } else # endif { Assert(0); return; } } #endif adc_enable_clock(adc); adc_ch->CTRL = ch_conf->ctrl; adc_ch->INTCTRL = ch_conf->intctrl; adc_ch->MUXCTRL = ch_conf->muxctrl; adc_ch->SCAN = ch_conf->scan; adc_ch->CORRCTRL = ch_conf->corrctrl; adc_ch->OFFSETCORR0 = ch_conf->offsetcorr0; adc_ch->OFFSETCORR1 = ch_conf->offsetcorr1; adc_ch->GAINCORR0 = ch_conf->gaincorr0; adc_ch->GAINCORR1 = ch_conf->gaincorr1; adc_ch->AVGCTRL = ch_conf->avgctrl; adc_disable_clock(adc); cpu_irq_restore(flags); }
/** * \brief Read configuration from ADC channel * * Reads out the current configuration from the ADC channel to the specified * buffer. * * \param adc Pointer to ADC module. * \param ch_mask Mask of ADC channel(s): * \arg \c ADC_CHn , where \c n specifies the channel. (Only a single channel * can be given in mask) * \param ch_conf Pointer to ADC channel configuration. */ void adcch_read_configuration(ADC_t * adc, uint8_t ch_mask, struct adc_channel_config *ch_conf) { ADC_CH_t *adc_ch; irqflags_t flags; adc_ch = adc_get_channel(adc, ch_mask); flags = cpu_irq_save(); adc_enable_clock(adc); ch_conf->ctrl = adc_ch->CTRL; ch_conf->intctrl = adc_ch->INTCTRL; ch_conf->muxctrl = adc_ch->MUXCTRL; if (ch_mask & ADC_CH0) { /* USB devices has channel scan available on ADC channel 0 */ ch_conf->scan = adc_ch->SCAN; } adc_disable_clock(adc); cpu_irq_restore(flags); }