Exemplo n.º 1
0
DMP_INLINE(unsigned long) _setAlarmAllSeconds(int sec, int min, int hour, int day, int month, int year) {
	struct tm tms;
	
	tms.tm_isdst = -1;
	tms.tm_yday  = 0;
	tms.tm_wday  = 0;
	
	if(year < 0)
		tms.tm_year  = getRTCYear() + EPOCH_TIME_YEAR_OFF;
	else
		tms.tm_year  = year + EPOCH_TIME_YEAR_OFF;
	
	if(month < 0)
		tms.tm_mon   = getRTCMonth() - 1;
	else
		tms.tm_mon   = month - 1;
	
	if(day < 0)
		tms.tm_mday  = getRTCDay();
	else
		tms.tm_mday  = day;
	
	if(hour < 0)
		tms.tm_hour  = getRTCHours();
	else
		tms.tm_hour  = hour;
	
	if(min < 0)
		tms.tm_min   = getRTCMinutes();
	else
		tms.tm_min   = min;
	
	if(sec < 0)
		tms.tm_sec   = getRTCSeconds();
	else
		tms.tm_sec   = sec;
	
	return mktime(&tms);
}
/* 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
	}
}