This thread has been locked.
If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.
Dear all:
Mcasp transfer data by EDMA in ARM. In the begining , the mcasp can transfer data. When the hard disk or nand flash read and write large block data by multithreading, the tx can't tansfer data but rx can receive data. Otherwise, the TXEVT is normal.
Moreover,Mcasp can't transfer data when syslink.ko is loaded or engine_open() is called.
The EDMA is ping-pong structure and interrupt period is 4 ms.
Following is that EDMA request configuration:
static int ys_tdm_dma_request(int id, int buf_size, int tx_channel, int rx_channel, int fifo_address) {
//init tx
tx_dma_params_arry[id]->area = dma_alloc_writecombine(NULL, buf_size, &tx_dma_params_arry[id]->addr, GFP_KERNEL);
tx_dma_params_arry[id]->ping_size = buf_size >> 1;
tx_dma_params_arry[id]->asp_channel = edma_alloc_channel(tx_channel, NULL, NULL,EVENTQ_DEFAULT);
tx_dma_params_arry[id]->slot_link[0] = edma_alloc_slot(EDMA_CTLR(tx_dma_params_arry[id]->asp_channel), EDMA_SLOT_ANY);
tx_dma_params_arry[id]->slot_link[1] = edma_alloc_slot(EDMA_CTLR(tx_dma_params_arry[id]->asp_channel), EDMA_SLOT_ANY);
edma_link(tx_dma_params_arry[id]->slot_link[0], tx_dma_params_arry[id]->slot_link[1]);
edma_link(tx_dma_params_arry[id]->slot_link[1], tx_dma_params_arry[id]->slot_link[0]);
edma_read_slot(tx_dma_params_arry[id]->slot_link[0], &p_ram);
p_ram.opt |= EDMA_TCC(EDMA_CHAN_SLOT(tx_dma_params_arry[id]->asp_channel));
edma_write_slot(tx_dma_params_arry[id]->slot_link[0], &p_ram);
edma_read_slot(tx_dma_params_arry[id]->slot_link[1], &p_ram);
p_ram.opt |= EDMA_TCC(EDMA_CHAN_SLOT(tx_dma_params_arry[id]->asp_channel));
edma_write_slot(tx_dma_params_arry[id]->slot_link[1], &p_ram);
//init rx
rx_dma_params_arry[id]->area = dma_alloc_writecombine(NULL, buf_size, &rx_dma_params_arry[id]->addr, GFP_KERNEL);
rx_dma_params_arry[id]->ping_size = buf_size >> 1;
if(id == YSTDM_PRI_ID)
rx_dma_params_arry[id]->asp_channel = edma_alloc_channel(rx_channel, ys_tdm_dma_irq_pri,NULL, EVENTQ_DEFAULT); //分配channel,RX的channel
else if(id == YSTDM_FX_ID)
rx_dma_params_arry[id]->asp_channel = edma_alloc_channel(rx_channel, ys_tdm_dma_irq_fx ,NULL, EVENTQ_DEFAULT); //分配channel,RX的channel
rx_dma_params_arry[id]->slot_link[0] = edma_alloc_slot(EDMA_CTLR(rx_dma_params_arry[id]->asp_channel), EDMA_SLOT_ANY);
rx_dma_params_arry[id]->slot_link[1] = edma_alloc_slot( EDMA_CTLR(rx_dma_params_arry[id]->asp_channel), EDMA_SLOT_ANY);
/** circle ping-pong buffers */
edma_link(rx_dma_params_arry[id]->slot_link[0], rx_dma_params_arry[id]->slot_link[1]);
edma_link(rx_dma_params_arry[id]->slot_link[1], rx_dma_params_arry[id]->slot_link[0]);
edma_read_slot(rx_dma_params_arry[id]->slot_link[0], &p_ram);
p_ram.opt |= TCINTEN | EDMA_TCC(EDMA_CHAN_SLOT(rx_dma_params_arry[id]->asp_channel));
edma_write_slot(rx_dma_params_arry[id]->slot_link[0], &p_ram);
edma_read_slot(rx_dma_params_arry[id]->slot_link[1], &p_ram);
p_ram.opt |= TCINTEN | EDMA_TCC(EDMA_CHAN_SLOT(rx_dma_params_arry[id]->asp_channel));
edma_write_slot(rx_dma_params_arry[id]->slot_link[1], &p_ram);
return 0;
}
Is the nand/hard drive block data transfers using EDMA? If so, are they using the same queue as the McASP. If that is the case, you should move those requests to a different EDMA queue.
For background: The EDMA services requests on a given queue (which maps to a given TC) in order. Thus, if a queue is servicing requests with a (relatively) short real time deadline (like McASP), you should avoid using the same queue for other purposes, especially for long transfers, or for transfers to slow peripherals.
Regards
Kyle