【朝花夕拾】RT600 DSP代码GPIO中断添加

一 文档简介

RT600带有ARM CM33和HiFi4 DSP, 对于普通的GPIO中断,在ARM代码中使用非常简单:初始化GPIO引脚,配置中断类型并使能中断,使能中断IRQ号,添加对应中断服务函数。这样,一旦满足配置的GPIO中断类型产生,即可产生中断并且触发中断服务函数。那么,如果要在RT600 DSP中添加一个简单GPIO中断或者PINT中断,是否也是如上那么简单,直接拷贝ARM 代码就行了呢?
有些客户鉴于思维惯性,把ARM CM33中测试可以的GPIO中断和PINT中断代码,直接搬运到DSP代码中,发现并不能触发中断,所以本文以此为题讲讲如何在RT600 DSP代码中添加引脚中断,测试平台MIMXRT600-EVK开发板,测试目标实现DSP代码中板上SW1,SW2中断触发,SW1使用GPIO中断,SW2使用PINT中断。
本文的DSP GPIO中断添加方法也适用于其他外设中断在DSP代码中的添加。

二 引脚中断机制

MIMXRT600-EVK开发板使用的SW1,SW2引脚为:
在这里插入图片描述

图1 SW引脚号

2.1 GPIO 引脚中断

RT600 GPIO包含两个中断,A和B,可以连接到任意的GPIO引脚上。INTENA0-7和INTENB0-7可以配置对应引脚PORT0-7的具体引脚号0-31实现中断,INTENA,INTENB为32bit,每个位对应具体port引脚的引脚号。
在这里插入图片描述

图2 GPIO中断框图
对应中断IRQ号:
在这里插入图片描述

图3 GPIO中断号
DSP的引脚中断代码也需要使用CM33的中断代码,CM33的GPIO中断代码可以参考SDK代码:
SDK_2_10_1_EVK-MIMXRT685\boards\evkmimxrt685\driver_examples\gpio\input_interrupt

2.2 PINT 引脚中断

引脚中断除了使用GPIO中断之外,还可以使用PINT,PINT可以同时支持port0,1的所有GPIO引脚中的8个引脚,而且具有不同的IRQ分开中断。
在这里插入图片描述

图4 PINT 中断框图
对应的中断IRQ号:
在这里插入图片描述在这里插入图片描述

图5 PINT IRQ号
PINT的相关代码可以参考SDK代码:
SDK_2_10_1_EVK-MIMXRT685\boards\evkmimxrt685\driver_examples\pint
这里需要注意,需要使用INPUT MUX去选择引脚。
在这里插入图片描述

图6 pin interrupt multiplexing
比如需要把PIO0_10接到PINT1,可以配置如下:
INPUTMUX_Init(INPUTMUX);
INPUTMUX_AttachSignal(INPUTMUX, kPINT_PinInt1, kINPUTMUX_GpioPort0Pin10ToPintsel
);
INPUTMUX_Deinit(INPUTMUX);
然后再使能PIT,配置PINT中断类型,添加中断callback。

2.3 DSP中引脚中断

DSP的外设中断需要使用INPUTMUX选择具体的中断号连接到HiFi. 对应的DSP中断号连接情况如下:
在这里插入图片描述
在这里插入图片描述

图7 Hifi4中断
比如,中断23对应的是DSP_INT0_SEL18.
将GPIOA的中断连接到DSP中断23号上,需要使用INPUTMUX去绑定:
INPUTMUX_AttachSignal(INPUTMUX, 18U, kINPUTMUX_NsHsGpioInt0ToDspInterrupt);
这里需要注意,不要使用错误的INPUTMUX_AttachSignal connection,之前使用如下代码:
INPUTMUX_AttachSignal(INPUTMUX, 18U, kINPUTMUX_GpioPort1Pin1ToPintsel);
就是因为没有使用正确的connection号,导致无法触发DSP GPIO中断。关于对应的connection选择,从DSP_INT0n_SEL也可以看出:
在这里插入图片描述

图8 DSP中断输入
kINPUTMUX_GpioPort1Pin1ToPintsel 并不是DSP的中断输入,而是PINT的。
除了inputmux需要选择中断连接,DSP中断还需要使用XOS注册中断handler。
xos_register_interrupt_handler(uint32_t num, XosIntFunc * handler, void * arg);
xos_interrupt_enable(uint32_t intnum);
那么这里面的num应该怎么选择呢?
其实就是对应的DSP中断号,比如上面使用了DSP_INT0_SEL18连接inputmux,那么根据表7,可以看到对应了23号。 Handler 就是对应的外设中断服务函数, arg 传入的外设base。
还是以GPIOA 为例,注册中断服务函数,使能对应DSP中断号:
xos_register_interrupt_handler(XCHAL_EXTINT19_NUM, (XosIntFunc )APP_GPIO_INTA_IRQHandler, GPIO);
xos_interrupt_enable(XCHAL_EXTINT19_NUM);
#define XCHAL_EXTINT19_NUM 23 /
(intlevel 2) */
如果多个DSP中断,就需要多个对应的xos中断服务函数注册。

三 测试代码与结果
下面给出P1_1 SW1, P0_10 SW2的引脚DSP中断代码,P1_1使用GPIO1 A的中断,P0_10使用PINT中断,具体代码添加如下:

gpio_pin_config_t sw_config    = {kGPIO_DigitalInput, 0};
gpio_interrupt_config_t config = {kGPIO_PinIntEnableEdge, kGPIO_PinIntEnableLowOrFall};

void APP_GPIO_INTA_IRQHandler(void)
{
	PRINTF("\r\nISR0=%x  \r\n", GPIO->INTSTATA[0]);
	PRINTF("\r\nISR1=%x  \r\n", GPIO->INTSTATA[1]);
    /* clear the interrupt status */
    GPIO_PinClearInterruptFlag(GPIO, APP_SW_PORT, APP_SW_PIN, 0);
    /* Change state of switch. */
    g_InputSignal = true;
    SDK_ISR_EXIT_BARRIER;
}
void pint_intr_callback(pint_pin_int_t pintr, uint32_t pmatch_status)
{
    PRINTF("\f\r\nPINT Pin Interrupt %d event detected.", pintr);
}
//=============Add SW1 GPIOA P1_1 interrupt==========================
 INPUTMUX_Init(INPUTMUX);
   INPUTMUX_AttachSignal(INPUTMUX, 18U, kINPUTMUX_NsHsGpioInt0ToDspInterrupt);
    /* Init input switch GPIO. */
    EnableIRQ(GPIO_INTA_IRQn);
    GPIO_PortInit(GPIO, 1U);
    GPIO_PinInit(GPIO, 1U, 1U, &sw_config);
    xos_register_interrupt_handler(XCHAL_EXTINT19_NUM, (XosIntFunc *)APP_GPIO_INTA_IRQHandler, GPIO);
    xos_interrupt_enable(XCHAL_EXTINT19_NUM);//23
    /* Enable GPIO pin interrupt */
    GPIO_SetPinInterruptConfig(GPIO, 1U,1U, &config);
    GPIO_PinEnableInterrupt(GPIO, 1U, 1U, 0);
    //=============Add SW2 PINT P0_10 interrupt===============================
INPUTMUX_AttachSignal(INPUTMUX, 1U, kINPUTMUX_GpioPort0Pin10ToPintsel);
    PINT_Init(PINT);
    INPUTMUX_AttachSignal(INPUTMUX, 2U, kINPUTMUX_GpioInt1ToDspInterrupt);
    PINT_PinInterruptConfig(PINT, 1U, kPINT_PinIntEnableFallEdge, pint_intr_callback);
    PINT_EnableCallbackByIndex(PINT, 1U);
    xos_register_interrupt_handler(XCHAL_EXTINT3_NUM, PIN_INT1_DriverIRQHandler, NULL);  // #define XCHAL_EXTINT3_NUM		7	->DSP_INT0_SEL2
    xos_interrupt_enable(XCHAL_EXTINT3_NUM);
    while (1)
    {
        if (g_InputSignal)
        {
            delay();
            if (APP_SW_CONNECTED_LEVEL == GPIO_PinRead(1U, 1U))
            {
                PRINTF("%s is turned on.\r\n", APP_SW_NAME);
            }
            /* Reset state of switch. */
            g_InputSignal = false;
        }
    }

测试结果如下:

在这里插入图片描述

图9 测试结果
综上,可见经过DSP中断和外设GPIO引脚中断的连接,能够成功在DSP代码中触发中断,实现GPIOA 和PINT的中断,其他外设中断在DSP代码中的添加也是一样的思路。

  • 13
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值