/* If FreeRTOS is not running, then we rely on RIT service to call this function,
 * otherwise we rely on FreeRTOS tick hook to provide system timer
 */
static void hl_periodic_service(void)
{
    sys_watchdog_feed();

    /* If FreeRTOS is running, user should use a dedicated task to call mesh service,
     * so we will not call it if freertos is running
     */
    if (taskSCHEDULER_RUNNING == xTaskGetSchedulerState()) {
        g_system_uptime_ms += MS_PER_TICK();

        /* We don't need RIT if FreeRTOS is running */
        if (sys_rit_running()) {
            sys_rit_disable();

            /* The timer value so far may be an odd number, and if MS_PER_TICK() is not 1
             * then we may increment it like 12, 22, 32, etc. so round this number once.
             */
            g_system_uptime_ms = (g_system_uptime_ms / 10) * 10;
        }
    }
    else {
        g_system_uptime_ms += g_time_per_rit_isr_ms;
        wireless_service();

        /**
         * Small hack to support interrupts if FreeRTOS is not running :
         * FreeRTOS API resets our base priority register, then all
         * interrupts higher priority than IP_SYSCALL will not get locked out.
         *   @see more notes at isr_priorities.h.  @see IP_SYSCALL
         */
        __set_BASEPRI(0);
    }
}
Exemplo n.º 2
0
/* If FreeRTOS is not running, then we rely on rit service to call this function,
 * otherwise we rely on FreeRTOS tick hook to provide system timer
 */
static void hl_periodic_service(void)
{
    const uint32_t timer_ms = sys_get_uptime_ms();

    /* If FreeRTOS is running, user should use a dedicated task to call mesh service,
     * so we will not call it if freertos is running
     */
    if (taskSCHEDULER_RUNNING == xTaskGetSchedulerState()) {
        m_system_uptime_ms += MS_PER_TICK();

        /* We don't need RIT if FreeRTOS is running */
        if (sys_rit_running()) {
            sys_rit_disable();

            /* Round up uptime_ms because if ms per tick is 10, then we don't want to
             * increment this timer by 10 from an odd number because % 10 won't work.
             */
            m_system_uptime_ms = (m_system_uptime_ms / 10) * 10;
        }
    }
    else {
        m_system_uptime_ms += m_time_per_rit_isr_ms;
        wireless_service();

        /**
         * Small hack to support interrupts if FreeRTOS is not running :
         * FreeRTOS API resets our base priority register, then all
         * interrupts higher priority than IP_SYSCALL will not get locked out.
         *   @see more notes at isr_priorities.h.  @see IP_SYSCALL
         */
        __set_BASEPRI(0);
    }
	
	/**
     * Call SD timer function at 100Hz.
     * Feed the watchdog too while we're at it.
     */
    if (0 == (timer_ms % 10)) {
        sd_timerproc();
        sys_watchdog_feed();
    }
}
Exemplo n.º 3
0
void TIMERX_BAD_IRQHandler()
#endif
{
    enum {
        timer_mr0_intr   = (1 << 0),
        timer_mr1_intr   = (1 << 1),
        timer_mr2_intr   = (1 << 2),
        timer_mr3_intr   = (1 << 3),
        timer_capt0_intr = (1 << 4),
        timer_capt1_intr = (1 << 5),
    };

    const uint32_t intr_reason = gp_timer_ptr->IR;

#if (1 == SYS_CFG_SYS_TIMER)
    /* TODO: Call capture ISR callback for IR receiver */
    if (intr_reason & timer_capt0_intr)
    {
        gp_timer_ptr->IR = timer_capt0_intr;

        // Setup timeout of IR signal (unless we reset it again)
        gp_timer_ptr->MR2 = 10000 + gp_timer_ptr->TC;
    }
    /* TODO MR2: End of IR capture (no IR capture after initial IR signal) */
    else if (intr_reason & timer_mr2_intr)
    {
        gp_timer_ptr->IR = timer_mr2_intr;
    }
    /* MR0 is used for the timer rollover count */
    else
#endif
    if(intr_reason & timer_mr0_intr)
    {
        gp_timer_ptr->IR = timer_mr0_intr;
        ++g_timer_rollover_count;
    }
    /* MR1 is used as a periodic interrupt to service background tasks and reset watchdog */
    else if(intr_reason & timer_mr1_intr)
    {
        gp_timer_ptr->IR = timer_mr1_intr;

        /* Setup the next periodic interrupt */
        gp_timer_ptr->MR1 += g_periodic_isr_time_value_us;

        /* In case someone else (you) spent too long inside another isr, we may not be able
         * to set the MR1 correctly since the TC may have already past our next MR1, so in
         * this case, make an adjustment.
         */
        if (gp_timer_ptr->MR1 < gp_timer_ptr->TC) {
            gp_timer_ptr->MR1 += (g_periodic_isr_time_value_us + gp_timer_ptr->TC);
        }

        /* If no one feeds watchdog interrupt, we will watchdog reset.  We are using a periodic ISR
         * to feed watchdog because if a critical exception hits, it will enter while(1) loop inside
         * the interrupt, and since watchdog won't reset, it will trigger system reset.
         */
        sys_watchdog_feed();

        // Service the background task if FreeRTOS is not running
        if ((taskSCHEDULER_RUNNING != xTaskGetSchedulerState())) {
            sys_background_service();
        }
        /**
         * If FreeRTOS is running, then decrease the frequency of the periodic ISR because
         * mesh service is performed by FreeRTOS task, and the only other thing we need to
         * do periodically is the watchdog feed.
         */
        else if (g_periodic_isr_time_value_us != LPC_SYS_TIME_1000US) {
             g_periodic_isr_time_value_us = 1000 * LPC_SYS_TIME_1000US;
        }
    }
    else
    {
        // Unexpected interrupt, so stay here to trigger watchdog interrupt
        puts("Unexpected ISR call at lpc_sys.c");
        while (1) {
            ;
        }
    }
}