Hello,
我使用3个GPIO作为唤醒定时器来源。两个源触发始终在同一级别(一个低点和一个高)和两个级别的第三个源(在IRQ例程期间,我切换此GPIO的触发器)。我没有比赛时间(0毫秒),我期待一旦发生至少一个源(计数器比较阈值为1)。一切都在运作良好。两个第一个源始终触发其预期水平和两个级别的第三个源触发器。
//init sequence:
hw_wkup_set_counter_threshold(1);
hw_wkup_set_debounce_time(0);
//etc
However, when at least two sources occur at the same time, the IRQ routine is never called; and for ever (I have observed the interrupt routine is never called only when two sources occur at same time). If I use a software watchdog which calls my IRQ routine, this call unlocks the system and the wakeup timer interrupt is thrown again (because, I think, the IRQ condition - GPIO level and/or trigger condition - is updated during watchdog call).
I have read in the documentation:
The event counter is edge sensitive. After detecting an
主动边缘必须首先检测反向边缘
在它回到空闲状态之前,从那里开始
starts waiting for a new active edge.
Is it my issue ? I cannot bypass this condition! I cannot change the source level (GPIO level) and I cannot change the trigger level (because I don't know if I am in the dead lock condition)...
Any reply will be greatly appreciated .
Regards,
guillaume.B.
嗨gbmej,
I dont see any issues when the interrupts are issued at the same time, what might occur and the interrupts from the wake up controller will not trigger is when one of the interrupt sources is allready asserted, for example, if lets say for example that you have configured to wake up the device from 3 different gpios and the trigger pollarity is low for the first two and high for the remaining one. Now if one those interrupts is allready asserted (low for one of the sources of the first two or high for the later) then no interrupt will occur until the asserted pin will be de-asserted. So perhaps this is what you are experiencing and not when the interrupts are triggered at the same time.
谢谢mt_dialog.
Hi,
谢谢您的回答。我已经进行了更多的调查以减少我的用例。我现在有一个GPIO中断,高于低变化,另一个在每个中断时切换的内容。当GPIO 2发生在GPIO 1中断之后发生时,我已经观察到,没有问题。但如果在GPIO结束之前发生变化1中断但是在GPIO 2检查后,我有锁定
kekuup_handler()
{
hw_wkup_reset_interrupt.();
if (checkGPIO1COndition()) performGPIO1Job();
if(checkgpio2condition())performgpio2job();//切换触发器
// 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.
}
With a watchdog, I have checked the GPIO states just after a lock (job1 performed but not job2): GPIO1 is HIGH and GPIO2 should throw the interrupt...
Regards,
guillaume.B.
嗨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.
//全局变量
__retated hw_gpio_mode my_gpio_mode = hw_gpio_mode_input_pullup;
__RETAINED HW_GPIO_FUNC my_gpio_function;
static void wkup_cb(void)
{
#if dg_configblack_orca_ic_rev == black_orca_ic_rev_a
hw_wkup_reset_counter();
#万一
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;
} 别的 {
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();//这将有助于每次中断触发时用薄的红线识别电源分布器中的中断
hrp_wkup_cb();
}
In the 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).
谢谢mt_dialog.
Hi,
Thanks a lot for your answer but I have no issue with the trigger toggle. I have an issue when a GPIO interrupt occur during another GPIO interrupt. This is my pseudo code (see attached file).
——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 interrupt occurs every 200ms. The first interrupt is thrown when level goes from HIGH to LOW. We toggle the trigger to check now LOW to HIGH. The task GPIOB forces the GPIOB to return from LOW to HIGH (the source which drives the GPIOB signal). Then the second interrupt is thrown and we toggle again. It is like as a button to get press/release events but source cannot release until press event is taken in consideration.
一切都适合,除了这个用例:
[T + 0ms的中断1]
- GPIOA go to LOW
- interrupt is thrown
- 有效的GPIOA条件:我们唤醒GPIOA任务
- invalid GPIOB condition: we don't toggle GPIOB trigger and we don't wakeup GPIOB task
- we leave the interrupt
[task GPIOA at t +1ms]
- we read the sensor
- the GPIOA level return to HIGH
[interrupt 2 at t +33ms]
- GPIOB转到低调
- interrupt is thrown
- invalid GPIOA condition: we don't wakeup GPIOA task
- valid GPIOB condition: we toggle GPIOB trigger and we wakeup GPIOB task
- we leave the interrupt
[task GPIOB at t +34ms]
- we ack the GPIOB level to let the source work (around 6 to 8 ms)
[T + 40ms的中断3]
- GPIOA go to LOW
- interrupt is thrown
- 我们唤醒GPIOA任务(有效的GPIOA条件)
- 我们唤醒gpiob任务(无效的gpiob条件)
- we leave the interrupt
[task GPIOA at t = +41ms]
- we read the sensor
- the GPIOA level return to HIGH
如果在中断3(我们留下中断向量例程)之后更新GPIOB低至高电平,则没有错误。如果此更新发生在检查GPIOB中断条件后,但在离开中断向量例程之前,则不会抛出更多中断。这是锁。我认为内部唤醒状态机保持在key_release状态,因为GPIOA的KEY_HIT返回零,但同时,GPIOB的KEY_HIT转到1 ...
再次感谢你的帮助
guillaume.
嗨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.
现在在您的情况下,我看到您的引脚配置了下拉和上拉的内部电阻,我可以想象这是锁定中断的原因,也许在外部设备未正确驱动特定线路的情况下状态将发生上拉并保持唤醒控制器的中断信号,用于至少一个引脚源,我假设是切换其状态的引脚源,这足以发生中断,并且唤醒控制器等待唤醒控制器对于在报告另一个中断之前要断言中断。因此,如果您确定外部传感器正常驱动线路,或者如果您想使用内部电阻,则可以尝试使用内部拉动UPS,或者您应该将电阻的默认状态更改为相反的电阻将触发唤醒的状态,使用HW_GPIO_SET_PIN_FUNCTION()在我的前一篇文章中提到的内容,以便更改默认引脚配置。
谢谢mt_dialog.
Hi,
我有一个锁定唤醒定时器中断,而不是在the other interrupts. As soon as I have a lock (after several seconds; my code works well during several seconds), the wakeup timer interrupt is never thrown again. When I am in the wakeup timer interrupt function due to GPIOA level change AND the conditions of GPIOB becomes valid just after the check of GPIOB conditions but before the end of the interrupt, I have the lock.
I have tried with gpio pin reconfiguration (input pull up then down then up etc.) + udpate of trigger level, no more result.
GPIOA任务在GPIOA Interpup(使用Freertos二进制信号量)上展现。就在GPIOA任务唤醒之后,我将GPIOB状态存储在RAM(级别,触发器)中。当我遇到锁(看门狗)时,我打印GPIOB状态:满足中断条件,但没有中断(唤醒定时器中断)被抛出。如果我在GPIOA中断期间将这个GPIOB状态与GPIOB状态进行比较)但在ISR之后满意。在锁后40ms后,GPIOA的条件也非常满足,但不抛出中断(唤醒定时器中断)。
If during my watchdog callback I call the wakeup interrupt function, this unlocks the lock and then the interrupt keep working...
守止你的帮助
guillaume.
嗨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.
Try to check with an analyser the signals and make sure that when the interrupts occur there is no overlapping in the assertion of the signals, meaning that when one interrupt occurs the other is not allready asserted, since this is the only condition that can stall the wake up controller.
谢谢mt_dialog.
Hi
I have updated my code to use锁存模式(第4.3章)。结果更好。但是,我有一个关于清除中断的问题:函数
hw_wkup_reset_interrupt.
is never called in the example with multiple interruption sources. Is it an error?Regards,
guillaume.B.
嗨gbmej,
The hw_wkup_reset_interrupt() is an API function and not a callback function, so it must be called by any user-specified interrupt callback, to clear the interrupt flag. If you don’t call this function, it will never be called by the application, so this isn’t an error. For more information, please read the Step #2 in 3.2. Key Points of the Initialization Function chapter, of Starting a Project tutorial from our support page.
谢谢,PM_DIALOG.