From 76fc6c0477a6fdb7eb602f2b07e133d681a1092d Mon Sep 17 00:00:00 2001 From: spacecoaster Date: Fri, 5 Sep 2014 22:41:12 +0000 Subject: [KINETIS] ADC LLD files. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@7250 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/hal/ports/KINETIS/K20x/kinetis_registry.h | 3 + os/hal/ports/KINETIS/K20x/platform.mk | 1 + os/hal/ports/KINETIS/KL2x/kinetis_registry.h | 4 + os/hal/ports/KINETIS/KL2x/platform.mk | 1 + os/hal/ports/KINETIS/LLD/adc_lld.c | 258 +++++++++++++++++++ os/hal/ports/KINETIS/LLD/adc_lld.h | 360 +++++++++++++++++++++++++++ 6 files changed, 627 insertions(+) create mode 100644 os/hal/ports/KINETIS/LLD/adc_lld.c create mode 100644 os/hal/ports/KINETIS/LLD/adc_lld.h (limited to 'os/hal/ports/KINETIS') diff --git a/os/hal/ports/KINETIS/K20x/kinetis_registry.h b/os/hal/ports/KINETIS/K20x/kinetis_registry.h index 004049cc7..9d1b0d753 100644 --- a/os/hal/ports/KINETIS/K20x/kinetis_registry.h +++ b/os/hal/ports/KINETIS/K20x/kinetis_registry.h @@ -41,6 +41,9 @@ #define KINETIS_PORTD_IRQ_VECTOR VectorEC #define KINETIS_PORTE_IRQ_VECTOR VectorF0 +/* ADC attributes.*/ +#define KINETIS_HAS_ADC0 TRUE +#define KINETIS_ADC0_IRC_VECTOR Vector98 /** @} */ diff --git a/os/hal/ports/KINETIS/K20x/platform.mk b/os/hal/ports/KINETIS/K20x/platform.mk index 9701ebee2..c7ae92d95 100644 --- a/os/hal/ports/KINETIS/K20x/platform.mk +++ b/os/hal/ports/KINETIS/K20x/platform.mk @@ -6,6 +6,7 @@ PLATFORMSRC = ${CHIBIOS}/os/hal/ports/common/ARMCMx/nvic.c \ ${CHIBIOS}/os/hal/ports/KINETIS/K20x/spi_lld.c \ ${CHIBIOS}/os/hal/ports/KINETIS/LLD/i2c_lld.c \ ${CHIBIOS}/os/hal/ports/KINETIS/LLD/ext_lld.c \ + ${CHIBIOS}/os/hal/ports/KINETIS/LLD/adc_lld.c \ ${CHIBIOS}/os/hal/ports/KINETIS/K20x/gpt_lld.c \ ${CHIBIOS}/os/hal/ports/KINETIS/K20x/st_lld.c diff --git a/os/hal/ports/KINETIS/KL2x/kinetis_registry.h b/os/hal/ports/KINETIS/KL2x/kinetis_registry.h index b07f4c18e..d76c059bf 100644 --- a/os/hal/ports/KINETIS/KL2x/kinetis_registry.h +++ b/os/hal/ports/KINETIS/KL2x/kinetis_registry.h @@ -38,6 +38,10 @@ #define KINETIS_PORTA_IRQ_VECTOR VectorB8 #define KINETIS_PORTD_IRQ_VECTOR VectorBC +/* ADC attributes.*/ +#define KINETIS_HAS_ADC0 TRUE +#define KINETIS_ADC0_IRC_VECTOR Vector7C + /** @} */ #endif /* _KINETIS_REGISTRY_H_ */ diff --git a/os/hal/ports/KINETIS/KL2x/platform.mk b/os/hal/ports/KINETIS/KL2x/platform.mk index a1ab56885..9179a723d 100644 --- a/os/hal/ports/KINETIS/KL2x/platform.mk +++ b/os/hal/ports/KINETIS/KL2x/platform.mk @@ -5,6 +5,7 @@ PLATFORMSRC = ${CHIBIOS}/os/hal/ports/common/ARMCMx/nvic.c \ ${CHIBIOS}/os/hal/ports/KINETIS/KL2x/serial_lld.c \ ${CHIBIOS}/os/hal/ports/KINETIS/LLD/i2c_lld.c \ ${CHIBIOS}/os/hal/ports/KINETIS/LLD/ext_lld.c \ + ${CHIBIOS}/os/hal/ports/KINETIS/LLD/adc_lld.c \ ${CHIBIOS}/os/hal/ports/KINETIS/KL2x/st_lld.c # Required include directories diff --git a/os/hal/ports/KINETIS/LLD/adc_lld.c b/os/hal/ports/KINETIS/LLD/adc_lld.c new file mode 100644 index 000000000..d226519ff --- /dev/null +++ b/os/hal/ports/KINETIS/LLD/adc_lld.c @@ -0,0 +1,258 @@ +/* + ChibiOS/HAL - Copyright (C) 2014 Derek Mulcahy + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +/** + * @file KINETIS/LLD/adc_lld.c + * @brief KINETIS ADC subsystem low level driver source. + * + * @addtogroup ADC + * @{ + */ + +#include "hal.h" + +#if HAL_USE_ADC || defined(__DOXYGEN__) + +/*===========================================================================*/ +/* Driver local definitions. */ +/*===========================================================================*/ + +#define ADC_CHANNEL_MASK 0x1f + +/*===========================================================================*/ +/* Driver exported variables. */ +/*===========================================================================*/ + +/** @brief ADC1 driver identifier.*/ +#if KINETIS_ADC_USE_ADC0 || defined(__DOXYGEN__) +ADCDriver ADCD1; +#endif + +/*===========================================================================*/ +/* Driver local variables and types. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver local functions. */ +/*===========================================================================*/ + +static void calibrate(ADCDriver *adcp) { + + /* Clock Divide by 8, Use Bus Clock Div 2 */ + /* At 48MHz this results in ADCCLK of 48/8/2 == 3MHz */ + adcp->adc->CFG1 = ADCx_CFG1_ADIV(ADCx_CFG1_ADIV_DIV_8) | + ADCx_CFG1_ADICLK(ADCx_CFG1_ADIVCLK_BUS_CLOCK_DIV_2); + + /* Use software trigger and disable DMA etc. */ + adcp->adc->SC2 = 0; + + /* Enable Hardware Average, Average 32 Samples, Calibrate */ + adcp->adc->SC3 = ADCx_SC3_AVGE | + ADCx_SC3_AVGS(ADCx_SC3_AVGS_AVERAGE_32_SAMPLES) | + ADCx_SC3_CAL; + + /* FIXME: May take several ms. Use an interrupt instead of busy wait */ + /* Wait for calibration completion */ + while (!(adcp->adc->SC1A & ADCx_SC1n_COCO)) + ; + + uint16_t gain = ((adcp->adc->CLP0 + adcp->adc->CLP1 + adcp->adc->CLP2 + + adcp->adc->CLP3 + adcp->adc->CLP4 + adcp->adc->CLPS) / 2) | 0x8000; + adcp->adc->PG = gain; + + gain = ((adcp->adc->CLM0 + adcp->adc->CLM1 + adcp->adc->CLM2 + + adcp->adc->CLM3 + adcp->adc->CLM4 + adcp->adc->CLMS) / 2) | 0x8000; + adcp->adc->MG = gain; + +} + +/*===========================================================================*/ +/* Driver interrupt handlers. */ +/*===========================================================================*/ + +#if KINETIS_ADC_USE_ADC0 || defined(__DOXYGEN__) +/** + * @brief ADC interrupt handler. + * + * @isr + */ +OSAL_IRQ_HANDLER(KINETIS_ADC0_IRC_VECTOR) { + OSAL_IRQ_PROLOGUE(); + + ADCDriver *adcp = &ADCD1; + + /* Disable Interrupt, Disable Channel */ + adcp->adc->SC1A = ADCx_SC1n_ADCH(ADCx_SC1n_ADCH_DISABLED); + + /* Read the sample into the buffer */ + adcp->samples[adcp->current_index++] = adcp->adc->RA; + + bool more = true; + + /* At the end of the buffer then we may be finished */ + if (adcp->current_index == adcp->number_of_samples) { + _adc_isr_full_code(&ADCD1); + + adcp->current_index = 0; + + /* We are never finished in circular mode */ + more = ADCD1.grpp->circular; + } + + if (more) { + + /* Signal half completion in circular mode. */ + if (ADCD1.grpp->circular && + (adcp->current_index == (adcp->number_of_samples / 2))) { + + _adc_isr_half_code(&ADCD1); + } + + /* Skip to the next channel */ + do { + adcp->current_channel = (adcp->current_channel + 1) & ADC_CHANNEL_MASK; + } while (((1 << adcp->current_channel) & adcp->grpp->channel_mask) == 0); + + /* Enable Interrupt, Select the Channel */ + adcp->adc->SC1A = ADCx_SC1n_AIEN | ADCx_SC1n_ADCH(adcp->current_channel); + } + + OSAL_IRQ_EPILOGUE(); +} +#endif + +/*===========================================================================*/ +/* Driver exported functions. */ +/*===========================================================================*/ + +/** + * @brief Low level ADC driver initialization. + * + * @notapi + */ +void adc_lld_init(void) { + +#if KINETIS_ADC_USE_ADC0 + /* Driver initialization.*/ + adcObjectInit(&ADCD1); +#endif + + /* The shared vector is initialized on driver initialization and never + disabled.*/ + nvicEnableVector(ADC0_IRQn, KINETIS_ADC_IRQ_PRIORITY); +} + +/** + * @brief Configures and activates the ADC peripheral. + * + * @param[in] adcp pointer to the @p ADCDriver object + * + * @notapi + */ +void adc_lld_start(ADCDriver *adcp) { + + /* If in stopped state then enables the ADC clock.*/ + if (adcp->state == ADC_STOP) { + SIM->SCGC6 |= SIM_SCGC6_ADC0; + +#if KINETIS_ADC_USE_ADC0 + if (&ADCD1 == adcp) { + adcp->adc = ADC0; + if (adcp->config->calibrate) { + calibrate(adcp); + } + } +#endif /* KINETIS_ADC_USE_ADC0 */ + } +} + +/** + * @brief Deactivates the ADC peripheral. + * + * @param[in] adcp pointer to the @p ADCDriver object + * + * @notapi + */ +void adc_lld_stop(ADCDriver *adcp) { + + /* If in ready state then disables the ADC clock.*/ + if (adcp->state == ADC_READY) { + SIM->SCGC6 &= ~SIM_SCGC6_ADC0; + +#if KINETIS_ADC_USE_ADC0 + if (&ADCD1 == adcp) { + /* Disable Interrupt, Disable Channel */ + adcp->adc->SC1A = ADCx_SC1n_ADCH(ADCx_SC1n_ADCH_DISABLED); + } +#endif + } +} + +/** + * @brief Starts an ADC conversion. + * + * @param[in] adcp pointer to the @p ADCDriver object + * + * @notapi + */ +void adc_lld_start_conversion(ADCDriver *adcp) { + const ADCConversionGroup *grpp = adcp->grpp; + + /* Enable the Bandgap Buffer if channel mask includes BANDGAP */ + if (grpp->channel_mask & ADC_BANDGAP) { + PMC->REGSC |= PMC_REGSC_BGBE; + } + + adcp->number_of_samples = adcp->depth * grpp->num_channels; + adcp->current_index = 0; + + /* Skip to the next channel */ + adcp->current_channel = 0; + while (((1 << adcp->current_channel) & grpp->channel_mask) == 0) { + adcp->current_channel = (adcp->current_channel + 1) & ADC_CHANNEL_MASK; + } + + /* Set clock speed and conversion size */ + adcp->adc->CFG1 = grpp->cfg1; + + /* Set averaging */ + adcp->adc->SC3 = grpp->sc3; + + /* Enable Interrupt, Select Channel */ + adcp->adc->SC1A = ADCx_SC1n_AIEN | ADCx_SC1n_ADCH(adcp->current_channel); +} + +/** + * @brief Stops an ongoing conversion. + * + * @param[in] adcp pointer to the @p ADCDriver object + * + * @notapi + */ +void adc_lld_stop_conversion(ADCDriver *adcp) { + const ADCConversionGroup *grpp = adcp->grpp; + + /* Disable the Bandgap buffer if channel mask includes BANDGAP */ + if (grpp->channel_mask & ADC_BANDGAP) { + /* Clear BGBE, ACKISO is w1c, avoid setting */ + PMC->REGSC &= ~(PMC_REGSC_BGBE | PMC_REGSC_ACKISO); + } + +} + +#endif /* HAL_USE_ADC */ + +/** @} */ diff --git a/os/hal/ports/KINETIS/LLD/adc_lld.h b/os/hal/ports/KINETIS/LLD/adc_lld.h new file mode 100644 index 000000000..d5fec99ea --- /dev/null +++ b/os/hal/ports/KINETIS/LLD/adc_lld.h @@ -0,0 +1,360 @@ +/* + ChibiOS/HAL - Copyright (C) 2014 Derek Mulcahy + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +/** + * @file KINETIS/LLD/adc_lld.h + * @brief KINETIS ADC subsystem low level driver header. + * + * @addtogroup ADC + * @{ + */ + +#ifndef _ADC_LLD_H_ +#define _ADC_LLD_H_ + +#if HAL_USE_ADC || defined(__DOXYGEN__) + +/*===========================================================================*/ +/* Driver constants. */ +/*===========================================================================*/ + +/** + * @name Absolute Maximum Ratings + * @{ + */ +/** + * @brief Minimum ADC clock frequency. + */ +#define KINETIS_ADCCLK_MIN 600000 + +/** + * @brief Maximum ADC clock frequency. + */ +#define KINETIS_ADCCLK_MAX 36000000 + +#define ADCx_SC3_AVGS_AVERAGE_4_SAMPLES 0 +#define ADCx_SC3_AVGS_AVERAGE_8_SAMPLES 1 +#define ADCx_SC3_AVGS_AVERAGE_16_SAMPLES 2 +#define ADCx_SC3_AVGS_AVERAGE_32_SAMPLES 3 + +#define ADCx_CFG1_ADIV_DIV_1 0 +#define ADCx_CFG1_ADIV_DIV_2 1 +#define ADCx_CFG1_ADIV_DIV_4 2 +#define ADCx_CFG1_ADIV_DIV_8 3 + +#define ADCx_CFG1_ADIVCLK_BUS_CLOCK 0 +#define ADCx_CFG1_ADIVCLK_BUS_CLOCK_DIV_2 1 +#define ADCx_CFG1_ADIVCLK_BUS_ALTCLK 2 +#define ADCx_CFG1_ADIVCLK_BUS_ADACK 3 + +#define ADCx_CFG1_MODE_8_OR_9_BITS 0 +#define ADCx_CFG1_MODE_12_OR_13_BITS 1 +#define ADCx_CFG1_MODE_10_OR_11_BITS 2 +#define ADCx_CFG1_MODE_16_BITS 3 + +#define ADCx_SC1n_ADCH_DAD0 0 +#define ADCx_SC1n_ADCH_DAD1 1 +#define ADCx_SC1n_ADCH_DAD2 2 +#define ADCx_SC1n_ADCH_DAD3 3 +#define ADCx_SC1n_ADCH_DADP0 0 +#define ADCx_SC1n_ADCH_DADP1 1 +#define ADCx_SC1n_ADCH_DADP2 2 +#define ADCx_SC1n_ADCH_DADP3 3 +#define ADCx_SC1n_ADCH_AD4 4 +#define ADCx_SC1n_ADCH_AD5 5 +#define ADCx_SC1n_ADCH_AD6 6 +#define ADCx_SC1n_ADCH_AD7 7 +#define ADCx_SC1n_ADCH_AD8 8 +#define ADCx_SC1n_ADCH_AD9 9 +#define ADCx_SC1n_ADCH_AD10 10 +#define ADCx_SC1n_ADCH_AD11 11 +#define ADCx_SC1n_ADCH_AD12 12 +#define ADCx_SC1n_ADCH_AD13 13 +#define ADCx_SC1n_ADCH_AD14 14 +#define ADCx_SC1n_ADCH_AD15 15 +#define ADCx_SC1n_ADCH_AD16 16 +#define ADCx_SC1n_ADCH_AD17 17 +#define ADCx_SC1n_ADCH_AD18 18 +#define ADCx_SC1n_ADCH_AD19 19 +#define ADCx_SC1n_ADCH_AD20 20 +#define ADCx_SC1n_ADCH_AD21 21 +#define ADCx_SC1n_ADCH_AD22 22 +#define ADCx_SC1n_ADCH_AD23 23 +#define ADCx_SC1n_ADCH_TEMP_SENSOR 26 +#define ADCx_SC1n_ADCH_BANDGAP 27 +#define ADCx_SC1n_ADCH_VREFSH 29 +#define ADCx_SC1n_ADCH_VREFSL 30 +#define ADCx_SC1n_ADCH_DISABLED 31 + +#define ADC_DAD0 (1 << ADCx_SC1n_ADCH_DAD0) +#define ADC_DAD1 (1 << ADCx_SC1n_ADCH_DAD1) +#define ADC_DAD2 (1 << ADCx_SC1n_ADCH_DAD2) +#define ADC_DAD3 (1 << ADCx_SC1n_ADCH_DAD3) +#define ADC_DADP0 (1 << ADCx_SC1n_ADCH_DADP0) +#define ADC_DADP1 (1 << ADCx_SC1n_ADCH_DADP1) +#define ADC_DADP2 (1 << ADCx_SC1n_ADCH_DADP2) +#define ADC_DADP3 (1 << ADCx_SC1n_ADCH_DADP3) +#define ADC_AD4 (1 << ADCx_SC1n_ADCH_AD4) +#define ADC_AD5 (1 << ADCx_SC1n_ADCH_AD5) +#define ADC_AD6 (1 << ADCx_SC1n_ADCH_AD6) +#define ADC_AD7 (1 << ADCx_SC1n_ADCH_AD7) +#define ADC_AD8 (1 << ADCx_SC1n_ADCH_AD8) +#define ADC_AD9 (1 << ADCx_SC1n_ADCH_AD9) +#define ADC_AD10 (1 << ADCx_SC1n_ADCH_AD10) +#define ADC_AD11 (1 << ADCx_SC1n_ADCH_AD11) +#define ADC_AD12 (1 << ADCx_SC1n_ADCH_AD12) +#define ADC_AD13 (1 << ADCx_SC1n_ADCH_AD13) +#define ADC_AD14 (1 << ADCx_SC1n_ADCH_AD14) +#define ADC_AD15 (1 << ADCx_SC1n_ADCH_AD15) +#define ADC_AD16 (1 << ADCx_SC1n_ADCH_AD16) +#define ADC_AD17 (1 << ADCx_SC1n_ADCH_AD17) +#define ADC_AD18 (1 << ADCx_SC1n_ADCH_AD18) +#define ADC_AD19 (1 << ADCx_SC1n_ADCH_AD19) +#define ADC_AD20 (1 << ADCx_SC1n_ADCH_AD20) +#define ADC_AD21 (1 << ADCx_SC1n_ADCH_AD21) +#define ADC_AD22 (1 << ADCx_SC1n_ADCH_AD22) +#define ADC_AD23 (1 << ADCx_SC1n_ADCH_AD23) +#define ADC_TEMP_SENSOR (1 << ADCx_SC1n_ADCH_TEMP_SENSOR) +#define ADC_BANDGAP (1 << ADCx_SC1n_ADCH_BANDGAP) +#define ADC_VREFSH (1 << ADCx_SC1n_ADCH_VREFSH) +#define ADC_VREFSL (1 << ADCx_SC1n_ADCH_VREFSL) +#define ADC_DISABLED (1 << ADCx_SC1n_ADCH_DISABLED) + +/** @} */ + +/*===========================================================================*/ +/* Driver pre-compile time settings. */ +/*===========================================================================*/ + +/** + * @name Configuration options + * @{ + */ + +/** + * @brief ADC1 driver enable switch. + * @details If set to @p TRUE the support for ADC1 is included. + * @note The default is @p TRUE. + */ +#if !defined(KINETIS_ADC_USE_ADC0) || defined(__DOXYGEN__) +#define KINETIS_ADC_USE_ADC0 FALSE +#endif + +/** + * @brief ADC interrupt priority level setting. + */ +#if !defined(KINETIS_ADC_IRQ_PRIORITY) || defined(__DOXYGEN__) +#define KINETIS_ADC_IRQ_PRIORITY 5 +#endif + +/** @} */ + +/*===========================================================================*/ +/* Derived constants and error checks. */ +/*===========================================================================*/ + +#if KINETIS_ADC_USE_ADC0 && !KINETIS_HAS_ADC0 +#error "ADC1 not present in the selected device" +#endif + +#if !KINETIS_ADC_USE_ADC0 +#error "ADC driver activated but no ADC peripheral assigned" +#endif + +/*===========================================================================*/ +/* Driver data structures and types. */ +/*===========================================================================*/ + +/** + * @brief ADC sample data type. + */ +typedef uint16_t adcsample_t; + +/** + * @brief Channels number in a conversion group. + */ +typedef uint16_t adc_channels_num_t; + +/** + * @brief Possible ADC failure causes. + * @note Error codes are architecture dependent and should not relied + * upon. + */ +typedef enum { + ADC_ERR_DMAFAILURE = 0, /**< DMA operations failure. */ + ADC_ERR_OVERFLOW = 1 /**< ADC overflow condition. */ +} adcerror_t; + +/** + * @brief Type of a structure representing an ADC driver. + */ +typedef struct ADCDriver ADCDriver; + +/** + * @brief ADC notification callback type. + * + * @param[in] adcp pointer to the @p ADCDriver object triggering the + * callback + * @param[in] buffer pointer to the most recent samples data + * @param[in] n number of buffer rows available starting from @p buffer + */ +typedef void (*adccallback_t)(ADCDriver *adcp, adcsample_t *buffer, size_t n); + +/** + * @brief ADC error callback type. + * + * @param[in] adcp pointer to the @p ADCDriver object triggering the + * callback + * @param[in] err ADC error code + */ +typedef void (*adcerrorcallback_t)(ADCDriver *adcp, adcerror_t err); + +/** + * @brief Conversion group configuration structure. + * @details This implementation-dependent structure describes a conversion + * operation. + */ +typedef struct { + /** + * @brief Enables the circular buffer mode for the group. + */ + bool circular; + /** + * @brief Number of the analog channels belonging to the conversion group. + */ + adc_channels_num_t num_channels; + /** + * @brief Callback function associated to the group or @p NULL. + */ + adccallback_t end_cb; + /** + * @brief Error callback or @p NULL. + */ + adcerrorcallback_t error_cb; + /* End of the mandatory fields.*/ + /** + * @brief Bitmask of channels for ADC conversion. + */ + uint32_t channel_mask; + /** + * @brief ADC CFG1 register initialization data. + * @note All the required bits must be defined into this field. + */ + uint32_t cfg1; + /** + * @brief ADC SC3 register initialization data. + * @note All the required bits must be defined into this field. + */ + uint32_t sc3; +} ADCConversionGroup; + +/** + * @brief Driver configuration structure. + * @note It could be empty on some architectures. + */ +typedef struct { + /* Perform first time calibration */ + bool calibrate; +} ADCConfig; + +/** + * @brief Structure representing an ADC driver. + */ +struct ADCDriver { + /** + * @brief Driver state. + */ + adcstate_t state; + /** + * @brief Current configuration data. + */ + const ADCConfig *config; + /** + * @brief Current samples buffer pointer or @p NULL. + */ + adcsample_t *samples; + /** + * @brief Current samples buffer depth or @p 0. + */ + size_t depth; + /** + * @brief Current conversion group pointer or @p NULL. + */ + const ADCConversionGroup *grpp; +#if ADC_USE_WAIT || defined(__DOXYGEN__) + /** + * @brief Waiting thread. + */ + thread_reference_t thread; +#endif +#if ADC_USE_MUTUAL_EXCLUSION || defined(__DOXYGEN__) + /** + * @brief Mutex protecting the peripheral. + */ + mutex_t mutex; +#endif /* ADC_USE_MUTUAL_EXCLUSION */ +#if defined(ADC_DRIVER_EXT_FIELDS) + ADC_DRIVER_EXT_FIELDS +#endif + /* End of the mandatory fields.*/ + /** + * @brief Pointer to the ADCx registers block. + */ + ADC_TypeDef *adc; + /** + * @brief Number of samples expected. + */ + size_t number_of_samples; + /** + * @brief Current position in the buffer. + */ + size_t current_index; + /** + * @brief Current channel index into group channel_mask. + */ + size_t current_channel; +}; + +/*===========================================================================*/ +/* Driver macros. */ +/*===========================================================================*/ + + +/*===========================================================================*/ +/* External declarations. */ +/*===========================================================================*/ + +#if KINETIS_ADC_USE_ADC0 && !defined(__DOXYGEN__) +extern ADCDriver ADCD1; +#endif + +#ifdef __cplusplus +extern "C" { +#endif + void adc_lld_init(void); + void adc_lld_start(ADCDriver *adcp); + void adc_lld_stop(ADCDriver *adcp); + void adc_lld_start_conversion(ADCDriver *adcp); + void adc_lld_stop_conversion(ADCDriver *adcp); +#ifdef __cplusplus +} +#endif + +#endif /* HAL_USE_ADC */ + +#endif /* _ADC_LLD_H_ */ + +/** @} */ -- cgit v1.2.3