Beispiel #1
0
void ppuConfigEDMA( PPU_DevHandle device, Int channelnum)
{
	Ptr					dest;
	Ptr					dest_lastframe;
	Int					framesize;
	Int					lastframesize;
	Int					numframes;
	
	PPU_ChannelHandle 				chan;
	const PPU_PictureChannelHAL *	hal;
	
	chan = &device->Channels[channelnum];
	hal = &(ppuHal.PictureChannel[channelnum]);	
	
	framesize = chan->Framesize;
	lastframesize = chan->LastFramesize;
	numframes = chan->NumFrames;
	
	//dbgLog("DMA set up on chan: %d. frame: %d, last: %d, num: %d", channelnum, framesize, lastframesize, numframes );
	//dbgLog("Picsize: %d", chan->PicSize );
	
		
	// Calculate the target pointers
	dest 			= (Ptr)( (Int)(chan->Buffer) + PIC_HEADERSIZE );
	dest_lastframe 	= (Ptr)( (Int)dest + (numframes * framesize) );
	
	
	// a macro which defines the OPT fields of the dma config. Its arguments define whether the DMA
	// will trigger a transfer completion interrupt, which tcc would be used for that interrupt and
	// if it is a linked DMA.
	#define PPU_EDMA_STDOPT(tcint, tcc, link) 	EDMA_OPT_RMK( 	0x0, 					/* Priority: urgent! //high, but not urgent.									*/ \
																0x0,                    /* element size (16 bit)											*/ \
																0,		                /* 2D source														*/ \
																00,	                    /* source update mode (Fixed address)								*/ \
																0x00,                   /* 2D dest															*/ \
																0x1,                    /* dest update mode													*/ \
																tcint,                  /* Transfer complete interrupt flag	(1=enable)						*/ \
																(tcc & 0xF),            /* Transfer complete code	(4bits)									*/ \
																((tcc & 0x30) >> 4),    /* Transfer complete code most significant bits (2bits, 64x only)	*/ \
																0,                      /* Alternate complete interrupt flag								*/ \
																0x00,                   /* Alternate transfer complete code									*/ \
																0,                      /* PDT source														*/ \
																0, 						/* PDT dest															*/ \
																link,                   /* link																*/ \
																1 )					  	/* Frame synchronisation	(0=element, 1=frame)					*/


	// Check if the DMA transfer has to be split up because the framesize doesn't fit
	if (lastframesize == 0)
	{
		// no split up required
		EDMA_configArgs( chan->DMA1,
						PPU_EDMA_STDOPT(1, chan->TCC, 1),						// Do interrupt, link to null table.
					    EDMA_SRC_RMK(hal->pFifo),								// Source Address
					    EDMA_CNT_RMK(numframes-1, framesize/4),					// Transfer Counter - Numeric  
					    EDMA_DST_RMK(dest),										// Destination Address - Numeric   
					    EDMA_IDX_RMK(0,0),	    								// Index register - Numeric  
					    EDMA_RLD_RMK(0, ppuDMANull) ); 							// No "Element Count Reload", but link to next DMA.
	}
	else if (numframes == 0)
	{
		// no split up (only the last frame needed.)
		EDMA_configArgs( chan->DMA1,
						PPU_EDMA_STDOPT(1, chan->TCC, 1),						// Do interrupt, link to null table.
					    EDMA_SRC_RMK(hal->pFifo),								// Source Address
					    EDMA_CNT_RMK(0, lastframesize/4),						// Transfer Counter - Numeric  
					    EDMA_DST_RMK(dest_lastframe),							// Destination Address - Numeric   
					    EDMA_IDX_RMK(0,0),	    								// Index register - Numeric  
					    EDMA_RLD_RMK(0, ppuDMANull) ); 							// No "Element Count Reload", but link to next DMA.
	}
	else
	{	// multiple frames, and a lastframe
		EDMA_configArgs( chan->DMA1,
						PPU_EDMA_STDOPT(0, chan->TCC, 1),						// no interrupt, but link with next dma.
					    EDMA_SRC_RMK(hal->pFifo),  								// Source Address
					    EDMA_CNT_RMK(numframes-1, framesize/4),					// Transfer Counter - Numeric  
					    EDMA_DST_RMK(dest),										// Destination Address - Numeric   
					    EDMA_IDX_RMK(0,0),	    								// Index register - Numeric  
					    EDMA_RLD_RMK(0, chan->DMA2)								// No "Element Count Reload", but link to next DMA.
					    );
			
		EDMA_configArgs(chan->DMA2,
						PPU_EDMA_STDOPT(1, chan->TCC, 1),						// Do generate an interrupt.
					    EDMA_SRC_RMK(hal->pFifo), 								// Source Address
					    EDMA_CNT_RMK(0, lastframesize/4),						// Transfer Counter - Numeric  
					    EDMA_DST_RMK( dest_lastframe ),							// Destination Address - Numeric   
					    EDMA_IDX_RMK(0,0),	    								// Index register - Numeric  
					    EDMA_RLD_RMK(0, ppuDMANull)								// No "Element Count Reload", but link to null DMA. 
					    );
	}
}
Beispiel #2
0
 * EDMA receive channel config
 */
EDMA_Config gEdmaRcvConfig = {
	EDMA_OPT_RMK(
		EDMA_OPT_PRI_LOW,
		EDMA_OPT_ESIZE_32BIT,
		EDMA_OPT_2DS_NO,
		EDMA_OPT_SUM_NONE,				// no source address update
		EDMA_OPT_2DD_NO,
		EDMA_OPT_DUM_INC,				// increment destination address
		EDMA_OPT_TCINT_YES,				// Source address update mode
		EDMA_OPT_TCC_DEFAULT,
		EDMA_OPT_LINK_YES,
		EDMA_OPT_FS_NO),				// Frame synchronisation, we copy element by element
	EDMA_SRC_OF(0x00000000),			// EDMA Channel Source Address
	EDMA_CNT_RMK(0, 108),				// Frame count (FRMCNT), Element count (FRMCNT)
	EDMA_DST_OF((Uint32) &gRcvBufferA),	// EDMA Channel Destination Address
	EDMA_IDX_RMK(EDMA_IDX_FRMIDX_DEFAULT, EDMA_IDX_ELEIDX_DEFAULT),		// Frame index, Element index
	EDMA_RLD_RMK(0x0000, 0x0000)		// Element count reload, Link address
};

/*
 * EDMA transmit channel config
 */
EDMA_Config gEdmaXmtConfig = {
	EDMA_OPT_RMK(
		EDMA_OPT_PRI_LOW,
		EDMA_OPT_ESIZE_32BIT,
		EDMA_OPT_2DS_NO,
		EDMA_OPT_SUM_INC,				// increment source address
		EDMA_OPT_2DD_NO,