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