This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts
This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

BLE APP TIMER

hi,

Our customer find BLE's app_timer emerge a deviation when use the BLE's app_timer. the customer is developing bracelet product , their programs with two app_timer, the one app_ timer generating 1 second timing for date and time information.another use in pedometer function.the app_timer wake up every 25ms when counting Steps,and it wake up every minute when not used in counting Steps. if Bracelet put on the table,or rarely walk. Calendar time is right, but the Calendar time will be faster when counting Steps frequently, it will be faster two or three minutes a day. However, it not emerge a deviation under s110 v6.0 SDK v5.2 and the same program , what is the reason?

Thanks and Best regards

  • Hi, We need more information to analyse this.

    1. what kind of intervals (if in connection or advertising) is the device using?

    2. when not counting steps, is the device still in connection/advertising? if not is it in sleep mode?

    3. the difference in app timer events when counting steps and when not countin steps is 40 times(1000ms/25ms). You say when counting steps the calender is faster by three minutes a day (which uses 25ms timer). Are you sure that when not counting steps (using app timer of 1 sec) the app_timer is still faster by 9 seconds (three minutes/40 = 180/40 = 9). If this is true then both of the deviations are atleast consistent.

  • my programer use two APP TIMER

    typedef struct{
    
        SoftWareRtcInterface Interface;
    
        //private:
    
        void (*mWakeUpIrq)(void * p_context);
    
        void (*mSecondIrq)(void * p_context);
    
        void (*mMinuteIrq)(void * p_context);
    
        void (*mHourIrq)(void *p_context);
    
        volatile uint32_t mWakeUpOverFlow;
    
        volatile uint32_t mSecondCount;
    
        volatile uint32_t mSecondtRecord;
    
        volatile uint32_t mPowerUpTime;
    
        //Used to generate one second timing to generate the date and time information
    
        app_timer_id_t    mSecondTimerId;  
    
        // Wake-up timer for system operation. Pedometer when 25MS wake every time.
    
        // Stationary wake every minute
    
        app_timer_id_t    mWakeUpTimerId;
    }SoftWareRtcHal;
    
    
    #define FW_APP_TIMER_MAX_TIMERS    6 
    
    #define FW_APP_TIMER_OP_QUEUE_SIZE 20 // I tried defined as 1 OR 20
    
    
    void lfclk_config(void)
    {
    
        NRF_CLOCK->LFCLKSRC = (CLOCK_LFCLKSRC_SRC_Xtal << CLOCK_LFCLKSRC_SRC_Pos);
    
        NRF_CLOCK->EVENTS_LFCLKSTARTED = 0;
    
        NRF_CLOCK->TASKS_LFCLKSTART = 1;
    
        while (NRF_CLOCK->EVENTS_LFCLKSTARTED == 0)
        {
        }
        NRF_CLOCK->EVENTS_LFCLKSTARTED = 0;
    }
    
    void AppTimeInit(void)
    {
    
        APP_TIMER_INIT(APP_TIMER_PRESCALER, FW_APP_TIMER_MAX_TIMERS, 
        FW_APP_TIMER_OP_QUEUE_SIZE, FALSE);
    
    }
    
    void InitSoftWareRtc(SoftWareRtcInterface *interface)
    {
    
        uint32_t err_code;
    
        SoftWareRtcHal *pRtcHal = (SoftWareRtcHal *)interface;    
    
    
        interface->SetWakeUpPeriod = &gRtcSetWakeUpPeriod;
    
        interface->GetSecond32 = &gRtcGetSecond32;
    
        interface->GetPowerUpTime = &gRtcGetPowerUpTime;
    
        interface->SetDate = &gRtcSetDate;
    
        interface->SetTime = &gRtcSetTime;
    
        interface->GetDate = &gRtcGetDate;
    
        interface->GetTime = &gRtcGetTime;
    
        interface->RegisterWakeUpIrq = &gRtcRegisterWakeUpIrq;
    
        interface->RegisterSecondIrq = &gRtcRegisterSecondIrq;
    
        interface->RegisterMinuteIrq = &gRtcRegisterMinuteIrq;
    
        interface->RegisterHourIrq = &gRtcRegisterHourIrq;
    
        interface->StateCheck = &gRtcStateCheck;
    
        //interface->IRQHandle = &gRtcIRQHandle;
    
        interface->RestStart = &gRtcRestStart;
    
        pRtcHal->mSecondtRecord = pRtcHal->mSecondCount;
    
        pRtcHal->mWakeUpIrq = NULL;
    
        pRtcHal->mSecondIrq = NULL;
    
        pRtcHal->mMinuteIrq = NULL;
    
        pRtcHal->mHourIrq = NULL;	
    
        TRACE2("pRtcHal->gRtcSecond = %x", pRtcHal->mSecondCount);
    
        err_code = app_timer_create(&pRtcHal->mSecondTimerId,
                     APP_TIMER_MODE_REPEATED,
                     gRtcAppTimerSecondHandle);
    
        APP_ERROR_CHECK(err_code);
    
        err_code = app_timer_start(pRtcHal->mSecondTimerId,
                    APP_TIMER_TICKS(1000, APP_TIMER_PRESCALER),
                    pRtcHal);
    
        APP_ERROR_CHECK(err_code);
    
        err_code = app_timer_create(&pRtcHal->mWakeUpTimerId,
                     APP_TIMER_MODE_REPEATED,
                     gRtcAppTimerWakeUpHandle);
    
        APP_ERROR_CHECK(err_code);
    }
    
    void gRtcAppTimerSecondHandle(void * p_context)
    {
    
        SoftWareRtcHal *pRTC = (SoftWareRtcHal *)p_context;
    
        pRTC->mSecondCount++;
    
        if(pRTC->mSecondIrq != NULL)
        {
            pRTC->mSecondIrq(NULL);
        }
    
        if((pRTC->mMinuteIrq != NULL) &&
            (pRTC->mSecondCount % 60 == 0))
        {
            pRTC->mMinuteIrq(NULL);
        }
    
        if((pRTC->mHourIrq != NULL) &&
            (pRTC->mSecondCount % 3600 == 0))
        {
            pRTC->mHourIrq(NULL);
        }
    
        //TRACE_INFO1("*");
    }
    
    bool gRtcSetWakeUpPeriod(SoftWareRtcInterface *RtcInterface, uint16_t period)
    {
    
        /*************************************
        *    Ftick = 1000mS/period;
        *    Ftick == 32768/(PRESCALER+1)
        *==> PRESCALER + 1 == 32768 / Ftick
        *==>
        *==> PRESCALER == 32768 * period / 1000 -1
        *
        *TICK = 32768 / (127+1); 128分频
        *T = 1/TICK;
        *PROID = T * WakeUpOverFlow = WakeUpOverFlow / TICK;
        *WakeUpOverFlow = PROID * (32768 / 128);
        *30mS => WakeUpOverFlow = 0.030 * (32768/128) = 8
        **************************************/
    
        uint32_t err_code;
    
        SoftWareRtcHal *pRTC;
    
        uint32_t mCurWakeUpOverFlow;
    
        if(RtcInterface == NULL)
            return -1;
    
        pRTC = (SoftWareRtcHal *)RtcInterface;
    
        mCurWakeUpOverFlow = APP_TIMER_TICKS(period, NRF_RTC1->PRESCALER);
    
        if(mCurWakeUpOverFlow == pRTC->mWakeUpOverFlow)
             return 0;
    
        pRTC->mWakeUpOverFlow = mCurWakeUpOverFlow;	
    
        TRACE2("pRTC->mWakeUpOverFlow = %x", pRTC->mWakeUpOverFlow);
    
        if((pRTC->mWakeUpOverFlow >= (MAX_RTC_CNT + 1 - RTC_COMPARE_OFFSET_MIN)) ||
    		(pRTC->mWakeUpOverFlow < 5))
        {
        
             TRACE_ERROR2("Rtc WakeUpPeriod Set ERR pRTC->mWakeUpOverFlow = %d",
    		              pRTC->mWakeUpOverFlow);
            while(1);			
        }    
    
        if(pRTC->mWakeUpIrq != NULL)
        {
             err_code = app_timer_stop(pRTC->mWakeUpTimerId);
             APP_ERROR_CHECK(err_code);
       
             err_code = app_timer_start(pRTC->mWakeUpTimerId,
                    pRTC->mWakeUpOverFlow,
                    pRTC);
             APP_ERROR_CHECK(err_code);
         }
    
        return 0;
    }
    
    1. what kind of intervals (if in connection or advertising) is the device using?
      Is usually not connected, but the advertising

    2. when not counting steps, is the device still in connection/advertising? if not is it in sleep mode? advertising or connection is possible, if it is connected APP. Program calls the following function into Sleep.

      uint8_t PowerSave(void) { uint8_t mSdIsEnabled; sd_softdevice_is_enabled(&mSdIsEnabled);

       if(mSdIsEnabled)
       {
           uint32_t err_code;
           //TRACE1("$");
           err_code = sd_app_evt_wait();
           APP_ERROR_CHECK(err_code);  
      }
      else
      {
           NRF_POWER->TASKS_LOWPWR = 1;
           __WFE();
      
           __SEV();
           __WFE();  
      }
      return mSdIsEnabled;
      

      }

    3. the difference in app timer events when counting steps and when not countin steps is 40 times(1000ms/25ms). You say when counting steps the calender is faster by three minutes a day (which uses 25ms timer). Are you sure that when not counting steps (using app timer of 1 sec) the app_timer is still faster by 9 seconds (three minutes/40 = 180/40 = 9). If this is true then both of the deviations are atleast consistent.

    From Friday to now, almost pedometer and computer time

  • Hi guozhong.chen I am sorry, i lost visibility of this thread, do you still have this problem?

Related