你好,
我使用3个GPIO作为唤醒定时器来源。两个源触发始终在同一级别(一个低点和一个高)和两个级别的第三个源(在IRQ例程期间,我切换此GPIO的触发器)。我没有比赛时间(0毫秒),我期待一旦发生至少一个源(计数器比较阈值为1)。一切都在运作良好。两个第一个源始终触发其预期水平和两个级别的第三个源触发器。
//init sequence:
hw_wkup_set_counter_threshold(1);
hw_wkup_set_debounce_time(0);
//等等
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).
我已阅读文档:
事件计数器是边缘敏感。检测到A.
主动边缘必须首先检测反向边缘
在它回到空闲状态之前,从那里开始
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.
你好,
谢谢您的回答。我已经进行了更多的调查以减少我的用例。我现在有一个GPIO中断,高于低变化,另一个在每个中断时切换的内容。当GPIO 2发生在GPIO 1中断之后发生时,我已经观察到,没有问题。但如果在GPIO结束之前发生变化1中断但是在GPIO 2检查后,我有锁定
kekuup_handler()
{
hw_wkup_reset_interrupt();
if (checkGPIO1COndition()) performGPIO1Job();
if(checkgpio2condition())performgpio2job();//切换触发器
//如果gpio2条件在gpio1中断期间在这里发生变化(我们称为performgpio1job()但不是performgpio2job())我有问题(GPIO中断从不抛出GPIO2。如果GPIO2条件发生在IRQ常规之后,我没有问题。
}
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,
我不确定我完全得到了这一点,你提到的部分当你锁定时让我感到困惑,试图复制你所提到的内容,我在HRP_Sensor中完成了以下测试,它已经实现了一个唤醒源。触发“静态”唤醒源触发低电平,默认引脚配置是上拉更改唤醒源(中断例程中的配置更改配置)具有最初相同的手机,以及执行更改的代码在下面连接。
//全局变量
__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);
只要触发中断,然后从触发状态释放行,都会出现在触发状态,因此应该检查上面的片段上的更改以及引脚的唤醒状态如何基于该中断用于检查默认引脚配置HW_GPIO_SET_PIN_FUNCTION()的默认引脚,HW_GPIO_GET_PIN_FUNCTION()用于设置正确的默认PIN状态(与先前中断命中相反)。
谢谢mt_dialog.
你好,
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任务责任GPIOA水平从低到高(它是清除传感器中断的传感器读数)。
- 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任务
- 无效的gpiob条件:我们不会切换gpiob触发器,我们不会唤醒gpiob任务
- 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
- 无效的GPIOA条件:我们不唤醒GPIOA任务
- 有效的GPIOB条件:我们切换GPIOB触发器,我们唤醒GPIOB任务
- we leave the interrupt
[T + 34MS的任务GPIOB]
- 我们确认GPIOB级别让源工作(大约6到8毫秒)
[T + 40ms的中断3]
- GPIOA go to LOW
- interrupt is thrown
- 我们唤醒GPIOA任务(有效的GPIOA条件)
- 我们唤醒gpiob任务(无效的gpiob条件)
- we leave the interrupt
[T = + 41ms的任务GPIOA]
- we read the sensor
- the GPIOA level return to HIGH
如果在中断3(我们留下中断向量例程)之后更新GPIOB低至高电平,则没有错误。如果此更新发生在检查GPIOB中断条件后,但在离开中断向量例程之前,则不会抛出更多中断。这是锁。我认为内部唤醒状态机保持在key_release状态,因为GPIOA的KEY_HIT返回零,但同时,GPIOB的KEY_HIT转到1 ...
再次感谢你的帮助
guillaume.
嗨gbmej,
你的意思是,M0正在执行一个按钮按下的ISR时没有中断?那是对的吗 ?这与唤醒控制器无关,而是M0和NVIC如何运行,如果处理器在执行中断处理程序时进行中断,因为两个中断都具有相同的优先级,因此挂起的中断标志将是相同的设置为1,一旦上一个ISR被执行,它将再次调用它来服务挂起的中断,并且就我测试了这正是68倍的所做中断。
现在在您的情况下,我看到您的引脚配置了下拉和上拉的内部电阻,我可以想象这是锁定中断的原因,也许在外部设备未正确驱动特定线路的情况下状态将发生上拉并保持唤醒控制器的中断信号,用于至少一个引脚源,我假设是切换其状态的引脚源,这足以发生中断,并且唤醒控制器等待唤醒控制器对于在报告另一个中断之前要断言中断。因此,如果您确定外部传感器正常驱动线路,或者如果您想使用内部电阻,则可以尝试使用内部拉动UPS,或者您应该将电阻的默认状态更改为相反的电阻将触发唤醒的状态,使用HW_GPIO_SET_PIN_FUNCTION()在我的前一篇文章中提到的内容,以便更改默认引脚配置。
谢谢mt_dialog.
你好,
我有一个锁定唤醒定时器中断,而不是在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,
唤醒定时器中断是我所讨论的,源可能是许多引脚,但唤醒定时器的中断是一个。如果有一个唤醒中断和ISR执行,然后在ISR执行期间又一次击中相同的中断,则将设置待处理的位(WKUP_GPIO_IRQN),并且只要ISR提供服务即可重新调用以服务待处理打断。
也许发生了以下情况,GPIOA变低(及其低触发),因此ISR运行,并且您提到任务正在读取传感器的状态以释放中断,因此瞬间有一个句点xGPIOA中断发生在断开中断的那一刻,即唤醒控制器不会接受来自其他源(包括GPIOB)的中断,因为GPIOA的状态仍然被断言,它与...不一定GPIOB中断的条件,如果仍然追随GPIOA,因此仍然触发GPIOB。
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.
你好
我更新了我的代码要使用锁存模式(第4.3章)。结果更好。但是,我有一个关于清除中断的问题:函数
hw_wkup_reset_interrupt.
在具有多个中断源的示例中永远不会调用。这是一个错误吗?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.