View previous topic :: View next topic |
Author |
Message |
m4k
Joined: 27 Mar 2018 Posts: 29
|
builtin_dmaoffset function |
Posted: Wed Apr 15, 2020 12:11 am |
|
|
Hi CCS forum
I want to config dma on dspic33f and i use Microchip example code for learning.
Code: | // Align the buffer to 128 words or 256 bytes. This is needed for peripheral indirect mode
unsigned int BufferA[4] __attribute__((space(dma))); |
Code: |
void InitDMA0(void)
{
DMA0CONbits.CHEN = 0; //Channel disabled
DMA0CONbits.SIZE = 0; //Data tranfer size:Word
DMA0CONbits.DIR = 0; //Read from peripheral address
DMA0CONbits.HALF = 0; //Initiate block transfer complete interrupt
//when all of the data has been moved
DMA0CONbits.NULLW = 0;//Normal Operation
DMA0CONbits.AMODE = 0;//Configure DMA for Peripheral indirect mode
DMA0CONbits.MODE = 0; //Continuous, Ping-Pong modes disabled
DMA0REQ = 13; //Automatic DMA transfer initiation by DMA request
//Select ADC1 as DMA Request source
DMA0PAD =(int)&ADC1BUF0;
DMA0CNT = 3; //4 transfers
DMA0STA = __builtin_dmaoffset(BufferA);
IPC1bits.DMA0IP = 5;
IFS0bits.DMA0IF = 0; //Clear the DMA interrupt flag bit
IEC0bits.DMA0IE = 1; //Set the DMA interrupt enable bit
DMA0CONbits.CHEN=1; // Enable DMA
}
|
But I don't understand this part:
Code: | __builtin_dmaoffset(BufferA); |
What does this function to do and what is the equivalent in CCS ?
tnx
best regard
m4k |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19492
|
|
Posted: Wed Apr 15, 2020 12:54 am |
|
|
With CCS, you setup the ram buffer for DMA, using the command
#bank_dma, followed by a variable declaration for the buffer you
require.
If using peripheral indirect addressing, this buffer must start on the
RAM boundary needed by the peripheral involved (so for instance on the
ADC, typically a 128word boundary). This is done using the __attribute__
command. So:
Code: |
#bank_dma byte buffer[256] __attribute__((aligned(0x100)));
|
Sets up 'buffer' as a 256 byte space aligned to a 256 byte boundary
inside the DMA RAM space. Alignment counts are in bytes.
By default the space always starts on a boundary, so the first buffer
declared will have the required alignment, but you need to use the
aligned declaration if you have multiple buffers. |
|
|
m4k
Joined: 27 Mar 2018 Posts: 29
|
|
Posted: Wed Apr 15, 2020 3:16 am |
|
|
Ttelmah wrote: | With CCS, you setup the ram buffer for DMA, using the command
#bank_dma, followed by a variable declaration for the buffer you
require.
If using peripheral indirect addressing, this buffer must start on the
RAM boundary needed by the peripheral involved (so for instance on the
ADC, typically a 128word boundary). This is done using the __attribute__
command. So:
Code: |
#bank_dma byte buffer[256] __attribute__((aligned(0x100)));
|
Sets up 'buffer' as a 256 byte space aligned to a 256byte boundary
inside the DMA RAM space. Alignment counts are in bytes.
By default the space always starts on a boundary, so the first buffer
declared will have the required alignment, but you need to use the
aligned declaration if you have multiple buffers. |
Thats right. The 4 adc channel simultaneous sampling and buffer in to dma module and when sampling completely the dma interrupt.
According to datasheet this line is the number of channel buffering:
Code: | DMA0CNT = 3; //4 transfers
|
and this line is refer to adc one channel buffer:
Code: | DMA0PAD =(int)&ADC1BUF0; |
But I do not understand completely this line:
Code: | __builtin_dmaoffset();
|
What does this function do?
Can you explain more or example in ccs function? |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19492
|
|
Posted: Wed Apr 15, 2020 4:02 am |
|
|
No.
You don't assign separate buffers. You assign a single buffer for the DMA
channel, and then structure this to suit the device.
If each ADC channel is set to use 8 word buffers, you would do something like:
Code: |
#bank_dma struct {
unsigned int16[8] CH0;
unsigned int16[8] CH1;
unsigned int16[8] CH2;
unsigned int16[8] CH3;
} ADC_BUFF __attribute__((aligned(0x100)));
|
Then ADC_BUFF.CH0 is the 8 word buffer used by channel 0 etc.
The actual sizes etc., depend on the number of channels you are enabling
and how many words each is assigned to use. |
|
|
jeremiah
Joined: 20 Jul 2010 Posts: 1344
|
|
Posted: Wed Apr 15, 2020 6:34 am |
|
|
m4k wrote: |
but I do not understand completely this line:
Code: | __builtin_dmaoffset();
|
What does this function do?
Can you explain more or example in ccs function? |
m4k,
__builtin_dmaoffset() is a Microchip XC16 function, not a CCS PCD function, so not many here are going to know what it means. For a full description, you would want to ask on the Microchip forums and maybe look at the XC16 manual. Offhand, maybe someone here is versed in XC16 and can help you, but it is a long shot.
Just looking at the code you are providing, the name of the function implies to me that it represents an offset relative to the start of the DMA bank (so sort of a relative address), but again, I am not versed in XC16, so you should really use the datasheet for that compiler to verify. Microchip provides both forums and manuals for its compiler to help better understand these type of things.
Now on the CCS side, Ttelmah already showed you how to set it up. You don't need the __builtin_dmaoffset() because CCS does it a different way (through the combination of the #bank_dma and aligned annotations that Ttelmah showed you). Those handle a lot of the stuff you are trying to manually do. |
|
|
m4k
Joined: 27 Mar 2018 Posts: 29
|
|
Posted: Wed Apr 15, 2020 12:35 pm |
|
|
Ttelmah wrote: | No.
You don't assign separate buffers. You assign a single buffer for the DMA
channel, and then structure this to suit the device.
If each ADC channel is set to use 8 word buffers, you would do something like:
Code: |
#bank_dma struct {
unsigned int16[8] CH0;
unsigned int16[8] CH1;
unsigned int16[8] CH2;
unsigned int16[8] CH3;
} ADC_BUFF __attribute__((aligned(0x100)));
|
Then ADC_BUFF.CH0 is the 8 word buffer used by channel 0 etc.
The actual sizes etc., depend on the number of channels you are enabling
and how many words each is assigned to use. |
tnx alot Ttelmah. i try it. |
|
|
|