examples of ADC to DMA in a mikroC project

Beta Testing discussion on mikroC PRO for dsPIC30/33 and PIC24.
Post Reply
Author
Message
orkidelolo
Posts: 12
Joined: 08 Nov 2016 17:22

examples of ADC to DMA in a mikroC project

#1 Post by orkidelolo » 20 Dec 2016 07:56

Hi everyone
I am using DSPIC33FJ256MC710-I/PT and I try to scan 2 ADC pins (AN22, AN23 )simultaneously. I want to use DMA for ADC sampling and I read a lot of document about it in Microchip but I have problem how to read from DMA buffer.
in the Microchip documentation , I face some codes that they are not cleared in MikroC pro for dspic like:
__eds__ int bufferA[NUMSAMP] __attribute__( (eds, space(dma)) );
__eds__ int bufferB[NUMSAMP] __attribute__( (eds, space(dma)) );
#else
int bufferA[NUMSAMP] __attribute__( (space(xmemory)) );
int bufferB[NUMSAMP] __attribute__( (space(xmemory)) );
#endif
void ProcessADCSamples( __eds__ int *adcBuffer );

void ProcessADCSamples( __eds__ int *adcBuffer )
{
/* Do something with ADC Samples */
}

void __attribute__ ( (interrupt, auto_psv) ) _DMA0Interrupt( void )

DMA0STAL = __builtin_dmaoffset( &bufferA );
DMA0STAH = __builtin_dmapage( &bufferA );

DMA0STBL = __builtin_dmaoffset( &bufferB );
DMA0STBH = __builtin_dmapage( &bufferB );

How to convert this codes from MPLAB to MikroC pro for dspic??
I read some topics in this forum about how to read DMA register like :
viewtopic.php?f=101&t=23974
but it is not clear for me :(
could you please help me how to read from DMA register and what is the DMA address?
in my dspic
DMA_START_ADDRESS = 0x7800;

Are there any examples of ADC to DMA in a mikroC project ?

please help me

thank you in advance
best regards

User avatar
uros.cvetinovic
mikroElektronika team
Posts: 803
Joined: 14 Dec 2015 09:24

Re: examples of ADC to DMA in a mikroC project

#2 Post by uros.cvetinovic » 20 Dec 2016 16:06

Hi,

Unfortunately, we don't have library, nor any example regarding DMA.

I can suggest you to check this document, DMA is well described there:
http://ww1.microchip.com/downloads/en/D ... 70182C.pdf

Use MCU's registers for accessing DMA.

Best regards,

Uros

orkidelolo
Posts: 12
Joined: 08 Nov 2016 17:22

Re: examples of ADC to DMA in a mikroC project

#3 Post by orkidelolo » 20 Dec 2016 17:27

Hi
thank you so much Uros because of your attention and helpful link
I read the document but Sorry I am new in dspic and I have question
I write the code but I have some problems that I cannot the show DMA value on the LCD screen
I mean I do not know how to read DMA register (which register I have to read) and show them on LCD
could you please or anybody help me
thank you so much in advance
/// Setup of LCD////
sbit LCD_RS at LATF8_bit;
sbit LCD_EN at LATD3_bit;
sbit LCD_D4 at LATC13_bit;
sbit LCD_D5 at LATD0_bit;
sbit LCD_D6 at LATD2_bit;
sbit LCD_D7 at LATF7_bit;

sbit LCD_RS_Direction at TRISF8_bit;
sbit LCD_EN_Direction at TRISD3_bit;
sbit LCD_D4_Direction at TRISC13_bit;
sbit LCD_D5_Direction at TRISD0_bit;
sbit LCD_D6_Direction at TRISD2_bit;
sbit LCD_D7_Direction at TRISF7_bit;

dma unsigned int dma_bufferA[24][4] absolute 0x7800;;//Offset 0 DMA_START_ADDRESS = 0x4000;
dma unsigned int dma_bufferB[24][4] absolute 0x7808;//Offset 8
void InitADC(){
////// ADC config/////
AD1CON1bits.FORM = 0; // Data Output Format: UnSigned Integer
AD1CON1bits.SSRC = 7; // Internal counter ends sampling and starts conversion (auto-convert)
AD1CON1bits.ASAM = 0; // Sampling begins when SAMP bit is set (for now)
AD1CON1bits.AD12B = 1; // 12-bit ADC operation
AD1CON1bits.ADDMABM = 0; // DMA buffers are built in scatter/gather mode

AD1CON2bits.VCFG=0; //Vref+=AVDD Vref-=AVSS//
AD1CON2bits.SMPI = 1; // (NUM_CHS2SCAN-1); // 2 ADC Channel is scanned
AD1CON2bits.CHPS = 0; /* Converts CH0/CH1 When AD12B = 1, CHPS<1:0> is: U-0, Unimplemented, Read as ‘0’*/
AD1CON2bits.CSCNA=1; //Scan inputs // Scan Input Selections for CH0+ during Sample A bit
AD1CON3bits.ADRC = 0; // ADC Clock is derived from Systems Clock
AD1CON3bits.SAMC = 2; // Auto Sample Time = 2*Tad
AD1CON3bits.ADCS = 3; //for 500 Khz sampling in 12-bit 1/500KHz=2*10^-6=200 ns
//200ns=14Tad-->Tad=142ns---> ADCS+1=40M*142ns=5.71--> ADCS=~4
AD1CON4bits.DMABL = 2; // Each buffer contains 4 words

//AD1CSSH/AD1CSSL: A/D Input Scan Selection Register

AD1CHS0bits.CH0NB = 0; // MUXA -ve input selection (Vref-) for CH0


AD1CSSH.CSS17=1; // Enable AN17 for channel scan
AD1CSSH.CSS18=1; // Enable AN18 for channel scan
AD1CSSL=0; //ADC1 INPUT SCAN SELECT REGISTER Low

IFS0bits.AD1IF = 0; // Clear the A/D interrupt flag bit
IEC0bits.AD1IE = 0; // Do Not Enable A/D interrupt
AD1CON1bits.ADON = 1; // Turn on the A/D converter
}

// DMA0 configuration
// Direction: Read from peripheral address 0-x300 (ADC1BUF0) and write to DMA RAM
// AMODE: Peripheral Indirect Addressing Mode
// MODE: Continuous, Ping-Pong Mode
// IRQ: ADC Interrupt

void initDma0(void)
{
DMA0CONbits.AMODE = 2; // Configure DMA for Peripheral indirect mode
DMA0CONbits.MODE = 2; // Configure DMA for Continuous Ping-Pong mode
DMA0PAD=(int)&ADC1BUF0;
DMA0CNT = 7; //(SAMP_BUFF_SIZE*NUM_CHS2SCAN)-1;
DMA0REQ = 13; // Select ADC1 as DMA Request source

// DMA0STA = __builtin_dmaoffset(BufferA);
// DMA0STB = __builtin_dmaoffset(BufferB);
DMA5STA = &dma_bufferA;
DMA5STB = &dma_bufferB;
IFS0bits.DMA0IF = 0; //Clear the DMA interrupt flag bit
IEC0bits.DMA0IE = 1; //Set the DMA interrupt enable bit

DMA0CONbits.CHEN=1; // Enable DMA

}
/*=============================================================================
_DMA0Interrupt(): ISR name is chosen from the device linker script.
=============================================================================*/
unsigned int DmaBuffer = 0;
int flag = 0;

void __attribute__((interrupt, no_auto_psv)) _DMA0Interrupt(void)
{

DmaBuffer ^= 1;

flag = 1;

IFS0bits.DMA0IF = 0; //Clear the DMA0 Interrupt Flag

}


void main() {
//AD1PCFGH/AD1PCFGL: Port Configuration Register
AD1PCFGL=0xFFFF;
AD1PCFGH=0xFFFF;
AD1PCFGHbits.PCFG17 = 0; // AN17 as Analog Input
AD1PCFGHbits.PCFG18 = 0; // AN18 as Analog Input

PORTA=0;
TRISA.F6= 1;
TRISA.F7= 1;
TRISF.F4= 0;
TRISF.F5= 0;
TRISB.F12= 0;
TRISB.F13= 0;
TRISC.F2= 1; // AN17
TRISC.F3= 1; // AN18

///////////////PLL configue////////
// Configure Oscillator to operate the device at 40Mhz
// Fosc= Fin*M/(N1*N2), Fcy=Fosc/2
// Fosc= 8M*40/(2*2)=80Mhz for 8M input clock
OSCCONbits.COSC=0x03; //0b 011 Primary oscillator (XT, HS, EC) with PLL
OSCCONbits.OSWEN=0x1; //
CLKDIVbits.PLLPRE=0; // N1=2 N1=PLLPRE+2
CLKDIVbits.PLLPOST=0; // N2=2 N2=2*(PLLPost+1)
PLLFBDbits.PLLDIV=38; // M=40 M=PLLDIV+2

////////////// Disable Watch Dog Timer////////
RCONbits.SWDTEN=0; // Disable Watch Dog Timer
/////////////////

Lcd_init(); // Initialize LCD
Lcd_Cmd(_LCD_CLEAR); // CLEAR display
Lcd_Cmd(_LCD_CURSOR_OFF); // Cursor off
Lcd_Out(1,1,"Hello");
delay_ms(1000);
Lcd_Cmd(_LCD_CLEAR); // CLEAR display
InitDma0(); // Initialise the DMA controller to buffer ADC data in conversion order
InitAdc1(); // Initialize the A/D converter to convert Channel 5
while(1){
Delay_ms(50);

LATF.F4=0;
LATF.F5=1;
LATB.F12=0;
LATB.F13=1;
delay_ms(50);
LATF.F4=1;
LATF.F5=0;
LATB.F12=1;
LATB.F13=0;
}

}

User avatar
uros.cvetinovic
mikroElektronika team
Posts: 803
Joined: 14 Dec 2015 09:24

Re: examples of ADC to DMA in a mikroC project

#4 Post by uros.cvetinovic » 21 Dec 2016 12:48

Hi,

Unfortunately, user's projects are out of scope of technical support.

I can suggest you to check reference manual that I gave you in details.

Can you also tell me if you have any problem regarding communication with LCD itself regardless of DMA?

Best regards,

Uros

orkidelolo
Posts: 12
Joined: 08 Nov 2016 17:22

Re: examples of ADC to DMA in a mikroC project

#5 Post by orkidelolo » 21 Dec 2016 13:40

Hi Dear Uros
you are right
thank you for your help
when I want to scan one ADC pin, I have no problem and I can get good result and show it on LCD without any problem
my problem is how to use DMA for 2 Pins :(

Post Reply

Return to “mikroC PRO for dsPIC30/33 and PIC24 Beta Testing”