int main(void) { struct Clock_Struct clock; //char str_buf[CLOCK_STRING_LENGTH]; buffer *rx_buf = NULL; buffer *tx_buf = NULL; uint8_t bytes_read; GPIO_init(); Timer_init(); UART_init(); NVIC_init(); // 16000000hz // 0.0000000625s // // prescale 16000 // 1000hz // 0.001s Clock_reset(&clock); Timer_set_mode(WTIMER0A, PERIODIC); Timer_set_config(WTIMER0A, INDEPENDENT); Timer_set_prescale(WTIMER0A, 16000); Timer_set_load(WTIMER0A, _wide_timer_load); Timer_enable_interrupt(WTIMER0A); Timer_enable(WTIMER0A); /*Timer_set_mode(TIMER0A, PERIODIC); Timer_set_config(TIMER0A, INDEPENDENT); Timer_set_prescale(TIMER0A, 160); Timer_set_load(TIMER0A, 50000); Timer_enable_interrupt(TIMER0A); Timer_enable(TIMER0A);*/ tx_buf = get_buffer(); strncpy(tx_buf->buf, "Clock application starting...\n\r", 32); tx_buf->fill = 32; UART_tx_message(tx_buf); tx_buf = NULL; tx_buf = get_buffer(); Clock_to_string(&clock, tx_buf->buf, CLOCK_STRING_LENGTH); tx_buf->fill = CLOCK_STRING_LENGTH; UART_tx_message(tx_buf); tx_buf = NULL; while (1) { if (_output_flag) { Clock_tick(&clock); if (_current_time_message_flag) { /*str_buf = get_buffer(); Clock_to_string(&clock, str_buf->buf, CLOCK_STRING_LENGTH); str_buf->fill = CLOCK_STRING_LENGTH; //UART_out_string(str_buf); UART_tx_message(str_buf);*/ tx_buf = get_buffer(); Clock_to_string(&clock, tx_buf->buf, CLOCK_STRING_LENGTH); tx_buf->fill = CLOCK_STRING_LENGTH; UART_tx_message(tx_buf); tx_buf = NULL; } _output_flag = 0; } // UART RX FIFO is half filled if (_rx_fill_flag) { if (rx_buf == NULL) { rx_buf = UART_rx_message(); } bytes_read = UART_read_bytes(rx_buf->buf + rx_buf->fill, FILL_LEVEL_BYTES); rx_buf->fill += bytes_read; _rx_carriage_return_received_flag = received_carriage_return(rx_buf->buf + rx_buf->fill, bytes_read); _rx_fill_flag = 0; } // UART RX FIFO timed out if (_rx_timeout_flag) { if (rx_buf == NULL) { rx_buf = UART_rx_message(); } bytes_read = UART_read_bytes(rx_buf->buf + rx_buf->fill, FILL_LEVEL_BYTES); rx_buf->fill += bytes_read; _rx_carriage_return_received_flag = received_carriage_return(rx_buf->buf + rx_buf->fill, bytes_read); _rx_timeout_flag = 0; } if (_rx_carriage_return_received_flag) { rx_buf->buf[(rx_buf->fill)++] = '\n'; rx_buf->buf[(rx_buf->fill)++] = '\0'; _rx_input_flag = 1; _rx_carriage_return_received_flag = 0; } if (_rx_input_flag) { char h_str[3]; char m_str[3]; uint8_t h; uint8_t m; _rx_input_command_enum = parse_command(rx_buf->buf); switch (_rx_input_command_enum) { case SET_TIME: h_str[0] = rx_buf->buf[1]; m_str[0] = rx_buf->buf[4]; h_str[1] = rx_buf->buf[2]; m_str[1] = rx_buf->buf[5]; h_str[2] = '\0'; m_str[2] = '\0'; h = atoi(h_str); m = atoi(m_str); Clock_set(&clock, h, m, 0); break; case PAUSE: pause_output(); break; case CONTINUE: continue_output(); break; case FASTER: faster_timer(); break; case SLOWER: slower_timer(); break; case INVALID: default: break; } tx_buf = rx_buf; rx_buf = NULL; _rx_input_flag = 0; } if (tx_buf != NULL) { if (_rx_input_command_enum != INVALID) { UART_tx_message(tx_buf); tx_buf = NULL; } else { release_buffer(tx_buf); tx_buf = NULL; } } if (_button_pressed_flag) { tx_buf = get_buffer(); strncpy(tx_buf->buf, "Button Pressed\r\n", 17); tx_buf->fill = 17; UART_tx_message(tx_buf); tx_buf = NULL; _button_pressed_flag = 0; } } buffer_queue_clean(); }
/** Start a timer. Specify if you'd like the timer to repeat and, if so, the interval at which you'd like it to repeat. If you have set up a handler with setHandler() then your handler function will get called at the specified interval. If the timer is already running, this will reset it. @param millis The number of milliseconds @param repeat Whether or not to repeat - true by default. */ int Timer_start( Timer *timer, int millis, bool repeat, bool freeOnStop ) { // debug if (millis < 0) { panic("Timer_start"); return CONTROLLER_ERROR_ILLEGAL_PARAMETER_VALUE; } //timer->started = timeval; timer->started = Timer_tick_count(); timer->value = millis; timer->timeCurrent = 0; timer->timeInitial = millis * TIMER_CYCLES_PER_MS; timer->repeat = repeat; timer->freeOnStop = freeOnStop; Timer *nextEntry = timer->next; timer->next = NULL; TRACE_TMR(">>Timer_start %x %d %d %d %d\r\n", timer, millis, repeat, freeOnStop, timer_manager.servicing); // this could be a lot smarter - for example, modifying the current period? if (sync && !timer_manager.servicing ) { Task_enterCritical(); //xSemaphoreTake(timer_mutex, -1); } TIMER_DBG_PROCESSING(true); if ( !timer_manager.running ) { // Timer_SetActive( true ); Timer_setTimeTarget( timer->timeInitial ); Timer_enable(); } /* // Calculate how long remaining int target = Timer_getTimeTarget(); int timeCurrent = Timer_getTime(); int remaining = target - timeCurrent; TRACE_TMR("t %d tc %d r %d\r\n", target, timeCurrent, remaining); */ // Get the entry ready to roll timer->timeCurrent = timer->timeInitial; // Add entry Timer* first = timer_manager.first; timer_manager.first = timer; timer->next = first; // Are we actually servicing an interupt right now? if ( !timer_manager.servicing ) { TRACE_TMR("srv 0\r\n"); // No - so does the time requested by this new timer make the time need to come earlier? // first, unlink the timer Timer *te = timer; while (te) { if (te->next && te->next == timer) { te->next = nextEntry; TRACE_TMR("Unlinking from the list %x\r\n", nextEntry); break; } te = te->next; } // Calculate how long remaining int target = Timer_getTimeTarget(); int timeCurrent = Timer_getTime(); int remaining = target - timeCurrent; TRACE_TMR("t %d tc %d r %d\r\n", target, timeCurrent, remaining); TRACE_TMR("%d < %d %d\r\n", timer->timeCurrent, remaining, TIMER_MARGIN); if ( timer->timeCurrent < ( remaining - TIMER_MARGIN ) ) { // Damn it! Reschedule the next callback Timer_setTimeTarget( target - ( remaining - timer->timeCurrent )); TRACE_TMR("%x rc %d cv %d\r\n", timer, timer_manager.tc->TC_RC, timer_manager.tc->TC_CV); // pretend that the existing time has been with us for the whole slice so that when the // IRQ happens it credits the correct (reduced) time. timer->timeCurrent += timeCurrent; } else { // pretend that the existing time has been with us for the whole slice so that when the // IRQ happens it credits the correct (reduced) time. timer->timeCurrent += timeCurrent; TRACE_TMR("sch %d\r\n", timer->timeCurrent); } } else { TRACE_TMR("srv 1\r\n"); // Yep... we're servicing something right now // Make sure the previous pointer is OK. This comes up if we were servicing the first item // and it subsequently wants to delete itself, it would need to alter the next pointer of the // the new head... err... kind of a pain, this if ( timer_manager.previous == NULL ) timer_manager.previous = timer; // Need to make sure that if this new time is the lowest yet, that the IRQ routine // knows that. Since we added this entry onto the beginning of the list, the IRQ // won't look at it again if ( timer_manager.nextTime == -1 || timer_manager.nextTime > timer->timeCurrent ) timer_manager.nextTime = timer->timeCurrent; } TIMER_DBG_PROCESSING(false); if (sync && !timer_manager.servicing ) { Task_exitCritical(); //xSemaphoreGive(timer_mutex); } TRACE_TMR("<<Timer_start %x\r\n", timer); return CONTROLLER_OK; }