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传输的中断例程

分享一个OMAPL138上在用GPIO触发EDMA传输,并产生中断的例程。

OMAPL138_GPIO_trigger_EDMA_Int_Demo.zip
  • 你好,可不可以发我邮箱zhangzhongkui1987@163.com,这个我下不下来。谢谢了

  • 不好意思,我好像也下载不不附件,能不能发一份到我的邮箱,sundian2008@yahoo.com.cn,非常感谢!

  • 还下不了吗?我试了可以下载的啊。

    OMAPL138_GPIO_trigger_EDMA_Int_Demo.zip
  • EDMA3 的紧急事件指的是什么

  • 什么事件是紧急的,是由事件本身的特性决定的,比如McBSP接口,使能后就一直在工作,当数据到了,必需在下一个数据到之前读走,否则就会把McBSP口卡死,而对于一些带FIFO的接口,因为有缓冲,对其事件的响应速度就没那么严格。

    在处理上,把紧急的事件映射到高优先级的队列与TC。

  • 这个例子要怎么在BIOS上实现呢? 因为要用到DSPLink! 我在任务中使能BANK的中断(BINTEN |= (1《 GPIO_BANK2)),程序就会挂掉! (例子是基于3.3下SEED的AD程序实现的,DMA能正常工作,放到readwrite例子下,DMA的目的地址上就没数据)
  • 可有linux下相关的例程

  • 您好,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左右,这会是什么原因?

  • 应该和C6748一样,学习了!

  • 请问通道使能是配置哪个寄存器?我好想出现了跟你一样的问题。

  • 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的,那么就会触发,其实这个应该很好定位的。

  • Tony Tang 说:

    还有在ARM侧使用的几个输入输出引脚--是什么意思?外设不分ARM还是DSP, 如果ARM用的这几个输入输出脚是GPIO4的,那么就会触发,其实这个应该很好定位的。

    你的意思是只要同BANK的PIN有其它配成INPUT的,一旦出现对应DMA的边沿翻转,那DMA就会被触发,对么?
    只要不是GPIO的input(PINMUX配置为非GPIO),是不会触发GPIO EVT DMA的,对么?
  • 你的意思是只要同BANK的PIN有其它配成INPUT的,一旦出现对应DMA的边沿翻转,那DMA就会被触发,对么?

    是的,event是按bank的,不是按gpio pin来的。

    只要不是GPIO的input(PINMUX配置为非GPIO,是不会触发GPIO EVT DMA的,对么?

    是的。