Hello,
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);
//etc
但是,当至少两个来源同时发生时,永远不会调用IRQ例程;而永远(我已经观察到中断例程,只有在两个源同时发生时才被调用)。如果我使用调用我的IRQ例程的软件看门狗,则此调用解锁系统,唤醒定时器中断再次抛出(因为我认为,IRQ条件 - GPIO级别和/或触发条件 - 在看门狗呼叫期间更新)。
I have read in the documentation:
The event counter is edge sensitive. After detecting an
active edge a reverse edge must be detected first
before it goes back to the IDLE state and from there
开始等待新的主动边缘。
是我的问题吗?我无法绕过这个条件!我无法更改源级别(GPIO级别),我无法更改触发级别(因为我不知道我是否在死锁条件下)......
任何答复都将非常欣赏。
问候,
Guillaume B.
Hi gbmej,
当您的同时发出中断时,我不会看到任何问题,唤醒控制器的中断不会触发的是,例如,如果允许说明您,则唤醒控制器的中断将不会触发。已配置为从3个不同的GPIO唤醒设备,并且触发手机对于剩余的两个和高电平,对于剩余的GPIO而高。现在,如果那些中断已经被置位(前两者的前两个或高度的一个来源的低电平),则不会发生中断,直到断言的引脚将被解除断言。所以也许这就是你正在遇到的,而不是在中断同时触发时。
Thanks MT_dialog
Hi,
谢谢你的回答。我已经完成更多的我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
// if GPIO2 condition change here during a GPIO1 interrupt (we have called performGPIO1Job() but not performGPIO2Job()) I have the issue (the GPIO interrupt is never thrown for GPIO2. If the GPIO2 condition changes just AFTER the IRQ routine, I have no issue.
}
通过看门狗,我已经在锁定(执行但没有JOB2的作业)之后检查了GPIO状态:GPIO1高,GPIO2应该抛出中断......
问候,
Guillaume B.
Hi gbmej,
I am not sure i get exactly the point, the part that you mentioned when you get the lock confused me a bit, tried to replicate what you mentioned, i ve done the following test in the hrp_sensor which allready implements one wake up source. The "static" wake up source is triggered LOW and the default pin configuration is PULLUP the changing wakeup source (the one that changes configuration in the interrupt routine) has initially the same pollarity, and the code that performs the change is attached below.
//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);
As long as you trigger the interrupt and then release the line from the triggered state both of the interrupts occur as they should, please check how the change is performed on the snippet above and how the wake up condition of the pin is configured based on the default state of the pin, hw_gpio_get_pin_function() used to check the default pin configuration hw_gpio_set_pin_function() is used to set the proper default pin state (opposite from the previous interrupt hit).
Thanks MT_dialog
Hi,
非常感谢您的答案,但我没有问题触发器切换。当GPIO中断发生在另一个GPIO中断时,我有一个问题。这是我的伪代码(请参阅附件)。
——GPIOA每40毫秒中断发生。的GPIOA助教k forces the GPIOA level to return from LOW to HIGH (it is a sensor read which clears the sensor interrupt).
- 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
- invalid GPIOB condition: we don't toggle GPIOB trigger and we don't wakeup GPIOB task
- 我们留下了中断
[任务GPIOA在T + 1ms]
- 我们读了传感器
- GPIOA水平返回高位
[T + 33ms的中断2]
- GPIOB go to LOW
- 抛出中断
- invalid GPIOA condition: we don't wakeup GPIOA task
- valid GPIOB condition: we toggle GPIOB trigger and we wakeup GPIOB task
- 我们留下了中断
[task GPIOB at t +34ms]
- we ack the GPIOB level to let the source work (around 6 to 8 ms)
[interrupt 3 at t +40ms]
- GPIOA降低
- 抛出中断
- we wakeup GPIOA task (valid GPIOA condition)
- we don't wakeup GPIOB task (invalid GPIOB condition)
- 我们留下了中断
[task 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
Hi gbmej,
You mean that there is no interrupt while the M0 is executing ISR of a button press ? Is that correct ? This doesn't have to do with the wake up controller but how the M0 and the NVIC operates, if the processor gets an interrupt while there is another interrupt executing the interrupt handler, since both interrupts have the same priority the pending interrupt flag will be set to 1 and as soon as the previous ISR gets executed it will be invoked again to serve the pending interrupt, and as far as i have tested this is exactly what the 68x does.
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
Hi,
我锁定了唤醒定时器中断,而不是另一个中断。一旦我有一个锁定(几秒钟后;我的代码在几秒钟内工作良好),唤醒定时器中断永远不会再抛出。当我在唤醒定时器中断功能由于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
Hi gbmej,
The wake up timer interrupts is what i am talking about as well, the sources might be many pins but the interrupt from the wake up timer is one. If there is a wake up interrupt and the ISR executes and then there is another hit of the same interrupt during ISR execution the pending bit (WKUP_GPIO_IRQn) will be set and soon as the ISR is served it will be re-invoked to serve the pending interrupt.
Perhaps the following occurs, the GPIOA goes low (and its low triggered), so the ISR runs, and you mentioned that a task is reading the state of the sensor in order to release the interrupt, so there is a period x from the moment that the GPIOA interrupt occurs up to the moment that the interrupt is de-asserted that the wake up controller wont accept interrupts from other sources (including GPIOB) since the status of the GPIOA is still asserted, it doesn't have to do with the conditions of the interrupt of GPIOB and if they are satisfied or not since the GPIOA is still asserted the GPIOB wont be triggered.
尝试使用分析仪检查信号并确保在信号断言时没有重叠,这意味着当另一个中断发生时,另一个不正常断言,因为这是唯一可以停止的条件唤醒控制器。
Thanks MT_dialog
Hi
I have updated my code to uselatch mode(chapter 4.3). The results are better. However, I have a question about clearing the interrupt: The function
hw_wkup_reset_interrupt
is never called in the example with multiple interruption sources. Is it an error?问候,
Guillaume B.
Hi gbmej,
hw_wkup_reset_interrupt()是API函数而不是回调函数,因此必须由任何用户指定的中断回调调用,以清除中断标志。如果您不调用此函数,则应用程序将永远不会调用,因此这不是错误。有关更多信息,请阅读3.2中的步骤#2。初始化功能章节的关键点,从我们的支持页面启动项目教程。
Thanks, PM_Dialog