Example #1
0
static void jump_to_app(void) {

	const uint32_t *app_base = (const uint32_t *)APP_LOAD_ADDRESS;

	// Check that flash has been programmed
	if (app_base[0] == 0xffffffff)
		goto fail;

	// Check that reset vector is somewhere in the app's boundaries
	if (app_base[1] < APP_LOAD_ADDRESS)
		goto fail;
	if (app_base[1] >= (APP_LOAD_ADDRESS + (1024 * 1024)))
			goto fail;

	// LEDs to known state
	green_led(1);
	red_led(0);

	// Set vector table address
	SCB->VTOR = APP_LOAD_ADDRESS;

	// Jump to the application
	do_jump(app_base[0], app_base[1]);

	// LEDs indicate error
	fail:
	green_led(0);
	red_led(0);
	for(;;);
}
Example #2
0
int main()                     // run over and over again
{
  while(1) 
  {
    // note that the following line could also be accomplished with:
    // int pot = analogRead(7);
    int pot = read_trimpot();  // determine the trimpot position
    
    // avoid clearing the LCD to reduce flicker
    lcd_goto_xy(0, 0);
    print("pot=");
    print_long(pot);               // print the trim pot position (0 - 1023)
    print("  ");              // overwrite any left over digits
    
    int motorSpeed = (512 - pot) / 2;
    lcd_goto_xy(0, 1);
    print("spd=");
    print_long(motorSpeed);        // print the resulting motor speed (-255 - 255)
    print("   ");
    set_motors(motorSpeed, motorSpeed);  // set speeds of motors 1 and 2

    // all LEDs off
    red_led(0);
    green_led(0);
    // turn green LED on when motors are spinning forward
    if (motorSpeed > 0)
      green_led(1);
    // turn red LED on when motors are spinning in reverse
    if (motorSpeed < 0)
      red_led(1);
    delay_ms(100);
  }
}
Example #3
0
void pot_test()
{
    long start = get_ms();
    char elapsed_ms;
    int value;

    set_analog_mode(MODE_10_BIT);
    print_long(read_trimpot());
    print("   "); // to clear the display

    while((elapsed_ms = get_ms() - start) < 100)
    {
        value = read_trimpot();
        play_frequency(value, 200, 15);

        if(value < elapsed_ms*10)
        {
            red_led(0);
            green_led(1);
        }
        else
        {
            red_led(1);
            green_led(0);
        }
    }
}
Example #4
0
int main()
{
  set_analog_mode(MODE_8_BIT);    // 8-bit analog-to-digital conversions
  sum = 0;
  samples = 0;
  avg = 0;
  start_analog_conversion(TRIMPOT);  // start initial conversion

  while(1)
  {
    if (!analog_is_converting())     // if conversion is done...
    {
      sum += analog_conversion_result();  // get result
      start_analog_conversion(TRIMPOT);   // start next conversion
      if (++samples == 20)           // if 20 samples have been taken...
      {
        avg = sum / 20;             // compute 20-sample average of ADC result
        samples = 0;
        sum = 0;
      }
    }
    
    // when avg == 0, the red LED is almost totally off.
    // when avg == 255, the red LED is almost totally on.
    // brightness should scale approximately linearly in between.
    red_led(0);                 // red LED off
    delay_us(256 - avg);
    red_led(1);                 // red LED on
    delay_us(avg+1);
  } 
}
Example #5
0
int main(void) {

	led_setup();

	for(int i = 0; i < 4; i++) {

		red_led(1);
		green_led(1);

		sleep(500);

		red_led(0);
		green_led(0);

		sleep(500);

		red_led(1);

		sleep(500);

		red_led(0);

		sleep(500);
	}
	jump_to_app();
}
Example #6
0
int main()
{
  TCCR0A = 0;         // configure timer0 to run at 78 kHz
  TCCR0B = 0x04;      // and overflow when TCNT0 = 256 (~3 ms)
  play_from_program_space(rhapsody);

  while(1)
  {
    // allow the sequence to keep playing automatically through the following delays
#ifndef ALWAYS_CHECK
    play_mode(PLAY_AUTOMATIC);
#else
    play_mode(PLAY_CHECK);
#endif
    lcd_goto_xy(0, 0);
    print("blink!");
    int i;
    for (i = 0; i < 8; i++)
    {
#ifdef ALWAYS_CHECK
      play_check();
#endif
      red_led(1);
      delay_ms(500);
      red_led(0);
      delay_ms(500);
    }
  
    lcd_goto_xy(0, 0);
    print("timing");
    lcd_goto_xy(0, 1);
    print("        ");    // clear bottom LCD line
    // turn off automatic playing so that our time-critical code won't be interrupted by
    // the buzzer's long timer1 interrupt.  Otherwise, this interrupt could throw off our
    // timing measurements.  Instead, we will now use playCheck() to keep the sequence
    // playing in a way that won't throw off our measurements.
#ifndef ALWAYS_AUTOMATIC
    play_mode(PLAY_CHECK);
#endif
    unsigned char maxTime = 0;
    for (i = 0; i < 8000; i++)
    {
      TCNT0 = 0;
      while (TCNT0 < 20)    // time for ~250 us
        ;
      if (TCNT0 > maxTime)
        maxTime = TCNT0;    // if the elapsed time is greater than the previous max, save it
#ifndef ALWAYS_AUTOMATIC
      play_check();   // check if it's time to play the next note and play it if so
#endif
    }
    lcd_goto_xy(0, 1);
    print("max=");
    print_long((unsigned int)maxTime);
    print(" ");  // overwrite any left over characters
  }
}
Example #7
0
// Blinks the LEDs
void led_test()
{
	play("c32");
	print("Red 1   ");

	red_led(1);
	if(wait_for_250_ms_or_button_b())
		return;
	red_led(0);
	if(wait_for_250_ms_or_button_b())
		return;

	play(">c32");
	lcd_goto_xy(0,0);
	print("Green 1 ");

	green_led(1);
	if(wait_for_250_ms_or_button_b())
		return;
	green_led(0);
	if(wait_for_250_ms_or_button_b())
		return;

	play("d32");
	lcd_goto_xy(0,0);
	print("Red 2   ");

	red_led2(1);
	if(wait_for_250_ms_or_button_b())
		return;
	red_led2(0);
	if(wait_for_250_ms_or_button_b())
		return;

	play(">d32");
	lcd_goto_xy(0,0);
	print("Green 2 ");

	green_led2(1);
	if(wait_for_250_ms_or_button_b())
		return;
	green_led2(0);
	if(wait_for_250_ms_or_button_b())
		return;

	play("e32>e32");
	lcd_goto_xy(0,0);
	print("Yellow  ");

	yellow_led(1);
	if(wait_for_250_ms_or_button_b())
		return;
	yellow_led(0);
	if(wait_for_250_ms_or_button_b())
		return;
}
Example #8
0
static void panic(void) {
	led_setup();
	green_led(0);
	for(;;){
		red_led(1);
		spin_sleep(200);
		red_led(0);
		spin_sleep(200);
	}
}
Example #9
0
int main()
{
	while(1)
	{
		red_led(1);     // Turn on the red LED.
		delay_ms(200);  // Wait for 200 ms.

		red_led(0);     // Turn off the red LED.
		delay_ms(200);  // Wait for 200 ms.
	}
}
Example #10
0
int main()
{
    while(1)
    {
        red_led(1);               // red LED on
        delay_ms(1000);           // waits for a second
        red_led(0);               // red LED off
        delay_ms(1000);           // waits for a second
        green_led(1);             // green LED on (will not work on the Baby Orangutan)
        delay_ms(500);            // waits for 0.5 seconds
        green_led(0);             // green LED off (will not work on the Baby Orangutan)
        delay_ms(500);            // waits for 0.5 seconds
    }
}
Example #11
0
void *dmr_sms_arrive_hook(void *pkt){
  /* This hooks the SMS arrival routine, but as best I can tell,
     dmr_sms_arrive() only handles the header and not the actual
     data payload, which is managed by dmr_handle_data() in each
     fragment chunk.

     *pkt points to a twelve byte header with two bytes of C5000
     overhead.  The body packets will arrive at dmr_handle_data_hook()
     in chunks of up to twelve bytes, varying by data rate.

     A full transaction from 3147092 to 99 looks like this:

             header
             |   / /flg\ /--dst-\ /--src-\ /flg\ /crc\
SMS header:  08 6a 02 40 00 00 63 30 05 54 88 00 83 0c
       Data: 08 7a 45 00 00 5c 00 03 00 00 40 11 5c a8
       Data: 08 7a 0c 30 05 54 0c 00 00 63 0f a7 0f a7
       Data: 08 72 00 48 d1 dc 00 3e e0 00 92 04 0d 00
       Data: 08 72 0a 00 54 00 68 00 69 00 73 00 20 00
       Data: 08 72 69 00 73 00 20 00 61 00 20 00 74 00
       Data: 08 7a 65 00 73 00 74 00 20 00 66 00 72 00
       Data: 08 7a 6f 00 6d 00 20 00 6b 00 6b 00 34 00
       Data: 08 7a 76 00 63 00 7a 00 21 00 9e 21 5a 5c
   */

  //Turn on the red LED to know that we're here.
  red_led(1);

  printf("SMS header: ");
  printhex((char*) pkt, 12+2);
  printf("\n");

  //Forward to the original function.
  return dmr_sms_arrive(pkt);
}
Example #12
0
static portTASK_FUNCTION( vBlockingQueueProducer, pvParameters )
{
unsigned short usValue = 0;
xBlockingQueueParameters *pxQueueParameters;
short sErrorEverOccurred = pdFALSE;

	pxQueueParameters = ( xBlockingQueueParameters * ) pvParameters;

	for( ;; )
	{
		if( xQueueSend( pxQueueParameters->xQueue, ( void * ) &usValue, pxQueueParameters->xBlockTime ) != pdPASS )
		{
			sErrorEverOccurred = pdTRUE;
		}
		else
		{
			/* We have successfully posted a message, so increment the variable
			used to check we are still running. */
			if( sErrorEverOccurred == pdFALSE )
			{
				( *pxQueueParameters->psCheckVariable )++;
			}

			/* Increment the variable we are going to post next time round.  The
			consumer will expect the numbers to	follow in numerical order. */
			++usValue;
            
            play_from_program_space(PSTR("d"));
            while (is_playing()){};
    		red_led(1);     // Turn on the red LED.
	    	delay_ms(20);  // Wait for 20 ms.
		}
	}
}
Example #13
0
// This is the main function, where the code starts.  All C programs
// must have a main() function defined somewhere.
int main()
{
	// Set all five user LEDs as outputs driven low.
	// Otherwise, the LEDs are driven by the LCD and can appear
	// on or partially on.
	red_led(0);
	green_led(0);
	red_led2(0);
	green_led2(0);
	yellow_led(0);

	clear();
	
	delay(10);

	// if any button is pressed, go into the old version of the test code
	if(button_is_pressed(ANY_BUTTON))
	{
		print("Simple Test");
		wait_for_button_release(button_is_pressed(ANY_BUTTON));
		test(); // activate the simpler test code
	}

	// set up the robot
	initialize();

	// This is the "main loop" - it will run forever.
	while(1)
	{
		menu_select();
	}
}
Example #14
0
int main()
{
	play_from_program_space(PSTR(">g32>>c32"));  // Play welcoming notes.

	while(1)
	{
		// Print battery voltage (in mV) on LCD.
		clear();
		print_long(read_battery_millivolts_sv());

		red_led(1);     // Turn on the red LED.
		delay_ms(200);  // Wait for 200 ms.

		red_led(0);     // Turn off the red LED.
		delay_ms(200);  // Wait for 200 ms.
	}
}
Example #15
0
void error()
{
	Led red_led(LED1, OFF);
	while (1) {
		red_led.toggle();
		delay();
	}
}
Example #16
0
int main()
{
	play_from_program_space(PSTR(">g32>>c32"));  // Play welcoming notes.

	while(1)
	{
		// Get battery voltage (in mV) from the auxiliary processor
		// and print it on the the LCD.
		clear();
		print_long(read_battery_millivolts_svp());

		red_led(1);     // Turn on the red LED.
		delay_ms(200);  // Wait for 200 ms.

		red_led(0);     // Turn off the red LED.
		delay_ms(200);  // Wait for 200 ms.
	}
}
Example #17
0
int main()
{
	print("Hello!");

	play("L16 ceg>c");

	while(1)
	{
		red_led(0);
		green_led(1);

		delay_ms(100);

		red_led(1);
		green_led(0);
		
		delay_ms(100);
	}

	return 0;
}
Example #18
0
int main (void) {
	int on=0, ID, calb;
	
	int batt_voltage = 0;    
	
	//init();
	//ID = readID();
	//calb = readCalibration();
	//	GPIO_SetValue(RED_LED_PORT, RED_LED_BIT,1);

	int i = 0; /* Used in main loop */
	uint32_t value = 0xaa;
	setup_ports();
	
	sc_time_t one_sec_timer = sc_get_timer(); /* Initialise the timer variable */
	sc_time_t test_in_timer = sc_get_timer(); /* Initialise the timer variable */

	
	/* Set LEDs to known states, i.e. on */
	red_led(ON);
	yellow_led(ON);
	
	
	
	GPIO_SetValue(CAN_EN_PORT, CAN_EN_BIT, ON);
	
	scandal_register_in_channel_handler(0, &in_channel_0_handler);
	

	/* This is the main loop, go for ever! */
	while (1) {
		/* This checks whether there are pending requests from CAN, and sends a heartbeat message.
		* The heartbeat message encodes some data in the first 4 bytes of the CAN message, such as
		* the number of errors and the version of scandal */
		handle_scandal();
		/*
		 * scandal_send_channel(TELEM_LOW, ID_VOLT, readVoltage());
		 * scandal_send_channel(TELEM_LOW, ID_TEMP, readTemperature());
		 * scandal_send_channel(TELEM_LOW, ID_VOLT, readVoltage());
		 */
		
		if(sc_get_timer() >= one_sec_timer + 1000) {
			toggle_red_led();
			toggle_yellow_led();
			one_sec_timer = sc_get_timer();
			batt_voltage = readVoltage();
			scandal_send_channel(TELEM_LOW, // priority 
							0,      // channel num 
							batt_voltage    // value 
							);
		}
	}
}
Example #19
0
void test_leds()
{
  while(!button_is_pressed(ALL_BUTTONS))
  {
    clear();
    printf("Check\n");
    printf("Red");

    red_led(1);
    play_frequency(440,50,15);
    delay_ms(250);

    if(button_is_pressed(ALL_BUTTONS))
      break;

    red_led(0);
    delay_ms(250);

    if(button_is_pressed(ALL_BUTTONS))
      break;
    
    clear();
    printf("Check\n");
    printf("Green");

    green_led(1);
    play_frequency(880,50,15);
    delay_ms(250);

    if(button_is_pressed(ALL_BUTTONS))
      break;

    green_led(0);
    delay_ms(250);
  }

  while(button_is_pressed(ALL_BUTTONS));
  delay_ms(100);
}
Example #20
0
// Blinks the LEDs
void led_test()
{
    play("c32");
    print("Red  ");

    red_led(1);
    if(wait_for_250_ms_or_button_b())
        return;
    red_led(0);
    if(wait_for_250_ms_or_button_b())
        return;

    play(">c32");
    lcd_goto_xy(0,0);
    print("Green");

    green_led(1);
    if(wait_for_250_ms_or_button_b())
        return;
    green_led(0);
    if(wait_for_250_ms_or_button_b())
        return;
}
Example #21
0
// *** triggered by middle button ***
// This function tests the motors by first ramping motor1 speed from zero
// to full speed "forward", to full speed "reverse", and finally back to zero.
// It then does the same for motor2 before repeating all over again.
// While motor1 is running, the red user LED is on, otherwise it is off.
// While the currently active motor is moving "forward", the green user LED
// is on, otherwise it is off.  The LCD gives you feedback as to which motor
// is currently moving in which direction (F = "forward", R = "reverse", and
// - = inactive).
unsigned char motorTest()
{
	unsigned char button;
	int speed;
	unsigned char motor = 0;

	clear();			// clear the LCD, go to the start of the first LCD line
	print("motor2");	// print to the first line of the LCD
	lcd_goto_xy(0, 1);	// go to the start of the second LCD line
	print("motor1");	// print to the second line of the LCD

	while (1)
	{
		red_led(!motor);	// turn red LED on when m1 is active, off for m2
		lcd_goto_xy(7, !motor);	// go to end of LCD line for active motor
		print("F");				// print "F" for "forward"
		lcd_goto_xy(7, motor);	// go to end of LCD line for inactive motor
		print("-");				// print "-" for "inactive"
		green_led(1);		// turn green LED on when motor is moving "forward"
		for (speed = 0; speed < 255; speed++)
		{
			button = motorUpdate(motor, speed);	// ramp up motor speed
			if (button != 0)					//  from 0 to 255
				return button;
		}

		for (speed = 255; speed > -255; speed--)
		{
			if (speed == -1)	// motor starts moving in "reverse"
			{
				green_led(0);	// green LED off when motor going "reverse"
				lcd_goto_xy(7, !motor);	// go to end of active motor's LCD line
				print("R");		// print "R" for "reverse"
			}

			button = motorUpdate(motor, speed);	// ramp down motor speed
			if (button != 0)					//  from 255 to -255
				return button;
		}

		for (speed = -255; speed <= 0; speed++)
		{
			button = motorUpdate(motor, speed);	// ramp up motor speed
			if (button != 0)					//  from -255 to 0
				return button;
		}

		motor = !motor;		// alternate between m1 and m2
	}
}
Example #22
0
void servo() {
	clear();

	const unsigned char demuxPins[] = { };
	servos_start(demuxPins, sizeof(demuxPins));

	set_servo_target(0, 1300);

	set_servo_speed(0, 0);

	while (1) {
		if (button_is_pressed(TOP_BUTTON)) {
			red_led(1);
			green_led(0);
			clear();
			print("Moving Left...");

			set_servo_target(0, 0);
			_delay_ms(400);

			set_servo_target(0, 200);
		}

		if (button_is_pressed(BOTTOM_BUTTON)) {
			red_led(0);
			green_led(1);
			clear();
			print("Moving Right...");

			set_servo_target(0, 0);
			_delay_ms(400);

			set_servo_target(0, 1800);
		}
	}
}
Example #23
0
// process_received_byte: Responds to a byte that has been received on
// USB_COMM.  If you are writing your own serial program, you can
// replace all the code in this function with your own custom behaviors.
void process_received_byte(char byte)
{
	clear();		// clear LCD
	print("RX: ");
	print_character(byte);
	lcd_goto_xy(0, 1);	// go to start of second LCD row

	switch(byte)
	{
		// If the character 'G' or 'g' is received, toggle the green LED.
		case 'G':
		case 'g':
			green_led(TOGGLE);
			print("green LED");
			break;

		// If the character 'R' or 'r' is received, toggle the red LED.
		case 'R':
		case 'r':
			red_led(TOGGLE);
			print("red LED");
			break;

		// If the character 'C' or 'c' is received, play the note C.
		case 'C':
		case 'c':
			play_from_program_space(PSTR("c16"));
			print("play note C");
			break;

		// If the character 'D' or 'd' is received, play the note D.
		case 'D':
		case 'd':
			play_from_program_space(PSTR("d16"));
			print("play note D");
			break;

		// If any other character is received, change its capitalization and
		// send it back.
		default:
			wait_for_sending_to_finish();
			send_buffer[0] = byte ^ 0x20;
			serial_send(USB_COMM, send_buffer, 1);
			print("TX: ");
			print_character(send_buffer[0]);
			break;
	}
}
Example #24
0
int main()
{
	// Set mode to CTC
	// WGM2 = 0
	// WGM1 = 1
	// WGM0 = 0

	TCCR0A &= ~(0 << WGM00);
	TCCR0A |= (1 << WGM01);
	TCCR0B &= ~(0 << WGM02);

	//Set the scaler to 256
	// CS00 = 0
	// CS01 = 0
	// CS02 = 1

	TCCR0B &= ~(0 << CS00);
	TCCR0B &= ~(0 << CS01);
	TCCR0B |= (1 << CS02);

	//Set the top
	OCR0A = 78;

	// Turn on global interupts
	sei();

	// Turn on interupt for 
	TIMSK0 |= (1 << OCIE0A);
	clear();

	while(1)
	{
		//lcd_goto_xy(0,0);
		//print_long(msTicks);
		if(redReleased)
		{
			redOn ^= 1;
			red_led(redOn);
			green_led(!redOn);
			redReleased = 0;
		}
		
		
	}

	return 0;
}
Example #25
0
int main()
{
	Led red_led(LED1, ON);
	Led green_led(LED2, OFF);
	Switch button(S2);

	while (1) {
		while (!button.is_pressed())
			;

		red_led.toggle();
		green_led.toggle();

		while (button.is_pressed())
			;
	}
}
Example #26
0
void *dmr_handle_data_hook(char *pkt, int len){
  /* This hook handles the dmr_contact_check() function, calling
     back to the original function where appropriate.

     Packes are up to twelve bytes, but they are always preceeded by
     two bytes of C5000 overhead.
   */

  //Turn on the red LED to know that we're here.
  red_led(1);

  printf("Data:       ");
  printhex(pkt,len+2);
  printf("\n");

  //Forward to the original function.
  return dmr_handle_data(pkt,len);
}
Example #27
0
// This function comprises the main part of the motor speed update loop.
// If a button press is detected, both the red and green user LEDs are
// turned off, as are the motor outputs.  This function also includes
// a brief delay that ensures the entire loop takes the desired amount
// of time.
unsigned char motorUpdate(unsigned char motor, int speed)
{
	unsigned char button;

	if (motor == 0)		// set the desired motor to the desired speed
		set_m1_speed(speed);
	else
		set_m2_speed(speed);

	delay_ms(2);		// delay here for 2 milliseconds

	// check if top or bottom buttons have been pressed
	button = button_is_pressed(TOP_BUTTON | MIDDLE_BUTTON);
	if (button != 0)	// if so, turn off motors and LEDs, return button ID
	{
		red_led(0);
		green_led(0);
		set_motors(0, 0);
	}
	return button;
}
Example #28
0
static portTASK_FUNCTION( vBlockingQueueConsumer, pvParameters )
{
unsigned short usData, usExpectedValue = 0;
xBlockingQueueParameters *pxQueueParameters;
short sErrorEverOccurred = pdFALSE;

	pxQueueParameters = ( xBlockingQueueParameters * ) pvParameters;

	for( ;; )
	{
		if( xQueueReceive( pxQueueParameters->xQueue, &usData, pxQueueParameters->xBlockTime ) == pdPASS )
		{
			if( usData != usExpectedValue )
			{
				/* Catch-up. */
				usExpectedValue = usData;

				sErrorEverOccurred = pdTRUE;
			}
			else
			{
				/* We have successfully received a message, so increment the
				variable used to check we are still running. */
				if( sErrorEverOccurred == pdFALSE )
				{
					( *pxQueueParameters->psCheckVariable )++;
				}

				/* Increment the value we expect to remove from the queue next time
				round. */
				++usExpectedValue;
 
            play_from_program_space(PSTR("c"));
            while (is_playing()){};
		    red_led(0);     // Turn off the red LED.
		    delay_ms(20);  // Wait for 20 ms.
			}
		}
	}
}
Example #29
0
/* This is your main function! You should have an infinite loop in here that
 * does all the important stuff your node was designed for */
int main(void) {
	/* variables for double buffer example */
	char buf_1[BUFFER_SIZE];
	char buf_2[BUFFER_SIZE];
	char *current_buf;
//	struct //UART_buffer_descriptor buf_desc_1, buf_desc_2;

	setup();

	scandal_init();

	//UART_Init(115200);

	sc_time_t one_sec_timer = sc_get_timer(); /* Initialise the timer variable */
	sc_time_t test_in_timer = sc_get_timer(); /* Initialise the timer variable */

	/* Set LEDs to known states */
	red_led(0);
	yellow_led(1);

	scandal_delay(100); /* wait for the UART clocks to settle */

	/* Display welcome header over UART */
	//UART_printf("Welcome to the template project! This is coming out over UART1\n\r");
	//UART_printf("The 2 debug LEDs should blink at a rate of 1HZ\n\r");
	//UART_printf("If you configure the in channel 0, I should print a message upon receipt of such a channel message\n\r");
	//UART_printf("This also shows an example of double buffer reading from the UART. Enter the text 'time' and press enter\n\r> ");

	scandal_register_in_channel_handler(0, &in_channel_0_handler);

	/*UART_init_double_buffer(&buf_desc_1, buf_1, BUFFER_SIZE,
								&buf_desc_2, buf_2, BUFFER_SIZE);
*/
	/* This is the main loop, go for ever! */
	while (1) {
		/* This checks whether there are pending requests from CAN, and sends a heartbeat message.
		 * The heartbeat message encodes some data in the first 4 bytes of the CAN message, such as
		 * the number of errors and the version of scandal */
		handle_scandal();

//		current_buf = //UART_readline_double_buffer(&buf_desc_1, &buf_desc_2);

		/* //UART_readline_double_buffer will return a pointer to the current buffer. */
//		if (current_buf != NULL) {
//			if (strncmp("time", current_buf, 4) == 0) {
				//UART_printf("The time is: %d\r\n> ", (int)sc_get_timer());
//			}
//		}

		/* Send a UART and CAN message and flash an LED every second */
		if(sc_get_timer() >= one_sec_timer + 1000) {
			/* Send the message */

			/* Send a channel message with a blerg value at low priority on channel 0 */
			scandal_send_channel(TELEM_LOW, /* priority */
									0,      /* channel num */
									0xaa   /* value */
			);

			/* Twiddle the LEDs */
			toggle_yellow_led();
			toggle_red_led();

			/* Update the timer */
			one_sec_timer = sc_get_timer();
		}

		/* The old way of checking for an incoming message that you've registered for.
		 * This is a silly way to do this. A better way is to use the scandal_register_in_channel_handler
		 * feature. Your function will get called when a new message comes in */
		if(scandal_get_in_channel_rcvd_time(TEMPLATE_TEST_IN) > test_in_timer) {

			

			/*UART_printf("I received a channel message in the main loop on in_channel 0, value %u at time %d\n\r", 
				(unsigned int)scandal_get_in_channel_value(TEMPLATE_TEST_IN), 
				(int)scandal_get_in_channel_rcvd_time(TEMPLATE_TEST_IN)
			);*/

			if(scandal_get_in_channel_value(TEMPLATE_TEST_IN) == 1) {
				toggle_red_led();
			} else {
				toggle_yellow_led();
			}

			test_in_timer = scandal_get_in_channel_rcvd_time(TEMPLATE_TEST_IN);
		}
	}
}
/* This is your main function! You should have an infinite loop in here that
 * does all the important stuff your node was designed for */
int main(void) {
    int initialGPSLock = 1;
	char nmea_buf_1[NMEA_BUFFER_SIZE];
	char nmea_buf_2[NMEA_BUFFER_SIZE];
	char *nmea_current_buf;
	struct UART_buffer_descriptor nmea_buf_desc_1, nmea_buf_desc_2;
	gps_point cur_point; 
	gps_speed cur_speed; 
	sc_time_t cur_point_stamp = 0; 
	sc_time_t last_timesync_time = 0; 
	uint32_t gga_parse_errors = 0;
	uint32_t next_baro_read=0;
	uint32_t next_rtc_time=0;

	/* We allow some time for the GPS to come up before we continue here */
	scandal_naive_delay(100000);
	setup();
	scandal_naive_delay(100000);

	scandal_init();
	scandal_delay(1000);

	/* Initialise the UART to the correct GPS baud rate */
#if defined(LOCOSYS)
	UART_Init(57600);
#else
#if defined(SANJOSE)
	UART_Init(38400);
#endif
#endif
	scandal_delay(1000); /* wait for the UART clocks to settle */

	sc_time_t one_sec_timer = sc_get_timer(); /* Initialise the timer variable */

	/* Set LEDs to known states */
	red_led(1);
	yellow_led(0);

	// Set up the barometer
	long b5, pres, temp, alt, up, ut;
	readCalibrationValues();		//read calibration values

	/* Some GPS config stuff that isn't really necessary */

	/* We can send a reset command if need be
	mtk_send_command("$PMTK103"); */

	/* Set which messages to send out
	 * This sets us to receive GPRMC and GPGGA on every position fix */
	mtk_send_command("$PMTK314,0,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0");

	/* put in 5Hz mode
	mtk_send_command("$PMTK220,200"); */

	/* Change the rate at which we fix the position. Presently every 1000ms */
	mtk_send_command("$PMTK300,1000,0,0,0,0*");

	/* We need a double buffer for reading the GPS messages while we parse them */
	UART_init_double_buffer(&nmea_buf_desc_1, nmea_buf_1, NMEA_BUFFER_SIZE,
								&nmea_buf_desc_2, nmea_buf_2, NMEA_BUFFER_SIZE);

	/* This is the main loop, go for ever! */
	while (1) {
		/* This checks whether there are pending requests from CAN, and sends a heartbeat message.
		 * The heartbeat message encodes some data in the first 4 bytes of the CAN message, such as
		 * the number of errors and the version of scandal */
		handle_scandal();

		if (sc_get_timer() > next_rtc_time){
		    ReadTime();
            UART_printf("Scandal Get Timer: %d\r\n", sc_get_timer_1());
		    next_rtc_time+=250;
		}

		/* Read a line from the UART into one of the buffers */
		nmea_current_buf = UART_readline_double_buffer(&nmea_buf_desc_1, &nmea_buf_desc_2);

		/* UART_readline_double_buffer will return a pointer to the current buffer. */
		if (nmea_current_buf != NULL) {

			/* If we didn't get a valid NMEA line */
			if(validate_nmea(nmea_current_buf) != 0)
				continue;

			/* check to see if we have a GGA message */ 
			if(strncmp(nmea_current_buf, "$GPGGA", 6) == 0){
				int res = parse_msg_gga(nmea_current_buf, &cur_point);
				if(res == 0){
                    if(initialGPSLock == 1) {
                        // Syncs GPS clock with RTC
                        SetTime(get_gga_time_array());
                        SetDate(get_rmc_date_array());
                        initialGPSLock = 0;
                    }
				   /*If the GPS is locked (res==0), send GPS data and set the RTC*/
					toggle_yellow_led();
                    
					cur_point_stamp = scandal_get_realtime32();
					scandal_send_channel_with_timestamp(CRITICAL_PRIORITY, GPSBAROMETER_FIX,
											1, cur_point_stamp);
					scandal_send_channel_with_timestamp(CRITICAL_PRIORITY, GPSBAROMETER_TIME,
											cur_point.time, cur_point_stamp);
					scandal_send_channel_with_timestamp(CRITICAL_PRIORITY, GPSBAROMETER_LATITUDE,
											cur_point.lat, cur_point_stamp);
					scandal_send_channel_with_timestamp(CRITICAL_PRIORITY, GPSBAROMETER_LONGITUDE,
											cur_point.lng, cur_point_stamp);
					scandal_send_channel_with_timestamp(CRITICAL_PRIORITY, GPSBAROMETER_ALTITUDE,
											cur_point.alt, cur_point_stamp);
					/* Only sets the RTC if the seconds value is under 58
					 * This is done to make sure nothing ticks over in the
					 * middle of a write process as strange values may result
					 */
                    
				/* an actual parse error */
				} else if (res == -1) {
					scandal_send_channel_with_timestamp(CRITICAL_PRIORITY, GPSBAROMETER_GGA_PARSE_ERROR_COUNT,
											gga_parse_errors++, cur_point_stamp);
				/* no fix yet */
				} else if (res == -2) {
					scandal_send_channel_with_timestamp(CRITICAL_PRIORITY, GPSBAROMETER_FIX,
											0, cur_point_stamp);
					//gps_lock=0;
				}
			}

			/* check to see if we have an RMC message */ 
			if(strncmp(nmea_current_buf, "$GPRMC", 6) == 0) {
				if(parse_msg_rmc(nmea_current_buf, &cur_speed) == 0) {
					toggle_red_led();

					/* Milliseconds since the epoch */
                    /* Converts date to milliseconds, adds time */
					uint64_t timestamp = days_since_epoch(getRTCDay(), getRTCMonth(), getRTCYear());
					timestamp *= 3600;
					timestamp *= 24;
					timestamp *= 1000;
                    timestamp += getRTCTimeSecond() * 1000;
                    timestamp += sc_get_timer_1();
                    
                    UART_printf("Day:%d Month:%d Year:%d\r\n", getRTCDay(), getRTCMonth(), getRTCYear());
                    
                    scandal_send_timesync(CRITICAL_PRIORITY, scandal_get_addr(), timestamp);
                    
                    scandal_set_realtime(timestamp);
                    
                    scandal_send_channel(CRITICAL_PRIORITY, GPSBAROMETER_SPEED, cur_speed.speed * 1000);
                    scandal_send_channel(CRITICAL_PRIORITY, GPSBAROMETER_MILLISECONDS_TODAY, cur_speed.time);
                    scandal_send_channel(CRITICAL_PRIORITY, GPSBAROMETER_DAYS_SINCE_EPOCH, cur_speed.date);
                    
					/* This is an evil hack to make sure that we get fairly consistent timestamps 
					Sometimes there seems to be a really long dela of ~0.3s on some timestamp
					messages. To get rid of this, we don't accept any time differences that are 
					more than 20ms later than we expect them to be. 
					This is pure evil, and the problem should really be fixed rather than 
					hacking around it like this */
					/*
                    if(last_timesync_time == 0)
						last_timesync_time = sc_get_timer();

					timediff = (sc_get_timer() - last_timesync_time) % 1000;
					if((timediff < 50) || (timediff > 600)) {
                        
						last_timesync_time = sc_get_timer();
						scandal_send_timesync(CRITICAL_PRIORITY, scandal_get_addr(), timestamp);
					}

					scandal_set_realtime(timestamp);

					scandal_send_channel(CRITICAL_PRIORITY, GPSBAROMETER_SPEED, cur_speed.speed * 1000);
					scandal_send_channel(CRITICAL_PRIORITY, GPSBAROMETER_MILLISECONDS_TODAY, cur_speed.time);
					scandal_send_channel(CRITICAL_PRIORITY, GPSBAROMETER_DAYS_SINCE_EPOCH, cur_speed.date);
                    */
					/*                    if(cur_point_stamp  != 0){
					scandal_send_channel_with_timestamp(CRITICAL_PRIORITY, GPSBAROMETER_TIME,
													cur_point.time, cur_point_stamp);
					scandal_send_channel_with_timestamp(CRITICAL_PRIORITY, GPSBAROMETER_LATITUDE,
													cur_point.lat, cur_point_stamp);
					scandal_send_channel_with_timestamp(CRITICAL_PRIORITY, GPSBAROMETER_LONGITUDE,
													cur_point.lng, cur_point_stamp);
					scandal_send_channel_with_timestamp(CRITICAL_PRIORITY, GPSBAROMETER_ALTITUDE,
													cur_point.alt, cur_point_stamp);
					cur_point_stamp = 0; 
					}
					*/

				}
			}
		}

#if 1
		if (sc_get_timer() > next_baro_read){

		    ut = bmp085ReadUT();					//read uncompensated temperature
		    scandal_delay(5);					//delay 4.5ms
		    up = bmp085ReadUP();					//read uncompensated pressure
		    scandal_delay(5);					//delay 4.5ms
		    b5 = bmp085Getb5(ut);				//calculate temperature constant
		    temp = bmp085GetTemperature(ut, b5);			//calculate true temperature
		    pres = bmp085GetPressure(up, b5);		//calculate true pressure
		    alt = bmp085GetAltitude(pres);				//estimate the altitude
		    next_baro_read=(sc_get_timer()+1000);
		}

#endif
		//UART_printf("B5: %d,Temp: %d:%d, Pres: %d:%d, Alt: %d\r\n", (int) b5,(int) ut, (int) temp, (int)up,(int) pres, (int) alt);
//		UART_printf("%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d\r\n",(int) barometerCal -> AC1,(int) barometerCal -> AC2,(int) barometerCal -> AC3,(int) barometerCal -> AC4,(int) barometerCal -> AC5,(int) barometerCal -> AC6,(int) barometerCal -> B1,(int) barometerCal -> B2,(int) barometerCal -> MB,(int) barometerCal -> MC,(int) barometerCal -> MD);

		#if 0
		/* Flash an LED every second */
		if(sc_get_timer() >= one_sec_timer + 1000) {
			toggle_red_led();
			one_sec_timer = sc_get_timer();
		}
#endif
	}
}