From 884dbaeabc65a1e2b53d5609652e66521e4f0998 Mon Sep 17 00:00:00 2001 From: marcoveeneman Date: Mon, 3 Jul 2017 21:40:53 +0200 Subject: Improved ADC driver and ADC testhal application. --- os/hal/ports/TIVA/LLD/ADC/hal_adc_lld.c | 67 ++++++++++++++++----------------- testhal/TIVA/TM4C123x/ADC/main.c | 14 +++---- 2 files changed, 40 insertions(+), 41 deletions(-) diff --git a/os/hal/ports/TIVA/LLD/ADC/hal_adc_lld.c b/os/hal/ports/TIVA/LLD/ADC/hal_adc_lld.c index a175664..6c1be30 100644 --- a/os/hal/ports/TIVA/LLD/ADC/hal_adc_lld.c +++ b/os/hal/ports/TIVA/LLD/ADC/hal_adc_lld.c @@ -59,34 +59,28 @@ ADCDriver ADCD2; */ static void serve_interrupt(ADCDriver *adcp) { - uint32_t dmachis = HWREG(UDMA_CHIS); + tiva_udma_table_entry_t *pri = &udmaControlTable.primary[adcp->dmanr]; + tiva_udma_table_entry_t *alt = &udmaControlTable.alternate[adcp->dmanr]; - if (dmachis & (1 << adcp->dmanr)) { + if ((pri->chctl & UDMA_CHCTL_XFERMODE_M) == UDMA_CHCTL_XFERMODE_STOP) { + /* Primary is used only for circular transfers */ if (adcp->grpp->circular) { - tiva_udma_table_entry_t *pri = &udmaControlTable.primary[adcp->dmanr]; - tiva_udma_table_entry_t *alt = &udmaControlTable.alternate[adcp->dmanr]; - - if ((pri->chctl & UDMA_CHCTL_XFERMODE_M) == UDMA_CHCTL_XFERMODE_STOP) { - if (adcp->depth > 1) { - _adc_isr_half_code(adcp); - } - else { - _adc_isr_full_code(adcp); - } - - /* Reconfigure DMA for new (lower half) transfer */ - pri->chctl = adcp->prictl; + if (adcp->depth > 1) { + _adc_isr_half_code(adcp); } - else if ((alt->chctl & UDMA_CHCTL_XFERMODE_M) == UDMA_CHCTL_XFERMODE_STOP) { - _adc_isr_full_code(adcp); - /* Reconfigure DMA for new upper half transfer */ - alt->chctl = adcp->altctl; - } + /* Reconfigure DMA for new lower half transfer */ + pri->chctl = adcp->prictl; } - else { - /* Transfer complete processing.*/ - _adc_isr_full_code(adcp); + } + + if ((alt->chctl & UDMA_CHCTL_XFERMODE_M) == UDMA_CHCTL_XFERMODE_STOP) { + /* Alternate is used for both linear and circular transfers */ + _adc_isr_full_code(adcp); + + if (adcp->grpp->circular) { + /* Reconfigure DMA for new upper half transfer */ + alt->chctl = adcp->altctl; } } } @@ -214,16 +208,18 @@ void adc_lld_stop(ADCDriver *adcp) if (adcp->state == ADC_READY) { /* Resets the peripheral.*/ + udmaChannelRelease(adcp->dmanr); + /* Disables the peripheral.*/ #if TIVA_ADC_USE_ADC0 if (&ADCD1 == adcp) { - + nvicDisableVector(TIVA_ADC0_SEQ0_NUMBER); } #endif #if TIVA_ADC_USE_ADC1 if (&ADCD2 == adcp) { - + nvicDisableVector(TIVA_ADC1_SEQ0_NUMBER); } #endif } @@ -260,8 +256,8 @@ void adc_lld_start_conversion(ADCDriver *adcp) /* Configure the sample control bits */ HWREG(adc + ADC_O_SSCTL0) = adcp->grpp->ssctl | 0x44444444; /* Enforce IEn bits */ - /* Primary source endpoint is the same for all transfers */ - primary->srcendp = (void *)(adcp->adc + ADC_O_SSFIFO0); + /* Alternate source endpoint is the same for all transfers */ + alternate->srcendp = (void *)(adcp->adc + ADC_O_SSFIFO0); /* Configure DMA */ if ((adcp->grpp->circular) && (adcp->depth > 1)) { @@ -271,8 +267,8 @@ void adc_lld_start_conversion(ADCDriver *adcp) uint32_t ctl; - /* configure the alternate source endpoint */ - alternate->srcendp = (void *)(adcp->adc + ADC_O_SSFIFO0); + /* configure the primary source endpoint */ + primary->srcendp = (void *)(adcp->adc + ADC_O_SSFIFO0); /* sample buffer is split in half, the upper half is used here */ primary->dstendp = (void *)(adcp->samples + @@ -289,19 +285,23 @@ void adc_lld_start_conversion(ADCDriver *adcp) adcp->prictl = ctl; adcp->altctl = ctl; + + dmaChannelPrimary(adcp->dmanr); } else { /* Configure the DMA in basic mode. This is used for both circular buffers with a depth of 1 and linear buffers.*/ - primary->dstendp = (void *)(adcp->samples + - (adcp->grpp->num_channels * adcp->depth) - 1); - adcp->prictl = UDMA_CHCTL_DSTSIZE_32 | UDMA_CHCTL_DSTINC_32 | + alternate->dstendp = (void *)(adcp->samples + + (adcp->grpp->num_channels * adcp->depth) - 1); + adcp->prictl = UDMA_CHCTL_XFERMODE_STOP; + adcp->altctl = UDMA_CHCTL_DSTSIZE_32 | UDMA_CHCTL_DSTINC_32 | UDMA_CHCTL_SRCSIZE_32 | UDMA_CHCTL_SRCINC_NONE | UDMA_CHCTL_ARBSIZE_1 | UDMA_CHCTL_XFERSIZE(adcp->grpp->num_channels * adcp->depth) | UDMA_CHCTL_XFERMODE_BASIC; - adcp->altctl = UDMA_CHCTL_XFERMODE_STOP; + + dmaChannelAlternate(adcp->dmanr); } /* Configure primary and alternate channel control fields */ @@ -309,7 +309,6 @@ void adc_lld_start_conversion(ADCDriver *adcp) alternate->chctl = adcp->altctl; /* Configure DMA channel */ - dmaChannelPrimary(adcp->dmanr); dmaChannelBurstOnly(adcp->dmanr); dmaChannelPriorityDefault(adcp->dmanr); dmaChannelEnableRequest(adcp->dmanr); diff --git a/testhal/TIVA/TM4C123x/ADC/main.c b/testhal/TIVA/TM4C123x/ADC/main.c index 5f06180..c538e6d 100644 --- a/testhal/TIVA/TM4C123x/ADC/main.c +++ b/testhal/TIVA/TM4C123x/ADC/main.c @@ -77,7 +77,7 @@ static void adcerrorcallback(ADCDriver *adcp, adcerror_t err) { /* * ADC conversion group. - * Mode: Linear buffer, 8 samples of 2 channels, SW triggered. + * Mode: Linear buffer, 8 samples of 2 channels, Always triggered. * Channels: TS, TS. */ static const ADCConversionGroup adcgrpcfg1 = { @@ -85,15 +85,15 @@ static const ADCConversionGroup adcgrpcfg1 = { ADC_GRP1_NUM_CHANNELS, NULL, adcerrorcallback, - 0xF, /* EMUX */ /* Continuous trigger */ + 0xF, /* EMUX */ /* Always trigger */ 0, /* SSMUX */ (1 << 7) | (1 << 5) | - (1 << 3) /* SSCTL */ /* 2 times TS, 2nd has end+int bit set */ + (1 << 3) /* SSCTL */ /* 2 times TS, 2nd has end bit set */ }; /* * ADC conversion group. - * Mode: Continuous, 16 samples of 8 channels, SW triggered. + * Mode: Continuous, 16 samples of 8 channels, Always triggered. * Channels: TS, TS, TS, TS, TS, TS, TS, TS. */ static const ADCConversionGroup adcgrpcfg2 = { @@ -101,8 +101,8 @@ static const ADCConversionGroup adcgrpcfg2 = { ADC_GRP2_NUM_CHANNELS, adccallback, adcerrorcallback, - 0xF, /* EMUX */ - 0, /* SSMUX */ + 0xF, /* EMUX */ /* Always trigger */ + 0, /* SSMUX */ (1 << 31) | (1 << 29) | (1 << 27) | (1 << 23) | @@ -110,7 +110,7 @@ static const ADCConversionGroup adcgrpcfg2 = { (1 << 15) | (1 << 11) | (1 << 7) | - (1 << 3) /* SSCTL */ + (1 << 3) /* SSCTL */ /* 8 times TS, 8th has end bit set */ }; /* -- cgit v1.2.3