Post Go back to editing

BF706 EPPI and Parallel ADC DMA illegal memory access issue.

Hi , Can you please help with the following issue .

 1) Using a parallel ADC9609 with ADSPBF706 EPPI channel 0

2) Configured DMA descriptor list mode  with two buffers of size 1250 samples each ( Ping Pong buffer approach)

3) ADC sends data at 5MHz.

4) while one buffer is getting filled , I am processing another buffer .

5) I am getting the following  error and code stops executing.

A non-recoverable error or exception has occurred.

Description: An illegal data memory access has occurred.

General Type: RunTimeError

Specific Type: DCPLBProtectionViolation

Error PC: 0x11a01380

I tried reaching out to our designated application engineer and he asked me to through ez.analog.com.

I have the following questions

  a) When the buffer full interrupt is received , the descriptor will point to the second buffer . How to pick which buffer to process in Ping-Pong buffer approach

b) How can I ensure DSP core will not access the buffer that is under DMA control . I am assuming the above error occurred because some where in the code executing I am accessing the buffer that is getting filled by DMA.

  • #include <sys/platform.h>
    #include <stdint.h>
    #include <services/int/adi_int.h>
    
    #include "Definitions.h"
    #include "Prototypes.h"
    #include "Macros.h"
    #include "spiLink.h"
    #include "EPPI_Common.h"
    
    
    int16_t	EPPI_Data_BUFF_PING[BUFF_SIZE];
    int16_t	EPPI_Data_BUFF_PONG[BUFF_SIZE];
    int16_t *p_EPPI_Data_BUFF_PING = &EPPI_Data_BUFF_PING[0] ;
    int16_t *p_EPPI_Data_BUFF_PONG = &EPPI_Data_BUFF_PONG[0] ;
    uint8_t	SetRxProcBuf;
    
    uint16_t high_ping = 0;
    uint16_t low_ping = 0;
    uint16_t tsh_ping = 0;
    uint16_t high_pong = 0;
    uint16_t low_pong = 0;
    uint16_t tsh_pong = 0;
    uint8_t ping_count = 0;
    uint8_t pong_count = 0;
    
    
    
    
    
    // This is for Half Scale ( 1V P-P)
    #define POS_TSH_150mV	0x04CC	//+150 mV
    #define POS_SIG_500mV	0x1000  //500mV
    #define POS_SIG_MAX		0x1FFF	//+1000mV(0x0FF0)
    
    int16_t const  pos_tsh_150mv = POS_TSH_150mV;
    int16_t const  pos_sig_500mv = POS_SIG_500mV;
    int16_t const  pos_sig_max = POS_SIG_MAX;
    
    #define NEG_TSH_150mV	0x3B30	//-150 mV
    #define NEG_SIG_500mV	0x3000	//-500 mV
    #define NEG_SIG_MAX		0x2000	//-1000mV
    
    int16_t const  neg_tsh_150mv = NEG_TSH_150mV;
    int16_t const  neg_sig_500mv = NEG_SIG_500mV;
    int16_t const  neg_sig_max = NEG_SIG_MAX;
    
    
    #pragma align 32
    dma_desc DescBuffer1;
    #pragma align 32
    dma_desc DescBuffer2;
    
    void Configure_Ping_Pong_Buffers(void)
    {
    	uint32_t Dma_CFG;
    
    	Dma_CFG = (		ENUM_DMA_CFG_EN			|ENUM_DMA_CFG_WRITE		|ENUM_DMA_CFG_NO_SYNC	|ENUM_DMA_CFG_LD_STARTADDR	|ENUM_DMA_CFG_PSIZE02		|
    					ENUM_DMA_CFG_MSIZE02	|ENUM_DMA_CFG_DSCLIST	|ENUM_DMA_CFG_NO_TRGWAIT|ENUM_DMA_CFG_FETCH07		|ENUM_DMA_CFG_XCNT_INT		|
    					ENUM_DMA_CFG_NO_TRIG	|ENUM_DMA_CFG_TOV_DIS	|ENUM_DMA_CFG_NO_COPY	|ENUM_DMA_CFG_ADDR1D		|ENUM_DMA_CFG_PDAT_NOTFWD
    				 );
    
    	// Init First DMA Link Descriptor
    	DescBuffer1.DMA_DSCPTR_NXT = (void*)&DescBuffer2;
    	DescBuffer1.DMA_ADDRSTART = (void*)p_EPPI_Data_BUFF_PING;
    	DescBuffer1.DMA_CFG = Dma_CFG;
    	DescBuffer1.DMA_XCNT = BUFF_SIZE;
    	DescBuffer1.DMA_XMOD = 0x02;
    	DescBuffer1.DMA_YCNT = 0x00;
    	DescBuffer1.DMA_YMOD = 0x00;
    
    	// Init Second DMA Link Descriptor
    	DescBuffer2.DMA_DSCPTR_NXT = (void*)&DescBuffer1;
    	DescBuffer2.DMA_ADDRSTART = (void*)p_EPPI_Data_BUFF_PONG;
    	DescBuffer2.DMA_XCNT = BUFF_SIZE;
    	DescBuffer2.DMA_CFG = Dma_CFG;
    	DescBuffer2.DMA_XMOD = 0x02;
    	DescBuffer2.DMA_YCNT = 0x00;
    	DescBuffer2.DMA_YMOD = 0x00;
    }
    
    
    void DMA14_INT_Handler(uint32_t iid, void* handlerArg)
    {
    	// Acknowledge DMA14 interrupt.
    	// Clear the data and status Interrupt from the latch
    	if( *pREG_DMA14_STAT & BITM_DMA_STAT_IRQDONE )
    	{
    		*pREG_DMA14_STAT = BITM_DMA_STAT_IRQDONE;
    	}
    	// Set a global Variable to Process the state machine
    	SetRxProcBuf = 0xAA;
    
    }
    
    void Receive_Satemachine()
    {
    	int16_t *p_EPPI_Data_BUFF_PING = &EPPI_Data_BUFF_PING[0] ;
    	int16_t *p_EPPI_Data_BUFF_PONG = &EPPI_Data_BUFF_PONG[0] ;
    
    	//if ( (*pREG_DMA14_ADDRSTART) == EPPI_Data_BUFF_PONG)
    	if ( (*pREG_DMA14_ADDRSTART) == &EPPI_Data_BUFF_PONG)
    	{
    		process_Ping_Buffer();
    	}
    	else
    	{
    		process_Pong_Buffer();
    	}
    
    }
    
    void process_Ping_Buffer(void)
    
    {
    	uint16_t Loop1;
    	uint8_t PosDetect=0;
    	uint8_t NegDetect=0;
    	uint8_t high = 0;
    	uint8_t low = 0;
    	uint8_t tsh = 0;
    
    	ping_count ++;
    
    	//Identify a Bit and append
    	for(Loop1 =0 ; Loop1 <= BUFF_SIZE ; Loop1++ )
    	{
    		//identify what type of sample it is and define the state
    		// Process Current Sample and Find the Event and Next state
    		if((*p_EPPI_Data_BUFF_PING>= neg_tsh_150mv) && (*p_EPPI_Data_BUFF_PING <= pos_tsh_150mv))
    		{
    			tsh_ping++;
    		}
    		else if (*p_EPPI_Data_BUFF_PING > pos_tsh_150mv )
    		{
    			high_ping++;
    		}
    
    		else //(*p_EPPI_Data_BUFF_PING < neg_tsh_150mv)
    		{
    			low_ping ++ ;
    		}
    		p_EPPI_Data_BUFF_PING++;
    	}
    }
    
    void process_Pong_Buffer(void)
    
    {
    	uint16_t Loop1;
    
    	pong_count++;
    
    	//Identify a Bit and append
    	for(Loop1 =0 ; Loop1 <= BUFF_SIZE ; Loop1++ )
    	{
    		//identify what type of sample it is and define the state
    		// Process Current Sample and Find the Event and Next state
    		if((*p_EPPI_Data_BUFF_PONG>= neg_tsh_150mv) && (*p_EPPI_Data_BUFF_PONG <= pos_tsh_150mv))
    		{
    			tsh_pong++;
    		}
    		else if (*p_EPPI_Data_BUFF_PONG > pos_tsh_150mv )
    		{
    			high_pong++;
    		}
    
    		else //(*p_EPPI_Data_BUFF_PING < neg_tsh_150mv)
    		{
    			low_pong ++ ;
    		}
    		p_EPPI_Data_BUFF_PONG++;
    	}
    }
    
    
    
    // Calling the following from main 
    	while(1)
    	{
    		if(SetRxProcBuf == 0xAA)
    		{
    			Receive_Satemachine();
    			SetRxProcBuf = 0x00;
    		}
    
    	}

    attaching code here

  • Hi,
    Apologies for the delay in response.

    Can you please refer the mentioned below Link. There is couple of simple register based EPPI codes to understand how EPPI can be configured. Please take this as reference. Hope this helps.
    ez.analog.com/.../eppi-peripheral-on-adsp-sc589


    Furthermore, Can you let us know which version of CCES are you using. As there is some constrain about the silicon revision in CCES older version, please ensure to use the latest version of CCES available at www.analog.com/.../adswt-cces.html

    As CPLB exceptions is highly dependent on project configurations, I recommend checking your cache protection options. Double click the "System.svc", navigate to the 'Startup Code/LDF' tab. In the 'Startup Code' tab there are options for  Instruction and Data Cache - enable or disable these as required.

    If the error still persists please let us know whether your target an EZ-KIT Lite, or a custom/third party board?

    Regards,
    Anand Selvaraj.