static void update_count(void){ tmr_reqattr_t chan_req; uint32_t now; chan_req.channel = LCD_USECOND_OC; hwpl_tmr_off(LCD_USECOND_TMR, 0); now = hwpl_tmr_get(LCD_USECOND_TMR, 0); chan_req.value = now + LCD_USECOND_COUNTS; if( chan_req.value > CAOS_USECOND_PERIOD ){ chan_req.value -= CAOS_USECOND_PERIOD; } hwpl_tmr_setoc(LCD_USECOND_TMR, &chan_req); hwpl_tmr_on(LCD_USECOND_TMR, 0); }
void sched_priv_timedblock(void * block_object, struct sched_timeval * abs_time){ #if SINGLE_TASK == 0 int id; tmr_reqattr_t chan_req; uint32_t now; bool time_sleep; //Initialization id = task_get_current(); sched_table[id].block_object = block_object; time_sleep = false; if (abs_time->tv_sec >= sched_usecond_counter){ sched_table[id].wake.tv_sec = abs_time->tv_sec; sched_table[id].wake.tv_usec = abs_time->tv_usec; if(abs_time->tv_sec == sched_usecond_counter){ hwpl_tmr_off(clk_usecond_tmr, NULL); //stop the timer //Read the current OC value to see if it needs to be updated chan_req.channel = CAOSLIB_USECOND_TMR_SLEEP_OC; hwpl_tmr_getoc(clk_usecond_tmr, &chan_req); if ( abs_time->tv_usec < chan_req.value ){ chan_req.value = abs_time->tv_usec; } //See if abs_time is in the past now = (uint32_t)hwpl_tmr_get(clk_usecond_tmr, NULL); if( abs_time->tv_usec > (now+40) ){ //needs to be enough in the future to allow the OC to be set before the timer passes it hwpl_tmr_setoc(clk_usecond_tmr, &chan_req); time_sleep = true; } hwpl_tmr_on(clk_usecond_tmr, NULL); //start the timer } else { time_sleep = true; } } if ( (block_object == NULL) && (time_sleep == false) ){ //Do not sleep return; } sched_priv_update_on_sleep(); #endif }
int priv_usecond_match_event(void * context, const void * data){ #if SINGLE_TASK == 0 int i; uint32_t next; uint32_t tmp; int new_priority; tmr_reqattr_t chan_req; static const uint32_t overflow = (CAOS_USECOND_PERIOD); uint32_t current_match; //Initialize variables chan_req.channel = CAOSLIB_USECOND_TMR_SLEEP_OC; chan_req.value = CAOS_USECOND_PERIOD + 1; new_priority = SCHED_LOWEST_PRIORITY - 1; next = overflow; hwpl_tmr_off(clk_usecond_tmr, NULL); //stop the timer current_match = hwpl_tmr_get(clk_usecond_tmr, NULL); for(i=1; i < task_get_total(); i++){ if ( task_enabled(i) && !sched_active_asserted(i) ){ //enabled and inactive tasks only tmp = sched_table[i].wake.tv_usec; //compare the current clock to the wake time if ( (sched_table[i].wake.tv_sec < sched_usecond_counter) || ( (sched_table[i].wake.tv_sec == sched_usecond_counter) && (tmp <= current_match) ) ){ //wake this task sched_table[i].wake.tv_sec = SCHED_TIMEVAL_SEC_INVALID; sched_priv_assert_active(i, SCHED_UNBLOCK_SLEEP); if ( sched_get_priority(i) > new_priority ){ new_priority = sched_get_priority(i); } } else if ( (sched_table[i].wake.tv_sec == sched_usecond_counter) && (tmp < next) ) { //see if this is the next event to wake up next = tmp; } } } if ( next < overflow ){ chan_req.value = next; } hwpl_tmr_setoc(clk_usecond_tmr, &chan_req); sched_priv_update_on_wake(new_priority); hwpl_tmr_on(clk_usecond_tmr, NULL); #endif return 1; }
void Timer::wait_usec(uint32_t timeout){ Tmr tmr(port); tmr_reqattr_t chan_req; //enable the interrupt hwpl_tmr_off(port, 0); chan_req.channel = TMR_ACTION_CHANNEL_OC0; chan_req.value = hwpl_tmr_get(port, 0) + timeout; hwpl_tmr_setoc(port, &chan_req); tmr_is_expired = false; hwpl_tmr_on(port, 0); while( !tmr_is_expired ){ _hwpl_core_sleep(CORE_SLEEP); } }
void sched_priv_get_realtime(struct sched_timeval * tv){ tv->tv_sec = sched_usecond_counter; tv->tv_usec = (uint32_t)hwpl_tmr_get(clk_usecond_tmr, NULL); }
tmr_sample_t Tmr::get(void){ return (tmr_sample_t)hwpl_tmr_get(port_, NULL); }
int Timer::clock_usec(void){ return hwpl_tmr_get(port, 0); }