예제 #1
0
파일: main.c 프로젝트: margoraja/SYSC_4906
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();
}
예제 #2
0
파일: timer.c 프로젝트: ArakniD/dynawa
/**
  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;
}