|
- #include "config.h"
- #include "adc.h"
- #include "timer.h"
-
- /* Layout of buffer:
- adc_dmabuf[x] contains 16 samples of channel AN0
- */
- uint16_t adc_dmabuf[16] __attribute__((space(dma)));
-
- void (*adc_adc_callback)(void) = 0;
- void (*adc_dma_callback)(void) = 0;
-
- /* ADC1 interrupt after each sample (if enabled) */
- void __attribute__((__interrupt__,auto_psv)) _ADC1Interrupt(void)
- {
- if (adc_adc_callback)
- (*adc_adc_callback)();
- IFS0bits.AD1IF = 0;
- }
-
- /* DMA0 interrupt after 16 samples */
- void __attribute__((__interrupt__,auto_psv)) _DMA0Interrupt(void)
- {
- if (adc_dma_callback)
- (*adc_dma_callback)();
- IFS0bits.DMA0IF = 0;
- }
-
- /* Initialize ADC1 to constantly DMA AN0. */
- void adc_init(void)
- {
- /* AD1CON1 */
- AD1CON1bits.ADDMABM = 1; /* Scatter-gather DMA */
- AD1CON1bits.AD12B = 1; /* 12-bit, 1 channel */
- AD1CON1bits.FORM = 0; /* Integer output 0000dddddddddddd */
- AD1CON1bits.SSRC = 2; /* Convert on Timer3 */
- AD1CON1bits.ASAM = 1; /* Automatically start sampling */
- AD1CON1bits.SIMSAM = 0; /* Simul sampling, N/A when AD12B=1 */
-
- /* AD1CON2 */
- AD1CON2bits.VCFG = 0; /* Ref: AVDD / AVSS */
- // AD1CON2bits.VCFG = 3; /* Ref: VREF+ / VREF- */
- AD1CON2bits.CSCNA = 0; /* Do not scan inputs on Mux A */
- AD1CON2bits.CHPS = 0; /* Convert CH0 only, N/A when AD12B=1 */
- AD1CON2bits.SMPI = 0; /* Increase DMA address at each sample */
- AD1CON2bits.BUFM = 0; /* Fill buffer from start */
- AD1CON2bits.ALTS = 0; /* Always use Mux A settings */
-
- /* AD1CON3 */
- AD1CON3bits.ADRC = 0; /* Use system clock, not internal RC */
- AD1CON3bits.SAMC = 0; /* Sample time, N/A when ADRC = 0 */
- AD1CON3bits.ADCS = 0x7; /* Tad = 8 * Tcy */
-
- /* AD1CON4 */
- AD1CON4bits.DMABL = 4; /* Each input gets 16 words in DMA buf */
-
- /* Channel 0 setup */
- AD1CHS0bits.CH0NA = 0; /* CH0-: Vrefl */
- AD1CHS0bits.CH0SA = 0; /* CH0+: AN0 */
-
- /* Set Timer3 to trigger conversion at 128KHz */
- timer_setup_16bit(3, 128000, 0);
-
- /* Turn it on */
- AD1PCFGL = 0xfffe; /* Analog = AN0 */
- AD1PCFGH = 0xffff;
- AD2PCFGL = 0xffff;
- AD1CON1bits.ADON = 1;
-
- /* DMA0 setup */
- DMA0CONbits.AMODE = 0; /* Register indirect, post-increment */
- DMA0CONbits.MODE = 0; /* Continuous, no ping-pong */
- DMA0PAD = (int)&ADC1BUF0; /* Get addresses from ADC1 */
- DMA0CNT = 15; /* 16 transfers before wraparound */
- DMA0STA = __builtin_dmaoffset(&adc_dmabuf);
- DMA0REQbits.IRQSEL = 13; /* Triggered by ADC1 */
- IFS0bits.DMA0IF = 0;
- IEC0bits.DMA0IE = 1; /* DMA interrupt (every 16 samples) */
- DMA0CONbits.CHEN = 1; /* enable this DMA channel */
-
- IFS0bits.AD1IF = 0;
- IEC0bits.AD1IE = 0; /* No ADC interrupt (every sample) */
- }
|