找回密码
 立即注册

微信扫码登录

查看: 400|回复: 4

Zigbee using Timer with GPIO trigger.

[复制链接]

10

主题

18

回帖

158

积分

注册会员

积分
158
发表于 2024-9-16 13:43:24 | 显示全部楼层 |阅读模式
I have asked the question about using the timer with GPIO trigger in the old forum, but never got a solution, so I have to ask it again.
How to use timer with GPIO trigger in ZigBee SDK?


In BLE SDK I was doing this like below:
Init timer for gpio trigger function
timer2_gpio_init(GPIO_HALL, POL_RISING);    
    timer2_set_mode(TIMER_MODE_GPIO_TRIGGER, 0, 2);   
    irq_enable();
    timer_start(TIMER2);

And irq function
_attribute_ram_code_ void irq_handler(void) {
    if((reg_tmr_sta & FLD_TMR_STA_TMR2) == FLD_TMR_STA_TMR2) {
        reg_tmr_sta |= FLD_TMR_STA_TMR2;
        ++hall_count;
    }
    irq_blt_sdk_handler();
}



After looking in timer.c functions in ZigBee SDK, to init timer I have to do it like this:
Init timer:
timer_gpio_init(TIMER0, GPIO_HALL, POL_RISING);    // POL_FALLING);
    timer_set_init_tick(TIMER0, 0);
    timer_set_cap_tick(TIMER0, 3);
    timer_set_mode(TIMER0, TIMER_MODE_GPIO_TRIGGER);
    timer_irq_enable(TIMER0);
//    hwTimerSet(TIMER0, 3);
//    hwTimerInit(TIMER0, TIMER_MODE_GPIO_TRIGGER);
    timer_start(TIMER0);



But how do I use/set up interrupt for this timer?
ZigBee is using void irq_handler(void) function in irq_handler.c
In this function there is the following:
if((src & FLD_IRQ_TMR1_EN)){
        reg_irq_src = FLD_IRQ_TMR1_EN;
        reg_tmr_sta = FLD_TMR_STA_TMR1;
        T_DBG_irqTest[3]++;
        drv_timer_irq1_handler();
    }

Which calls drv_timer_irq1_handler() in drv_timer.c
void drv_timer_irq1_handler(void)
{
    drv_hwTmr_irq_process(TIMER_IDX_1);
}

How do I create a callback function for this interrupt process function?
Is my code for setup the timer correct?

By the way, what happened with all the posts in the old Telink Forum? There was a lot of valuable information there and I made a lot of posts. Everything is gone!


27

主题

121

回帖

447

积分

版主

积分
447
发表于 2024-9-18 16:23:26 | 显示全部楼层
Hi,


Please refer to the following code, which has been verified in test module.

Hope this can help you.

volatile u8 T_DBG_irqTest[16] = {0};
_attribute_ram_code_ void irq_handler(void){
        u32 src = irq_get_src();

        if((src & FLD_IRQ_TMR0_EN)){
                reg_irq_src = FLD_IRQ_TMR0_EN;
                reg_tmr_sta = FLD_TMR_STA_TMR0;
                T_DBG_irqTest[2]++;
                //drv_timer_irq0_handler();
        }

}

void moduleTest_timer(void){
        drv_gpio_func_set(GPIO_PD2);
        drv_gpio_output_en(GPIO_PD2, 1);                 //enable output
        drv_gpio_input_en(GPIO_PD2, 0);                //disable input
        drv_gpio_write(GPIO_PD2, 1);                     //LED On

        timer_gpio_init(TIMER0, GPIO_PD0, POL_FALLING);
        gpio_en_interrupt_risc0(GPIO_PD0, 1);
        timer_set_mode(TIMER0, TIMER_MODE_GPIO_TRIGGER);
        timer_set_init_tick(TIMER0, 0);
        timer_set_cap_tick(TIMER0, 2);
        timer_irq_enable(TIMER0);
        timer_start(TIMER0);

        drv_enable_irq();

        while(1){
                WaitMs(500);
                gpio_toggle(GPIO_PD2);
        }

}


10

主题

18

回帖

158

积分

注册会员

积分
158
 楼主| 发表于 2024-9-19 13:30:40 | 显示全部楼层

Hi,
I will try it, but I don't understand how it will work.
Interrupt for Timer with GPIO trigger is triggered after number of ticks set in  
timer_set_cap_tick(TIMER0, 2);

So it means that in this example after 2 gpio changes the timer interrupt should occur.
You commented out drv_timer_irq0_handler(); so how will you get an interrupt?
You have enabled in your code gpio_en_interrupt_risc0, but there is no callback function from this interrupt. And I think that this interrupt will be triggered on every falling (change) of GPIO_PD0. Not on the second or whatever is set in timer_set_cap_tick() function.
Timer interrupt depends also on the initial ticks set in timer_set_init_tick(). It is 0 in the example but can be any number.
Correct me if I am wrong but how would gpio interrupt manage this?

10

主题

18

回帖

158

积分

注册会员

积分
158
 楼主| 发表于 2024-9-21 11:59:22 | 显示全部楼层
本帖最后由 wes58 于 2024-9-22 06:32 编辑

Hi,
I have tried your code and it works. And I understand why, because I had a look in BLE SDK in the timer.c function timer0_gpio_init(GPIO_PinTypeDef pin, GPIO_PolTypeDef pol). There is a separate function for timer1. In those functions appropriate irq irisc0/risc1 is set

So, in the ZigBee SDK the function that you used - timer_gpio_init(TIMER_TypeDef type, GPIO_PinTypeDef pin, GPIO_PolTypeDef pol) - needs a separte call to enable gpio irq? It would be good if it was mentioned somewhere in the documentation.

And what about other timer modes that are missing from ZigBee SDK? How do we handle them?

Since interrupts in ZigBee SDK work based on registering callback functions. I think there should be a callback function for this timer mode.
This would enable processing of the interrupt in the drv_timer.c function drv_hwTmr_irq_process(). Otherwise I (and anybody who is using this mode) would have to modify irq_handler() and change it depending what project I am working on.
This doesn't make sense.
That's why BLE SDK is good because you can have a local  irq_handler() in your project which then calls irq_blt_sdk_handler();

I am not sure how to create this callback function so any suggestions would be welcomed.
For now I just have in my project a function tmrTrig_irq_handler() to process the irq and:
In app_cfg.h defined
#define TIMER0_GPIOTRIG                    0
#define TIMER1_GPIOTRIG                    1
extern void tmrTrig_irq_handler(void);

And in irq_handler.c function irq_handler() have
if((src & FLD_IRQ_TMR0_EN)){
        reg_irq_src = FLD_IRQ_TMR0_EN;
        reg_tmr_sta = FLD_TMR_STA_TMR0;
        T_DBG_irqTest[2]++;
#if defined TIMER0_GPIOTRIG && (TIMER0_GPIOTRIG == 1)
        tmrTrig_irq_handler();
#else
        drv_timer_irq0_handler();
#endif
    }

    if((src & FLD_IRQ_TMR1_EN)){
        reg_irq_src = FLD_IRQ_TMR1_EN;
        reg_tmr_sta = FLD_TMR_STA_TMR1;
        T_DBG_irqTest[3]++;
#if defined TIMER1_GPIOTRIG && (TIMER1_GPIOTRIG == 1)
        tmrTrig_irq_handler();
#else
        drv_timer_irq1_handler();
#endif
    }

27

主题

121

回帖

447

积分

版主

积分
447
发表于 2024-9-23 14:52:29 | 显示全部楼层
Hi,
It looks fine.
It should be noted that when using timer gpio trigger mode, it will occupy gpio risc resources.
So, timer gpio trigger mode and gpio interrupt risc cannot be used simultaneously.
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

Telink forum ( 沪ICP备17008231号-1 )

GMT+8, 2024-11-24 06:22 , Processed in 0.086406 second(s), 18 queries .

Powered by Telink 隐私政策

泰凌微电子版权所有 © 。保留所有权利。 2024

快速回复 返回顶部 返回列表