CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug Reports on this forum. Send them to

Has anyone played with PIC24 DMA sampling multi-channels?

Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message

Joined: 11 Mar 2010
Posts: 16345

View user's profile Send private message

Has anyone played with PIC24 DMA sampling multi-channels?
PostPosted: Sun Jan 14, 2018 10:35 am     Reply with quote


Trying to implement the ability to sample three channels sequentially with DMA on a PIC24FJ256GA702.

Now according to the data, it appears you can set the channels you want to sample in the AD1CSS register, use legacy mode (so the channel data is stored sequentially rather than indexed by channel number), select 'autoconvert' mode, with a suitable Tad multiplier programmed to acquire, enable autoscanning (CSCNA=TRUE), and specify the number of samples you want it to perform, set the DMA to trigger on ADC1, start the DMA transaction. Then trigger the ADC to start and when it completes the DMA should keep cycling through the selected channels for the selected number of cycles.
I currently have the clock divider to give 312.5uSec and 3.12uSec acquire time.

Now unfortunately the CCS example on ADC's like this only handles one channel, and is on a chip where the setup is a little different (offers DMA_IN_ADC1, rather than DMA_TRIGGER_ADC1).

I'm actually getting correct results right through the buffer, but for AN1 only.

Will query CCS about this, but wondered if anyone had played with this type of setup?.

My 'play' code so far is:

int1 DMA_complete; // Flag to test if DMA interupt has been serviced.
#define BUFFER_SIZE 54  //DMA BUFFER Size


//This interrupt gets triggered after 54 DMA transfers(DMACOUNT) are complete
void DMA0_ISR(void)
   DMA_complete = TRUE; 

#BIT ASEN=getenv("BIT:ASEN")
#BIT BUFM=getenv("BIT:BUFM")
#BIT ADON=getenv("BIT:ADON")
#BIT ASAM=getenv("BIT:ASAM")
#BIT ALTS=getenv("BIT:ALTS")
#WORD AD1CON1=getenv("SFR:AD1CON1")
#WORD AD1CON2=getenv("SFR:AD1CON2")
#WORD AD1CON3=getenv("SFR:AD1CON3")
#WORD AD1CON4=getenv("SFR:AD1CON4")
#WORD AD1CON5=getenv("SFR:AD1CON5")

void launch_dma(void)
   //Now need to tweak the ADC settings. Must set the individual enable
   //bits for the three channels required, and set the mode to automatically
   //scan the channels
   //Need to disable ADC before configuring
   DMAEN=FALSE; //extended features off
   DMABM=FALSE; //default mode
   AD1CSS=0b0000000000110010; //AN1, 4 & 5 in the scan
   AD1CSSH=0; //No other channels used
   ASEN=FALSE; //turn off the threshold detect scan
   ALTS=FALSE; //single MUX
   CSCNA=TRUE; //continuous scan of selected channels
   BUFM=TRUE; //This should each read back to ADC1BUF0
   PUMPEN=FALSE; //disable charge pump (AVdd=3.3v)
   AD1CON2 &= 0xFF83; //SMPI=0000 forces interrupt/DMA on every sample
   //trying note from download setting 3 instead - no change
   //AD1CON2 |= 0x0080; //every third?
   BUFREGEN=FALSE; //All I/O through ADC1BUF0
   ASAM=TRUE; //automatic sample timing
   AD1CON5 &= 0xFCF3; //ensure ASINT is disabled and WM=00
   AD1CON1 = (AD1CON1 & 0xFF0F) | 0x0070; //SSRC=0111, selects Autoconvert mode

   //Now enable the ADC again
   //set_adc_channel(1); //select 1 as first channel
   DMA_complete = FALSE;
   setup_dma(0, DMA_TRIGGER_ADC1, DMA_WORD);
   enable_interrupts(INT_DMA0);  //dma will now depend on ADC
   //Now triggering a read_adc, should force the buffer to fill with 54 samples
//Then where I check for the results:
      if (DMA_complete)
          //here I process the results, then retrigger

         read_adc(ADC_START_ONLY); //retrigger DMA       

I seem actually to be getting results, but only from AN1.

There is a thread showing doing this on a PIC33 in the code library, but here scatter/gather is used, rather than the sequential sampling.

Joined: 11 Mar 2010
Posts: 16345

View user's profile Send private message

PostPosted: Thu Jan 18, 2018 9:19 am     Reply with quote

as an update to this.
Anyone else trying on this chip, there appear to be some 'discrepancies' between the chip and the data sheet. Currently investigating.
Code slightly patched, working OK on a PIC24GJGB210, but refusing to work properly on the PIC24FJ256GA702....

Joined: 11 Mar 2010
Posts: 16345

View user's profile Send private message

PostPosted: Sat Jan 20, 2018 3:49 pm     Reply with quote

As a final update.

On these chips it turns out the data to feed to the DMA is not available on ADC1BUF0. It is instead on a register called AD1RESDMA. If you define this and use it to feed the DMA routines, everything starts addressing as it should. It is listed in the data sheet, but with no reference to what it is for. The application note for the chip has the data being read from ADC1BUF0. However if you use this it 'sort of works', you don't get the proper data indexing.
You don't even have to enable PIA addressing. It is like a virtual 'window' that automatically sequences the available ADC data.
A caveat for anyone playing with this in the future...
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum

Powered by phpBB © 2001, 2005 phpBB Group