A strange problem for DMA to read the AD register(MPC5744P)

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

A strange problem for DMA to read the AD register(MPC5744P)

764 Views
778939159
Contributor I

1. The DMA is used to read the value from a AD register into a variable (i.e.ADC1_data[0])

void initTCDs_16(void) { /* Transfer string to port pin output */

DMA_0.TCD[16].SADDR.R = (vuint32_t) (&ADC_1.CDR[0].R); // TCD0_SourceData; /* Load source address*/
DMA_0.TCD[16].ATTR.B.SSIZE = 2; /* Read 2**0 = 1 byte per transfer */
DMA_0.TCD[16].ATTR.B.SMOD = 0; /* Source modulo feature not used */
DMA_0.TCD[16].SOFF.R = 4; /* After transfer add 1 to src addr*/
DMA_0.TCD[16].SLAST.R = -4; /* After major loop, reset src addr*/

DMA_0.TCD[16].DADDR.R = (vuint32_t) &ADC1_data[0]; /* Load dest. address*/
DMA_0.TCD[16].ATTR.B.DSIZE = 2; /* Write 2**0 = 1 byte per transfer*/
DMA_0.TCD[16].ATTR.B.DMOD = 0; /* Dest. modulo feature not used */
DMA_0.TCD[16].DOFF.R = 4; /* After transfer add 1 to dst addr*/
DMA_0.TCD[16].DLASTSGA.R = -4; /* After major loop no dest addr change*/

DMA_0.TCD[16].NBYTES.MLNO.R = 4; /* Transfer 1 byte per minor loop */
DMA_0.TCD[16].BITER.ELINKNO.B.ELINK = 0; /* No Enabling channel LINKing */
DMA_0.TCD[16].BITER.ELINKNO.B.BITER = 1; /* 12 major loop iterations */
DMA_0.TCD[16].CITER.ELINKNO.B.ELINK = 0; /* No Enabling channel LINKing */
DMA_0.TCD[16].CITER.ELINKNO.B.CITER = 1; /* Init. current iteraction count */

DMA_0.TCD[16].CSR.B.DREQ = 1; /* Disable channel when major loop is done*/
DMA_0.TCD[16].CSR.B.INTHALF = 0; /* No interrupt when major count half complete */
DMA_0.TCD[16].CSR.B.INTMAJOR = 0; /* No interrupt when major count completes */
DMA_0.TCD[16].CSR.B.MAJORELINK = 0; /* Dynamic program is not used */
DMA_0.TCD[16].CSR.B.MAJORLINKCH = 0; /* No link channel # used */
DMA_0.TCD[16].CSR.B.ESG = 0; /* Scatter Gather not Enabled */
DMA_0.TCD[16].CSR.B.BWC = 0; /* Default bandwidth control- no stalls */
DMA_0.TCD[16].CSR.B.START = 0; /* Initialize status flags START, DONE, ACTIVE */
DMA_0.TCD[16].CSR.B.DONE = 0;
DMA_0.TCD[16].CSR.B.ACTIVE = 0;
}

2. A large number of calibration variables (i.e 60K Bytes) are defined. The define method is shown as below. The whole programme is complied using S32DS. The DMA can't transfer the value from ADC_1.CDR[0].R  into ADC1_data[0] correctly even if I don't use the calibration variables. If the calibration variables aren't defined, the transfer is correct.

#define CAL __attribute__ ((section(".CalRefPage")))

CAL UInt32 FromBSWOvrdValSfty_C = 0

3. The cache is disabled.

void DCACHE_Invalidate(void)
{
asm("mfspr %r3,1010"); //L1CSR0
asm("e_lis %r4,0");
asm("e_or2i %r4,0xFFFE");
asm("se_and %r3,%r4");
asm("mtspr 1010,%r3"); //L1CSR0
asm("se_isync");
}

4. The RAM and FLASH configurations are shown as below. The region "cali_flash" is used for calibration data.

/* Entry Point */
ENTRY(_start)

/* define heap and stack size */
__HEAP_SIZE = 1024 ;
__STACK_SIZE = 8192 ;

SRAM_SIZE = 384K;
/* Define SRAM Base Address */
SRAM_BASE_ADDR = 0x40000000;

/* Define CPU0 Local Data SRAM Allocation */
LOCALDMEM_SIZE = 64K;
/* Define CPU0 Local Data SRAM Base Address */
/*LOCALDMEM_BASE_ADDR = 0x50800000;*/
LOCALDMEM_BASE_ADDR = 0x4002D000;
LOCALDMEM_BASE_2_ADDR = 0x50800000;

MEMORY
{
flash_rchw : org = 0x00FA0000, len = 0x4
cpu0_reset_vec : org = 0x00FA0004, len = 0x4

eeprom_flash_bsw1 : org = 0x00800000, len = 16K /*16KB,EEPROM-low block0, RWW_P:0*/
eeprom_flash_bsw2 : org = 0x00804000, len = 16K /*16KB,EEPROM-low block1, RWW_P:0*/
eeprom_flash_boot : org = 0x00808000, len = 32K /*32KB,EEPROM-mid block0, RWW_P:2*/
eeprom_flash_asw : org = 0x00810000, len = 4K /*32KB,EEPROM-mid block1, RWW_P:3*/

cali_flash : org = 0x08FB0000, len = 128K /*0x00FB_0000~0x00FC_FFFF*/

cali_bsw : org = 0x08FF0000, len = 64K /*0x00FF_0000~0x00FF_FFFF*/
m_text : org = 0x01000000, len = 2048K /*0x0100_0000~0x011F_FFFF*/

/*the whole ram address is 384K: 0x40000000~0x4005FFFF*/

m_data : org = 0x40000000, len = 180K /*384K-128K-3*4k=244K*/
eeprom_ram_bsw1 : org = 0x4003D000, len = 4K
eeprom_ram_bsw2 : org = 0x4003E000, len = 4K
eeprom_ram_asw : org = 0x4003F000, len = 4K
cali_ram : org = 0x40040000, len = 128K
/* local_dmem : org = 0x50800000, len = 64K*/
local_dmem : org = 0x4002D000, len = 64K

}


SECTIONS
{
.rchw :
{
KEEP(*(.rchw))
} > flash_rchw

.cpu0_reset_vector :
{
KEEP(*(.cpu0_reset_vector))
} > cpu0_reset_vec

.startup : ALIGN(0x400)
{
__start = . ;
*(.startup)
} > m_text

.core_exceptions_table : ALIGN(4096)
{
__IVPR_VALUE = . ;
KEEP(*(.core_exceptions_table))
} > m_text

.intc_vector_table : ALIGN(4096)
{
KEEP(*(.intc_vector_table))
} > m_text

.Cal_Section :
{
KEEP(*(.CalRefPage))
KEEP(*(.CalRefPage.*))

} > cali_flash

.Cal_bsw_Section :
{
KEEP(*(.CalRefPageBsw))
KEEP(*(.CalRefPageBsw.*))

} > cali_bsw

.text :
{
*(.text.startup)
*(.text)
*(.text.*)
KEEP (*(.init))
KEEP (*(.fini))
. = ALIGN(16);
} > m_text

.ctors :
{
__CTOR_LIST__ = .;
/* gcc uses crtbegin.o to find the start of
the constructors, so we make sure it is
first. Because this is a wildcard, it
doesn't matter if the user does not
actually link against crtbegin.o; the
linker won't look for a file to match a
wildcard. The wildcard also means that it
doesn't matter which directory crtbegin.o
is in. */
KEEP (*crtbegin.o(.ctors))
KEEP (*crtbegin?.o(.ctors))
/* We don't want to include the .ctor section from
from the crtend.o file until after the sorted ctors.
The .ctor section from the crtend file contains the
end of ctors marker and it must be last */
KEEP (*(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors))
KEEP (*(SORT(.ctors.*)))
KEEP (*(.ctors))
__CTOR_END__ = .;
} > m_text

.dtors :
{
__DTOR_LIST__ = .;
KEEP (*crtbegin.o(.dtors))
KEEP (*crtbegin?.o(.dtors))
KEEP (*(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors))
KEEP (*(SORT(.dtors.*)))
KEEP (*(.dtors))
__DTOR_END__ = .;
} > m_text

.preinit_array :
{
PROVIDE_HIDDEN (__preinit_array_start = .);
KEEP (*(.preinit_array*))
PROVIDE_HIDDEN (__preinit_array_end = .);
} > m_text

.init_array :
{
PROVIDE_HIDDEN (__init_array_start = .);
KEEP (*(SORT(.init_array.*)))
KEEP (*(.init_array*))
PROVIDE_HIDDEN (__init_array_end = .);
} > m_text

.fini_array :
{
PROVIDE_HIDDEN (__fini_array_start = .);
KEEP (*(SORT(.fini_array.*)))
KEEP (*(.fini_array*))
PROVIDE_HIDDEN (__fini_array_end = .);
} > m_text

.rodata :
{
*(.rodata)
*(.rodata.*)
} > m_text

.eh_frame_hdr : { *(.eh_frame_hdr) } > m_text
.eh_frame : { KEEP (*(.eh_frame)) } > m_text

.data :
{
*(.data)
*(.data.*)
} > m_data AT>m_text

.sdata2 :
{
*(.sdata2)
*(.sdata2.*)
} > m_data AT>m_text

.sbss2 (NOLOAD) :
{
/* _SDA2_BASE_ = .; */
*(.sbss2)
*(.sbss2.*)
} > m_data

.sdata :
{
*(.sdata)
*(.sdata.*)
} > m_data AT>m_text

.bss (NOLOAD) :
{
__BSS_START = .;
*(.sbss)
*(.sbss.*)
*(.bss)
*(.bss.*)
*(COMMON)
__BSS_END = .;
} > m_data

.stack (NOLOAD) : ALIGN(16)
{
__HEAP = . ;
PROVIDE (_end = . );
PROVIDE (end = . );
. += __HEAP_SIZE ;
__HEAP_END = . ;
_stack_end = . ;
. += __STACK_SIZE ;
_stack_addr = . ;
__SP_INIT = . ;
. += 4;
} > local_dmem

.eeprom_array :
{
KEEP(*(.eeprom_sec))
} > eeprom_ram_asw

/*-------- LABELS USED IN CODE -------------------------------*/

/* Labels for Copying Initialised Data from Flash to RAM */
__DATA_SRAM_ADDR = ADDR(.data);
__SDATA_SRAM_ADDR = ADDR(.sdata);

__DATA_SIZE = SIZEOF(.data);
__SDATA_SIZE = SIZEOF(.sdata);

__DATA_ROM_ADDR = LOADADDR(.data);
__SDATA_ROM_ADDR = LOADADDR(.sdata);

/* Labels Used for Initialising SRAM ECC */
__SRAM_SIZE = SRAM_SIZE;
__SRAM_BASE_ADDR = SRAM_BASE_ADDR;

__LOCAL_DMEM_SIZE = LOCALDMEM_SIZE;
__LOCAL_DMEM_BASE_ADDR = LOCALDMEM_BASE_ADDR;
__LOCAL_DMEM_BASE_2_ADDR = LOCALDMEM_BASE_2_ADDR;

__BSS_SIZE = __BSS_END - __BSS_START;

}

0 Kudos
3 Replies

749 Views
davidtosenovjan
NXP TechSupport
NXP TechSupport

Hi, I guess you don't have configured DMAMUX. It is also necessary to get it to run.

0 Kudos

741 Views
778939159
Contributor I

This is my dma mux, is that correct?

static void init_dma_mux()
{
/*0 1 2 3 4 5 6 7*/
/*ENBL TRIG SOURCE */
DMAMUX_0.CHCFG[0].R = 0x92; /* DMA Channel 0 enables ADC_0's DMA (slot 18 in DMAMUX_0,P205) TCD[0]*/;
DMAMUX_0.CHCFG[1].R = 0x92; /* DMA Channel 1 enables ADC_0's DMA (slot 18 in DMAMUX_0,P205) TCD[1]*/;
DMAMUX_0.CHCFG[2].R = 0x92; /*TCD[2]*/
DMAMUX_0.CHCFG[3].R = 0x92; /*TCD[3]*/
DMAMUX_0.CHCFG[4].R = 0x92; /*TCD[4]*/
DMAMUX_0.CHCFG[5].R = 0x92; /*TCD[5]*/
DMAMUX_0.CHCFG[6].R = 0x92; /*TCD[6]*/
DMAMUX_0.CHCFG[7].R = 0x92; /*TCD[7]*/
DMAMUX_0.CHCFG[8].R = 0x92; /*TCD[8]*/

DMAMUX_0.CHCFG[9].R = 0x92; /*TCD[9]*/
DMAMUX_0.CHCFG[10].R = 0x92; /*TCD[10]*/
DMAMUX_0.CHCFG[11].R = 0x92; /*TCD[11]*/
DMAMUX_0.CHCFG[12].R = 0x92; /*TCD[12]*/

DMAMUX_1.CHCFG[0].R = 0x8C; /* DMA Channel 0 enables ADC_1's DMA (slot 12 in DMAMUX_1,P205) TCD[16]*/
DMAMUX_1.CHCFG[1].R = 0x8C; /*TCD[17]*/
DMAMUX_1.CHCFG[2].R = 0x8C;
DMAMUX_1.CHCFG[3].R = 0x8C;
DMAMUX_1.CHCFG[4].R = 0x8C;
DMAMUX_1.CHCFG[5].R = 0x8C;
DMAMUX_1.CHCFG[6].R = 0x8C;
DMAMUX_1.CHCFG[7].R = 0x8C;
DMAMUX_1.CHCFG[8].R = 0x8C;
}

0 Kudos

681 Views
davidtosenovjan
NXP TechSupport
NXP TechSupport

I am apologizing for my previous response (deleted). You are correct. I confused it with another device

0 Kudos