aboutsummaryrefslogtreecommitdiffstats
path: root/os/hal/src/adc.c
diff options
context:
space:
mode:
authorgdisirio <gdisirio@35acf78f-673a-0410-8e92-d51de3d6d3f4>2009-11-28 12:25:35 +0000
committergdisirio <gdisirio@35acf78f-673a-0410-8e92-d51de3d6d3f4>2009-11-28 12:25:35 +0000
commit16178e1c45a76544d34ce63db37932838353637c (patch)
treeb5dbcc988f6d518819b9182f60b8ae6f81bbf61b /os/hal/src/adc.c
parent9b10a6c67a38fa040eb62e63190aed0880ead8ec (diff)
downloadChibiOS-16178e1c45a76544d34ce63db37932838353637c.tar.gz
ChibiOS-16178e1c45a76544d34ce63db37932838353637c.tar.bz2
ChibiOS-16178e1c45a76544d34ce63db37932838353637c.zip
git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@1333 35acf78f-673a-0410-8e92-d51de3d6d3f4
Diffstat (limited to 'os/hal/src/adc.c')
-rw-r--r--os/hal/src/adc.c210
1 files changed, 210 insertions, 0 deletions
diff --git a/os/hal/src/adc.c b/os/hal/src/adc.c
new file mode 100644
index 000000000..5a041f056
--- /dev/null
+++ b/os/hal/src/adc.c
@@ -0,0 +1,210 @@
+/*
+ ChibiOS/RT - Copyright (C) 2006-2007 Giovanni Di Sirio.
+
+ This file is part of ChibiOS/RT.
+
+ ChibiOS/RT is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ ChibiOS/RT is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+/**
+ * @file adc.c
+ * @brief ADC Driver code.
+ * @addtogroup ADC
+ * @{
+ */
+
+#include "ch.h"
+#include "hal.h"
+
+#if CH_HAL_USE_ADC
+
+/**
+ * @brief ADC Driver initialization.
+ */
+void adcInit(void) {
+
+ adc_lld_init();
+}
+
+/**
+ * @brief Initializes the standard part of a @p ADCDriver structure.
+ *
+ * @param[in] adcp pointer to the @p ADCDriver object
+ */
+void adcObjectInit(ADCDriver *adcp) {
+
+ adcp->ad_state = ADC_STOP;
+ adcp->ad_config = NULL;
+ adcp->ad_callback = NULL;
+ adcp->ad_samples = NULL;
+ adcp->ad_depth = 0;
+ adcp->ad_grpp = NULL;
+ chSemInit(&adcp->ad_sem, 0);
+}
+
+/**
+ * @brief Configures and activates the ADC peripheral.
+ *
+ * @param[in] adcp pointer to the @p ADCDriver object
+ * @param[in] config pointer to the @p ADCConfig object
+ */
+void adcStart(ADCDriver *adcp, const ADCConfig *config) {
+
+ chDbgCheck((adcp != NULL) && (config != NULL), "adcStart");
+
+ chSysLock();
+ chDbgAssert((adcp->ad_state == ADC_STOP) || (adcp->ad_state == ADC_READY),
+ "adcStart(), #1",
+ "invalid state");
+ adcp->ad_config = config;
+ adc_lld_start(adcp);
+ adcp->ad_state = ADC_READY;
+ chSysUnlock();
+}
+
+/**
+ * @brief Deactivates the ADC peripheral.
+ *
+ * @param[in] adcp pointer to the @p ADCDriver object
+ */
+void adcStop(ADCDriver *adcp) {
+
+ chDbgCheck(adcp != NULL, "adcStop");
+
+ chSysLock();
+ chDbgAssert((adcp->ad_state == ADC_STOP) || (adcp->ad_state == ADC_READY),
+ "adcStop(), #1",
+ "invalid state");
+ adc_lld_stop(adcp);
+ adcp->ad_state = ADC_STOP;
+ chSysUnlock();
+}
+
+/**
+ * @brief Starts an ADC conversion.
+ * @details Starts a conversion operation, there are two kind of conversion
+ * modes:
+ * - <b>LINEAR</b>, this mode is activated when the @p callback
+ * parameter is set to @p NULL, in this mode the buffer is filled
+ * once and then the conversion stops automatically.
+ * - <b>CIRCULAR</b>, when a callback function is defined the
+ * conversion never stops and the buffer is filled circularly.
+ * During the conversion the callback function is invoked when
+ * the buffer is 50% filled and when the buffer is 100% filled,
+ * this way is possible to process the conversion stream in real
+ * time. This kind of conversion can only be stopped by explicitly
+ * invoking @p adcStopConversion().
+ * .
+ *
+ * @param[in] adcp pointer to the @p ADCDriver object
+ * @param[in] grpp pointer to a @p ADCConversionGroup object
+ * @param[out] samples pointer to the samples buffer
+ * @param[in] depth buffer depth (matrix rows number). The buffer depth
+ * must be one or an even number.
+ * @param[in] callback pointer to the conversion callback function
+ * @return The operation status.
+ * @retval FALSE the conversion has been started.
+ * @retval TRUE the driver is busy, conversion not started.
+ *
+ * @note The buffer is organized as a matrix of M*N elements where M is the
+ * channels number configured into the conversion group and N is the
+ * buffer depth. The samples are sequentially written into the buffer
+ * with no gaps.
+ */
+bool_t adcStartConversion(ADCDriver *adcp,
+ const ADCConversionGroup *grpp,
+ adcsample_t *samples,
+ size_t depth,
+ adccallback_t callback) {
+
+ chDbgCheck((adcp != NULL) && (grpp != NULL) && (samples != NULL) &&
+ ((depth == 1) || ((depth & 1) == 0)),
+ "adcStartConversion");
+
+ chSysLock();
+ chDbgAssert((adcp->ad_state == ADC_READY) ||
+ (adcp->ad_state == ADC_RUNNING),
+ "adcStartConversion(), #1",
+ "invalid state");
+ if (adcp->ad_state == ADC_RUNNING) {
+ chSysUnlock();
+ return TRUE;
+ }
+ adcp->ad_callback = callback;
+ adcp->ad_samples = samples;
+ adcp->ad_depth = depth;
+ adcp->ad_grpp = grpp;
+ adc_lld_start_conversion(adcp);
+ adcp->ad_state = ADC_RUNNING;
+ chSysUnlock();
+ return FALSE;
+}
+
+/**
+ * @brief Stops an ongoing conversion.
+ *
+ * @param[in] adcp pointer to the @p ADCDriver object
+ */
+void adcStopConversion(ADCDriver *adcp) {
+
+ chDbgCheck(adcp != NULL, "adcStopConversion");
+
+ chSysLock();
+ chDbgAssert((adcp->ad_state == ADC_READY) ||
+ (adcp->ad_state == ADC_RUNNING),
+ "adcStopConversion(), #1",
+ "invalid state");
+ if (adcp->ad_state == ADC_RUNNING) {
+ adc_lld_stop_conversion(adcp);
+ adcp->ad_grpp = NULL;
+ adcp->ad_state = ADC_READY;
+ chSemResetI(&adcp->ad_sem, 0);
+ chSchRescheduleS();
+ }
+ chSysUnlock();
+}
+
+/**
+ * @brief Waits for completion.
+ *
+ * @param[in] adcp pointer to the @p ADCDriver object
+ * @param[in] timeout the number of ticks before the operation timeouts,
+ * the following special values are allowed:
+ * - @a TIME_IMMEDIATE immediate timeout.
+ * - @a TIME_INFINITE no timeout.
+ * .
+ * @return The operation result.
+ * @retval RDY_OK conversion finished (or not started).
+ * @retval RDY_TIMEOUT conversion not finished within the specified time.
+ */
+msg_t adcWaitConversion(ADCDriver *adcp, systime_t timeout) {
+
+ chSysLock();
+ chDbgAssert((adcp->ad_state == ADC_READY) ||
+ (adcp->ad_state == ADC_RUNNING),
+ "adcWaitConversion(), #1",
+ "invalid state");
+ if (adcp->ad_state == ADC_RUNNING) {
+ if (chSemWaitTimeoutS(&adcp->ad_sem, timeout) == RDY_TIMEOUT) {
+ chSysUnlock();
+ return RDY_TIMEOUT;
+ }
+ }
+ chSysUnlock();
+ return RDY_OK;
+}
+
+#endif /* CH_HAL_USE_ADC */
+
+/** @} */