分享一个OMAPL138上在用GPIO触发EDMA传输,并产生中断的例程。
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.
分享一个OMAPL138上在用GPIO触发EDMA传输,并产生中断的例程。
您好,DSP端也可以用GP8中断触发EDMACC1的18通道吗?为什么中断发生了,就是触发不了18通道,无奈只是在GPIO中断服务程序里手动触发18通道。有哪些可能的原因?我的程序是CSL芯片支持里Event触发改的,同为GPIO8中断触发,对应着CC1的18通道 。查了好久,就是没查出来,配置不对?谢谢您,可以看下程序是不是哪配置的不行?
这是通道设置部分的程序,其中edma3ccRegs的基地址为0x01E3 0000:
static void setup_EDMA (void)
{
// Clear Event Registers
CSL_FINST(edma3ccRegs->ECR, EDMA3CC_ECR_REG, MASK);
CSL_FINST(edma3ccRegs->SECR, EDMA3CC_SECR_REG, MASK);
// Enable Channel 18 to DSP (Region 1)
CSL_FINST(edma3ccRegs->DRA[CSL_EDMA3_REGION_1].DRAE,EDMA3CC_DRAE_E18, ENABLE);
// Assign Channel 18 to Queue 0
CSL_FINST(edma3ccRegs->DMAQNUM[2], EDMA3CC_DMAQNUM_E2, Q0);
// Initialize PaRAM Transfer Context for Event 18
init_PaRAM_event18();
// Enable Interrupts for Channel 18
CSL_FINST(edma3ccRegs->IESR, EDMA3CC_IESR_I18, SET);
}/* setup_EDMA */
这是参数设置部分:
static void init_PaRAM_event18(void)
{
// Reset EDMA PaRAM OPT Register
edma3ccRegs->PARAMSET[18].OPT = CSL_EDMA3CC_OPT_RESETVAL;
// Config PaRAM OPT (Enable TC Interrupt; Set TCC)
edma3ccRegs->PARAMSET[18].OPT =
CSL_FMKT(EDMA3CC_OPT_TCINTEN, ENABLE) |
CSL_FMK(EDMA3CC_OPT_TCC, 18);
// Initialize EDMA Event Src and Dst Addresses
edma3ccRegs->PARAMSET[18].SRC = (Uint32)&srcBuffer;
edma3ccRegs->PARAMSET[18].DST = (Uint32)&dstBuffer;
// Set EDMA Event PaRAM A,B,C CNT
edma3ccRegs->PARAMSET[18].A_B_CNT =
CSL_FMK(EDMA3CC_A_B_CNT_ACNT, XFER_BYTES) |
CSL_FMK(EDMA3CC_A_B_CNT_BCNT, XFER_ARRAYS);
edma3ccRegs->PARAMSET[18].CCNT = XFER_FRAMES;
// Set EDMA Event PaRAM SRC/DST BIDX
edma3ccRegs->PARAMSET[18].SRC_DST_BIDX =
CSL_FMK(EDMA3CC_SRC_DST_BIDX_SRCBIDX, SRC_ARRAY_SIZE) |
CSL_FMK(EDMA3CC_SRC_DST_BIDX_DSTBIDX, DST_ARRAY_SIZE);
// Set EDMA Event PaRAM SRC/DST CIDX
edma3ccRegs->PARAMSET[18].SRC_DST_CIDX =
CSL_FMK(EDMA3CC_SRC_DST_CIDX_SRCCIDX, 0) |
CSL_FMK(EDMA3CC_SRC_DST_CIDX_DSTCIDX, 0);
// Set EDMA Event PaRAM LINK and BCNTRLD
edma3ccRegs->PARAMSET[18].LINK_BCNTRLD =
CSL_FMK(EDMA3CC_LINK_BCNTRLD_LINK, PaRAM_NULL_LINK) |
CSL_FMK(EDMA3CC_LINK_BCNTRLD_BCNTRLD, 0);
}/* init_PaRAM_event 18 of EMACC1 */
由于中断触发触发不了,只好自己在GPIO服务程序里手动触发它一下。
interrupt void GPIO_BNK8_isr (void)
{
// Disable Interrupt Trigger on Falling Edge
gpioRegs->BANK[GP8].CLR_RIS_TRIG = GP8P12;
//gpioRegs->BANK[GP8].CLR_FAL_TRIG = GP8P12;
printf("GPIO Interrupt occurred!\n");
CSL_FINST(edma3ccRegs->ESR, EDMA3CC_ESR_E18, SET);
}
你好:
Tony Tang,GPIO中断触发EDMA已经可以跑起来了,但是关于参数设置这一块还有一些疑惑,向你请教下。
1.A_B_CNT:是不是只要A*B=数据字节数就OK了,没有特殊要求?
2.SRC_DST_BIDX:只要都是对应的数组长度就行了?
3.你的程序里ParameterBase_EDMA_1_36_LINK_BCNTRLD = (0<<16 | 0x480);这里的链接地址代表什么意思
4.我只用了18通道,除了链接地址外,其它的都和你的设的一样,我设的链接地址是空。这会不会有什么影响
5.发现,有的时候并没有传进到目的数组里,但时有发生,比例有个0.2左右,这会是什么原因?
Tony,好
现在碰到个问题,也是GPIO触发DMA的,还是得请教下你:
之前的代码中,用GP6[15]作为一路DMA触发,五年前已经开发好一直都这么用的没什么问题。
现在需要增加一个新的GPIO事件触发DMA,选择GP4[1]。GP6[15]是10KHz的信号,现在GP4[1]是相当于GP6[15]的分频信号,即GP4[1]也是10KHz,但GP6[15]到GP4[1]之间是50us间隔。对于GP4[1]的PaRAM配置基本上copy自GP6[15],仅修改:
1)CC由EDMA31CC_0改为EDMA30CC_0
2)TCC由EDMA3_CHA_GPIO_BNKINT6改为EDMA3_CHA_GPIO_BNKINT4
3)DST地址修改为新buffer
现在发现GP4[1]的脉冲输入不使能时,对应的DMA dest buffer数据也在刷新。会不会以下细节有关:
1)EDMA30CC_0还有另外两个EVT也是在用的,而GP6[15]在EDMA31CC_0中就它一个EVT
2)EDMA30CC_0目前的三个EVT都是放在QUEUE0
顺带问一下:EDMA30CC_0另两个EVT配置为QUEUE0,GP4[1]能独立配置到QUEUE1么(对应TC1了),看手册貌似可以。
3)GP4其它PIN有配置为EMIFdata的,还有在ARM侧使用的几个输入输出引脚——ARM侧的input会触发DSP这个BANK的EVT么?
Young Jim 说:EDMA30CC_0另两个EVT配置为QUEUE0,GP4[1]能独立配置到QUEUE1么(对应TC1了),看手册貌似可以。
可以。
Young Jim 说:3)GP4其它PIN有配置为EMIFdata的,还有在ARM侧使用的几个输入输出引脚——ARM侧的input会触发DSP这个BANK的EVT么?
还有在ARM侧使用的几个输入输出引脚--是什么意思?外设不分ARM还是DSP, 如果ARM用的这几个输入输出脚是GPIO4的,那么就会触发,其实这个应该很好定位的。