aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authortheshed <theshed@35acf78f-673a-0410-8e92-d51de3d6d3f4>2014-03-01 21:28:21 +0000
committertheshed <theshed@35acf78f-673a-0410-8e92-d51de3d6d3f4>2014-03-01 21:28:21 +0000
commitba0368ae0b08fadfc138f2488c2995c3d849a6a0 (patch)
treed5301f28da07e879f0b09b387a8e3e408a552d43
parentc0aab7fd964705dc61e6e0dea1950965dac91458 (diff)
downloadChibiOS-ba0368ae0b08fadfc138f2488c2995c3d849a6a0.tar.gz
ChibiOS-ba0368ae0b08fadfc138f2488c2995c3d849a6a0.tar.bz2
ChibiOS-ba0368ae0b08fadfc138f2488c2995c3d849a6a0.zip
Change LPC17xx ADC DMA driver.
git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@6739 35acf78f-673a-0410-8e92-d51de3d6d3f4
-rw-r--r--os/hal/platforms/LPC17xx/adc_lld.c60
-rw-r--r--os/hal/platforms/LPC17xx/adc_lld.h5
2 files changed, 38 insertions, 27 deletions
diff --git a/os/hal/platforms/LPC17xx/adc_lld.c b/os/hal/platforms/LPC17xx/adc_lld.c
index 2363dd12f..c5e6a786f 100644
--- a/os/hal/platforms/LPC17xx/adc_lld.c
+++ b/os/hal/platforms/LPC17xx/adc_lld.c
@@ -20,6 +20,7 @@
* @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
* @{
*/
@@ -45,6 +46,8 @@ ADCDriver ADCD1;
/* Driver local variables and types. */
/*===========================================================================*/
+static lpc17xx_dma_lli_config_t lpc_adc_lli[2] __attribute__((aligned(0x10)));
+
/*===========================================================================*/
/* Driver local functions. */
/*===========================================================================*/
@@ -58,25 +61,16 @@ ADCDriver ADCD1;
static void adc_serve_dma_interrupt(ADCDriver *adcp, uint32_t flags) {
(void) flags;
- adcp->num++;
- if (adcp->num == 1) {
- dmaChannelSrcAddr(LPC17xx_ADC_DMA_CHANNEL, adcp->adc_dma_cfg.srcaddr);
- dmaChannelDstAddr(LPC17xx_ADC_DMA_CHANNEL, \
- &adcp->samples[adcp->nsamples/2]);
- dmaChannelControl(LPC17xx_ADC_DMA_CHANNEL, adcp->adc_dma_cfg.control);
- dmaChannelConfig(LPC17xx_ADC_DMA_CHANNEL, adcp->adc_dma_cfg.config);
+ 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 {
- adcp->num = 0;
- if (adcp->grpp->circular == TRUE) {
- dmaChannelSrcAddr(LPC17xx_ADC_DMA_CHANNEL, adcp->adc_dma_cfg.srcaddr);
- dmaChannelDstAddr(LPC17xx_ADC_DMA_CHANNEL, adcp->adc_dma_cfg.dstaddr);
- dmaChannelControl(LPC17xx_ADC_DMA_CHANNEL, adcp->adc_dma_cfg.control);
- dmaChannelConfig(LPC17xx_ADC_DMA_CHANNEL, adcp->adc_dma_cfg.config);
- }
_adc_isr_full_code(adcp);
+ adcp->half_buffer = false;
}
}
#endif
@@ -204,7 +198,9 @@ 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
@@ -217,19 +213,21 @@ void adc_lld_start_conversion(ADCDriver *adcp) {
}
#if LPC17xx_ADC_USE_DMA
+ adcp->half_buffer = false;
+
ch = 0;
for (i = 0; i < 8; i++) {
if (cr & (1UL << i)) {
- ch = i; /* Get enabled channel number */
+ ch = i; /* Get number of first enabled channel. */
break;
}
}
/* DMA configuration */
- adcp->adc_dma_cfg.srcaddr = (uint32_t)&adcp->adc->DR[ch];
- adcp->adc_dma_cfg.dstaddr = (uint32_t)&adcp->samples[0];
- adcp->adc_dma_cfg.lli = 0;
- adcp->adc_dma_cfg.control =
+ 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 |
@@ -242,17 +240,29 @@ void adc_lld_start_conversion(ADCDriver *adcp) {
DMA_CTRL_PROT3_NONCACHE |
DMA_CTRL_INT;
- adcp->adc_dma_cfg.config =
+ 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, adcp->adc_dma_cfg.srcaddr);
- dmaChannelDstAddr(LPC17xx_ADC_DMA_CHANNEL, adcp->adc_dma_cfg.dstaddr);
- dmaChannelControl(LPC17xx_ADC_DMA_CHANNEL, adcp->adc_dma_cfg.control);
- dmaChannelConfig(LPC17xx_ADC_DMA_CHANNEL, adcp->adc_dma_cfg.config);
+ 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. */
diff --git a/os/hal/platforms/LPC17xx/adc_lld.h b/os/hal/platforms/LPC17xx/adc_lld.h
index 0f13cd731..dbff8f746 100644
--- a/os/hal/platforms/LPC17xx/adc_lld.h
+++ b/os/hal/platforms/LPC17xx/adc_lld.h
@@ -20,6 +20,7 @@
* @brief LPC17xx ADC subsystem low level driver header.
* @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
* @{
*/
@@ -308,9 +309,9 @@ struct ADCDriver {
uint32_t num;
#if LPC17xx_ADC_USE_DMA
/**
- * @brief ADC DMA configuration structure.
+ * @brief Half buffer indicator.
*/
- lpc17xx_dma_channel_config_t adc_dma_cfg;
+ bool_t half_buffer;
#endif
};