Difference between revisions of "Non-blocking DMA"

From WikiPrizm
Jump to navigationJump to search
m
(Specified category.)
Line 45: Line 45:
  
 
As you can see, there are two functions. Call DoDMAlcdNonblock() to start a transfer and DmaWaitNext() before doing another transfer.
 
As you can see, there are two functions. Call DoDMAlcdNonblock() to start a transfer and DmaWaitNext() before doing another transfer.
 +
[[Category: Useful Routines]]

Revision as of 21:29, 17 April 2014

This function allows you to perform calculations while drawing to the screen. this should increase frame rate. It is based on an assembly function found in Simon's documentation. I rewrote it in C.

#define LCD_GRAM 0x202
#define LCD_BASE	0xB4000000
#define VRAM_ADDR 0xA8000000
#define SYNCO() __asm__ volatile("SYNCO\n\t":::"memory");
// Module Stop Register 0
#define MSTPCR0	(volatile unsigned *)0xA4150030
// DMA0 operation register
#define DMA0_DMAOR	(volatile unsigned short*)0xFE008060
#define DMA0_SAR_0	(volatile unsigned *)0xFE008020
#define DMA0_DAR_0  (volatile unsigned *)0xFE008024
#define DMA0_TCR_0	(volatile unsigned *)0xFE008028
#define DMA0_CHCR_0	(volatile unsigned *)0xFE00802C
void DmaWaitNext(void){
	while(1){
		if((*DMA0_DMAOR)&4)//Address error has occured stop looping
			break;
		if((*DMA0_CHCR_0)&2)//Transfer is done
			break;
	}
	SYNCO();
	*DMA0_CHCR_0&=~1;
	*DMA0_DMAOR=0;
}

void DoDMAlcdNonblock(void){
	Bdisp_WriteDDRegister3_bit7(1);
	Bdisp_DefineDMARange(6,389,0,215);
	Bdisp_DDRegisterSelect(LCD_GRAM);

	*MSTPCR0&=~(1<<21);//Clear bit 21
	*DMA0_CHCR_0&=~1;//Disable DMA on channel 0
	*DMA0_DMAOR=0;//Disable all DMA
	*DMA0_SAR_0=VRAM_ADDR&0x1FFFFFFF;//Source address is VRAM
	*DMA0_DAR_0=LCD_BASE&0x1FFFFFFF;//Desination is LCD
	*DMA0_TCR_0=(216*384)/16;//Transfer count bytes/32
	*DMA0_CHCR_0=0x00101400;
	*DMA0_DMAOR|=1;//Enable DMA on all channels
	*DMA0_DMAOR&=~6;//Clear flags
	*DMA0_CHCR_0|=1;//Enable channel0 DMA
}

As you can see, there are two functions. Call DoDMAlcdNonblock() to start a transfer and DmaWaitNext() before doing another transfer.