你好,
I am using 3 GPIO as wakeup timer sources. Two sources trigger always on same level (one LOW and one HIGH) and the third source on both levels (during IRQ routine, I toggle the trigger of this GPIO). I have no debounce time (0 ms) and I am expecting an interrupt as soon as at least one source occurs (counter compare threshold is 1). Everything is working well. Two first sources always trigger on their expected levels and third source triggers on the both levels.
//初始化序列:
硬件工作设置计数器阈值(1);
hw_wkup_set_debounce_time(0);
//等等
然而,当至少两个源同时出现时,IRQ例程从不被调用;而且永远不会(我观察到只有在两个源同时出现时才调用中断例程)。如果我使用一个软件看门狗来调用我的IRQ例程,这个调用会解锁系统,唤醒计时器中断会再次抛出(因为,我认为IRQ条件-GPIO级别和/或触发器条件-会在看门狗调用期间更新)。
我在文件中读到:
事件计数器是边缘敏感的。在检测到
active edge a reverse edge must be detected first
before it goes back to the IDLE state and from there
开始等待新的活动边。
是我的问题吗?我不能绕过这个条件!我无法更改源级别(GPIO级别)和触发器级别(因为我不知道是否处于死锁状态)。。。
如有任何答复,将不胜感激。
当做,
纪尧姆B。
您好!gbmej公司,
我没有看到任何问题,当中断是在同一时间发出,什么可能发生和中断从唤醒控制器将不会触发是当一个中断源是allready断言,例如,例如,假设您已配置为从3个不同的GPIO唤醒设备,并且前两个GPIO的触发器轮询度较低,其余的GPIO的触发器轮询度较高。现在,如果其中一个中断是allready断言的(前两个源之一的低或后两个源的高),那么在断言的pin被反断言之前,不会发生中断。所以也许这就是你正在经历的,而不是当中断同时被触发的时候。
Thanks MT_dialog
你好,
谢谢你的回答。我已经完成更多的我nvestigation to reduce my use case. I have now one GPIO interrupt on HIGH to LOW change and another one which toggles at every interrupt. I have observed when the GPIO 2 change occurs just after the GPIO 1 interrupt, there is no issue. But If the change occurs before the end of GPIO 1 interrupt but AFTER the GPIO 2 check, I have the lock
wakeuup_handler()
{
hw_wkup_reset_interrupt();
if(checkGPIO1COndition())performGPIO1Job();
if (checkGPIO2COndition()) performGPIO2Job(); // toggle trigger
//如果在GPIO1中断期间GPIO2条件在这里发生变化(我们调用了performGPIO1Job(),但没有调用performGPIO2Job()),我就有问题了(GPIO2从未抛出GPIO中断。如果GPIO2条件在IRQ例程之后改变,我没有问题。
}
通过一个看门狗,我检查了锁定后的GPIO状态(job1执行,而不是job2):GPIO1高,GPIO2应该抛出中断。。。
当做,
纪尧姆B。
您好!gbmej公司,
我不确定我得到确切的点,你提到的部分,当你得到锁困惑了我一点,试图复制你提到的,我已经做了以下测试,在hrp\u传感器,allready实现一个唤醒源。“静态”唤醒源触发低,默认引脚配置为PULLUP。更改唤醒源(在中断例程中更改配置的唤醒源)最初具有相同的pollarity,执行更改的代码附在下面。
//Global variables
__RETAINED HW_GPIO_MODE my_gpio_mode = HW_GPIO_MODE_INPUT_PULLUP;
__保留HW\u GPIO\u FUNC my\u GPIO\u函数;
静态空隙率
{
#if dg_configBLACK_ORCA_IC_REV == BLACK_ORCA_IC_REV_A
hw_wkup_reset_counter();
#endif
hw_wkup_reset_interrupt();
hw \u gpio \u get \u pin \u函数(CFG \u START \u ADVERTISING \u TRIGGER \u 1 \u gpio \u PORT,CFG \u START \u ADVERTISING \u TRIGGER \u 1 \u gpio \u pin,&my \u gpio \u mode,&my \u gpio \u函数);
if(my\u gpio\u mode==HW\u gpio\u mode\u INPUT\u下拉列表){
my\u gpio\u mode=HW\u gpio\u mode\u INPUT\u PULLUP;
} else {
my_gpio_mode = HW_GPIO_MODE_INPUT_PULLDOWN;
}
hw\u gpio\u set\u pin\u function(CFG\u START\u ADVERTISING\u TRIGGER\u 1\u gpio\u PORT,CFG\u START\u ADVERTISING\u TRIGGER\u 1\u gpio\u pin,my\u gpio\u mode,hw\u gpio\u FUNC\u gpio);
hw\u wkup\u configure\u pin(CFG\u START\u ADVERTISING\u TRIGGER\u 1\u GPIO\u PORT,CFG\u START\u ADVERTISING\u TRIGGER\u 1\u GPIO\u pin,true,
我的gpio模式=硬件\ GPIO \模式\输入\下拉?硬件\工作\引脚\状态\低:硬件\工作\引脚\状态\高);
hw_cpm_trigger_sw_cursor(); //this will help identify the interrupt in the power profiler with a thin red line each time the interrupt triggers
hrp_wkup_cb();
}
在periph\u init()中:
hw\u gpio\u set\u pin\u function(CFG\u START\u ADVERTISING\u TRIGGER\u 1\u gpio\u PORT,CFG\u START\u ADVERTISING\u TRIGGER\u 1\u gpio\u pin,my\u gpio\u mode,hw\u gpio\u FUNC\u gpio);
只要您触发中断,然后将线路从触发状态释放出来,两个中断都会发生,请检查如何对上面的代码段执行更改,以及如何根据pin的默认状态配置pin的唤醒条件,hw\u gpio\u get\u pin\u function()用于检查默认pin配置hw\u gpio\u set\u pin\u function()用于设置正确的默认pin状态(与上一次中断命中相反)。
Thanks MT_dialog
你好,
非常感谢你的回答,但我对触发开关没有异议。我有一个问题,当一个GPIO中断发生在另一个GPIO中断。这是我的伪代码(见附件)。
-GPIOA中断每40ms发生一次。GPIOA任务强制GPIOA级别从低变高(这是一个清除传感器中断的传感器读取)。
-GPIOB中断每200ms发生一次。当电平从高到低时抛出第一个中断。我们打开触发器,从低到高检查。任务GPIOB强制GPIOB从低返回高(驱动GPIOB信号的源)。然后第二个中断被抛出,我们再次切换。它就像一个按钮来获取新闻/发布事件,但是在考虑新闻事件之前,源代码不能发布。
Everything works well, except this use case:
[interrupt 1 at t +0ms ]
-GPIOA调低
-中断被抛出
- valid GPIOA condition: we wakeup GPIOA task
-无效的GPIOB条件:我们不切换GPIOB触发器,也不唤醒GPIOB任务
-我们不插嘴
[t+1ms时的任务GPIOA]
-我们读取传感器
-GPIOA水平返回高位
[t+33ms时中断2]
- GPIOB go to LOW
-中断被抛出
-无效的GPIOA条件:我们不唤醒GPIOA任务
-有效的GPIOB条件:我们切换GPIOB触发器并唤醒GPIOB任务
-我们不插嘴
[t+34ms时的任务GPIOB]
-我们确认GPIOB级别以使源工作(大约6到8毫秒)
[interrupt 3 at t +40ms]
-GPIOA调低
-中断被抛出
- we wakeup GPIOA task (valid GPIOA condition)
- we don't wakeup GPIOB task (invalid GPIOB condition)
-我们不插嘴
[任务GPIOA at t=+41ms]
-我们读取传感器
-GPIOA水平返回高位
If the GPIOB LOW to HIGH level is updated just AFTER interrupt 3 (we have left interrupt vector routine), there is no error. If this update occurs just after the check of GPIOB interrupt condition but before leaving the interrupt vector routine, no more interrupt is thrown. This is the lock. I think the internal wakeup state machine stays in the KEY_RELEASE state because key_hit of GPIOA back to zero but at same time, key_hit of GPIOB go to 1...
Thank you again for your help
Guillaume
您好!gbmej公司,
你的意思是当M0执行一个按钮按下的ISR时没有中断?对吗?这与唤醒控制器无关,但与M0和NVIC的工作方式有关,如果处理器在执行中断处理程序时发生中断,由于两个中断具有相同的优先级,挂起的中断标志将被设置为1,一旦上一个ISR被执行,它将再次被调用,以服务挂起的中断,据我所测试,这正是68x所做的。
Now in your case i see that your pins are configured with the internal resistors in pulldown and pullup, i can imagine that this is the reason for the interrupts to lock, perhaps in case that the external device is not properly driving the line in a specific state the pullups will take place and keep the interrupt signal for the wake up controller asserted for at least one pin source which i suppose is the one that toggles its state, and this is enough for no interrupts to occur and the wake up controller to wait for the interrupt to be asserted before reporting another interrupt. So you can try to either not to use the internal pull ups in case you are certain that the external sensor is driving the lines properly, or if you would like to use the internal resistors you should alter the default state of the resistor to the opposite of the state that will trigger the wake up, something like i have mentioned in my previous post, using the hw_gpio_set_pin_function() in order to change the default pin configuration.
Thanks MT_dialog
你好,
我锁定了唤醒计时器中断,而不是其他中断。一旦我有了锁(几秒钟后;我的代码在几秒钟内运行良好),唤醒计时器中断不会再次抛出。当我由于GPIOA电平变化而处于唤醒定时器中断功能中,并且GPIOB的条件在检查GPIOB条件之后但在中断结束之前变得有效时,我拥有锁。
我尝试过gpio引脚重新配置(输入上拉,然后下拉,然后上等)+触发电平的udpate,没有更多的结果。
GPIOA task is waked up on GPIOA interrup (using freertos binary semaphore). Just after the GPIOA task wakeup, I store the GPIOB state in RAM (level, trigger). When I encounter the lock (watchdog), I print the GPIOB state: the interrupt conditions are satisfied but no interrupt (wakeup timer interrupt) is thrown. If I compare this GPIOB state with the GPIOB state during the GPIOA interrupt (just before leaving the wakeup timer interrupt, I store in RAM GPIOB state too), I can see the GPIOB conditions were not satisfied before the end of ISR (wakeup timer interrupt) but satisfied after the ISR. After 40ms after the lock, the conditions of GPIOA are satisfied again too but the interrupt (wakeup timer interrupt) is not thrown.
如果在我的看门狗回调我调用唤醒中断函数,这将解锁锁,然后中断继续工作。。。
Thanlks for your help
Guillaume
您好!gbmej公司,
唤醒计时器中断也是我所说的,来源可能是许多引脚,但从唤醒计时器中断是一个。如果有一个唤醒中断,并且ISR执行,然后在ISR执行期间,同一中断的另一次命中,将设置挂起位(WKUP\u GPIO\u IRQn),一旦ISR被服务,它将被重新调用以服务挂起的中断。
可能会发生以下情况,GPIOA变低(并触发其低),因此ISR运行,并且您提到一个任务正在读取传感器的状态以释放中断,因此,从GPIOA中断发生的时刻到中断被反断言的时刻有一个周期x,因为GPIOA的状态仍然被断言,所以唤醒控制器不会接受来自其他源(包括GPIOB)的中断,这与GPIOB中断的条件无关,如果它们满足或不满足,因为GPIOA仍然被断言,GPIOB将不会被触发。
尝试用分析仪检查信号,并确保当中断发生时,信号的断言没有重叠,这意味着当一个中断发生时,另一个没有完全就绪断言,因为这是唯一可能使唤醒控制器失速的条件。
Thanks MT_dialog
您好!
我已更新代码以使用latch mode(chapter 4.3). The results are better. However, I have a question about clearing the interrupt: The function
hw_wkup_reset_interrupt
在具有多个中断源的示例中从未调用。是错误吗?当做,
纪尧姆B。
您好!gbmej公司,
hw\u wkup\u reset\u interrupt()是一个API函数而不是回调函数,因此任何用户指定的中断回调都必须调用它,以清除中断标志。如果不调用此函数,应用程序将永远不会调用它,因此这不是错误。有关更多信息,请阅读3.2中的步骤2。初始化函数一章的要点,从我们的支持页开始一个项目教程。
Thanks, PM_Dialog