DMA Generic Task API

Pedro Luis D. L. carcadiz at hotmail.com
Tue Sep 25 00:06:40 EST 2007


Hello,

As I wrote before, I'm trying to use the DMA API to copy audio data to the PSC1 which has a digital - analog - converter attached to it.
I read the explanation that Sylvain wrote at: http://ozlabs.org/pipermail/linuxppc-dev/2007-May/036229.html and programmed the following code:


static void SPI_setup(void)
{

	int psc_num = 1;
	phys_addr_t rx_fifo;
	phys_addr_t tx_fifo;
	struct bcom_bd *bd;

	uint32 SICR;

	psc = ioremap(MPC52xx_PA(MPC52xx_PSCx_OFFSET(1)), MPC52xx_PSC_SIZE);
	
	gpio = ioremap(MPC52xx_PA(MPC52xx_GPIO_OFFSET), MPC52xx_GPIO_SIZE);
	
	cdm = ioremap(MPC52xx_PA(MPC52xx_CDM_OFFSET), MPC52xx_CDM_SIZE);

	switch(psc_num) {
		case 1:
			initiator_tx = BCOM_INITIATOR_PSC1_TX;
			initiator_rx = BCOM_INITIATOR_PSC1_RX;
			break;
		case 2:
			initiator_tx = BCOM_INITIATOR_PSC2_TX;
			initiator_rx = BCOM_INITIATOR_PSC2_RX;
			break;
		default:
			panic("snd-SPImgt.o: invalid value for psc_num (%i)\n",psc_num);
			break;
	};
	
	printk("Before gpio->port_config\n");

	gpio->port_config 		|= PORT_CONFIG_PSC1;
	printk("Before cdm->clk_enables\n");
	cdm->clk_enables 		|= PSC1_CLK_EN;
	printk("Before cdm->mclken_div_psc1\n");
	cdm->mclken_div_psc1 	= MCLKEN_DIV;
	
	SICR = 0x02000000;
	SICR |= 0x00002000;
	SICR |= 0x0090C000;
	
	psc->command 	= 0x0A;
	psc->sicr	= SICR;
	psc->ctur	= 0x00;
	psc->ctlr	= 0x84;
	psc->ccr	&= 0xFF0000FF;
	psc->rfalarm	= 0x000C;		/* alarm occurs if 12 bytes space in the RxFIFO */
	psc->tfalarm	= 0x0010;		/* alarm occurs if 16 bytes are in the TxFIFO */
	psc->rfcntl	&= 0xF8;		/* set granularity to 0 */
	psc->tfcntl	&= 0xF8;		/* set granularity to 0 */
	psc->isr_imr.isr	= 0x01;
	psc->isr_imr.imr	= 0x00;		/* enable TxRDY interrupt */ 
	psc->mode	= 0x00;			/* set RX interrupt to RxRDY */
	psc->command	= 0x05;			/* enable Tx and Rx */

	psc->tfdata = 0xF001;
	wait(1000);
	psc->tfdata = 0xF000;

	printk("Before bcom_gen_bd_rx_init\n");
 	rx_bcom = bcom_gen_bd_rx_init(64, (phys_addr_t)&(psc->rfdata), initiator_rx, 6, 1024);
	printk("Before bcom_gen_bd_tx_init\n");
 	tx_bcom = bcom_gen_bd_tx_init(64, (phys_addr_t)&(psc->tfdata), initiator_tx, 6);

	printk("txtask is %d rxtask is %d\n", tx_bcom->tasknum, rx_bcom->tasknum);

	r_irq = bcom_get_task_irq(rx_bcom);
	t_irq = bcom_get_task_irq(tx_bcom);
	
	printk("t_irq is %d r_irq is %d\n", t_irq, r_irq);

	if (request_irq(r_irq, &SPI_rx_irq, IRQF_DISABLED, "SPI rx dma", NULL)) {
		printk(KERN_ERR "SPI: SDMA rx irq allocation failed\n");
		return;
	} else printk("SPI: SDA rx irq allocation succeded\n");
	if (request_irq(t_irq, &SPI_tx_irq, IRQF_DISABLED, "SPI tx dma", NULL)) {
		printk(KERN_ERR "SPI: SDMA tx irq allocation failed\n");
		return;
	} else printk("SPI: SDA tx irq allocation succeded\n");

	bcom_gen_bd_tx_reset(tx_bcom);
	bcom_gen_bd_rx_reset(rx_bcom);

	bcom_retrieve_buffer(tx_bcom, NULL, NULL);
	bd = bcom_prepare_next_buffer(tx_bcom);
	bd->status = 1024;
	bd->data[0] = (void *)SPI_tx_silence.pa;
	bcom_submit_next_buffer(tx_bcom, (void *)SPI_tx_silence.pa);

	bcom_dump_bdring(tx_bcom);
	bcom_dump_bdring(rx_bcom);

	printk("Tasks enabled\n");

 	psc->command = MPC52xx_PSC_TX_ENABLE | MPC52xx_PSC_RX_ENABLE;
	
}


Although everything seems to be executed without problems, the interrupt routines are never called, and no data seems to be copied to the PSC.
Could it be that  I don´t understand the purpose of bd->data and bd->status correctly? Is there any other Documentation or example code I can take a look and learn how to use the API?

Thanks,

Pedro L. Dominguez
carcadiz at hotmail.com
_________________________________________________________________
Consigue el nuevo Windows Live Messenger
http://get.live.com/messenger/overview


More information about the Linuxppc-embedded mailing list