diff options
author | marcoveeneman <marco-veeneman@hotmail.com> | 2017-07-03 21:40:53 +0200 |
---|---|---|
committer | marcoveeneman <marco-veeneman@hotmail.com> | 2017-07-03 22:24:07 +0200 |
commit | 884dbaeabc65a1e2b53d5609652e66521e4f0998 (patch) | |
tree | 752bc5411423ba046d9f1423def56f0fc3fb2a61 /os/hal | |
parent | ffd9d3fd90ffe7f8a7f9d824fa3d9d8b6f33c196 (diff) | |
download | ChibiOS-Contrib-884dbaeabc65a1e2b53d5609652e66521e4f0998.tar.gz ChibiOS-Contrib-884dbaeabc65a1e2b53d5609652e66521e4f0998.tar.bz2 ChibiOS-Contrib-884dbaeabc65a1e2b53d5609652e66521e4f0998.zip |
Improved ADC driver and ADC testhal application.
Diffstat (limited to 'os/hal')
-rw-r--r-- | os/hal/ports/TIVA/LLD/ADC/hal_adc_lld.c | 67 |
1 files changed, 33 insertions, 34 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); |