static void sm_set(heater_sm_t state) { switch (state) { case SM_IDLE_MIN: pump_off(); timer_set_alarm(IDLE_MIN_TIME); break; case SM_IDLE: timer_set_alarm(IDLE_MAX_TIME); break; case SM_PUMPING_MIN: pump_on(); timer_set_alarm(PUMPING_MIN_TIME); break; case SM_PUMPING: timer_set_alarm(PUMPING_MAX_TIME); break; case SM_CLEANING: pump_on(); timer_set_alarm(PUMPING_MAX_TIME); break; } curr_state = state; }
int timer_remove(struct timer *t) { struct timer *curr, *prev; if (!t) return -1; if(t->used == 0) return 0; t->used = 0; for (prev = NULL, curr = TQ; curr != NULL; prev = curr, curr = curr->next) { if (curr == t) { if (prev == NULL) { TQ = curr->next; /* Update the alarm */ timer_set_alarm(); } else prev->next = curr->next; curr->next = NULL; return 0; } } /* We didn't find the timer... */ return -1; }
int timer_timeout_now(struct timer *t) { struct timer *curr, *prev; if (!t) return -1; t->used = 0; for (prev = NULL, curr = TQ; curr != NULL; prev = curr, curr = curr->next) { if (curr == t) { /* Decouple timer from queue */ if (prev == NULL) { TQ = curr->next; /* Update alarm since this was the first in queue */ timer_set_alarm(); } else prev->next = curr->next; /* Call handler function */ curr->handler(curr->data); curr->next = NULL; /* if (curr->data) */ /* free (curr->data); */ return 0; } } /* We didn't find the timer... */ return -1; }
/* Called when a timer should timeout */ void timer_timeout() { struct timer *prev, *expiredTQ, *tmp; struct timeval now; gettimeofday(&now, NULL); #ifdef DEBUG_TIMER_QUEUE printf("timer_timeout: called!!\n"); printTQ(); #endif expiredTQ = TQ; for (prev = NULL; TQ != NULL; prev = TQ, TQ = TQ->next) { /* Check if the current timer should not expire yet... */ if (timeval_diff(&TQ->timeout, &now) > 0) { if (prev == NULL) /* No timers have expired yet... */ goto end; prev->next = NULL; break; } } while (expiredTQ) { tmp = expiredTQ; expiredTQ->used = 0; expiredTQ = expiredTQ->next; tmp->next = NULL; #ifdef DEBUG_TIMER_QUEUE printf("timer_timeout: removing timer\n"); #endif /* Execute handler function for expired timer... */ if (tmp->handler) tmp->handler(tmp->data); } /* Schedule a new timeout... */ end: timer_set_alarm(); }
int main(void) { WDTCTL = WDTPW + WDTHOLD; // Stop watchdog timer eint(); clock_dco_set(8); // DCO 8MHz clock_mclk_set(CLOCK_SOURCE_DCO, 1); // MCLK 8MHz clock_smclk_set(CLOCK_SOURCE_DCO, 8); // SMCLK 1MHz clock_aclk_set(1); leds_init(); leds_off(LEDS_ALL); mac_init(); mac_set_tx_cb(sent); mac_set_rx_cb(rx); timer_start(TIMER_SOURCE_ACLK, 1); timer_register_cb(TIMER_ALARM_0, send); timer_set_alarm(TIMER_ALARM_0, 12000, 12000, TIMER_MODE_FROM_NOW, 0); leds_on(LEDS_ALL); while (1) { event = 0; LPM0; switch (event) { case EVENT_SEND: mac_send(msg, strlen(msg), MAC_BROADCAST); break; case EVENT_SENT: leds_toggle(LED_GREEN); break; case EVENT_RX: leds_toggle(LED_RED); break; } } return 0; }
/** * \brief Application loader. * * This worker function loads the alarm light bitmaps, then loads the background * image before showing all the widgets and starting the process simulation. * * If memory for bitmaps cannot be allocated, or the background image cannot be * loaded, the application will exit immediately. * * \param task Workqueue task for this worker function. */ static void tank_loader(struct workqueue_task *task) { enum status_code result; hugemem_ptr_t bitmap_data; /* Handle the individual bitmap load states. * * All states, except LOAD_FINISHED, will cause the current workqueue * task to be re-enqueued after loading of the corresponding bitmap has * completed. This task worker will thus go through the states in * sequence. */ switch (tank_ctx->loader_state) { case LOAD_RED_LIGHT: // Enqueue loading of the red alarm light bitmap. bitmap_data = load_file_to_hugemem(BITMAP_RED_LIGHT_FILENAME, task); /* If memory could be allocated for the bitmap, update the * pointer in the bitmap metadata and set next load state. * Otherwise, exit the application load error. */ if (bitmap_data != HUGEMEM_NULL) { tank_bitmap_data[BITMAP_RED_LIGHT] = bitmap_data; tank_ctx->bitmaps[BITMAP_RED_LIGHT].data.hugemem = bitmap_data; tank_ctx->loader_state = LOAD_GREEN_LIGHT; } else { goto exit_load_error; } break; case LOAD_GREEN_LIGHT: bitmap_data = load_file_to_hugemem(BITMAP_GREEN_LIGHT_FILENAME, task); if (bitmap_data != HUGEMEM_NULL) { tank_bitmap_data[BITMAP_GREEN_LIGHT] = bitmap_data; tank_ctx->bitmaps[BITMAP_GREEN_LIGHT].data.hugemem = bitmap_data; tank_ctx->loader_state = LOAD_BACKGROUND; } else { goto exit_load_error; } break; case LOAD_BACKGROUND: // Now load the background image. result = load_file_to_screen(BITMAP_BACKGROUND_FILENAME, BITMAP_BACKGROUND_POSITION_X, BITMAP_BACKGROUND_POSITION_Y, BITMAP_BACKGROUND_SIZE_X, BITMAP_BACKGROUND_SIZE_Y, task); if (result == STATUS_OK) { tank_ctx->loader_state = LOAD_FINISHED; } else { goto exit_load_error; } break; case LOAD_FINISHED: // Now show the application's frame. This will draw all widgets. win_show(wtk_basic_frame_as_child(tank_ctx->frame)); // Set the worker function that updates the application. workqueue_task_set_work_func(task, tank_worker); // Set the timer alarm to trigger application updates. timer_start(CONFIG_TIMER_ID, &tank_ctx->timer); timer_set_alarm(CONFIG_TIMER_ID, &tank_ctx->timer, tank_ctx->timer_delay); break; default: // Should not end up here. unhandled_case(tank_ctx->loader_state); break; } return; // If a load error occurred, go back to the desktop. exit_load_error: win_destroy(wtk_basic_frame_as_child(tank_ctx->frame)); memcpy(&sysfont, &tank_ctx->old_sysfont, sizeof(struct font)); membag_free(tank_ctx); tank_ctx = NULL; app_desktop_restart(); }
/** * \brief Application timer callback function. * * This callback function is used with the \ref timer_group "Timer driver" and * will enqueue the task for application updates. * * \param timer Pointer to timer struct associated with the callback. */ static void tank_timer_callback(struct timer *timer) { timer_set_alarm(CONFIG_TIMER_ID, &tank_ctx->timer, tank_ctx->timer_delay); workqueue_add_task(&main_workqueue, tank_ctx->task); }
static void timer_add(struct timer *t) { struct timer *curr, *prev; /* Sanity checks: */ if (!t) { perror("NULL timer!!!\n"); exit(-1); } if (!t->handler) { perror("NULL handler!!!\n"); exit(-1); } /* Make sure we remove unexpired timers before adding a new timeout... */ if (t->used) timer_remove(t); t->used = 1; #ifdef DEBUG_TIMER_QUEUE printf("timer_add: New timer added!\n"); #endif /* Base case when queue is empty: */ if (!TQ) { TQ = t; t->next = NULL; /* Since we insert first in the queue we must reschedule the first timeout */ timer_set_alarm(); goto end; } for (prev = NULL, curr = TQ; curr != NULL; prev = curr, curr = curr->next) { if (timeval_diff(&t->timeout, &curr->timeout) < 0) { /* OK, we found the spot to insert the timer */ if (prev == NULL) { /* We insert first in queue */ TQ = t; t->next = curr; /* Since we insert first in the queue we must reschedule the first timeout */ timer_set_alarm(); goto end; } t->next = curr; prev->next = t; goto end; } } /* We insert last in queue */ prev->next = t; t->next = NULL; end: #ifdef DEBUG_TIMER_QUEUE printTQ(); #endif return; }