aboutsummaryrefslogtreecommitdiffstats
path: root/os/hal
diff options
context:
space:
mode:
authorgdisirio <gdisirio@35acf78f-673a-0410-8e92-d51de3d6d3f4>2010-09-11 10:14:05 +0000
committergdisirio <gdisirio@35acf78f-673a-0410-8e92-d51de3d6d3f4>2010-09-11 10:14:05 +0000
commitf9fd465da5bd86e2c650fe7f8f6f54b528c46aff (patch)
tree5ec4392911dd1b95ebfab69fc245ffc844ee93ae /os/hal
parent8596d3e4aed62a256fd8f607cd64d8a4ede5fd5b (diff)
downloadChibiOS-f9fd465da5bd86e2c650fe7f8f6f54b528c46aff.tar.gz
ChibiOS-f9fd465da5bd86e2c650fe7f8f6f54b528c46aff.tar.bz2
ChibiOS-f9fd465da5bd86e2c650fe7f8f6f54b528c46aff.zip
git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@2173 35acf78f-673a-0410-8e92-d51de3d6d3f4
Diffstat (limited to 'os/hal')
-rw-r--r--os/hal/include/adc.h6
-rw-r--r--os/hal/src/adc.c77
2 files changed, 76 insertions, 7 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.