aboutsummaryrefslogtreecommitdiffstats
path: root/os/hal/platforms/LPC17xx/adc_lld.c
diff options
context:
space:
mode:
Diffstat (limited to 'os/hal/platforms/LPC17xx/adc_lld.c')
-rw-r--r--os/hal/platforms/LPC17xx/adc_lld.c588
1 files changed, 294 insertions, 294 deletions
diff --git a/os/hal/platforms/LPC17xx/adc_lld.c b/os/hal/platforms/LPC17xx/adc_lld.c
index c5e6a786f..aebd04b38 100644
--- a/os/hal/platforms/LPC17xx/adc_lld.c
+++ b/os/hal/platforms/LPC17xx/adc_lld.c
@@ -1,294 +1,294 @@
-/*
- ChibiOS/RT - Copyright (C) 2006-2013 Giovanni Di Sirio
- LPC17xx ADC driver - Copyright (C) 2013 Marcin Jokel
-
- 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 LPC17xx/adc_lld.c
- * @brief LPC17xx ADC subsystem low level driver source.
- * @note Values in samples buffer are from DR register.
- * To get ADC values make conversion (DR >> 6) & 0x03FF.
- * DMA only support one ADC channel.
- * @addtogroup ADC
- * @{
- */
-
-#include "ch.h"
-#include "hal.h"
-
-#if HAL_USE_ADC || defined(__DOXYGEN__)
-
-/*===========================================================================*/
-/* Driver local definitions. */
-/*===========================================================================*/
-
-
-/*===========================================================================*/
-/* Driver exported variables. */
-/*===========================================================================*/
-
-/** @brief ADC1 driver identifier.*/
-ADCDriver ADCD1;
-
-/*===========================================================================*/
-/* Driver local variables and types. */
-/*===========================================================================*/
-
-static lpc17xx_dma_lli_config_t lpc_adc_lli[2] __attribute__((aligned(0x10)));
-
-/*===========================================================================*/
-/* Driver local functions. */
-/*===========================================================================*/
-
-#if LPC17xx_ADC_USE_DMA
-/**
- * @brief Common IRQ handler.
- *
- * @param[in] adcp pointer to the @p ADCDriver object
- */
-static void adc_serve_dma_interrupt(ADCDriver *adcp, uint32_t flags) {
- (void) flags;
-
- if ((flags & (1 << LPC17xx_ADC_DMA_CHANNEL)) != 0) {
- _adc_isr_error_code(adcp, flags); /* DMA errors handling.*/
- }
- else if (adcp->half_buffer == false) {
- _adc_isr_half_code(adcp);
- adcp->half_buffer = true;
- }
- else {
- _adc_isr_full_code(adcp);
- adcp->half_buffer = false;
- }
-}
-#endif
-/*===========================================================================*/
-/* Driver interrupt handlers. */
-/*===========================================================================*/
-
-/**
- * @brief ADC interrupt handler.
- *
- * @isr
- */
-CH_IRQ_HANDLER(Vector98) {
- uint32_t status;
- uint32_t n;
- uint8_t i;
-
- CH_IRQ_PROLOGUE();
- status = LPC_ADC->STAT;
-
- n = ADCD1.num;
-
- /* Note, an overrun may occur only in burst mode, if one or more
- conversions was (were) lost. */
- if ((status & ADC0STAT_OVERRUN_MASK)) {
- if (ADCD1.grpp != NULL)
- _adc_isr_error_code(&ADCD1, ADC_ERR_OVERRUN);
- }
- else {
-
- status = status & ADC0STAT_DONE_MASK;
- for (i = 0; i < ADC_MAX_CHANNELS; i++) {
- if (status & (0x01 << i)) {
- ADCD1.samples[n] = LPC_ADC->DR[i];
- n++;
- }
- }
-
- if (n == (ADCD1.nsamples / 2)) {
- _adc_isr_half_code(&ADCD1);
- }
-
- if (n == ADCD1.nsamples) {
- n = 0;
- _adc_isr_full_code(&ADCD1);
- }
- }
- ADCD1.num = n;
- CH_IRQ_EPILOGUE();
-}
-
-
-/*===========================================================================*/
-/* Driver exported functions. */
-/*===========================================================================*/
-
-/**
- * @brief Low level ADC driver initialization.
- *
- * @notapi
- */
-void adc_lld_init(void) {
-
- /* Driver initialization.*/
- adcObjectInit(&ADCD1);
- ADCD1.adc = LPC_ADC;
-
-#if LPC17xx_ADC_USE_DMA
- nvicDisableVector(ADC_IRQn);
-#else
- nvicEnableVector(ADC_IRQn, CORTEX_PRIORITY_MASK(LPC17xx_ADC_IRQ_PRIORITY));
-#endif
-}
-
-/**
- * @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. */
- if (adcp->state == ADC_STOP) {
- LPC_SC->PCONP |= (1UL << 12); /* Enable ADC power */
-
-#if LPC17xx_ADC_USE_DMA
- dmaChannelAllocate(LPC17xx_ADC_DMA_CHANNEL, \
- (lpc17xx_dmaisr_t)adc_serve_dma_interrupt, \
- (void *)adcp);
-#endif
- }
-}
-
-/**
- * @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) {
- adcp->adc->CR = 0; /* Clear PDN bit */
- LPC_SC->PCONP &= ~(1UL << 12); /* Disable ADC power */
-
-#if LPC17xx_ADC_USE_DMA
- dmaChannelRelease(LPC17xx_ADC_DMA_CHANNEL);
-#endif
- }
-}
-
-/**
- * @brief Starts an ADC conversion.
- *
- * @param[in] adcp pointer to the @p ADCDriver object
- *
- * @notapi
- */
-void adc_lld_start_conversion(ADCDriver *adcp) {
-
- uint32_t dummy;
- uint32_t cr;
- uint8_t i;
-
-#if LPC17xx_ADC_USE_DMA
- uint32_t dma_ch_config;
- uint8_t ch;
-#endif
-
- cr = adcp->grpp->cr0;
- adcp->num = 0;
- adcp->nsamples = adcp->depth * adcp->grpp->num_channels;
-
- for (i = 0; i < ADC_MAX_CHANNELS; i++) {
- dummy = adcp->adc->DR[i]; /* Clear all DONE and OVERRUN flags. */
- }
-
-#if LPC17xx_ADC_USE_DMA
- adcp->half_buffer = false;
-
- ch = 0;
- for (i = 0; i < 8; i++) {
- if (cr & (1UL << i)) {
- ch = i; /* Get number of first enabled channel. */
- break;
- }
- }
-
- /* DMA configuration */
- lpc_adc_lli[0].srcaddr = (uint32_t)&adcp->adc->DR[ch];
- lpc_adc_lli[0].dstaddr = (uint32_t)&adcp->samples[0];
- lpc_adc_lli[0].lli = (uint32_t) &lpc_adc_lli[1];
- lpc_adc_lli[0].control =
- DMA_CTRL_TRANSFER_SIZE(adcp->nsamples/2) |
- DMA_CTRL_SRC_BSIZE_1 |
- DMA_CTRL_DST_BSIZE_1 |
- DMA_CTRL_SRC_WIDTH_WORD |
- DMA_CTRL_DST_WIDTH_WORD |
- DMA_CTRL_SRC_NOINC |
- DMA_CTRL_DST_INC |
- DMA_CTRL_PROT1_USER |
- DMA_CTRL_PROT2_NONBUFF |
- DMA_CTRL_PROT3_NONCACHE |
- DMA_CTRL_INT;
-
- lpc_adc_lli[1].srcaddr = lpc_adc_lli[0].srcaddr;
- lpc_adc_lli[1].dstaddr = (uint32_t)&adcp->samples[adcp->nsamples/2];
- lpc_adc_lli[1].control = lpc_adc_lli[0].control;
-
- if (adcp->grpp->circular == true) {
- lpc_adc_lli[1].lli = (uint32_t) &lpc_adc_lli[0];
- }
- else {
- lpc_adc_lli[1].lli = 0;
- }
-
- dma_ch_config =
- DMA_CFG_CH_ENABLE |
- DMA_CFG_SRC_PERIPH(DMA_ADC) |
- DMA_CFG_TTYPE_P2M |
- DMA_CFG_IE |
- DMA_CFG_ITC;
-
- dmaChannelSrcAddr(LPC17xx_ADC_DMA_CHANNEL, lpc_adc_lli[0].srcaddr);
- dmaChannelDstAddr(LPC17xx_ADC_DMA_CHANNEL, lpc_adc_lli[0].dstaddr);
- dmaChannelLinkedList(LPC17xx_ADC_DMA_CHANNEL, lpc_adc_lli[0].lli);
- dmaChannelControl(LPC17xx_ADC_DMA_CHANNEL, lpc_adc_lli[0].control);
- dmaChannelConfig(LPC17xx_ADC_DMA_CHANNEL, dma_ch_config);
-#endif
-
- /* ADC configuration and conversion start. */
- adcp->adc->INTEN = adcp->grpp->inten; /* Set ADC interrupt on selected channels */
- adcp->adc->CR = (cr & 0x0000FFFF) | ((LPC17xx_ADC_CLKDIV - 1) << 8) | AD0CR_PDN;
- adcp->adc->CR |= cr & 0xFFFF0000;
-
-}
-
-/**
- * @brief Stops an ongoing conversion.
- *
- * @param[in] adcp pointer to the @p ADCDriver object
- *
- * @notapi
- */
-void adc_lld_stop_conversion(ADCDriver *adcp) {
-
-#if LPC17xx_ADC_USE_DMA
- dmaChannelDisable(LPC17xx_ADC_DMA_CHANNEL);
-#endif
- adcp->adc->CR &= ~(AD0CR_MODE_BURST | AD0CR_START_MASK); /* Disable ADC conversion. */
- adcp->adc->INTEN = 0; /* Mask ADC interrupts. */
-}
-
-
-#endif /* HAL_USE_ADC */
-
-/** @} */
+/*
+ ChibiOS/RT - Copyright (C) 2006-2013 Giovanni Di Sirio
+ LPC17xx ADC driver - Copyright (C) 2013 Marcin Jokel
+
+ 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 LPC17xx/adc_lld.c
+ * @brief LPC17xx ADC subsystem low level driver source.
+ * @note Values in samples buffer are from DR register.
+ * To get ADC values make conversion (DR >> 6) & 0x03FF.
+ * DMA only support one ADC channel.
+ * @addtogroup ADC
+ * @{
+ */
+
+#include "ch.h"
+#include "hal.h"
+
+#if HAL_USE_ADC || defined(__DOXYGEN__)
+
+/*===========================================================================*/
+/* Driver local definitions. */
+/*===========================================================================*/
+
+
+/*===========================================================================*/
+/* Driver exported variables. */
+/*===========================================================================*/
+
+/** @brief ADC1 driver identifier.*/
+ADCDriver ADCD1;
+
+/*===========================================================================*/
+/* Driver local variables and types. */
+/*===========================================================================*/
+
+static lpc17xx_dma_lli_config_t lpc_adc_lli[2] __attribute__((aligned(0x10)));
+
+/*===========================================================================*/
+/* Driver local functions. */
+/*===========================================================================*/
+
+#if LPC17xx_ADC_USE_DMA
+/**
+ * @brief Common IRQ handler.
+ *
+ * @param[in] adcp pointer to the @p ADCDriver object
+ */
+static void adc_serve_dma_interrupt(ADCDriver *adcp, uint32_t flags) {
+ (void) flags;
+
+ if ((flags & (1 << LPC17xx_ADC_DMA_CHANNEL)) != 0) {
+ _adc_isr_error_code(adcp, flags); /* DMA errors handling.*/
+ }
+ else if (adcp->half_buffer == false) {
+ _adc_isr_half_code(adcp);
+ adcp->half_buffer = true;
+ }
+ else {
+ _adc_isr_full_code(adcp);
+ adcp->half_buffer = false;
+ }
+}
+#endif
+/*===========================================================================*/
+/* Driver interrupt handlers. */
+/*===========================================================================*/
+
+/**
+ * @brief ADC interrupt handler.
+ *
+ * @isr
+ */
+CH_IRQ_HANDLER(Vector98) {
+ uint32_t status;
+ uint32_t n;
+ uint8_t i;
+
+ CH_IRQ_PROLOGUE();
+ status = LPC_ADC->STAT;
+
+ n = ADCD1.num;
+
+ /* Note, an overrun may occur only in burst mode, if one or more
+ conversions was (were) lost. */
+ if ((status & ADC0STAT_OVERRUN_MASK)) {
+ if (ADCD1.grpp != NULL)
+ _adc_isr_error_code(&ADCD1, ADC_ERR_OVERRUN);
+ }
+ else {
+
+ status = status & ADC0STAT_DONE_MASK;
+ for (i = 0; i < ADC_MAX_CHANNELS; i++) {
+ if (status & (0x01 << i)) {
+ ADCD1.samples[n] = LPC_ADC->DR[i];
+ n++;
+ }
+ }
+
+ if (n == (ADCD1.nsamples / 2)) {
+ _adc_isr_half_code(&ADCD1);
+ }
+
+ if (n == ADCD1.nsamples) {
+ n = 0;
+ _adc_isr_full_code(&ADCD1);
+ }
+ }
+ ADCD1.num = n;
+ CH_IRQ_EPILOGUE();
+}
+
+
+/*===========================================================================*/
+/* Driver exported functions. */
+/*===========================================================================*/
+
+/**
+ * @brief Low level ADC driver initialization.
+ *
+ * @notapi
+ */
+void adc_lld_init(void) {
+
+ /* Driver initialization.*/
+ adcObjectInit(&ADCD1);
+ ADCD1.adc = LPC_ADC;
+
+#if LPC17xx_ADC_USE_DMA
+ nvicDisableVector(ADC_IRQn);
+#else
+ nvicEnableVector(ADC_IRQn, CORTEX_PRIORITY_MASK(LPC17xx_ADC_IRQ_PRIORITY));
+#endif
+}
+
+/**
+ * @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. */
+ if (adcp->state == ADC_STOP) {
+ LPC_SC->PCONP |= (1UL << 12); /* Enable ADC power */
+
+#if LPC17xx_ADC_USE_DMA
+ dmaChannelAllocate(LPC17xx_ADC_DMA_CHANNEL, \
+ (lpc17xx_dmaisr_t)adc_serve_dma_interrupt, \
+ (void *)adcp);
+#endif
+ }
+}
+
+/**
+ * @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) {
+ adcp->adc->CR = 0; /* Clear PDN bit */
+ LPC_SC->PCONP &= ~(1UL << 12); /* Disable ADC power */
+
+#if LPC17xx_ADC_USE_DMA
+ dmaChannelRelease(LPC17xx_ADC_DMA_CHANNEL);
+#endif
+ }
+}
+
+/**
+ * @brief Starts an ADC conversion.
+ *
+ * @param[in] adcp pointer to the @p ADCDriver object
+ *
+ * @notapi
+ */
+void adc_lld_start_conversion(ADCDriver *adcp) {
+
+ uint32_t dummy;
+ uint32_t cr;
+ uint8_t i;
+
+#if LPC17xx_ADC_USE_DMA
+ uint32_t dma_ch_config;
+ uint8_t ch;
+#endif
+
+ cr = adcp->grpp->cr0;
+ adcp->num = 0;
+ adcp->nsamples = adcp->depth * adcp->grpp->num_channels;
+
+ for (i = 0; i < ADC_MAX_CHANNELS; i++) {
+ dummy = adcp->adc->DR[i]; /* Clear all DONE and OVERRUN flags. */
+ }
+
+#if LPC17xx_ADC_USE_DMA
+ adcp->half_buffer = false;
+
+ ch = 0;
+ for (i = 0; i < 8; i++) {
+ if (cr & (1UL << i)) {
+ ch = i; /* Get number of first enabled channel. */
+ break;
+ }
+ }
+
+ /* DMA configuration */
+ lpc_adc_lli[0].srcaddr = (uint32_t)&adcp->adc->DR[ch];
+ lpc_adc_lli[0].dstaddr = (uint32_t)&adcp->samples[0];
+ lpc_adc_lli[0].lli = (uint32_t) &lpc_adc_lli[1];
+ lpc_adc_lli[0].control =
+ DMA_CTRL_TRANSFER_SIZE(adcp->nsamples/2) |
+ DMA_CTRL_SRC_BSIZE_1 |
+ DMA_CTRL_DST_BSIZE_1 |
+ DMA_CTRL_SRC_WIDTH_WORD |
+ DMA_CTRL_DST_WIDTH_WORD |
+ DMA_CTRL_SRC_NOINC |
+ DMA_CTRL_DST_INC |
+ DMA_CTRL_PROT1_USER |
+ DMA_CTRL_PROT2_NONBUFF |
+ DMA_CTRL_PROT3_NONCACHE |
+ DMA_CTRL_INT;
+
+ lpc_adc_lli[1].srcaddr = lpc_adc_lli[0].srcaddr;
+ lpc_adc_lli[1].dstaddr = (uint32_t)&adcp->samples[adcp->nsamples/2];
+ lpc_adc_lli[1].control = lpc_adc_lli[0].control;
+
+ if (adcp->grpp->circular == true) {
+ lpc_adc_lli[1].lli = (uint32_t) &lpc_adc_lli[0];
+ }
+ else {
+ lpc_adc_lli[1].lli = 0;
+ }
+
+ dma_ch_config =
+ DMA_CFG_CH_ENABLE |
+ DMA_CFG_SRC_PERIPH(DMA_ADC) |
+ DMA_CFG_TTYPE_P2M |
+ DMA_CFG_IE |
+ DMA_CFG_ITC;
+
+ dmaChannelSrcAddr(LPC17xx_ADC_DMA_CHANNEL, lpc_adc_lli[0].srcaddr);
+ dmaChannelDstAddr(LPC17xx_ADC_DMA_CHANNEL, lpc_adc_lli[0].dstaddr);
+ dmaChannelLinkedList(LPC17xx_ADC_DMA_CHANNEL, lpc_adc_lli[0].lli);
+ dmaChannelControl(LPC17xx_ADC_DMA_CHANNEL, lpc_adc_lli[0].control);
+ dmaChannelConfig(LPC17xx_ADC_DMA_CHANNEL, dma_ch_config);
+#endif
+
+ /* ADC configuration and conversion start. */
+ adcp->adc->INTEN = adcp->grpp->inten; /* Set ADC interrupt on selected channels */
+ adcp->adc->CR = (cr & 0x0000FFFF) | ((LPC17xx_ADC_CLKDIV - 1) << 8) | AD0CR_PDN;
+ adcp->adc->CR |= cr & 0xFFFF0000;
+
+}
+
+/**
+ * @brief Stops an ongoing conversion.
+ *
+ * @param[in] adcp pointer to the @p ADCDriver object
+ *
+ * @notapi
+ */
+void adc_lld_stop_conversion(ADCDriver *adcp) {
+
+#if LPC17xx_ADC_USE_DMA
+ dmaChannelDisable(LPC17xx_ADC_DMA_CHANNEL);
+#endif
+ adcp->adc->CR &= ~(AD0CR_MODE_BURST | AD0CR_START_MASK); /* Disable ADC conversion. */
+ adcp->adc->INTEN = 0; /* Mask ADC interrupts. */
+}
+
+
+#endif /* HAL_USE_ADC */
+
+/** @} */