TI中文支持网
TI专业的中文技术问题搜集分享网站

GPIO触发EDMA读GPMC的数据

使用的am335x,现在已经可以用EDMA读GPMC数据,但每次都是使用的edma_start()来启动DMA,请问如何使用GPIO触发EDMA自动读取GPMC数据。

edma和gpmc的配置如下:

static int gpmc_config(void)
{
int error;
u32 val;
int cnt;

// Chip-select configurations
val = gpmc_cs_read_reg(GPMC_FPGA_CS, GPMC_CS_CONFIG7);

val &= ~GPMC_CONFIG7_CSVALID; /*disable chip-select*/

gpmc_cs_write_reg(GPMC_FPGA_CS, GPMC_CS_CONFIG7, val);

gpmc_cs_configure(GPMC_FPGA_CS, GPMC_SET_IRQ_STATUS, 0); /*set irq status*/
gpmc_cs_configure(GPMC_FPGA_CS, GPMC_ENABLE_IRQ, 0); /*disable irqs*/

// Config NOR Memory Type
gpmc_cs_write_reg(GPMC_FPGA_CS,GPMC_CS_CONFIG1, GPMC_CONFIG1_READTYPE_ASYNC | /*set read type Asynchronous*/
GPMC_CONFIG1_WRITETYPE_ASYNC | /*set write type Asynchronous*/
GPMC_CONFIG1_DEVICESIZE_16 | /*set device size 16bit*/
GPMC_CONFIG1_DEVICETYPE_NOR | /*set device type NOR*/
GPMC_CONFIG1_FCLK_DIV3); /*GPMC_CLK frequency=GPMC_FCLK frequency/3*/

// Non-mutiplexed Address and Data
val = gpmc_cs_read_reg(GPMC_FPGA_CS, GPMC_CS_CONFIG1);
val &= ~GPMC_CONFIG1_MUXADDDATA; /*Non-multiplexed attached device*/
gpmc_cs_write_reg(GPMC_FPGA_CS, GPMC_CS_CONFIG1, val);

//GPMC Timing parameters
error = gpmc_cs_set_timings(GPMC_FPGA_CS, &fpga_timings); /*set timing parameters*/
if(error < 0){
DPRINTK(KERN_ERR "Unable to set gpmc timings\n");
return error;
}

/***********为FIFO申请GPMC chip-select空间**********/
if (gpmc_cs_request(GPMC_FPGA_CS, GPMC_FIFO_SIZE, &gpmc_membase)<0)
{
DPRINTK(KERN_ERR "gpmc_cs_request failed.\n");
return -1;
}

return error;
}

static int edma_config(void)
{
int result = 0; unsigned int BRCnt = 0;
int srcbidx = 0;
int desbidx = 0;
int srccidx = 0;
int descidx = 0;
struct edmacc_param param_set;

/* Set B count reload as B count. */
BRCnt = bcnt;

/* Setting up the SRC/DES Index */
srcbidx = 0;
desbidx = acnt;

/* A Sync Transfer Mode */
srccidx = 0;
descidx = acnt;

result = edma_alloc_channel (52, callback1, NULL, EVENTQ_0);

if (result < 0) {
DPRINTK ("edma_config::edma_alloc_channel ""failed for dma_ch1, error:%d\n", result);
return result;
}

dma_ch1 = result;
edma_set_src (dma_ch1, (unsigned long)(gpmc_membase), INCR, W16BIT);
edma_set_dest (dma_ch1, (unsigned long)(dmaphysdest1), INCR, W16BIT);
edma_set_src_index (dma_ch1, srcbidx, srccidx);
edma_set_dest_index (dma_ch1, desbidx, descidx);
edma_set_transfer_params (dma_ch1, acnt, bcnt, ccnt, BRCnt, ASYNC);

/* Enable the Interrupts on Channel 1 */
edma_read_slot (dma_ch1, &param_set);
param_set.opt |= (1 << ITCINTEN_SHIFT);
param_set.opt |= (1 << TCINTEN_SHIFT);
param_set.opt |= EDMA_TCC(EDMA_CHAN_SLOT(dma_ch1));
edma_write_slot(dma_ch1, &param_set);

/* Request a Link Channel */
result = edma_alloc_slot (0, 64);
if (result < 0) {
DPRINTK ("edma_config::edma_alloc_channel ""failed for dma_ch2, error:%d\n", result);
edma_free_channel(dma_ch1);
return result;
}
DPRINTK ("edma_config::edma_alloc_channel ""success for dma_ch2, dma_ch2:%d\n", result);
dma_ch2 = result;
edma_set_src (dma_ch2, (unsigned long)(gpmc_membase), INCR, W16BIT);
edma_set_dest (dma_ch2, (unsigned long)(dmaphysdest2), INCR, W16BIT);
edma_set_src_index (dma_ch2, srcbidx, srccidx);
edma_set_dest_index (dma_ch2, desbidx, descidx);
edma_set_transfer_params (dma_ch2, acnt, bcnt, ccnt, BRCnt, ASYNC);

/* Enable the Interrupts on Channel 2 */
edma_read_slot (dma_ch2, &param_set);
param_set.opt |= (1 << ITCINTEN_SHIFT);
param_set.opt |= (1 << TCINTEN_SHIFT);
param_set.opt |= EDMA_TCC(EDMA_CHAN_SLOT(dma_ch1));
edma_write_slot(dma_ch2, &param_set);

/* Link both the channels */
edma_link(dma_ch1, dma_ch2);

/* Request a Link Channel */
result = edma_alloc_slot (0, 65);

if (result < 0) {
DPRINTK ("edma_config::edma_alloc_channel ""failed for dma_ch3, error:%d\n", result);
edma_free_channel(dma_ch1);
edma_free_slot(dma_ch2);
edma_free_channel(dma_ch2);
return result;
}
DPRINTK ("edma_config::edma_alloc_channel ""success for dma_ch2, dma_ch2:%d\n", result);
dma_ch3 = result;
edma_set_src (dma_ch3, (unsigned long)(gpmc_membase), INCR, W16BIT);
edma_set_dest (dma_ch3, (unsigned long)(dmaphysdest1), INCR, W16BIT);
edma_set_src_index (dma_ch3, srcbidx, srccidx);
edma_set_dest_index (dma_ch3, desbidx, descidx);
edma_set_transfer_params (dma_ch3, acnt, bcnt, ccnt, BRCnt, ASYNC);

/* Enable the Interrupts on Channel 2 */
edma_read_slot (dma_ch3, &param_set);
param_set.opt |= (1 << ITCINTEN_SHIFT);
param_set.opt |= (1 << TCINTEN_SHIFT);
param_set.opt |= EDMA_TCC(EDMA_CHAN_SLOT(dma_ch1));
edma_write_slot(dma_ch3, &param_set);

/* Link both the channels */
edma_link(dma_ch2, dma_ch3); edma_link(dma_ch3, dma_ch2); return 0;
}

leo chen:

增加个gpio中断呗

在中断中传数据或者在中断中设置标志位

user3784487:

回复 leo chen:

这个方法也可以,只是我想用硬件的方式,操作相关寄存器完成。

每次来一个外部触发信号,硬件自动启动DMA读取GPMC数据到内存,读取完后通知应用程序读取这段数据。

也就是如何利用图中标记的这块。

Steven Liu1:

回复 user3784487:

这个指的就是外部的module之间产生的DMA事件,比如GPIO的GPIO_EOI Register里提到的DMA event.

你想要的是不是中断号为90和123和134的DMA外部中断事件DMA_INTR_PIN2, DMA_INTR_PIN0,  DMA_INTR_PIN1。在硬件的设计pin脚上就是下面这三个管脚:

SIGNAL NAME  DESCRIPTION                                 ZCE BALL         ZCZ BALL 

dma_event_intr0 External DMA Event or Interrupt 0   I C15                  A15xdma_event_intr1 External DMA Event or Interrupt 1 I B15                  D14xdma_event_intr2 External DMA Event or Interrupt 2 I B16, E18, K18 C15, C18, H18

赞(0)
未经允许不得转载:TI中文支持网 » GPIO触发EDMA读GPMC的数据
分享到: 更多 (0)