This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

CC2530: TIMAC CC530 Sleep Timer

Part Number: CC2530
Other Parts Discussed in Thread: TIMAC,

我使用协议栈为TIMAC,采用信标模式,所有设备同步,我需要的情景为信标帧携带设备信息后,设备信息匹配的终端设备在发送数据给协调器,其它终端设备进行休眠,我最开始采用的为协议栈的halSleep()函数,并且使能了Power saving,但是发现终端设备并没有进行休眠,后面我采取了睡眠定时器的 方式,但是中断函数不能触发,发现睡眠定时器的中断函数已经被协议栈给写好了,协议栈的中断函数也是清除中断标志和睡眠模式,所以我认为可以使用协议栈的中断函数,通过实验发现,这种方式只能使协调器进入一次规定好的休眠。在后续信标帧到来后无法触发休眠。

  • 我认为 TIMAC 1.5.2 的 msa_cc2530 示例正在接受评估。请注意,如果 MSA_MAC_BEACON_ORDER 不等于 15,则 MSA_PWR_MGMT_ENABLED 将默认用于设备并使能于协调器上。MSA_PWR_MGMT_ENABLED 本身必须设置为 TRUE。这两个定义都在 msa.h 文件中建立,之后不需要进一步修改功率。您能否详细说明对默认项目进行了哪些更改以及如何确认设备是否进入低功耗状态?

  • Bo设置为10,S0设置为9,信标帧间隔大约为15秒,对每一个终端设备进行编号,协调器发送的信标帧中携带了设备号,当检测到信标帧携带的设备号与自身的设备号不一样时,触发休眠事件,设备立马进行休眠,我使用了CC2530的sleep timer。

    以上是关于sleep timer的设置,下面是协议栈写好的中断函数,我没有改动。

    因为设备在进入PM2模式时,只有睡眠定时器工作,串口不能正常工作,我只设定了休眠事件,在事件触发前,串口可以接收并且回复,休眠事件触发后,串口无法接收,所以我判断设备进入了PM2模式。同时,通过调试,发现触发了睡眠定时器的中断。

  • 看起来查询已转向串口问题。串口将不会在 PM2 模式下运行,因为为该外设提供时钟的高频振荡器被禁用。在为串口提供服务之前,设备需要退出睡眠状态。

  •           case 0xA2:
                if(Beacon_Receive[4] != MSA_DEVICE_NUMBER)
                {
                  HalUARTWrite(HAL_UART_PORT_0 , "The Enddevice Sleep" , sizeof("The Enddevice Sleep"));
                  osal_set_event(MSA_TaskId, DEVICE_SLEEP_EVENT);
                }

    可以看得到,如果信标帧携带的信息与设备自身不一样,设备就开始休眠,但是从结果来看,设备只能在第一次信标帧发送后进入休眠,然后定时唤醒,当协调器再次发送信标帧后,设备不会进入休眠。

  • 已将您的回复转达至E2E英文论坛工程师,您也可以访问e2e.ti.com/.../cc2530-timac-cc530-sleep-timer关注最新进展

  • 我不太清楚您提供的代码的上下文,您可以具体说明此代码的实施位置吗?此问题涉及协调器 (FFD) 还是设备 (RFD)?是否可以使用默认的 msa_2530 示例和 MSA_PWR_MGMT_ENABLED 设置为 TRUE 来确认协调器或设备是否能够定期进入睡眠模式?请使用功耗测量屏幕截图进行验证。此外,请进一步调试设备以确定在设备不休眠时正在处理哪些代码。

  • 设备(RFD)在收到信标帧后,即系统事件中的MAC_MLME_BEACON_NOTIFY_IND,判断信标帧的的负载,然后休眠。

      /* sleep event */
      if(events & DEVICE_SLEEP_EVENT)
      {
        setSleepPeriod(10);//set sleep time
        setPowerMode(2);//device sleep
      }
      /* the function of setting sleep time */
      static void setSleepPeriod(uint8 nS)
    {
        uint32 sleepTimer = 0;
        sleepTimer  = (uint32)ST0;
        sleepTimer |= (uint32)ST1 << 8;
        sleepTimer |= (uint32)ST2 << 16;
    
        sleepTimer += (uint32)nS * 32768;
    
        ST2 = (uint8)(sleepTimer >> 16);
        ST1 = (uint8)(sleepTimer >> 8);
        ST0 = (uint8)(sleepTimer);
    }
    
      /* set the sleep mode */
      static void setPowerMode(uint8 mode)
    {
         if(mode > 0 && mode < 4)
         {
            SLEEPCMD |= mode;    //设置系统睡眠模式
            PCON = 0x01;         //进入睡眠模式 ,通过中断唤醒
         }
         else
         {
             PCON = 0x00;        //主动/空闲模   通过中断唤醒系统
         }
    }

    中断函数则是使用的协议栈内关于睡眠定时器的中断函数

    HAL_ISR_FUNCTION(halSleepTimerIsr, ST_VECTOR)
    {
    
      HAL_ENTER_ISR();
      HAL_SLEEP_TIMER_CLEAR_INT();
    
    #ifdef HAL_SLEEP_DEBUG_POWER_MODE
      halSleepInt = TRUE;
    #endif
    
      CLEAR_SLEEP_MODE();
      HAL_EXIT_ISR();
    
    
    }

    使用的为msa_2530示例,同时已经 将MSA_PWR_MGMT_ENABLED 设置为 TRUE。至于功耗测量的话,身边暂时还没有设备。

    设备在不休眠时在进行串口打印,即收到信标帧后进行打印。

  • 您是否确定 FFD(信标发射器)和 RFD(信标接收器)都在使用 BO 和 SO 的值​​?

    FFD 是否能够接收来自 RFD 的消息?

  • 我可以确认,RFD和FFD都在使用BO 和SO的值,将RFD串口收到的数据发送给FFD,FFD可以成功接收并在串口上打印出来

  • 现在找到了问题,在第一次休眠结束后,终端不会接收第二次的信标帧,即不会进入到系统事件里的MAC_MLME_BEACON_NOTIFY_IND,所以不会进行第二次休眠,反而去执行其它没有触发的事件。

  • 感谢您的分享

  • 那现在RFD退出休眠后,接收不到信标帧应该在哪里处理哎,在终端的接收消息的callback函数里吗

  • 已为您在E2E英文论坛询问工程师,稍后给您回复

  • 感谢您向我分享您问题的最新进展。您可以使用计时器来检测丢失的信标帧。您应该添加要由事件处理器提供服务的事件 ID,以避免在硬件中断的背景下花费太多周期。