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 support@ccsinfo.com

ADC / DMA / dsPIC33FJ128MC706

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



Joined: 09 May 2019
Posts: 24

View user's profile Send private message

ADC / DMA / dsPIC33FJ128MC706
PostPosted: Mon Sep 02, 2019 1:37 am     Reply with quote

On an existing application the ADC sampling of five channels is done
in "scatter / gather mode" with 50KHz. The associated
DMA interrupt routine eats 50% of processor time!

I want to modify the application - in the end I want convert the five
AD channels in "conversion order mode" eight times before the DMA
interrupt routine will process them with 6.25KHz.

In a first step, I wanted want to convert the five AD channels once
in "conversion order mode", before they are processed in the
DMA interrupt routine still with 50kHz, but not even that works.

It seems, that the same AD channel is converted five times (picture left
"conversion order mode", right picture "scatter / gather mode").

Does anyone have a tip, what I'm doing wrong (on the internet I can
find only "conversion order mode" examples converting a single channel
several times) ? Or do I understand the datasheet wrong and
the controller doesn't support converting multiple AD channels in
"conversion order mode"?

Ttelmah



Joined: 11 Mar 2010
Posts: 19215

View user's profile Send private message

PostPosted: Mon Sep 02, 2019 2:10 am     Reply with quote

It's not clear from what you post, where you are telling the DMA to fetch
the value 'from'?. I found this was what caused issues. You have to set the
DMA to fetch it's results from the register ADC1RESDMA to get the correct
figures. It is this register that sequentially is loaded with the ADC results.

So:
Code:

#word DMAADC=getenv("SFR:AD1RESDMA")

//and for 'one shot', rather than ping_pong, using 132 byte buffer
   setup_dma(0, DMA_TRIGGER_ADC1, DMA_WORD); // | DMA_RELOAD_ADDRESS);
   dma_start(0, DMA_ONE_SHOT | DMA_INC_DEST_ADDR , DMA_BUFFER , &DMAADC, 132); //2*34



You seem not to be using the CCS DMA functions?.

In fact looking at what you have posted, the register names you are
using are the MicroChip values. You do realise this is a forum for CCS C,
not a generic 'PIC' forum?. If you are using MicroChip C, you need to be
asking your question on the MicroChip forum, not here.
ulg



Joined: 09 May 2019
Posts: 24

View user's profile Send private message

PostPosted: Mon Sep 02, 2019 4:55 am     Reply with quote

The value 'from' is configured in line 175:

DMA0PAD = (int)&ADC1BUF0;

Because I have to work with both, CCS & Microchip C, I wasn't aware. that
I have translated my problem from German to English for a CCS forum - sorry.
When I relized this, I have had the hope, I will get hints to solve it also
from people ready to help in a CCS forum, as the problem seems to be a
hardware specific, not a Microchip C specific (right side with "scatter/gather
mode" will work).
Ttelmah



Joined: 11 Mar 2010
Posts: 19215

View user's profile Send private message

PostPosted: Mon Sep 02, 2019 5:02 am     Reply with quote

My answer applies to the problem. ADCBUF1, is _not_ the right register.

You have to use the ADC1RESDMA register. Otherwise you won't get
the correct increment of the channel.

It is not well explained in the chip data sheet. It looks as if you should use
the ADC buffer, but you don't....
ulg



Joined: 09 May 2019
Posts: 24

View user's profile Send private message

PostPosted: Mon Sep 02, 2019 5:22 am     Reply with quote

I'm confused, because whether MPLAB nor the datasheet know about ADC1RESDMA (or ADC1RES*) !?

In the datasheet I found:
"3. On devices with a DMA module, the ADC
module has only 1 ADC result buffer, (i.e.,
ADC1BUF0), per ADC peripheral and the ADC
conversion result must be read either by the
CPU or DMA controller before the next ADC
conversion is complete to avoid overwriting the
previous value."
Ttelmah



Joined: 11 Mar 2010
Posts: 19215

View user's profile Send private message

PostPosted: Mon Sep 02, 2019 6:34 am     Reply with quote

Being 'hardware specific', makes it even less applicable to this forum.
As I said, 'this is a forum for issues with CCS C'. Not a generic 'PIC' forum.

Now the AD1RESDMA solution, was one I was given by MicroChip, when I
was having an issue on another chip with DMA, where it continuously
returned the value from the first analog channel, and they said to access
this register for DMA, not the buffer register (though the data sheet said
to access the buffer register). Probably does not apply to your chip.

You do not seem to be setting the ALTS, or BUFM bits in the ADC
configuration. These affect the order the values are allocated to the
buffer.

You also have to increment the address whichever mode you are using.
Otherwise you are always only reading the result from the first channel.

If you want ot access AN0 to AN8 without using scatter/gather, you would
need to use 9 readings. With scatter/gather, just 5.
ulg



Joined: 09 May 2019
Posts: 24

View user's profile Send private message

PostPosted: Mon Sep 02, 2019 9:31 am     Reply with quote

As I understood the datasheet, I can fill with "conversion order mode" a one dimensional DMA buffer with the first sample sequence of the five channels, I have enabled to scan, then the second sample sequence, the third, the fourth, ...

Code:

Name         type      Value
Buffer1A     int[40]
Buffer1A[0]  int       AN0_Sample0
Buffer1A[1]  int       AN1_Sample0
Buffer1A[2]  int       AN3_Sample0
Buffer1A[3]  int       AN4_Sample0
Buffer1A[4]  int       AN8_Sample0
Buffer1A[5]  int       AN0_Sample1
Buffer1A[6]  int       AN1_Sample1
Buffer1A[7]  int       AN3_Sample1
Buffer1A[8]  int       AN4_Sample1
Buffer1A[9]  int       AN8_Sample1
Buffer1A[10] int       AN0_Sample2
Buffer1A[11] int       AN1_Sample2
Buffer1A[12] int       AN3_Sample2
Buffer1A[13] int       AN4_Sample2
Buffer1A[14] int       AN8_Sample2
Buffer1A[15] int       AN0_Sample3
Buffer1A[16] int       AN1_Sample3
Buffer1A[17] int       AN3_Sample3
Buffer1A[18] int       AN4_Sample3
Buffer1A[19] int       AN8_Sample3
Buffer1A[20] int       AN0_Sample4
Buffer1A[21] int       AN1_Sample4
Buffer1A[22] int       AN3_Sample4
Buffer1A[23] int       AN4_Sample4
Buffer1A[24] int       AN8_Sample4
Buffer1A[25] int       AN0_Sample5
Buffer1A[26] int       AN1_Sample5
Buffer1A[27] int       AN3_Sample5
Buffer1A[28] int       AN4_Sample5
Buffer1A[29] int       AN8_Sample5
Buffer1A[30] int       AN0_Sample6
Buffer1A[31] int       AN1_Sample6
Buffer1A[32] int       AN3_Sample6
Buffer1A[33] int       AN4_Sample6
Buffer1A[34] int       AN8_Sample6
Buffer1A[35] int       AN0_Sample7
Buffer1A[36] int       AN1_Sample7
Buffer1A[37] int       AN3_Sample7
Buffer1A[38] int       AN4_Sample7
Buffer1A[39] int       AN8_Sample7


Maybe I have misinterpreted the datasheet!?
Ttelmah



Joined: 11 Mar 2010
Posts: 19215

View user's profile Send private message

PostPosted: Mon Sep 02, 2019 10:46 am     Reply with quote

If build mode is set to 1, the results in the buffer are built in channel
order, not the enabled order. So you will have big gaps in the data. So with
your example, you will get AN0, AN1, gap, AN3, AN4, gap, gap gap, AN8.
and you will need to take 9 readings, to get a complete 'set'.
You will need to configure 9 readings for each loop, or the counter
resets to the first channel.
ulg



Joined: 09 May 2019
Posts: 24

View user's profile Send private message

PostPosted: Wed Sep 04, 2019 12:14 am     Reply with quote

Problem solved!

Under "Register 16-2: ADxCON2: ADCx Control Register 2" one can find:

Code:

bit 5-2 SMPI<3:0>: Sample and Conversion Operation bits (1,2)
    For devices with DMA:
    1111 = Increments the DMA address after completion of every 16th sample/conversion operation
    1110 = Increments the DMA address after completion of every 15th sample/conversion operation
    .
    .
    .
    0001 = Increments the DMA address after completion of every 2nd sample/conversion operation
    0000 = Increments the DMA address after completion of every sample/conversion operation


Consistent with this seems to be, what one can find in Microchip's examples with "conversion order mode" - "SMPI must be 0" - as you would like, that the next conversion result will be stored one int16 behind the last one..

Code:

    AD1CON2bits.SMPI    = 0;  // SMPI must be 0



That's wrong - SMPI must be set equal to the number of inputs to scan minus 1!

Code:

    AD1CON2bits.SMPI    = NumberOfInputsToScan - 1;


Because under "16.4.6.2 SMPI FOR DEVICES WITH DMA" one can find:

Code:

When channel scanning is used (and Alternate Input Selection mode is disabled), the SMPI<3:0>
bits should be set to the number of inputs being scanned minus one (i.e., SMPI<3:0> = N - 1).


Now all five channels will be scanned.

https://www.mikrocontroller.net/attachment/427929/ADC1values1Dgood.png

In addition, if the DMA is programmed to collect the results of eight such scan sequences, one obtains a DMA interrupt after every 40 conversions, which then occur at an interrupt frequency of 6.25 kHz.

https://www.mikrocontroller.net/attachment/427930/ADC1values1D40_1.png

Thx for your willingness to help.
Ttelmah



Joined: 11 Mar 2010
Posts: 19215

View user's profile Send private message

PostPosted: Wed Sep 04, 2019 7:23 am     Reply with quote

As I said.

Yes, the SMPI setting is awfully documented, but if you look at their
own examples, you will see they set it to handle the number of channels
that have to be sampled. The key is that when this triggers, it sets the
internal counter used to handle the offsets used for the channels back to 0.
So with it set to zero, you only ever sample the first channel....
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