Satellite Observers Workbench. NOT yet complete, just published for forum posters to \"cherry pick\" pieces of code as requiered as an example.
gps.c
00001 /**************************************************************************** 00002 * Copyright 2010 Andy Kirkham, Stellar Technologies Ltd 00003 * 00004 * This file is part of the Satellite Observers Workbench (SOWB). 00005 * 00006 * SOWB is free software: you can redistribute it and/or modify 00007 * it under the terms of the GNU General Public License as published by 00008 * the Free Software Foundation, either version 3 of the License, or 00009 * (at your option) any later version. 00010 * 00011 * SOWB is distributed in the hope that it will be useful, 00012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00014 * GNU General Public License for more details. 00015 * 00016 * You should have received a copy of the GNU General Public License 00017 * along with SOWB. If not, see <http://www.gnu.org/licenses/>. 00018 * 00019 * $Id: main.cpp 5 2010-07-12 20:51:11Z ajk $ 00020 * 00021 ***************************************************************************/ 00022 00023 /* 00024 Implementation notes. 00025 The SOWB reads GPS data in on RDX1. We don't use TDX1 as we use it as part 00026 of the SSP/SPI for the MAX7456/Flash card reader. However, we are not really 00027 interested in writing to the GPS module as the most crucial data is the time 00028 rather than the location. We do use the location data but we don't need any 00029 WAAS data correction, 10metres is enough accuracy. So we only use Uart1 Rx to 00030 get data. 00031 00032 Additionally, the GPS 1 pulse per second signal is connected to a P29 (P0.5) 00033 and the gpioirq.c module routes that interrupt back to us via the _gps_pps_irq() 00034 callback function. 00035 */ 00036 00037 #include "sowb.h" 00038 #include "rit.h" 00039 #include "gpio.h" 00040 #include "gps.h" 00041 #include "math.h" 00042 #include "debug.h" 00043 00044 /* Module global variables. */ 00045 double lat_average; 00046 double lon_average; 00047 double lat_history[GPS_HISTORY_SIZE]; 00048 double lon_history[GPS_HISTORY_SIZE]; 00049 int history_in_index; 00050 int history_complete; 00051 GPS_TIME the_time; 00052 GPS_LOCATION_RAW the_location; 00053 00054 double lat_acc_average; 00055 double lon_acc_average; 00056 double cnt_acc_average; 00057 00058 /* We maintain two serial input buffers so that the 00059 _process() function can be processing one buffer 00060 while the serial interrupt system can be capturing 00061 to the other. */ 00062 char uart1_buffer[2][GPS_BUFFER_SIZE]; 00063 00064 #define UART1_BUFFER_A 0 00065 #define UART1_BUFFER_B 1 00066 00067 char active_buffer, active_buffer_in; 00068 char passive_buffer_ready; 00069 00070 /* Update flag to signal new data in the active buffer. */ 00071 char have_new_location; 00072 00073 /* Set to non-zero by the updater interrupts. */ 00074 char time_updated; 00075 char location_updated; 00076 00077 /* Internal function prototypes. */ 00078 void _gps_process_rmc(char passive_buffer); 00079 void _gps_process_gga(char passive_buffer); 00080 void _gps_time_inc(GPS_TIME *q); 00081 void _gps_date_inc(GPS_TIME *q); 00082 void _gps_timer_tick_cb(int); 00083 void _gps_pps_alive_cb(int); 00084 void Uart1_init(void); 00085 00086 /** gps_process 00087 */ 00088 void gps_process(void) { 00089 int i, j; 00090 uint32_t ier_copy; 00091 char passive_buffer; 00092 double lat_temp, lon_temp; 00093 00094 if (passive_buffer_ready == 1) { 00095 /* Disable serial interrupts on UART1 */ 00096 ier_copy = LPC_UART1->IER; 00097 LPC_UART1->IER = 0x0; 00098 00099 /* What index is the passive buffer, i.e., what is the opposite 00100 of the current active buffer? */ 00101 passive_buffer = active_buffer == 0 ? 1 : 0; 00102 00103 if (!strncmp(uart1_buffer[passive_buffer], "$GPRMC", 6)) { 00104 _gps_process_rmc(passive_buffer); 00105 } 00106 else if (!strncmp(uart1_buffer[passive_buffer], "$GPGGA", 6)) { 00107 _gps_process_gga(passive_buffer); 00108 } 00109 00110 /* Flag we have completed processing the passive buffer. */ 00111 passive_buffer_ready = 0; 00112 00113 /* Enable serial interrupts on UART1 */ 00114 LPC_UART1->IER = ier_copy; 00115 } 00116 00117 /* Update the latitude/longitude moving average filter. */ 00118 if (the_location.is_valid && have_new_location != 0) { 00119 have_new_location = 0; 00120 lat_history[history_in_index] = gps_convert_coord(the_location.lat, GPS_LAT_STR); 00121 lon_history[history_in_index] = gps_convert_coord(the_location.lon, GPS_LON_STR); 00122 history_in_index++; 00123 if (history_in_index >= GPS_HISTORY_SIZE) { 00124 history_in_index = 0; 00125 history_complete = 1; 00126 } 00127 j = history_complete == 1 ? GPS_HISTORY_SIZE+1 : history_in_index; 00128 for(lat_temp = lon_temp = 0., i = 1; i < j; i++) { 00129 lat_temp += lat_history[i - 1]; 00130 lon_temp += lon_history[i - 1]; 00131 } 00132 if (i) { 00133 lat_average = lat_temp / (double)(i - 1); 00134 lon_average = lon_temp / (double)(i - 1); 00135 location_updated = 1; 00136 } 00137 } 00138 } 00139 00140 /** _gps_process_rmc 00141 * 00142 * Extract the NMEA data from an RMC packet. 00143 * Sample:- 00144 * $GPRMC,132555.639,A,5611.5374,N,00302.0325,W,000.0,129.3,020910,,,A*75 00145 * 00146 * @param char passive_buffer Which buffer holds the RMC packet data. 00147 */ 00148 void _gps_process_rmc(char passive_buffer) { 00149 char *token; 00150 int token_counter = 0; 00151 char *time = (char *)NULL; 00152 char *date = (char *)NULL; 00153 char *status = (char *)NULL; 00154 00155 token = strtok(uart1_buffer[passive_buffer], ","); 00156 while (token) { 00157 switch (token_counter) { 00158 case 9: date = token; break; 00159 case 1: time = token; break; 00160 case 2: status = token; break; 00161 } 00162 token = strtok((char *)NULL, ","); 00163 token_counter++; 00164 } 00165 00166 if (status && date && time) { 00167 the_time.hour = (char)((time[0] - '0') * 10) + (time[1] - '0'); 00168 the_time.minute = (char)((time[2] - '0') * 10) + (time[3] - '0'); 00169 the_time.second = (char)((time[4] - '0') * 10) + (time[5] - '0'); 00170 the_time.day = (char)((date[0] - '0') * 10) + (date[1] - '0'); 00171 the_time.month = (char)((date[2] - '0') * 10) + (date[3] - '0'); 00172 the_time.year = (int)((date[4] - '0') * 10) + (date[5] - '0') + 2000; 00173 the_time.is_valid = status[0] == 'A' ? 1 : 0; 00174 the_time.prev_valid = 1; 00175 } 00176 else { 00177 the_time.is_valid = 0; 00178 } 00179 } 00180 00181 /** _gps_process_gga 00182 * 00183 * Extract the NMEA data from a GGA packet. 00184 * Sample:- 00185 * $GPGGA,132526.639,5611.5417,N,00302.0298,W,1,05,7.3,43.4,M,52.0,M,,0000*70 00186 * 00187 * @param char passive_buffer Which buffer holds the GGA packet data. 00188 */ 00189 void _gps_process_gga(char passive_buffer) { 00190 char *token; 00191 int token_counter = 0; 00192 char *latitude = (char *)NULL; 00193 char *longitude = (char *)NULL; 00194 char *lat_dir = (char *)NULL; 00195 char *lon_dir = (char *)NULL; 00196 char *qual = (char *)NULL; 00197 char *altitude = (char *)NULL; 00198 char *sats = (char *)NULL; 00199 00200 token = strtok(uart1_buffer[passive_buffer], ","); 00201 while (token) { 00202 switch (token_counter) { 00203 case 2: latitude = token; break; 00204 case 4: longitude = token; break; 00205 case 3: lat_dir = token; break; 00206 case 5: lon_dir = token; break; 00207 case 6: qual = token; break; 00208 case 7: sats = token; break; 00209 case 9: altitude = token; break; 00210 } 00211 token = strtok((char *)NULL, ","); 00212 token_counter++; 00213 } 00214 00215 /* If the fix quality is valid set our location information. */ 00216 if (latitude && longitude && altitude && sats) { 00217 memcpy(the_location.lat, latitude, 10); /* Fixed length string. */ 00218 memcpy(the_location.lon, longitude, 10); /* Fixed length string. */ 00219 memset(the_location.alt, 0, sizeof(the_location.alt)); /* Clean string out first. */ 00220 strncpy(the_location.alt, altitude, 10); /* Variable length string. */ 00221 strncpy(the_location.sats, sats, 3); /* Variable length string. */ 00222 the_location.north_south = lat_dir[0]; 00223 the_location.east_west = lon_dir[0]; 00224 the_location.is_valid = qual[0]; 00225 the_location.updated++; 00226 have_new_location = 1; 00227 } 00228 else { 00229 the_location.is_valid = qual[0]; 00230 } 00231 } 00232 00233 /** gps_convert_coord 00234 * 00235 * Given a string and a type convert the string into a double. 00236 * 00237 * @param char *s A pointer to the string to convert. 00238 * @param int type The conversion type required (lat or lon) 00239 * @return double the converted string. 00240 */ 00241 double gps_convert_coord(char *s, int type) { 00242 int deg, min, sec; 00243 double fsec, val; 00244 00245 if (type == GPS_LAT_STR) { 00246 deg = ( (s[0] - '0') * 10) + s[1] - '0'; 00247 min = ( (s[2] - '0') * 10) + s[3] - '0'; 00248 sec = ( ((s[5] - '0') * 1000) + ((s[6] - '0') * 100) + ((s[7] - '0') * 10) + (s[8] - '0')); 00249 fsec = (double)((double)sec /10000.0); 00250 val = (double)deg + ((double)((double)min/60.0)) + (fsec/60.0); 00251 return val; 00252 } 00253 else { 00254 deg = ( (s[0] - '0') * 100) + ((s[1] - '0') * 10) + (s[2] - '0'); 00255 min = ( (s[3] - '0') * 10) + s[4] - '0'; 00256 sec = ( ((s[6] - '0') * 1000) + ((s[7] - '0') * 100) + ((s[8] - '0') * 10) + (s[9] - '0')); 00257 fsec = (double)((double)sec /10000.0); 00258 val = (double)deg + ((double)((double)min/60.0)) + (fsec/60.0); 00259 return val; 00260 } 00261 } 00262 00263 /** gps_init 00264 */ 00265 void gps_init(void) { 00266 int i; 00267 00268 DEBUG_INIT_START; 00269 00270 /* Set the time to a known starting point in the past. */ 00271 the_time.year = 2000; 00272 the_time.month = 1; 00273 the_time.day = 1; 00274 the_time.hour = 0; 00275 the_time.minute = 0; 00276 the_time.second = 0; 00277 the_time.tenth = 0; 00278 the_time.hundreth = 0; 00279 the_time.is_valid = 0; 00280 the_time.prev_valid = 0; 00281 00282 memset(&the_location, 0, sizeof(GPS_LOCATION_RAW)); 00283 00284 /* Initial condition. */ 00285 time_updated = 0; 00286 00287 /* Zero out the moving average filter. */ 00288 lat_average = 0.; 00289 lon_average = 0.; 00290 history_in_index = 0; 00291 history_complete = 0; 00292 for(i = 0; i < GPS_HISTORY_SIZE; i++) { 00293 lat_history[i] = 0.; 00294 lon_history[i] = 0.; 00295 } 00296 00297 lat_acc_average = 0.; 00298 lon_acc_average = 0.; 00299 cnt_acc_average = 0.; 00300 00301 /* Init the active buffer and the serial in pointer. */ 00302 active_buffer = active_buffer_in = 0; 00303 00304 /* Flag the passive buffer is not ready. The passive buffer 00305 is the opposite of the active buffer. When the serial irq 00306 system detects the end of a NEMA message it automatically 00307 switches buffers and sets passive_buffer_ready non-zero to 00308 indicate it's just finished dumping data into it. */ 00309 passive_buffer_ready = 0; 00310 00311 /* Updated to non-zero after a new location packet is received. */ 00312 have_new_location = 0; 00313 00314 /* Setup the 0.01second timer. */ 00315 rit_timer_set_reload(RIT_TIMER_CB_GPS, 10); /* Recurring reload. */ 00316 rit_timer_set_counter(RIT_TIMER_CB_GPS, 10); /* Start timer. */ 00317 00318 DEBUG_INIT_END; 00319 00320 Uart1_init(); 00321 } 00322 00323 /** gps_get_time 00324 * 00325 * Copies our internal time data structure to a buffer supplied by the caller. 00326 * 00327 * Note, the update flag is set to non-zero by the interrupt routines when an 00328 * update occurs. The loop is to test if an update occured while the copy was 00329 * in progress. If it did, do the copy again as it's most likely corrupted the 00330 * orginal copy operation. 00331 * 00332 * @param GPS_TIME *q A pointer to the GPS_TIME data structure to copy to. 00333 * @return GPS_TIME * The supplied pointer. 00334 */ 00335 GPS_TIME *gps_get_time(GPS_TIME *q) { 00336 00337 do { 00338 time_updated = 0; 00339 memcpy(q, &the_time, sizeof(GPS_TIME)); 00340 } while (time_updated != 0); 00341 00342 return q; 00343 } 00344 00345 /** gps_get_location_raw 00346 * 00347 * Copies our internal location data structure to a buffer supplied by the caller. 00348 * 00349 * Note, the update flag is set to non-zero by the interrupt routines when an 00350 * update occurs. The loop is to test if an update occured while the copy was 00351 * in progress. If it did, do the copy again as it's most likely corrupted the 00352 * orginal copy operation. 00353 * 00354 * @param GPS_LOCATION_RAW *q A pointer to the GPS_LOCATION_RAW data structure to copy to. 00355 * @return GPS_LOCATION_RAW * The supplied pointer. 00356 */ 00357 GPS_LOCATION_RAW *gps_get_location_raw(GPS_LOCATION_RAW *q) { 00358 00359 do { 00360 location_updated = 0; 00361 memcpy(q, &the_location, sizeof(GPS_LOCATION_RAW)); 00362 } while (location_updated != 0); 00363 00364 return q; 00365 } 00366 00367 /** gps_get_location_average 00368 * 00369 * Places the current average location into the supplied struct buffer. 00370 * The caller is responsible for allocating the buffer storage space. 00371 * 00372 * Note, the update flag is set to non-zero by the interrupt routines when an 00373 * update occurs. The loop is to test if an update occured while the copy was 00374 * in progress. If it did, do the copy again as it's most likely corrupted the 00375 * orginal copy operation. 00376 * 00377 * @param GPS_LOCATION_AVERAGE *q A pointer to the struct buffer to write data to. 00378 * @return GPS_LOCATION_AVERAGE * The supplied pointer returned. 00379 */ 00380 GPS_LOCATION_AVERAGE *gps_get_location_average(GPS_LOCATION_AVERAGE *q) { 00381 char **p = NULL; 00382 00383 do { 00384 location_updated = 0; 00385 q->north_south = the_location.north_south; 00386 q->latitude = lat_average; 00387 q->east_west = the_location.east_west; 00388 q->longitude = lon_average; 00389 q->height = strtod(the_location.alt, p); 00390 q->sats = the_location.sats; 00391 q->is_valid = the_location.is_valid; 00392 } while (location_updated != 0); 00393 00394 /* Test the values to ensure the data is valid. */ 00395 if (isnan(q->latitude) || isnan(q->longitude) || isnan(q->height)) { 00396 q->is_valid = 0; 00397 } 00398 00399 return q; 00400 } 00401 00402 /** gps_julian_day_number 00403 * 00404 * Gets the Julian Day Number from the supplied time reference passed. 00405 * http://en.wikipedia.org/wiki/Julian_day#Converting_Gregorian_calendar_date_to_Julian_Day_Number 00406 * 00407 * @param GPS_TIME *t A pointer to a time data structure. 00408 * @return double The Julian Day Number. 00409 */ 00410 double gps_julian_day_number(GPS_TIME *t) { 00411 double wikipedia_jdn = (double)(1461 * ((int)t->year + 4800 + ((int)t->month - 14) / 12)) / 4 + (367 * ((int)t->month - 2 - 12 * (((int)t->month - 14) / 12))) / 12 - (3 * (((int)t->year + 4900 + ((int)t->month - 14) / 12 ) / 100)) / 4 + (int)t->day - 32075; 00412 00413 /* Not sure why yet but the calculation on the Wikipedia site returns a value that 00414 is 0.5 too big. */ 00415 return wikipedia_jdn; 00416 } 00417 00418 /** gps_julian_date 00419 * 00420 * Find the Julian Date based on the supplied args. 00421 * 00422 * @param GPS_TIME *t A pointer to a time data structure. 00423 * @return double The Julian Date. 00424 */ 00425 double gps_julian_date(GPS_TIME *t) { 00426 double hour, minute, second, jd; 00427 hour = (double)t->hour; 00428 minute = (double)t->minute; 00429 second = (double)t->second + ((double)t->tenth / 10.) + ((double)t->hundreth / 100.); 00430 /* Wiki fix, see above. */ 00431 jd = gps_julian_day_number(t) - 0.5 + 00432 ((hour - 12.) / 24.) + 00433 (minute / 1440.) + 00434 (second / 86400.); 00435 00436 return jd; 00437 } 00438 00439 /** gps_siderealDegrees_by_jd 00440 * 00441 * Calculate the sidereal degree angle based on the 00442 * Julian Date supplied. 00443 * 00444 * @param double jd Julian Date. 00445 * @return The sidereal angle in degrees. 00446 */ 00447 double gps_siderealDegrees_by_jd(double jd) { 00448 double sidereal, gmst, lmst, mul; 00449 double T = jd - 2451545.0; 00450 double T1 = T / 36525.0; 00451 double T2 = T1 * T1; 00452 double T3 = T2 * T1; 00453 00454 /* Calculate gmst angle. */ 00455 sidereal = 280.46061837 + (360.98564736629 * T) + (0.000387933 * T2) - (T3 / 38710000.0); 00456 00457 /* Convert to degrees. */ 00458 sidereal = fmod(sidereal, 360.0); 00459 if (sidereal < 0.0) sidereal += 360.0; 00460 00461 mul = (the_location.east_west == 'W') ? -1.0 : 1.0; 00462 00463 gmst = sidereal; 00464 lmst = gmst + (lon_average * mul); 00465 return lmst; 00466 } 00467 00468 /** gps_siderealDegrees_by_time 00469 * 00470 * Calculate the sidereal degree angle based on the 00471 * time data structure supplied. 00472 * 00473 * @param GPS_TIME *t A pointer to the time structure. 00474 * @return The sidereal angle in degrees. 00475 */ 00476 double gps_siderealDegrees_by_time(GPS_TIME *t) { 00477 GPS_TIME temp; 00478 if (t == (GPS_TIME *)NULL) { 00479 t = &temp; 00480 gps_get_time(t); 00481 } 00482 return gps_siderealDegrees_by_jd(gps_julian_date(t)); 00483 } 00484 00485 /** gps_siderealHA_by_jd 00486 * 00487 * Calculate the HA (hour angle) based on the supplied Julian Date. 00488 * 00489 * @param double jd The Julian Date. 00490 * @return double The Hour Angle. 00491 */ 00492 double gps_siderealHA_by_jd(double jd) { 00493 double lmst = gps_siderealDegrees_by_jd(jd); 00494 return lmst / 360.0 * 24.0; 00495 } 00496 00497 /** gps_siderealHA_by_time 00498 * 00499 * Calculate the HA (hour angle) based on the supplied time data structure. 00500 * 00501 * @param GPS_TIME *t The time data structure. 00502 * @return double The Hour Angle. 00503 */ 00504 double gps_siderealHA_by_time(GPS_TIME *t) { 00505 double lmst = gps_siderealDegrees_by_time(t); 00506 return lmst / 360.0 * 24.0; 00507 } 00508 00509 /** _gps_inc_time 00510 * 00511 * Used to increment the time structure by 0.01sec. 00512 * Called by the RIT timer callback. 00513 * 00514 * @see gpioirq.c 00515 * @param int t_index The timer's index number (handle). 00516 */ 00517 void _gps_timer_tick_cb(int t_index) { 00518 00519 /* We use x so that the_time.hundreth can never be 10 as I have noticed 00520 occasionally between the ++ and the == 10 test an interrupt can occur 00521 and then the_time.hundreth contains an invalid value. So using x to do 00522 the ++ and ==10 test means the_time.hundreth can never itself be 10. 00523 We reuse x on the tenths for a similar reason. */ 00524 char x = the_time.hundreth; 00525 x++; 00526 00527 if (x == 10) { 00528 the_time.hundreth = 0; 00529 x = the_time.tenth + 1; 00530 if (x < 10) { 00531 the_time.tenth = x; 00532 time_updated = 1; 00533 } 00534 } 00535 else { 00536 the_time.hundreth = x; 00537 time_updated = 1; 00538 } 00539 } 00540 00541 /** _gps_pps_alive_cb 00542 * 00543 * Timeout that goes off if the GPS 1PPS signal doesn't 00544 * fire within 1.5seconds telling us that the GPS isn't 00545 * connected. Not currently used. 00546 */ 00547 void _gps_pps_alive_cb(int index) { 00548 the_time.is_valid = 0; 00549 } 00550 00551 /** gps_pps_fall 00552 * 00553 * Increments the seconds. Called by the GPS 1PP callback interrupt. 00554 * 00555 * Note, some GPS modules, including the one used in this design, 00556 * provide a 1PPS signal. However, it's almost always positive logic 00557 * and it doesn't interface directly to an Mbed pin/interrupt. So we 00558 * have a simple FET that buffers the signal and in so doing it becomes 00559 * an active low signal. Hence why this is a falling edge interrupt. 00560 * 00561 * @see gpioirq.c 00562 */ 00563 void gps_pps_fall(void) { 00564 the_time.hundreth = 0; 00565 the_time.tenth = 0; 00566 _gps_time_inc(&the_time); 00567 } 00568 00569 /** gps_date_inc 00570 * 00571 * Increment the time. 00572 * 00573 * @param GPS_TIME *q Pointer the data struct holding the time. 00574 */ 00575 void _gps_time_inc(GPS_TIME *q) { 00576 00577 time_updated = 1; 00578 00579 q->second++; 00580 if (q->second == 60) { 00581 q->second = 0; 00582 q->minute++; 00583 if (q->minute == 60) { 00584 q->minute = 0; 00585 q->hour++; 00586 if (q->hour == 24) { 00587 q->hour = 0; 00588 _gps_date_inc(q); 00589 } 00590 } 00591 } 00592 } 00593 00594 /** _gps_date_inc 00595 * 00596 * Increment the date. 00597 * 00598 * @param GPS_TIME *q Pointer the data struct holding the time. 00599 */ 00600 void _gps_date_inc(GPS_TIME *q) { 00601 const int days[12] = { 31,28,31,30,31,30,31,31,30,31,30,31 } ; 00602 00603 /* Handle February leap year. */ 00604 int leap_year = ((the_time.year % 4 == 0 && the_time.year % 100 != 0) || the_time.year % 400 == 0) ? 1 : 0; 00605 int days_this_month = days[q->month - 1]; 00606 if (q->month == 2 && leap_year) days_this_month++; 00607 00608 q->day++; 00609 if (q->day > days_this_month) { 00610 q->day = 1; 00611 q->month++; 00612 if (q->month == 13) { 00613 q->year++; 00614 } 00615 } 00616 } 00617 00618 /* UART1 functions. */ 00619 00620 extern "C" void UART1_IRQHandler(void) __irq { 00621 volatile uint32_t iir; 00622 volatile char c; 00623 00624 iir = LPC_UART1->IIR; 00625 00626 if (iir & 0x1) return; 00627 00628 /* Do we have a serial character(s) in the fifo? */ 00629 if (UART_RX_INTERRUPT) { 00630 while (UART1_FIFO_NOT_EMPTY) { 00631 c = UART1_GETC; 00632 uart1_buffer[active_buffer][active_buffer_in++] = c; 00633 active_buffer_in &= (GPS_BUFFER_SIZE - 1); 00634 if (c == '\n') { 00635 /* Swap buffers and clean it out. */ 00636 active_buffer = active_buffer == 0 ? 1 : 0; 00637 memset(uart1_buffer[active_buffer], 0, GPS_BUFFER_SIZE); 00638 active_buffer_in = 0; 00639 passive_buffer_ready = 1; 00640 } 00641 } 00642 } 00643 } 00644 00645 /** Uart1_init 00646 */ 00647 void Uart1_init(void) { 00648 00649 DEBUG_INIT_START; 00650 00651 LPC_SC->PCONP |= (1UL << 4); 00652 LPC_SC->PCLKSEL0 &= ~(3UL << 8); 00653 LPC_SC->PCLKSEL0 |= (1UL << 8); 00654 LPC_PINCON->PINSEL4 &= ~(3UL << 2); /* TXD1 not used. See SSP0_init() in max7456.c */ 00655 LPC_PINCON->PINSEL4 |= (2UL << 2); /* TXD1 not used. See SSP0_init() in max7456.c */ 00656 LPC_UART1->LCR = 0x83; 00657 LPC_UART1->DLL = 0x71; 00658 LPC_UART1->DLM = 0x02; 00659 LPC_UART1->LCR = 0x03; 00660 LPC_UART1->FCR = 0x07; 00661 00662 NVIC_SetVector(UART1_IRQn, (uint32_t)UART1_IRQHandler); 00663 NVIC_EnableIRQ(UART1_IRQn); 00664 00665 /* Enable the RDA interrupt. */ 00666 LPC_UART1->IER = 0x01; 00667 00668 DEBUG_INIT_END; 00669 } 00670
Generated on Tue Jul 12 2022 18:05:35 by 1.7.2