Satellite Observers Workbench. NOT yet complete, just published for forum posters to \"cherry pick\" pieces of code as requiered as an example.
nexstar.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 Update: This whole module requires refactoring into something much more 00025 sane. Basically, I "organically" grew the code in this module with trial 00026 and error using the hardware since getting simple things done proved hard. 00027 I did design (see below) what I thought reasonable system but the Nexstar 00028 kept throwing up problems. So I really need to come back to this code and 00029 sort it out properly. 00030 00031 Frustrations: I originally implemented an "intelligent" start-up routine 00032 that sent echo requests to check the Nexstar was there, then requested 00033 isAligned and, once aligned, would finally send the Tracking Off command 00034 and enter operational state. However, that's all out the window. 00035 00036 Basically, I have found that if you send anything down the serial cable 00037 while the Nexstar is powering up it goes dumb and won't responsd to 00038 anything you send it. How useless, someone needs to educate their 00039 software engineers to designing robust serial protocols that can 00040 handle battery/power failure. Really very silly because I now know 00041 that my software MUST assume the end user has powered on their Nexstar 00042 before I start sending serial commands! Rubbish design, I like smart 00043 designs that don't rely on the end user having to do "special things", 00044 they should just work! 00045 00046 Additionally, I have found that, based on documents from TheSky program 00047 you cannot ask the Nexstar for it's pointing position faster than once 00048 per second! WTF? Asking too fast can crash the Nexstar hand controller. 00049 Doh! Since we really need the position at a higher frequency then at the 00050 subsecond level, the pointing position is calculated from the last position 00051 known +/- whatever variable speed rates have been sent since then. 00052 00053 For the purposes of trying to track a fast moving object (an artificial 00054 satellite in this case) we end up having to do most of the work ourselves 00055 and hope the Nexstar tracks it with a sub-standard pointing system. 00056 Hopefully I'll get it right! 00057 00058 Means the serial protocol I develop here is more basic than I would have 00059 prefered. For example, rather than sending periodic echo requests to 00060 detect the Nexstar, I'll send just one. If no reply I'll have to prompt 00061 the user to "Power on the Nexstar and press a key to continue". Doh. 00062 */ 00063 00064 #define NEXSTAR_C 00065 00066 #include "sowb.h" 00067 #include "nexstar.h" 00068 #include "utils.h" 00069 #include "rit.h" 00070 #include "user.h" 00071 #include "osd.h" 00072 #include "debug.h" 00073 #include "gpio.h" 00074 #include "main.h" 00075 00076 /* Module global variables. */ 00077 int nexstar_status; 00078 int nexstar_command; 00079 int nexstar_command_status; 00080 char rx_buffer[NEXSTAR_BUFFER_SIZE]; 00081 int rx_buffer_in; 00082 00083 bool nexstar_aligned; 00084 00085 double last_elevation; 00086 double last_azmith; 00087 double virtual_elevation; 00088 double virtual_azmith; 00089 00090 double elevation_rate; 00091 double elevation_rate_coarse; 00092 double elevation_rate_fine; 00093 double elevation_rate_auto; 00094 00095 double azmith_rate; 00096 double azmith_rate_coarse; 00097 double azmith_rate_fine; 00098 double azmith_rate_auto; 00099 00100 bool nexstar_goto_in_progress; 00101 char nexstar_goto_elevation[5]; 00102 char nexstar_goto_azmith[5]; 00103 00104 int virtual_update_counter; 00105 00106 /* Local function prototypes. */ 00107 static void Uart2_init(void); 00108 static inline void Uart2_putc(char c); 00109 static inline void Uart2_puts(char *s, int len); 00110 00111 /** nexstar_process 00112 * 00113 * Our system _process function. 00114 */ 00115 void nexstar_process(void) { 00116 00117 if (nexstar_command_status != 0) { 00118 switch (nexstar_command) { 00119 case NEXSTAR_IS_ALIGNED: 00120 nexstar_aligned = rx_buffer[0] == 1 ? true : false; 00121 nexstar_command = 0; 00122 nexstar_command_status = 0; 00123 break; 00124 case NEXSTAR_GET_AZMALT: 00125 last_azmith = virtual_azmith = 360.0 * (((double)hex2bin(&rx_buffer[0], 4)) / 65536.0); 00126 last_elevation = virtual_elevation = 360.0 * (((double)hex2bin(&rx_buffer[5], 4)) / 65536.0); 00127 nexstar_command = 0; 00128 nexstar_command_status = 0; 00129 virtual_update_counter = 0; 00130 if (nexstar_goto_in_progress) { 00131 if (!memcmp(&rx_buffer[0], nexstar_goto_azmith, 4) && !memcmp(&rx_buffer[5], nexstar_goto_elevation, 4)) { 00132 nexstar_goto_in_progress = false; 00133 osd_clear_line(2); 00134 osd_clear_line(3); 00135 _nexstar_set_tracking_mode(0); 00136 } 00137 } 00138 break; 00139 case NEXSTAR_GET_RADEC: 00140 00141 break; 00142 case NEXSTAR_SET_ELEVATION_RATE: 00143 case NEXSTAR_SET_AZMITH_RATE: 00144 nexstar_command = 0; 00145 nexstar_command_status = 0; 00146 break; 00147 case NEXSTAR_GOTO: 00148 nexstar_command = 0; 00149 nexstar_command_status = 0; 00150 break; 00151 case NEXSTAR_GOTO_AZM_FAST: 00152 nexstar_command = 0; 00153 nexstar_command_status = 0; 00154 break; 00155 case NEXSTAR_SET_APPROACH: 00156 nexstar_command = 0; 00157 nexstar_command_status = 0; 00158 break; 00159 case NEXSTAR_SET_TIME: 00160 nexstar_command = 0; 00161 nexstar_command_status = 0; 00162 break; 00163 case NEXSTAR_SET_LOCATION: 00164 nexstar_command = 0; 00165 nexstar_command_status = 0; 00166 break; 00167 case NEXSTAR_SYNC: 00168 nexstar_command = 0; 00169 nexstar_command_status = 0; 00170 break; 00171 } 00172 } 00173 } 00174 00175 /** nexstar_timeout_callback 00176 * 00177 * The generic timer callback handler. 00178 * 00179 * @param int index The timer index (handle). 00180 */ 00181 void _nexstar_timeout_callback(int index) { 00182 nexstar_status = NEXSTAR_STATE_NOT_CONN; 00183 } 00184 00185 void _nexstar_one_second_timer(int index) { 00186 _nexstar_get_altazm(); 00187 //_nexstar_get_radec(); 00188 rit_timer_set_counter(RIT_ONESEC_NEXSTAR, 200); 00189 } 00190 00191 double nexstar_get_rate_azm(void) { 00192 if (nexstar_goto_in_progress) return 0.0; 00193 return azmith_rate_coarse + azmith_rate_fine + azmith_rate_auto; 00194 } 00195 00196 double nexstar_get_rate_alt(void) { 00197 if (nexstar_goto_in_progress) return 0.0; 00198 return elevation_rate_coarse + elevation_rate_fine + elevation_rate_auto; 00199 } 00200 00201 void _nexstar_100th_timer(int index) { 00202 rit_timer_set_counter(RIT_100TH_NEXSTAR, 100); 00203 } 00204 00205 /** nexstar_init 00206 * 00207 * Used to initialise the system. 00208 */ 00209 void nexstar_init(void) { 00210 00211 DEBUG_INIT_START; 00212 00213 rit_timer_set_counter(RIT_TIMER_NEXSTAR, 0); 00214 rit_timer_set_counter(RIT_ONESEC_NEXSTAR, 250); 00215 rit_timer_set_counter(RIT_100TH_NEXSTAR, 100); 00216 nexstar_status = NEXSTAR_STATE_IDLE; 00217 nexstar_command = 0; 00218 nexstar_command_status = 0; 00219 last_elevation = 0.0; 00220 last_azmith = 0.0; 00221 virtual_elevation = 0.0; 00222 virtual_azmith = 0.0; 00223 00224 elevation_rate = elevation_rate_coarse = elevation_rate_fine = elevation_rate_auto = 0.0; 00225 azmith_rate = azmith_rate_coarse = azmith_rate_fine = azmith_rate_auto = 0.0; 00226 00227 nexstar_goto_in_progress = false; 00228 00229 nexstar_aligned = false; 00230 00231 rx_buffer_in = 0; 00232 virtual_update_counter = 0; 00233 00234 DEBUG_INIT_END; 00235 00236 Uart2_init(); 00237 } 00238 00239 /* External API functions. */ 00240 void nexstar_get_elazm(double *el, double *azm) { 00241 *(el) = last_elevation; 00242 *(azm) = last_azmith; 00243 } 00244 00245 /* Internal API functions. */ 00246 int _nexstar_set_tracking_mode(int mode) { 00247 if (nexstar_status == NEXSTAR_STATE_IDLE) { 00248 nexstar_status = NEXSTAR_STATE_BUSY; 00249 rx_buffer_in = 0; 00250 nexstar_command_status = 0; 00251 nexstar_command = NEXSTAR_SET_TRACKING; 00252 LPC_UART2->FCR = UART2_SET_FCR_CLEAR; 00253 Uart2_putc('T'); 00254 Uart2_putc((char)mode); 00255 rit_timer_set_counter(RIT_TIMER_NEXSTAR, NEXSTAR_SERIAL_TIMEOUT); 00256 return 1; 00257 } 00258 return 0; 00259 } 00260 00261 int _nexstar_get_altazm(void) { 00262 if (nexstar_status == NEXSTAR_STATE_IDLE) { 00263 nexstar_status = NEXSTAR_STATE_BUSY; 00264 rx_buffer_in = 0; 00265 nexstar_command_status = 0; 00266 nexstar_command = NEXSTAR_GET_AZMALT; 00267 LPC_UART2->FCR = UART2_SET_FCR_CLEAR; 00268 Uart2_putc('Z'); 00269 rit_timer_set_counter(RIT_TIMER_NEXSTAR, NEXSTAR_SERIAL_TIMEOUT); 00270 return 1; 00271 } 00272 return 0; 00273 } 00274 00275 int _nexstar_get_radec(void) { 00276 if (nexstar_status == NEXSTAR_STATE_IDLE) { 00277 nexstar_status = NEXSTAR_STATE_BUSY; 00278 rx_buffer_in = 0; 00279 nexstar_command_status = 0; 00280 nexstar_command = NEXSTAR_GET_RADEC; 00281 LPC_UART2->FCR = UART2_SET_FCR_CLEAR; 00282 Uart2_putc('E'); 00283 rit_timer_set_counter(RIT_TIMER_NEXSTAR, NEXSTAR_SERIAL_TIMEOUT); 00284 return 1; 00285 } 00286 return 0; 00287 } 00288 00289 void _nexstar_set_elevation_rate_coarse(double rate) { 00290 elevation_rate_coarse = rate; 00291 _nexstar_set_elevation_rate(); 00292 } 00293 00294 void _nexstar_set_elevation_rate_fine(double rate) { 00295 elevation_rate_fine = rate; 00296 _nexstar_set_elevation_rate(); 00297 } 00298 00299 void _nexstar_set_elevation_rate_auto(double rate) { 00300 elevation_rate_auto = rate; 00301 _nexstar_set_elevation_rate(); 00302 } 00303 00304 int _nexstar_set_elevation_rate(void) { 00305 char dir, high, low, cmd[32]; 00306 double rate; 00307 00308 rate = elevation_rate_coarse + elevation_rate_fine + elevation_rate_auto; 00309 00310 if (elevation_rate == rate) return 0; 00311 00312 if (rate != 0.0) { 00313 if (nexstar_goto_in_progress || nexstar_status != NEXSTAR_STATE_IDLE) return 0; 00314 } 00315 00316 while (nexstar_status != NEXSTAR_STATE_IDLE) { 00317 if (nexstar_status == NEXSTAR_STATE_NOT_CONN) return 0; 00318 user_wait_ms(1); 00319 }; 00320 00321 //if (rate >= 0.0) osd_string_xyl(0, 14, cmd, sprintf(cmd, " ALT >> %c%.1f", '+', rate)); 00322 //else osd_string_xyl(0, 14, cmd, sprintf(cmd, " ALT >> %+.1f", rate)); 00323 nexstar_status = NEXSTAR_STATE_BUSY; 00324 rx_buffer_in = 0; 00325 nexstar_command_status = 0; 00326 nexstar_command = NEXSTAR_SET_ELEVATION_RATE; 00327 LPC_UART2->FCR = UART2_SET_FCR_CLEAR; 00328 dir = 6; 00329 if (rate < 0.0) { 00330 dir = 7; 00331 rate *= -1; 00332 } 00333 high = ((int)(3600.0 * rate * 4.0) / 256) & 0xFF; 00334 low = ((int)(3600.0 * rate * 4.0) % 256) & 0xFF; 00335 Uart2_puts(cmd, sprintf(cmd, "P%c%c%c%c%c%c%c", 3, 17, dir, high, low, 0, 0)); 00336 rit_timer_set_counter(RIT_TIMER_NEXSTAR, NEXSTAR_SERIAL_TIMEOUT); 00337 elevation_rate = rate; 00338 return 1; 00339 } 00340 00341 void _nexstar_set_azmith_rate_coarse(double rate) { 00342 azmith_rate_coarse = rate; 00343 _nexstar_set_azmith_rate(); 00344 } 00345 00346 void _nexstar_set_azmith_rate_fine(double rate) { 00347 azmith_rate_fine = rate; 00348 _nexstar_set_azmith_rate(); 00349 } 00350 00351 void _nexstar_set_azmith_rate_auto(double rate) { 00352 azmith_rate_auto = rate; 00353 _nexstar_set_azmith_rate(); 00354 } 00355 00356 int _nexstar_set_azmith_rate(void) { 00357 char dir, high, low, cmd[32]; 00358 double rate; 00359 00360 rate = azmith_rate_coarse + azmith_rate_fine + azmith_rate_auto; 00361 00362 if (azmith_rate == rate) return 0; 00363 00364 if (rate != 0.0) { 00365 if (nexstar_goto_in_progress || nexstar_status != NEXSTAR_STATE_IDLE) return 0; 00366 } 00367 00368 while (nexstar_status != NEXSTAR_STATE_IDLE) { 00369 if (nexstar_status == NEXSTAR_STATE_NOT_CONN) return 0; 00370 user_wait_ms(1); 00371 }; 00372 00373 //if (rate >= 0.0) osd_string_xyl(14, 14, cmd, sprintf(cmd, " AZM >> %c%.1f", '+', rate)); 00374 //else osd_string_xyl(14, 14, cmd, sprintf(cmd, " AZM >> %+.1f", rate)); 00375 nexstar_status = NEXSTAR_STATE_BUSY; 00376 nexstar_status = NEXSTAR_STATE_BUSY; 00377 rx_buffer_in = 0; 00378 nexstar_command_status = 0; 00379 nexstar_command = NEXSTAR_SET_AZMITH_RATE; 00380 LPC_UART2->FCR = UART2_SET_FCR_CLEAR; 00381 dir = 6; 00382 if (rate < 0.0) { 00383 dir = 7; 00384 rate *= -1; 00385 } 00386 high = ((int)(3600.0 * rate * 4.0) / 256) & 0xFF; 00387 low = ((int)(3600.0 * rate * 4.0) % 256) & 0xFF; 00388 Uart2_puts(cmd, sprintf(cmd, "P%c%c%c%c%c%c%c", 3, 16, dir, high, low, 0, 0)); 00389 rit_timer_set_counter(RIT_TIMER_NEXSTAR, NEXSTAR_SERIAL_TIMEOUT); 00390 azmith_rate = rate; 00391 return 1; 00392 } 00393 00394 int _nexstar_goto(uint32_t elevation, uint32_t azmith) { 00395 char cmd[32], buf1[6], buf2[6]; 00396 double azm_target, azm_current; 00397 00398 if (nexstar_goto_in_progress) return 0; 00399 00400 printDouble_3_2(buf1, 360.0 * ((double)elevation / 65536)); 00401 osd_stringl(2, cmd, sprintf(cmd, " GOTO > %s < ALT", buf1)); 00402 printDouble_3_2(buf2, 360.0 * ((double)azmith / 65536)); 00403 osd_stringl(3, cmd, sprintf(cmd, " > %s < AZM", buf2)); 00404 osd_clear_line(14); 00405 00406 /* Adjust the GOTO approach based on where we are pointing now 00407 comapred to where we want to go. */ 00408 azm_target = 360.0 * ((double)((double)azmith / 65536.0)); 00409 azm_current = last_azmith - azm_target; 00410 00411 if (azm_current > 180.) _nexstar_set_azm_approach(1); 00412 else _nexstar_set_azm_approach(-1); 00413 00414 while(nexstar_status != NEXSTAR_STATE_IDLE) { 00415 if(nexstar_status == NEXSTAR_STATE_NOT_CONN) return 0; 00416 user_wait_ms(1); 00417 }; 00418 00419 nexstar_goto_in_progress = true; 00420 nexstar_status = NEXSTAR_STATE_BUSY; 00421 rx_buffer_in = 0; 00422 nexstar_command_status = 0; 00423 nexstar_command = NEXSTAR_GOTO; 00424 LPC_UART2->FCR = UART2_SET_FCR_CLEAR; 00425 sprintf(nexstar_goto_azmith, "%04X", azmith); 00426 sprintf(nexstar_goto_elevation, "%04X", elevation); 00427 Uart2_puts(cmd, sprintf(cmd, "B%s,%s", nexstar_goto_azmith, nexstar_goto_elevation)); 00428 rit_timer_set_counter(RIT_TIMER_NEXSTAR, 60000); 00429 return 1; 00430 } 00431 00432 int _nexstar_goto_azm_fast(uint32_t azmith) { 00433 char cmd[16]; 00434 00435 while(nexstar_status != NEXSTAR_STATE_IDLE) { 00436 if(nexstar_status == NEXSTAR_STATE_NOT_CONN) return 0; 00437 user_wait_ms(1); 00438 }; 00439 00440 nexstar_status = NEXSTAR_STATE_BUSY; 00441 rx_buffer_in = 0; 00442 nexstar_command_status = 0; 00443 nexstar_command = NEXSTAR_GOTO_AZM_FAST; 00444 LPC_UART2->FCR = UART2_SET_FCR_CLEAR; 00445 Uart2_puts(cmd, sprintf(cmd, "P%c%c%c%c%c%c%c", 3, 16, 2, (azmith >> 8) & 0xFF, azmith & 0xFF, 0, 0)); 00446 00447 rit_timer_set_counter(RIT_TIMER_NEXSTAR, 60000); 00448 return 1; 00449 } 00450 00451 void _nexstar_set_azm_approach(int approach) { 00452 char cmd[16]; 00453 00454 while(nexstar_status != NEXSTAR_STATE_IDLE) { 00455 if(nexstar_status == NEXSTAR_STATE_NOT_CONN) return; 00456 user_wait_ms(1); 00457 }; 00458 00459 nexstar_command = NEXSTAR_SET_APPROACH; 00460 nexstar_command_status = 0; 00461 nexstar_status = NEXSTAR_STATE_BUSY; 00462 rx_buffer_in = 0; 00463 LPC_UART2->FCR = UART2_SET_FCR_CLEAR; 00464 Uart2_puts(cmd, sprintf(cmd, "P%c%c%c%c%c%c%c", 3, 16, 0xFD, approach < 0 ? 1 : 0, 0, 0, 0)); 00465 rit_timer_set_counter(RIT_TIMER_NEXSTAR, NEXSTAR_SERIAL_TIMEOUT); 00466 } 00467 00468 bool _nexstar_is_aligned(void) { 00469 00470 while(nexstar_status != NEXSTAR_STATE_IDLE) { 00471 if(nexstar_status == NEXSTAR_STATE_NOT_CONN) return false; 00472 user_wait_ms(1); 00473 }; 00474 00475 nexstar_command = NEXSTAR_IS_ALIGNED; 00476 nexstar_command_status = 0; 00477 nexstar_status = NEXSTAR_STATE_BUSY; 00478 rx_buffer_in = 0; 00479 LPC_UART2->FCR = UART2_SET_FCR_CLEAR; 00480 Uart2_putc('J'); 00481 rit_timer_set_counter(RIT_TIMER_NEXSTAR, NEXSTAR_SERIAL_TIMEOUT); 00482 00483 /* This command blocks while we wait for an answer. */ 00484 while(nexstar_status != NEXSTAR_STATE_IDLE) { 00485 user_wait_ms(10); 00486 }; 00487 00488 return nexstar_aligned; 00489 } 00490 00491 void _nexstar_sync(RaDec *radec) { 00492 char cmd[32]; 00493 uint16_t ra, dec; 00494 00495 while(nexstar_status != NEXSTAR_STATE_IDLE) { 00496 user_wait_ms(1); 00497 }; 00498 00499 ra = (uint16_t)((radec->ra / 360.0) * 65536); 00500 dec = (uint16_t)((radec->dec / 360.0) * 65536); 00501 00502 nexstar_command = NEXSTAR_SYNC; 00503 nexstar_command_status = 0; 00504 nexstar_status = NEXSTAR_STATE_BUSY; 00505 rx_buffer_in = 0; 00506 LPC_UART2->FCR = UART2_SET_FCR_CLEAR; 00507 Uart2_puts(cmd, sprintf(cmd, "S%02X,%02X", ra, dec)); 00508 rit_timer_set_counter(RIT_TIMER_NEXSTAR, NEXSTAR_SERIAL_TIMEOUT); 00509 00510 } 00511 00512 void _nexstar_set_time(GPS_TIME *t) { 00513 char cmd[32]; 00514 GPS_TIME rt; 00515 00516 while(nexstar_status != NEXSTAR_STATE_IDLE) { 00517 user_wait_ms(1); 00518 }; 00519 00520 if (t == (GPS_TIME *)NULL) { 00521 t = &rt; 00522 gps_get_time(t); 00523 } 00524 00525 nexstar_command = NEXSTAR_SET_TIME; 00526 nexstar_command_status = 0; 00527 nexstar_status = NEXSTAR_STATE_BUSY; 00528 rx_buffer_in = 0; 00529 LPC_UART2->FCR = UART2_SET_FCR_CLEAR; 00530 Uart2_puts(cmd, sprintf(cmd, "H%c%c%c%c%c%c%c%c", t->hour, t->minute, t->second, t->month, t->day, t->year - 2000, 0, 0)); 00531 rit_timer_set_counter(RIT_TIMER_NEXSTAR, NEXSTAR_SERIAL_TIMEOUT); 00532 } 00533 00534 void _nexstar_set_location(GPS_LOCATION_AVERAGE *l) { 00535 char cmd[32]; 00536 GPS_LOCATION_AVERAGE rl; 00537 double d, t; 00538 char lat_degrees, lat_minutes, lat_seconds, lon_degrees, lon_minutes, lon_seconds; 00539 00540 while(nexstar_status != NEXSTAR_STATE_IDLE) { 00541 user_wait_ms(1); 00542 }; 00543 00544 if (l == (GPS_LOCATION_AVERAGE *)NULL) { 00545 l = &rl; 00546 gps_get_location_average(l); 00547 } 00548 00549 d = l->latitude; 00550 lat_degrees = (char)d; t = (d - (double)lat_degrees) * 60.0; 00551 lat_minutes = (char)t; 00552 lat_seconds = (t - (double)lat_minutes) * 60.0; 00553 d = l->longitude; 00554 lon_degrees = (int)d; t = (d - (double)lon_degrees) * 60.0; 00555 lon_minutes = (int)t; 00556 lon_seconds = (t - (double)lon_minutes) * 60.0; 00557 00558 nexstar_command = NEXSTAR_SET_LOCATION; 00559 nexstar_command_status = 0; 00560 nexstar_status = NEXSTAR_STATE_BUSY; 00561 rx_buffer_in = 0; 00562 LPC_UART2->FCR = UART2_SET_FCR_CLEAR; 00563 Uart2_puts(cmd, sprintf(cmd, "W%c%c%c%c%c%c%c%c", lat_degrees, lat_minutes, lat_seconds, l->north_south == 'N' ? 0 : 1, lon_degrees, lon_minutes, lon_seconds, l->east_west == 'E' ? 0 : 1)); 00564 rit_timer_set_counter(RIT_TIMER_NEXSTAR, NEXSTAR_SERIAL_TIMEOUT); 00565 } 00566 00567 /** UART2_IRQHandler(void) 00568 * 00569 * The interrupt service routine for the UART2. 00570 */ 00571 extern "C" void UART2_IRQHandler(void) __irq { 00572 volatile uint32_t iir; 00573 char c; 00574 00575 /* Get the interrupt identification register which also resets IIR. */ 00576 iir = LPC_UART2->IIR; 00577 00578 if (iir & 0x1) return; 00579 00580 iir = (iir >> 1) & 0x3; 00581 00582 /* Handle the incoming character. */ 00583 if (iir == 2) { 00584 c = LPC_UART2->RBR; 00585 //Uart0_putc(c); 00586 rit_timer_set_counter(RIT_TIMER_NEXSTAR, NEXSTAR_SERIAL_TIMEOUT); 00587 rx_buffer[rx_buffer_in] = c; 00588 rx_buffer_in++; 00589 if (rx_buffer_in >= NEXSTAR_BUFFER_SIZE) { 00590 rx_buffer_in = 0; 00591 } 00592 if (c == '#') { 00593 rit_timer_set_counter(RIT_TIMER_NEXSTAR, 0); 00594 nexstar_command_status = 1; 00595 nexstar_status = NEXSTAR_STATE_IDLE; 00596 } 00597 } 00598 } 00599 00600 /** Uart2_init 00601 * 00602 * Initialise UART2 to our requirements for Nexstar. 00603 */ 00604 static void Uart2_init (void) { 00605 volatile char c __attribute__((unused)); 00606 00607 DEBUG_INIT_START; 00608 00609 LPC_SC->PCONP |= (1UL << 24); 00610 LPC_SC->PCLKSEL1 &= ~(3UL << 16); 00611 LPC_SC->PCLKSEL1 |= (1UL << 16); 00612 LPC_PINCON->PINSEL0 |= ((1UL << 20) | (1UL << 22)); 00613 LPC_UART2->LCR = 0x80; 00614 LPC_UART2->DLM = 0x2; // 115200 baud, for 9600 use 0x2; 00615 LPC_UART2->DLL = 0x71; // 115200 baud, for 9600 use 0x71; 00616 LPC_UART2->LCR = 0x3; 00617 LPC_UART2->FCR = 0x1; 00618 00619 /* Ensure the FIFO is empty. */ 00620 while (LPC_UART2->LSR & 0x1) c = (char)LPC_UART2->RBR; 00621 00622 NVIC_SetVector(UART2_IRQn, (uint32_t)UART2_IRQHandler); 00623 NVIC_EnableIRQ(UART2_IRQn); 00624 00625 /* Enable UART0 RX interrupt only. */ 00626 LPC_UART2->IER = 0x1; 00627 00628 DEBUG_INIT_END; 00629 } 00630 00631 static inline void Uart2_putc(char c) { 00632 //Uart0_putc(c); 00633 LPC_UART2->THR = (uint32_t)(c & 0xFF); 00634 } 00635 00636 static inline void Uart2_puts(char *s, int len) { 00637 int i; 00638 if (len > 0) for (i = 0; len; i++, len--) Uart2_putc(s[i]); 00639 } 00640
Generated on Tue Jul 12 2022 18:05:35 by 1.7.2