Hi,
I am trying to get DMA working with a PPC8245 processor, on a Sandpoint
PPC8245 eval system. I think I am doing all the right steps to get this
working, but apparently I am missing something. According to the PPC manual
(sect 8-5) I need to do the following:
page 8-5 in the MPC88245 Processor Users Manual
For DMA Direct Mode:
- Poll the DSR[CB] bit to ensure DMA channel is idle
- Init SAR, DAR, BCR registers
- Init the CTT bit in the CDAR to indicate transfer type
- Init the CTM bit in the DMR to indicate Direct Mode
- Clear and set the DMR[CS] bit to start the XFR
I think I am setting everything correctly, but I find that it always boils
down to operator error. So is there something else I need to do, or may be
the better question is what am I doing wrong?
I included my DMA setup/transfer code for reference, but from reading things
on the net I suspect that the problem does not lie in the setup of the DMA
(shown below), but actually lies in the placement of the information in the
buffers. The source and destination addresses for the buffers being passed
into the function below are just character buffers, they are not protected,
or DMA safe, or whatever they need to be.
There are a lot of articles on google groups referencing a document called
shmem.txt somewhere on the ftp.qnx.com site. Where exactly can I find this
document or example code on setting up DMA safe memory and how to actually
perform the DMA transfer.
Thanks in advance,
Mike
P.S. In case you could not tell, this is my first try at DMA transfers -
Thanks
The following function should setup and initiate a DMA transfer
//global variable this is mmap(ed)
//in another function to location 0x8000000
//of total length 0x1000
volatile unsigned int *DMAChannel;
int DoDMATransfer(unsigned char *sourceAddr, unsigned char *destAddr, int
xfrBytes)
{
//the DMA Base address (DMAChannel) is set to 0x80001000
printf(“The sourceAddr is %x\n”, sourceAddr);
printf(“The destAddr is %x\n”, destAddr);
printf(“The xfrBytes are %x\n”, xfrBytes);
/*
page 8-5 in the MPC88245 Processor Users Manual
For DMA Direct Mode:
- Poll the DSR[CB] bit to ensure DMA channel is idle
- Init SAR, DAR, BCR registers
- Init the CTT bit in the CDAR to indicate transfer type
- Init the CTM bit in the DMR to indicate Direct Mode
- Clear and set the DMR[CS] bit to start the XFR
*/
//1) Poll the DSR[CB] bit to ensure DMA channel is idle
if((DMAChannel[DMA0_DSR] & 0x4) == 0)
{
printf(“DmaChannel 0 is inactive and can be used\n”);
//set up the starting & ending transfer addresses
//and the data transfer size
//2) Init SAR, DAR, BCR registers
DMAChannel[DMA0_SAR] = (int) sourceAddr; //0x110 + base
DMAChannel[DMA0_DAR] = (int)destAddr; //0x118 + base
DMAChannel[DMA0_BCR] = xfrBytes; //0x120 + base
//re-read the stored data
printf(“The DMA0_SAR is %x\n”, DMAChannel[DMA0_SAR]);
printf(“The DMA0_DAR is %x\n”, DMAChannel[DMA0_DAR]);
printf(“The DMA0_BCR is %x\n”, DMAChannel[DMA0_BCR]);
//3) Init the CTT bit in the CDAR to indicate transfer type
//in this case we want a local memory transfer or bits 1 & 2 to == 0
DMAChannel[DMA0_CDAR] = DMAChannel[DMA0_CDAR] & 0xF9; //0x108 + base
printf(“The DMA0_CDAR is %x\n”, DMAChannel[DMA0_CDAR]);
//4) Init the CTM bit in the DMR to indicate Direct Mode
//see the current state of the DMR = 0
printf(“The DMA0_DMR is %d\n”, DMAChannel[DMA0_DMR]);
//turn on bit 2 (Chanel Transfer Mode) of the DMR indicate a direct mode
transfer
DMAChannel[DMA0_DMR] = DMAChannel[DMA0_DMR] | 0x4; //0x100 + base
//(DMR now = 4)
printf(“The DMA0_DMR was changed to %d\n”, DMAChannel[DMA0_DMR]);
//5) Clear and set the DMR[CS] bit to start the XFR
printf(“The DMA0_DMR is %d\n”,DMAChannel[DMA0_DMR]);
DMAChannel[DMA0_DMR] = DMAChannel[DMA0_DMR] & 0xFE;
//(DMR = 4)
printf(“The DMA0_DMR was changed to %d\n”, DMAChannel[DMA0_DMR]);
//set bit 0 (Chanel Start) of the the DMA regs
DMAChannel[DMA0_DMR] = DMAChannel[DMA0_DMR] | 0x01;
//(DMR now = 5)
printf(“The DMA0_DMR was changed to %d\n”, DMAChannel[DMA0_DMR]);
sleep(1);
//check the status register to see if any errors
//(none ever reported)
printf(“The DMA0_DSR is %x\n”, DMAChannel[DMA0_DSR]);
}
return(0);
}