aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--os/hal/include/adc.h6
-rw-r--r--os/hal/src/adc.c77
-rw-r--r--readme.txt3
-rw-r--r--todo.txt2
4 files changed, 80 insertions, 8 deletions
diff --git a/os/hal/include/adc.h b/os/hal/include/adc.h
index 983fe0f78..8b1bfd47b 100644
--- a/os/hal/include/adc.h
+++ b/os/hal/include/adc.h
@@ -83,7 +83,13 @@ extern "C" {
adcsample_t *samples,
size_t depth,
adccallback_t callback);
+ bool_t adcStartConversionI(ADCDriver *adcp,
+ const ADCConversionGroup *grpp,
+ adcsample_t *samples,
+ size_t depth,
+ adccallback_t callback);
void adcStopConversion(ADCDriver *adcp);
+ void adcStopConversionI(ADCDriver *adcp);
msg_t adcWaitConversion(ADCDriver *adcp, systime_t timeout);
#ifdef __cplusplus
}
diff --git a/os/hal/src/adc.c b/os/hal/src/adc.c
index 5348d7e93..4eafafac4 100644
--- a/os/hal/src/adc.c
+++ b/os/hal/src/adc.c
@@ -143,28 +143,67 @@ bool_t adcStartConversion(ADCDriver *adcp,
adcsample_t *samples,
size_t depth,
adccallback_t callback) {
+ bool_t result;
+
+ chSysLock();
+ result = adcStartConversionI(adcp, grpp, samples, depth, callback);
+ chSysUnlock();
+ return result;
+}
+
+/**
+ * @brief Starts an ADC conversion.
+ * @details Starts a conversion operation, there are two kind of conversion
+ * modes:
+ * - <b>LINEAR</b>, in this mode the buffer is filled once and then
+ * the conversion stops automatically.
+ * - <b>CIRCULAR</b>, in this mode the conversion never stops and
+ * the buffer is filled circularly.<br>
+ * 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().
+ * .
+ * @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.
+ *
+ * @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, this
+ * parameter can be @p NULL if a callback is not required
+ * @return The operation status.
+ * @retval FALSE the conversion has been started.
+ * @retval TRUE the driver is busy, conversion not started.
+ */
+bool_t adcStartConversionI(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");
+ "adcStartConversionI");
- chSysLock();
chDbgAssert((adcp->ad_state == ADC_READY) ||
(adcp->ad_state == ADC_RUNNING) ||
(adcp->ad_state == ADC_COMPLETE),
- "adcStartConversion(), #1",
+ "adcStartConversionI(), #1",
"invalid state");
- if (adcp->ad_state == ADC_RUNNING) {
- chSysUnlock();
+ if (adcp->ad_state == ADC_RUNNING)
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;
}
@@ -196,6 +235,30 @@ void adcStopConversion(ADCDriver *adcp) {
}
/**
+ * @brief Stops an ongoing conversion.
+ *
+ * @param[in] adcp pointer to the @p ADCDriver object
+ */
+void adcStopConversionI(ADCDriver *adcp) {
+
+ chDbgCheck(adcp != NULL, "adcStopConversionI");
+
+ chDbgAssert((adcp->ad_state == ADC_READY) ||
+ (adcp->ad_state == ADC_RUNNING) ||
+ (adcp->ad_state == ADC_COMPLETE),
+ "adcStopConversionI(), #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);
+ }
+ else
+ adcp->ad_state = ADC_READY;
+}
+
+/**
* @brief Waits for completion.
* @details If the conversion is not completed or not yet started then the
* invoking thread waits for a conversion completion event.
diff --git a/readme.txt b/readme.txt
index 1661f3ebb..ddcbf53b3 100644
--- a/readme.txt
+++ b/readme.txt
@@ -94,6 +94,9 @@
driver in order to allow channel reprogramming from within callbacks or
other interrupt handlers. The new APIs are implemented as macros so there
is no footprint overhead.
+- NEW: Added adcStartConversionI() and adcStopConversionI() APIs to the ADC
+ driver in order to allow the driver control from within callbacks or other
+ interrupt handlers.
- NEW: Added a generic BaseFileStream interface for future File System
implementations or integrations (untested and not sure if it will stay or
change).
diff --git a/todo.txt b/todo.txt
index 25e042433..72aac6c09 100644
--- a/todo.txt
+++ b/todo.txt
@@ -17,7 +17,7 @@ X Resist doing more changes and optimizations in the kernel, fixes only.
X File System infrastructure.
X General HAL improvements.
X I2C device driver class support.
-- I-class functions for the ADC driver.
+X I-class functions for the ADC/PWM drivers.
- Evaluate making SPI and CAN drivers callback-based.
- MAC driver for STM32F105/STM32F107 (hardware missing).
- Device drivers for STM8 (SPI, ADC, PWM, bring it on par with STM32).