Cannot set DMA transfersize

cancel
Showing results for 
Search instead for 
Did you mean: 

Cannot set DMA transfersize

203 Views
NXP Employee
NXP Employee
Content originally posted in LPCWare by amaury on Thu Feb 26 07:29:51 MST 2015
Hello,

I'm trying to use ADC peripheral with DMA but I can't set DMA transfersize field. I'm trying to use channel 0 of DMA and channel 1 of ADC and I'm using peripheral to memory transfertype.  (LPC1788)

All seems fine,but... in debugger i see corretly set burst, src/dst, etc bits but transfersize field is always stays zero even if just write 0x01 to Control register for test purposes. Here's the part of the code.

/*********************************************************************//**
* Macro defines for DMA channel control registers
**********************************************************************/
/** Transfer size*/
#define GPDMA_DMACCxControl_TransferSize(n) (((n&0xFFF)<<0))
/** Source burst size*/
#define GPDMA_DMACCxControl_SBSize(n)(((n&0x07)<<12))
/** Destination burst size*/
#define GPDMA_DMACCxControl_DBSize(n)(((n&0x07)<<15))
/** Source transfer width*/
#define GPDMA_DMACCxControl_SWidth(n)(((n&0x07)<<18))
/** Destination transfer width*/
#define GPDMA_DMACCxControl_DWidth(n)(((n&0x07)<<21))
/** Source increment*/
#define GPDMA_DMACCxControl_SI((1UL<<26))
/** Destination increment*/
#define GPDMA_DMACCxControl_DI((1UL<<27))
/** Indicates that the access is in user mode or privileged mode*/
#define GPDMA_DMACCxControl_Prot1((1UL<<28))
/** Indicates that the access is bufferable or not bufferable*/
#define GPDMA_DMACCxControl_Prot2((1UL<<29))
/** Indicates that the access is cacheable or not cacheable*/
#define GPDMA_DMACCxControl_Prot3((1UL<<30))
/** Terminal count interrupt enable bit */
#define GPDMA_DMACCxControl_I((1UL<<31))
/** DMA channel control registers bit mask */
#define GPDMA_DMACCxControl_BITMASK((0xFCFFFFFF))

/*********************************************************************//**
* Macro defines for DMA Channel Configuration registers
**********************************************************************/
/** DMA control enable*/
#define GPDMA_DMACCxConfig_E ((1UL<<0))
/** Source peripheral*/
#define GPDMA_DMACCxConfig_SrcPeripheral(n) (((n&0x1F)<<1))
/** Destination peripheral*/
#define GPDMA_DMACCxConfig_DestPeripheral(n) (((n&0x1F)<<6))
/** This value indicates the type of transfer*/
#define GPDMA_DMACCxConfig_TransferType(n) (((n&0x7)<<11))
/** Interrupt error mask*/
#define GPDMA_DMACCxConfig_IE ((1UL<<14))
/** Terminal count interrupt mask*/
#define GPDMA_DMACCxConfig_ITC ((1UL<<15))
/** Lock*/
#define GPDMA_DMACCxConfig_L ((1UL<<16))
/** Active*/
#define GPDMA_DMACCxConfig_A ((1UL<<17))
/** Halt*/
#define GPDMA_DMACCxConfig_H ((1UL<<18))
/** DMA Channel Configuration registers bit mask */
#define GPDMA_DMACCxConfig_BITMASK((0x7FFFF))

/** GPDMA Transfer type definitions: Peripheral to memory - DMA control */
#define GPDMA_TRANSFERTYPE_P2M ((2UL))

/** Burst size in Source and Destination definitions */
#define GPDMA_BSIZE_1 ((0UL)) /**< Burst size = 1 */
#define GPDMA_BSIZE_4 ((1UL)) /**< Burst size = 4 */
#define GPDMA_BSIZE_8 ((2UL)) /**< Burst size = 8 */
#define GPDMA_BSIZE_16 ((3UL)) /**< Burst size = 16 */
#define GPDMA_BSIZE_32 ((4UL)) /**< Burst size = 32 */
#define GPDMA_BSIZE_64 ((5UL)) /**< Burst size = 64 */
#define GPDMA_BSIZE_128 ((6UL)) /**< Burst size = 128 */
#define GPDMA_BSIZE_256 ((7UL)) /**< Burst size = 256 */

/** Width in Source transfer width and Destination transfer width definitions */
#define GPDMA_WIDTH_BYTE ((0UL)) /**< Width = 1 byte */
#define GPDMA_WIDTH_HALFWORD ((1UL)) /**< Width = 2 bytes */
#define GPDMA_WIDTH_WORD ((2UL)) /**< Width = 4 bytes */

typedef struct {
uint32_t ChannelNum; /**< DMA channel number, should be in
range from 0 to 7.
Note: DMA channel 0 has the highest priority
and DMA channel 7 the lowest priority.
*/
uint32_t TransferSize;
uint32_t TransferWidth;
uint32_t SrcMemAddr;
uint32_t DstMemAddr;
uint32_t TransferType;
uint32_t SrcConn;
uint32_t DstConn;
uint32_t DMALLI;/**< Linker List Item structure data address
if there's no Linker List, set as '0'
*/
} GPDMA_Channel_CFG_Type;


#define DMA_SIZE 1
volatile uint32_t adc_value;
GPDMA_Channel_CFG_Type GPDMAChannelConfig0
// Setup GPDMA channel --------------------------------
// channel 0
GPDMAChannelConfig0.ChannelNum = 0;
// Source memory - unused
GPDMAChannelConfig0.SrcMemAddr = 0;
// Destination memory
GPDMAChannelConfig0.DstMemAddr = (uint32_t) &adc_value;
// Transfer size
GPDMAChannelConfig0.TransferSize = DMA_SIZE;
// Transfer width - unused
GPDMAChannelConfig0.TransferWidth = 0;
//GPDMACfg->TransferWidth = GPDMA_WIDTH_HALFWORD;
// Transfer type
GPDMAChannelConfig0.TransferType = GPDMA_TRANSFERTYPE_P2M;
// Source connection
GPDMAChannelConfig0.SrcConn = GPDMA_CONN_ADC;
//GPDMACfg->SrcConn = GPDMA_CONN_ADC_DR;
// Destination connection - unused
GPDMAChannelConfig0.DstConn = 0;
// Linker List Item - unused
GPDMAChannelConfig0.DMALLI = 0;

// Reset all channel configuration register
LPC_GPDMACH0->CConfig=0;
LPC_GPDMACH1->CConfig=0;
LPC_GPDMACH2->CConfig=0;
LPC_GPDMACH3->CConfig=0;
LPC_GPDMACH4->CConfig=0;
LPC_GPDMACH5->CConfig=0;
LPC_GPDMACH6->CConfig=0;
LPC_GPDMACH7->CConfig=0;

// Clear all DMA interupt and error flag

LPC_GPDMA->IntTCClear=0xFF;
LPC_GPDMA->IntErrClr=0xFF;

// Reset the Interrupt status
LPC_GPDMA->IntTCClear = (((1UL<<0)&0xFF));
        LPC_GPDMA->IntErrClr     = (((1UL<<0)&0xFF));

// Clear DMA configure
       LPC_GPDMACH0->CControl=0x00;
       LPC_GPDMACH0->CConfig=0x00;

/* Assign Linker List Item value */
        LPC_GPDMACH0->CLLI=0x00;

// Assign peripheral source address
        LPC_GPDMACH0->CSrcAddr=(&LPC_ADC->GDR);
        LPC_GPDMACH0->CDestAddr=GPDMAChannelConfig0.DstMemAddr;

          LPC_GPDMACH0->CControl =
                                                          GPDMA_DMACCxControl_TransferSize((uint32_t)DMA_SIZE) \
                                                          | GPDMA_DMACCxControl_SBSize((uint32_t)GPDMA_BSIZE_1) \
                                                          | GPDMA_DMACCxControl_DBSize((uint32_t)GPDMA_BSIZE_1) \
                                                          | GPDMA_DMACCxControl_SWidth((uint32_t)GPDMA_WIDTH_WORD) \
                                                          | GPDMA_DMACCxControl_DWidth((uint32_t)GPDMA_WIDTH_WORD) \
                                                          | GPDMA_DMACCxControl_DI \
                                                          | GPDMA_DMACCxControl_I;

         LPC_SC->DMAREQSEL &= ~(1<<(0));


/* Enable DMA channels, little endian */
LPC_GPDMA->Config = GPDMA_DMACConfig_E;
while (!(LPC_GPDMA->Config & GPDMA_DMACConfig_E));


// Calculate absolute value for Connection number
tmp1 = GPDMAChannelConfig->SrcConn;
tmp1 = ((tmp1 > 15) ? (tmp1 - 16) : tmp1);
tmp2 = GPDMAChannelConfig->DstConn;
tmp2 = ((tmp2 > 15) ? (tmp2 - 16) : tmp2);

// Configure DMA Channel, enable Error Counter and Terminate counter
LPC_GPDMACH0->CConfig = GPDMA_DMACCxConfig_IE
                |  GPDMA_DMACCxConfig_ITC /*| GPDMA_DMACCxConfig_E*/ \
| GPDMA_DMACCxConfig_TransferType((uint32_t)GPDMAChannelConfig->TransferType) \
| GPDMA_DMACCxConfig_SrcPeripheral(tmp1) \
| GPDMA_DMACCxConfig_DestPeripheral(tmp2);

                                                          
       What am i doing wrong?thanks

0 Kudos
1 Reply

78 Views
NXP Employee
NXP Employee
Content originally posted in LPCWare by Superfred on Fri Feb 27 00:03:46 MST 2015
Hello amaury,

here is my working DMA code for  GPIO to memory transfer triggered by Timer1, maybe it helps.

volatile unsigned int BlockSize = 0x0FFF; 

void DMA_Init( void )
{
/* Enable CLOCK into GPDMA controller */
LPC_SC->PCONP |= (1 << 29);

/* Select secondary function(Timer) in DMA channels */
LPC_SC->DMAREQSEL = 0xFF;

/* Clear DMA channel 0~3 interrupts. */
LPC_GPDMA->DMACIntTCClear = 0x0F;
LPC_GPDMA->DMACIntErrClr = 0x0F;

LPC_GPDMA->DMACConfig = 0x01;/* Enable DMA channels, little endian */
while ( !(LPC_GPDMA->DMACConfig & 0x01) );

NVIC_SetPriority(DMA_IRQn, 30);
NVIC_EnableIRQ(DMA_IRQn);
}

void StartDma(void)
{
LPC_GPDMACH0->DMACCSrcAddr = (uint32_t) &LPC_GPIO2->FIOPIN;
LPC_GPDMACH0->DMACCDestAddr = (uintptr_t) CameraBuffer1;
LPC_GPDMACH0->DMACCControl = (BlockSize & 0x0FFF)|0x88408000;
LPC_GPDMACH0->DMACCLLI = 0;
LPC_GPDMACH0->DMACCConfig = 0x0000D015;

LPC_GPDMA->DMACIntTCClear = 0x01<<0;
LPC_GPDMA->DMACIntErrClr = 0x01<<0;
LPC_TIM1->IR = 1;/* clear Timer interrupt flag */
}

void DMA_IRQHandler(void)
{
uint32_t regVal;
regVal = LPC_GPDMA->DMACIntTCStat;
if ( regVal )
{
LPC_GPDMA->DMACIntTCClear = regVal;
if ( regVal & (0x01<<0) )
{
//DmaTerminalInterrupt code here
}
}

regVal = LPC_GPDMA->DMACIntErrStat;
if ( regVal )
{
LPC_GPDMA->DMACIntErrClr = regVal;
}
}



Fred
0 Kudos