你好,
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.
// init序列:
hw_wkup_set_counter_threshold(1);
hw_wkup_set_debounce_time(0);
//等等
但是,当至少两个来源同时发生时,永远不会调用IRQ例程;而永远(我已经观察到中断例程,只有在两个源同时发生时才被调用)。如果我使用调用我的IRQ例程的软件看门狗,则此调用解锁系统,唤醒定时器中断再次抛出(因为我认为,IRQ条件 - GPIO级别和/或触发条件 - 在看门狗呼叫期间更新)。
我已阅读文档:
事件计数器是边缘敏感。检测到A.
active edge a reverse edge must be detected first
before it goes back to the IDLE state and from there
开始等待新的主动边缘。
是我的问题吗?我无法绕过这个条件!我无法更改源级别(GPIO级别),我无法更改触发级别(因为我不知道我是否在死锁条件下)......
任何答复都将非常欣赏。
问候,
Guillaume B.
你好GBMEJ.,
当您的同时发出中断时,我不会看到任何问题,唤醒控制器的中断不会触发的是,例如,如果允许说明您,则唤醒控制器的中断将不会触发。已配置为从3个不同的GPIO唤醒设备,并且触发手机对于剩余的两个和高电平,对于剩余的GPIO而高。现在,如果那些中断已经被置位(前两者的前两个或高度的一个来源的低电平),则不会发生中断,直到断言的引脚将被解除断言。所以也许这就是你正在遇到的,而不是在中断同时触发时。
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
//如果gpio2条件在gpio1中断期间在这里发生变化(我们称为performgpio1job()但不是performgpio2job())我有问题(GPIO中断从不抛出GPIO2。如果GPIO2条件发生在IRQ常规之后,我没有问题。
}
通过看门狗,我已经在锁定(执行但没有JOB2的作业)之后检查了GPIO状态:GPIO1高,GPIO2应该抛出中断......
问候,
Guillaume B.
你好GBMEJ.,
我不确定我完全得到了这一点,你提到的部分当你锁定时让我感到困惑,试图复制你所提到的内容,我在HRP_Sensor中完成了以下测试,它已经实现了一个唤醒源。触发“静态”唤醒源触发低电平,默认引脚配置是上拉更改唤醒源(中断例程中的配置更改配置)具有最初相同的手机,以及执行更改的代码在下面连接。
//Global variables
__RETAINED HW_GPIO_MODE my_gpio_mode = HW_GPIO_MODE_INPUT_PULLUP;
__ retated hw_gpio_func my_gpio_function;
静态void wkup_cb(空白)
{
#if dg_configBLACK_ORCA_IC_REV == BLACK_ORCA_IC_REV_A
hw_wkup_reset_counter();
#endif
hw_wkup_reset_interrupt();
hw_gpio_get_pin_function(cfg_start_advertising_trigger_1_gpio_port,cfg_start_advertising_trigger_1_gpio_pin,&my_gpio_mode,&my_gpio_function);
if(my_gpio_mode == hw_gpio_mode_input_pulldown){
my_gpio_mode = hw_gpio_mode_input_pullup;
} else {
my_gpio_mode = HW_GPIO_MODE_INPUT_PULLDOWN;
}
hw_gpio_set_pin_function(cfg_start_advertising_trigger_1_gpio_port,cfg_start_advertising_trigger_1_gpio_pin,my_gpio_mode,hw_gpio_func_gpio);
hw_wkup_configure_pin(cfg_start_advertising_trigger_1_gpio_port,cfg_start_advertising_trigger_1_gpio_pin,true,
my_gpio_mode!= hw_gpio_mode_input_pulldown?hw_wkup_pin_state_low:hw_wkup_pin_state_high);
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_init():
hw_gpio_set_pin_function(cfg_start_advertising_trigger_1_gpio_port,cfg_start_advertising_trigger_1_gpio_pin,my_gpio_mode,hw_gpio_func_gpio);
只要触发中断,然后从触发状态释放行,都会出现在触发状态,因此应该检查上面的片段上的更改以及引脚的唤醒状态如何基于该中断用于检查默认引脚配置HW_GPIO_SET_PIN_FUNCTION()的默认引脚,HW_GPIO_GET_PIN_FUNCTION()用于设置正确的默认PIN状态(与先前中断命中相反)。
Thanks MT_dialog
你好,
非常感谢您的答案,但我没有问题触发器切换。当GPIO中断发生在另一个GPIO中断时,我有一个问题。这是我的伪代码(请参阅附件)。
- GPIOA中断每40毫秒发生一次。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任务
- 我们留下了中断
[任务GPIOA在T + 1ms]
- 我们读了传感器
- 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)
- 我们留下了中断
[T = + 41ms的任务GPIOA]
- 我们读了传感器
- 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被执行,它将再次调用它来服务挂起的中断,并且就我测试了这正是68倍的所做中断。
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_GPIO_IRQN),并且只要ISR提供服务即可重新调用以服务待处理打断。
也许发生了以下情况,GPIOA变低(及其低触发),因此ISR运行,并且您提到任务正在读取传感器的状态以释放中断,因此瞬间有一个句点xGPIOA中断发生在断开中断的那一刻,即唤醒控制器不会接受来自其他源(包括GPIOB)的中断,因为GPIOA的状态仍然被断言,它与...不一定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
在具有多个中断源的示例中永远不会调用。这是一个错误吗?问候,
Guillaume B.
你好GBMEJ.,
hw_wkup_reset_interrupt()是API函数而不是回调函数,因此必须由任何用户指定的中断回调调用,以清除中断标志。如果您不调用此函数,则应用程序将永远不会调用,因此这不是错误。有关更多信息,请阅读3.2中的步骤#2。初始化功能章节的关键点,从我们的支持页面启动项目教程。
Thanks, PM_Dialog