Satellite Observers Workbench. NOT yet complete, just published for forum posters to \"cherry pick\" pieces of code as requiered as an example.
nexstar_old.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 #ifdef NEVERCOMPILETHIS 00024 00025 #include "mbed.h" 00026 #include "nexstar.h" 00027 #include "utils.h" 00028 #include "debug.h" 00029 #include "main.h" 00030 00031 DigitalOut led1(LED1); 00032 DigitalOut led2(LED2); 00033 DigitalOut led3(LED3); 00034 DigitalOut led4(LED4); 00035 00036 /* The main place holder data structure for the Nexstar. */ 00037 NEXSTAR_DATA nexstar; 00038 00039 /* A timer to look for serial comms failure. */ 00040 OneMS timeout; 00041 00042 /** nexstar_process(void) 00043 * 00044 * Standard module _process function. 00045 */ 00046 void nexstar_process(void) { 00047 int i, j, q; 00048 signed char status, type; 00049 00050 BLAT4; 00051 00052 /* Multiple queued requests will start automatically after the previous 00053 request (see the ISR for details). However, it is possible that when 00054 the ISR detects the completion of a request there are, at that time, 00055 no more pending requests in the queue. So loop over the request queue 00056 and if none are in progress, initiate a request transfer to the Nexstar. */ 00057 if (! nexstar_request_count_status(NEXSTAR_REQUEST_IN_PROGRESS)) { 00058 if (nexstar_request_count_status(NEXSTAR_REQUEST_PENDING)) { 00059 for (i = 0, q = nexstar.currentRequest; i < NEXSTAR_NUM_OF_PACKETS; i++) { 00060 if (nexstar.commsPackets[q].requestStatus == NEXSTAR_REQUEST_PENDING) { 00061 nexstar.currentRequest = q; 00062 nexstar_send_request(q); 00063 i = NEXSTAR_NUM_OF_PACKETS; 00064 } 00065 else { 00066 NEXSTAR_NEXT_REQUEST(q); 00067 } 00068 } 00069 } 00070 } 00071 00072 /* look through all the comms request packets and see if any need processing. */ 00073 /* 00074 for (i = 0; i < NEXSTAR_NUM_OF_PACKETS; i++) { 00075 status = nexstar.commsPackets[i].requestStatus; 00076 type = nexstar.commsPackets[i].requestType; 00077 if (status == NEXSTAR_REQUEST_TIMEOUT) { 00078 for (j = 0; j < NEXSTAR_NUM_OF_PACKETS; j++) { 00079 REQUEST_SET_PACKET_STATUS(j, NEXSTAR_REQUEST_IDLE); 00080 nexstar_request_packet_reset(&nexstar.commsPackets[j]); 00081 } 00082 NEXSTAR_SET_STATUS(NEXSTAR_NOT_CONNECTED); 00083 } 00084 else if (status == NEXSTAR_REQUEST_COMPLETE) { 00085 switch (type) { 00086 case NEXSTAR_ECHO_COMMS: 00087 nexstar_request_echo(NEXSTAR_PROCESS_REQUEST, i); 00088 break; 00089 case NEXSTAR_ASK_IS_ALIGNED: 00090 nexstar_request_get_aligned(NEXSTAR_PROCESS_REQUEST, i); 00091 break; 00092 case NEXSTAR_ASK_ALTAZM_POSITION: 00093 nexstar_request_get_altazm(NEXSTAR_PROCESS_REQUEST, i); 00094 break; 00095 } 00096 } 00097 } 00098 */ 00099 00100 if (nexstar.commsPackets[nexstar.currentRequest].requestStatus; == NEXSTAR_REQUEST_COMPLETE) { 00101 switch (type) { 00102 case NEXSTAR_ECHO_COMMS: 00103 nexstar_request_echo(NEXSTAR_PROCESS_REQUEST, nexstar.currentRequest); 00104 break; 00105 case NEXSTAR_ASK_IS_ALIGNED: 00106 nexstar_request_get_aligned(NEXSTAR_PROCESS_REQUEST, nexstar.currentRequest); 00107 break; 00108 case NEXSTAR_ASK_ALTAZM_POSITION: 00109 nexstar_request_get_altazm(NEXSTAR_PROCESS_REQUEST, nexstar.currentRequest); 00110 break; 00111 } 00112 } 00113 00114 /* If the Nexstar is in an unknown state attempt to ask it for 00115 alignment. Once we get a positive response we at least know 00116 a Nexstar is connected and responding. Until we have that 00117 knowledge there is little else we can do. */ 00118 switch(nexstar.status) { 00119 case NEXSTAR_NOT_CONNECTED: 00120 if (! nexstar_request_count_request_type(NEXSTAR_ECHO_COMMS)) { 00121 Uart2_flush_rxfifo(); 00122 nexstar_request_echo(NEXSTAR_SEND_REQUEST, 0); 00123 } 00124 return; 00125 00126 case NEXSTAR_CONNECTED: 00127 case NEXSTAR_NOT_ALIGNED: 00128 if (! nexstar_request_count_request_type(NEXSTAR_ASK_IS_ALIGNED)) { 00129 Uart2_flush_rxfifo(); 00130 nexstar_request_get_aligned(NEXSTAR_SEND_REQUEST, 0); 00131 } 00132 return; 00133 00134 default: 00135 debug.printf("I don't know what to do! status is %d\r\n", nexstar.status); 00136 break; 00137 } 00138 00139 /* As possible as often, request the Nexstar's pointing position. */ 00140 if (! nexstar_request_count_request_type(NEXSTAR_ASK_ALTAZM_POSITION)) { 00141 nexstar_request_get_altazm(NEXSTAR_SEND_REQUEST, 0); 00142 } 00143 00144 00145 } 00146 00147 /** nexstar_init(void) 00148 * 00149 * Standard module _init function. 00150 */ 00151 void nexstar_init(void) { 00152 00153 /* Setup the global mode of this Nexstar. */ 00154 NEXSTAR_SET_STATUS(NEXSTAR_NOT_CONNECTED); 00155 00156 /* Initialise the comms packets and buffers. */ 00157 nexstar.currentRequest = 0; 00158 nexstar.availableRequest = 0; 00159 for (int i = 0; i < NEXSTAR_NUM_OF_PACKETS; i++) { 00160 nexstar_request_packet_reset(&nexstar.commsPackets[i]); 00161 //nexstar.commsPackets[i].requestType = 0; 00162 //nexstar.commsPackets[i].requestStatus = NEXSTAR_REQUEST_IDLE; 00163 //nexstar.commsPackets[i].bufferPointer = 0; 00164 //nexstar.commsPackets[i].callback = NULL; 00165 //memset(nexstar.commsPackets[i].buffer, 0, NEXSTAR_PACKET_BUFFER_SIZE); 00166 } 00167 00168 /* Prepare the one-shot timeout timers. */ 00169 timeout.mode(ONEMS_MODE_TIMEOUT_CALLBACK); 00170 timeout.attach(nexstar_timeout); 00171 00172 /* Initialise the UART we use. */ 00173 Uart2_init(); 00174 } 00175 00176 /** nexstar_request_packet_reset 00177 * 00178 * Return a request packet back to default state. 00179 * 00180 * @param NEXSTAR_COMMS_PACKET *p A pointer to the packet to reset. 00181 */ 00182 void nexstar_request_packet_reset(NEXSTAR_COMMS_PACKET *p) { 00183 p->requestType = 0; 00184 p->bufferPointer = 0; 00185 p->callback = NULL; 00186 memset(p->buffer, 0, NEXSTAR_PACKET_BUFFER_SIZE); 00187 p->requestStatus = NEXSTAR_REQUEST_IDLE; 00188 } 00189 00190 /** nexstar_p(void) 00191 * 00192 * Get a pointer to the data structure for the Nexstar. 00193 * Used by the API to get data. 00194 */ 00195 NEXSTAR_DATA * nexstar_p(void) { 00196 return &nexstar; 00197 } 00198 00199 /** nexstar_request_count_request_type(char requestType) 00200 * 00201 * Used to find out if any of the packets are currently marked as the supplied request type. 00202 * 00203 * @param char The status to test. 00204 * @return bool True otherwise false 00205 */ 00206 int nexstar_request_count_request_type(char requestType) { 00207 int count, i; 00208 00209 for (count = 0, i = 0; i < NEXSTAR_NUM_OF_PACKETS; i++) { 00210 if (nexstar.commsPackets[i].requestType == requestType) { 00211 count++;; 00212 } 00213 } 00214 return count; 00215 } 00216 00217 /** nexstar_request_count_status (char status) 00218 * 00219 * Used to find out if any of the packets are currently marked as the supplied status. 00220 * 00221 * @param char The status to test. 00222 * @return bool True otherwise false 00223 */ 00224 int nexstar_request_count_status(char status) { 00225 int count, i; 00226 00227 for (count = 0, i = 0; i < NEXSTAR_NUM_OF_PACKETS; i++) { 00228 if (nexstar.commsPackets[i].requestStatus == status) { 00229 count++;; 00230 } 00231 } 00232 return count; 00233 } 00234 00235 /** nexstar_timeout(class OneMS *q) 00236 * 00237 * A callback for the timeout timer. 00238 * 00239 * @param pointer class OneMS that invoked the callback. 00240 */ 00241 void nexstar_timeout(class OneMS *q) { 00242 q->stop(); /* Ensure we stop this timer. */ 00243 00244 /* Mark this request timed out. */ 00245 REQUEST_SET_PACKET_STATUS(nexstar.currentRequest, NEXSTAR_REQUEST_TIMEOUT); 00246 } 00247 00248 /** nexstar_request_get_altazm(int mode, unsigned char handle) 00249 * 00250 * Used to either create a request to get the current AltAzm position of the Nextsra 00251 * or to process a previously completed request. 00252 * 00253 * @param int mode Determine what action to create, queue request or process packet. 00254 * @param unsigned char handle If processing a request this is the index of the packet to be processed. 00255 * @return zero on failure or error, non-zero otherwise. 00256 */ 00257 int nexstar_request_get_altazm(int mode, unsigned char handle) { 00258 00259 /* Create a request to get the ALT/AZM and queue it. */ 00260 if (mode == NEXSTAR_SEND_REQUEST) { 00261 REQUEST_HANDLE; 00262 nexstar.commsPackets[handle].buffer[0] = 'Z'; 00263 REQUEST_SET(NEXSTAR_ASK_ALTAZM_POSITION, 1); 00264 led3 = 1; 00265 return 1; 00266 } 00267 00268 /* Given a completed request, parse the data and update our information. */ 00269 if (mode == NEXSTAR_PROCESS_REQUEST) { 00270 if (nexstar.commsPackets[handle].requestStatus != NEXSTAR_REQUEST_COMPLETE) return 0; 00271 char *buffer = nexstar.commsPackets[handle].buffer; 00272 REQUEST_BUFFER_CHECK(9, 0); 00273 nexstar.currentAltRaw = hex2bin(buffer + 5, 4); 00274 nexstar.currentAlt = (double)(((double)nexstar.currentAltRaw / 65536.) * 360.); 00275 nexstar.currentAzmRaw = hex2bin(buffer + 0, 4); 00276 nexstar.currentAzm = (double)(((double)nexstar.currentAzmRaw / 65536.) * 360.); 00277 nexstar_request_packet_reset(&nexstar.commsPackets[handle]); 00278 REQUEST_SET_PACKET_STATUS(handle, NEXSTAR_REQUEST_IDLE); 00279 led3 = 0; 00280 return 1; 00281 } 00282 00283 return 0; 00284 } 00285 00286 /** nexstar_request_get_aligned(int mode, unsigned char handle) 00287 * 00288 * Used to either create a request to check teh Nexstar is aligned 00289 * or to process a previously completed request. 00290 * 00291 * @param int mode Determine what action to create, queue request or process packet. 00292 * @param unsigned char handle If processing a request this is the index of the packet to be processed. 00293 * @return zero on failure or error, non-zero otherwise. 00294 */ 00295 int nexstar_request_get_aligned(int mode, unsigned char handle) { 00296 00297 /* Create a request to get the ALT/AZM and queue it. */ 00298 if (mode == NEXSTAR_SEND_REQUEST) { 00299 REQUEST_HANDLE; 00300 nexstar.commsPackets[handle].buffer[0] = 'J'; 00301 nexstar.commsPackets[handle].timeout = 2000; 00302 REQUEST_SET(NEXSTAR_ASK_IS_ALIGNED, 1); 00303 led2 = 1; 00304 return 1; 00305 } 00306 00307 /* Given a completed request, parse the data and update our information. */ 00308 if (mode == NEXSTAR_PROCESS_REQUEST) { 00309 if (nexstar.commsPackets[handle].requestStatus == NEXSTAR_REQUEST_TIMEOUT) { 00310 NEXSTAR_SET_STATUS(NEXSTAR_NOT_CONNECTED); 00311 nexstar_request_packet_reset(&nexstar.commsPackets[handle]); 00312 led2 = 0; 00313 return 0; 00314 } 00315 if (nexstar.commsPackets[handle].requestStatus != NEXSTAR_REQUEST_COMPLETE) return 0; 00316 char *buffer = nexstar.commsPackets[handle].buffer; 00317 REQUEST_BUFFER_CHECK(1, 0); 00318 NEXSTAR_SET_STATUS((buffer[0] == 1) ? NEXSTAR_ALIGNED : NEXSTAR_NOT_ALIGNED); 00319 nexstar_request_packet_reset(&nexstar.commsPackets[handle]); 00320 REQUEST_SET_PACKET_STATUS(handle, NEXSTAR_REQUEST_IDLE); 00321 led2 = 0; 00322 return 1; 00323 } 00324 00325 return 0; 00326 } 00327 00328 /** nexstar_request_echo(int mode, unsigned char handle) 00329 * 00330 * Used to either echo a data byte off the Nexstar. 00331 * 00332 * @param int mode Determine what action to create, queue request or process packet. 00333 * @param unsigned char handle If processing a request this is the index of the packet to be processed. 00334 * @return zero on failure or error, non-zero otherwise. 00335 */ 00336 int nexstar_request_echo(int mode, unsigned char handle) { 00337 00338 /* Create a request to get the ALT/AZM and queue it. */ 00339 if (mode == NEXSTAR_SEND_REQUEST) { 00340 REQUEST_HANDLE; 00341 nexstar.commsPackets[handle].buffer[0] = 'K'; 00342 nexstar.commsPackets[handle].buffer[1] = 'k'; 00343 nexstar.commsPackets[handle].timeout = 2000; 00344 REQUEST_SET(NEXSTAR_ECHO_COMMS, 2); 00345 led1 = 1; 00346 return 1; 00347 } 00348 00349 /* Given a completed request, parse the data and update our information. */ 00350 if (mode == NEXSTAR_PROCESS_REQUEST) { 00351 led3 = 1; 00352 if (nexstar.commsPackets[handle].requestStatus == NEXSTAR_REQUEST_TIMEOUT) { 00353 NEXSTAR_SET_STATUS(NEXSTAR_NOT_CONNECTED); 00354 nexstar_request_packet_reset(&nexstar.commsPackets[handle]); 00355 led1 = 0; 00356 return 0; 00357 } 00358 if (nexstar.commsPackets[handle].requestStatus != NEXSTAR_REQUEST_COMPLETE) return 0; 00359 char *buffer = nexstar.commsPackets[handle].buffer; 00360 REQUEST_BUFFER_CHECK(1, 0); 00361 if (buffer[0] == 'k') debug.printf("YES! "); 00362 else debug.printf("NO! "); 00363 00364 NEXSTAR_SET_STATUS((buffer[0] == 'k') ? NEXSTAR_CONNECTED : NEXSTAR_NOT_CONNECTED); 00365 nexstar_request_packet_reset(&nexstar.commsPackets[handle]); 00366 REQUEST_SET_PACKET_STATUS(handle, NEXSTAR_REQUEST_IDLE); 00367 led1 = 0; 00368 return 1; 00369 } 00370 00371 return 0; 00372 } 00373 00374 /** nexstar_request_set_tracking_mode(int mode, unsigned char handle, char tracking) 00375 * 00376 * Used to set the tracking mode of the Nexstar 00377 * 00378 * @param int mode Determine what action to create, queue request or process packet. 00379 * @param unsigned char handle If processing a request this is the index of the packet to be processed. 00380 * @param char tracking The mode to send. 00381 * @return zero on failure or error, non-zero otherwise. 00382 */ 00383 int nexstar_request_set_tracking_mode(int mode, unsigned char handle, char tracking) { 00384 00385 /* Create request and queue. */ 00386 if (mode == NEXSTAR_SEND_REQUEST) { 00387 REQUEST_HANDLE; 00388 nexstar.commsPackets[handle].buffer[0] = 'T'; 00389 nexstar.commsPackets[handle].buffer[1] = tracking; 00390 REQUEST_SET(NEXSTAR_SET_TRACKING, 2); 00391 return 1; 00392 } 00393 00394 /* Given a completed request, parse the data and update our information. */ 00395 if (mode == NEXSTAR_PROCESS_REQUEST) { 00396 if (nexstar.commsPackets[handle].requestStatus != NEXSTAR_REQUEST_COMPLETE) return 0; 00397 char *buffer = nexstar.commsPackets[handle].buffer; 00398 REQUEST_BUFFER_CHECK(0, 0); 00399 nexstar_request_packet_reset(&nexstar.commsPackets[handle]); 00400 REQUEST_SET_PACKET_STATUS(handle, NEXSTAR_REQUEST_IDLE); 00401 return 1; 00402 } 00403 00404 return 0; 00405 } 00406 00407 /** nexstar_request_get_tracking_mode(int mode, unsigned char handle) 00408 * 00409 * Used to find out what tracking mode Nexstar is in. 00410 * 00411 * @param int mode Determine what action to create, queue request or process packet. 00412 * @param unsigned char handle If processing a request this is the index of the packet to be processed. 00413 * @return zero on failure or error, non-zero otherwise. 00414 */ 00415 int nexstar_request_get_tracking_mode(int mode, unsigned char handle) { 00416 00417 /* Create request and queue. */ 00418 if (mode == NEXSTAR_SEND_REQUEST) { 00419 REQUEST_HANDLE; 00420 nexstar.commsPackets[handle].buffer[0] = 't'; 00421 REQUEST_SET(NEXSTAR_ASK_TRACKING, 1); 00422 return 1; 00423 } 00424 00425 /* Given a completed request, parse the data and update our information. */ 00426 if (mode == NEXSTAR_PROCESS_REQUEST) { 00427 if (nexstar.commsPackets[handle].requestStatus != NEXSTAR_REQUEST_COMPLETE) return 0; 00428 char *buffer = nexstar.commsPackets[handle].buffer; 00429 REQUEST_BUFFER_CHECK(1, 0); 00430 nexstar.trackingMode = buffer[0]; 00431 nexstar_request_packet_reset(&nexstar.commsPackets[handle]); 00432 REQUEST_SET_PACKET_STATUS(handle, NEXSTAR_REQUEST_IDLE); 00433 return 1; 00434 } 00435 00436 return 0; 00437 } 00438 00439 /** nexstar_request_set_slew(int mode, unsigned char handle, double alt, double azm) 00440 * 00441 * Used to set a variable slew rate. 00442 * 00443 * @param int mode Determine what action to create, queue request or process packet. 00444 * @param unsigned char handle If processing a request this is the index of the packet to be processed. 00445 * @param double alt The alt slew rate in degrees per second. 00446 * @param double azm The azm slew rate in degrees per second. 00447 * @return zero on failure or error, non-zero otherwise. 00448 */ 00449 int nexstar_request_set_slew(int mode, unsigned char handle, double alt, double azm) { 00450 int i; 00451 00452 /* Create request and queue. */ 00453 if (mode == NEXSTAR_SEND_REQUEST) { 00454 REQUEST_HANDLE; 00455 nexstar.commsPackets[handle].buffer[0] = 'P'; 00456 nexstar.commsPackets[handle].buffer[1] = '\x3'; 00457 nexstar.commsPackets[handle].buffer[2] = '\x11'; 00458 nexstar.commsPackets[handle].buffer[3] = alt > 0 ? '\x6' : '\x7'; 00459 i = ((int)(alt * 3600.)) * 4; 00460 nexstar.commsPackets[handle].buffer[4] = (char)((i & 0xFF00) >> 8); 00461 nexstar.commsPackets[handle].buffer[5] = (char)(i & 0xFF); 00462 nexstar.commsPackets[handle].buffer[6] = '\0'; 00463 nexstar.commsPackets[handle].buffer[7] = '\0'; 00464 REQUEST_SET(NEXSTAR_SET_ALT_RATE, 8); 00465 00466 REQUEST_HANDLE; 00467 nexstar.commsPackets[handle].buffer[0] = 'P'; 00468 nexstar.commsPackets[handle].buffer[1] = '\x3'; 00469 nexstar.commsPackets[handle].buffer[2] = '\x10'; 00470 nexstar.commsPackets[handle].buffer[3] = azm > 0 ? '\x6' : '\x7'; 00471 i = ((int)(azm * 3600.)) * 4; 00472 nexstar.commsPackets[handle].buffer[4] = (char)((i & 0xFF00) >> 8); 00473 nexstar.commsPackets[handle].buffer[5] = (char)(i & 0xFF); 00474 nexstar.commsPackets[handle].buffer[6] = '\0'; 00475 nexstar.commsPackets[handle].buffer[7] = '\0'; 00476 REQUEST_SET(NEXSTAR_SET_AZM_RATE, 8); 00477 return 1; 00478 } 00479 00480 /* Given a completed request, parse the data and update our information. */ 00481 if (mode == NEXSTAR_PROCESS_REQUEST) { 00482 if (nexstar.commsPackets[handle].requestStatus != NEXSTAR_REQUEST_COMPLETE) return 0; 00483 char *buffer = nexstar.commsPackets[handle].buffer; 00484 REQUEST_BUFFER_CHECK(0, 0); 00485 nexstar_request_packet_reset(&nexstar.commsPackets[handle]); 00486 REQUEST_SET_PACKET_STATUS(handle, NEXSTAR_REQUEST_IDLE); 00487 return 1; 00488 } 00489 00490 return 0; 00491 } 00492 00493 /** nexstar_request_set_location(int mode, unsigned char handle, NEXSTAR_LOCATION *location) 00494 * 00495 * Used to set the Nexstar's location. 00496 * 00497 * @param int mode Determine what action to create, queue request or process packet. 00498 * @param unsigned char handle If processing a request this is the index of the packet to be processed. 00499 * @param NEXSTAR_LOCATION *location A pointer to a data struct holding the data. 00500 * @return zero on failure or error, non-zero otherwise. 00501 */ 00502 int nexstar_request_set_location(int mode, unsigned char handle, NEXSTAR_LOCATION *location) { 00503 00504 /* Create request and queue. */ 00505 if (mode == NEXSTAR_SEND_REQUEST) { 00506 REQUEST_HANDLE; 00507 nexstar.commsPackets[handle].buffer[0] = 'W'; 00508 memcpy((char *)nexstar.commsPackets[handle].buffer + 1, (char *)location, 8); 00509 REQUEST_SET(NEXSTAR_SET_LOCATION, 9); 00510 return 1; 00511 } 00512 00513 /* Given a completed request, parse the data and update our information. */ 00514 if (mode == NEXSTAR_PROCESS_REQUEST) { 00515 if (nexstar.commsPackets[handle].requestStatus != NEXSTAR_REQUEST_COMPLETE) return 0; 00516 char *buffer = nexstar.commsPackets[handle].buffer; 00517 REQUEST_BUFFER_CHECK(1, 0); 00518 nexstar.trackingMode = buffer[0]; 00519 nexstar_request_packet_reset(&nexstar.commsPackets[handle]); 00520 REQUEST_SET_PACKET_STATUS(handle, NEXSTAR_REQUEST_IDLE); 00521 return 1; 00522 } 00523 00524 return 0; 00525 } 00526 00527 /** nexstar_request_set_time(int mode, unsigned char handle, NEXSTAR_TIME *time) 00528 * 00529 * Used to set the Nexstar time. 00530 * 00531 * @param int mode Determine what action to create, queue request or process packet. 00532 * @param unsigned char handle If processing a request this is the index of the packet to be processed. 00533 * @param NEXSTAR_TIME *time A pointer to a data struct holding the data. 00534 * @return zero on failure or error, non-zero otherwise. 00535 */ 00536 int nexstar_request_set_time(int mode, unsigned char handle, NEXSTAR_TIME *time) { 00537 00538 /* Create request and queue. */ 00539 if (mode == NEXSTAR_SEND_REQUEST) { 00540 REQUEST_HANDLE; 00541 nexstar.commsPackets[handle].buffer[0] = 'H'; 00542 memcpy((char *)nexstar.commsPackets[handle].buffer + 1, (char *)time, 8); 00543 REQUEST_SET(NEXSTAR_SET_TIME, 9); 00544 return 1; 00545 } 00546 00547 /* Given a completed request, parse the data and update our information. */ 00548 if (mode == NEXSTAR_PROCESS_REQUEST) { 00549 if (nexstar.commsPackets[handle].requestStatus != NEXSTAR_REQUEST_COMPLETE) return 0; 00550 char *buffer = nexstar.commsPackets[handle].buffer; 00551 REQUEST_BUFFER_CHECK(0, 0); 00552 nexstar_request_packet_reset(&nexstar.commsPackets[handle]); 00553 REQUEST_SET_PACKET_STATUS(handle, NEXSTAR_REQUEST_IDLE); 00554 return 1; 00555 } 00556 00557 return 0; 00558 } 00559 00560 /** nexstar_request_get_version(int mode, unsigned char handle) 00561 * 00562 * Used to set the Nexstar software version. 00563 * 00564 * @param int mode Determine what action to create, queue request or process packet. 00565 * @param unsigned char handle If processing a request this is the index of the packet to be processed. 00566 * @return zero on failure or error, non-zero otherwise. 00567 */ 00568 int nexstar_request_get_version(int mode, unsigned char handle) { 00569 00570 /* Create request and queue. */ 00571 if (mode == NEXSTAR_SEND_REQUEST) { 00572 REQUEST_HANDLE; 00573 nexstar.commsPackets[handle].buffer[0] = 'V'; 00574 REQUEST_SET(NEXSTAR_ASK_VERSION, 1); 00575 return 1; 00576 } 00577 00578 /* Given a completed request, parse the data and update our information. */ 00579 if (mode == NEXSTAR_PROCESS_REQUEST) { 00580 if (nexstar.commsPackets[handle].requestStatus != NEXSTAR_REQUEST_COMPLETE) return 0; 00581 char *buffer = nexstar.commsPackets[handle].buffer; 00582 REQUEST_BUFFER_CHECK(2, 0); 00583 nexstar.version = (buffer[0] << 8) | buffer[1]; 00584 nexstar_request_packet_reset(&nexstar.commsPackets[handle]); 00585 REQUEST_SET_PACKET_STATUS(handle, NEXSTAR_REQUEST_IDLE); 00586 return 1; 00587 } 00588 00589 return 0; 00590 } 00591 00592 /** nexstar_request_raw(int mode, unsigned char handle, NEXSTAR_COMMS_PACKET *q) 00593 * 00594 * Used for external callers to setup a REQUEST based on an externally defined packet structure. 00595 * 00596 * This function allows other parts of the system to make Nextstar requests that are not covered 00597 * by the API or just want to handle a request via a callback. 00598 * 00599 * @param int mode Determine what action to create, queue request or process packet. 00600 * @param unsigned char handle If processing a request this is the index of the packet to be processed. 00601 * @param pointer A pointer to a predefined comms request packet to copy into our queue. 00602 * @return zero on failure or error, non-zero otherwise. 00603 */ 00604 int nexstar_request_raw(int mode, unsigned char handle, NEXSTAR_COMMS_PACKET *q) { 00605 00606 /* Create request and queue. */ 00607 if (mode == NEXSTAR_SEND_REQUEST) { 00608 /* Externally handled requests must have a callback defined as a completion handler. */ 00609 if (q->callback == NULL) { 00610 return 0; 00611 } 00612 REQUEST_HANDLE; 00613 memcpy(&nexstar.commsPackets[handle], q, sizeof(NEXSTAR_COMMS_PACKET)); 00614 REQUEST_SET(NEXSTAR_REQUEST_RAW, 0); 00615 return 1; 00616 } 00617 00618 /* Given a completed request, parse the data and update our information. */ 00619 if (mode == NEXSTAR_PROCESS_REQUEST) { 00620 if (nexstar.commsPackets[handle].requestStatus != NEXSTAR_REQUEST_COMPLETE) return 0; 00621 if (nexstar.commsPackets[handle].callback != NULL) { 00622 (nexstar.commsPackets[handle].callback)(&nexstar.commsPackets[handle]); 00623 } 00624 nexstar_request_packet_reset(&nexstar.commsPackets[handle]); 00625 REQUEST_SET_PACKET_STATUS(handle, NEXSTAR_REQUEST_IDLE); 00626 return 1; 00627 } 00628 00629 return 0; 00630 } 00631 00632 00633 /** nexstar_send_request(int handle) 00634 * 00635 * Used to send a request packet to Nexstar via the serial port. 00636 * 00637 * @param int handle The packet to send. 00638 * @return zero on failure, non-zero otherwise. 00639 */ 00640 int nexstar_send_request(int handle) { 00641 if (nexstar.commsPackets[handle].requestStatus == NEXSTAR_REQUEST_PENDING) { 00642 nexstar.commsPackets[handle].requestStatus = NEXSTAR_REQUEST_IN_PROGRESS; 00643 if (Uart2_puts(nexstar.commsPackets[handle].buffer, (int)nexstar.commsPackets[handle].txLength) != 0) { 00644 memset(nexstar.commsPackets[handle].buffer, 0, NEXSTAR_PACKET_BUFFER_SIZE); 00645 nexstar.commsPackets[handle].bufferPointer = 0; 00646 // Note, we only start the timeout timer AFTER the TxFIFO goes empty, see below. 00647 return 1; 00648 } 00649 else { 00650 /* If we failed to fill the Tx FIFo then switch this request back to pending. */ 00651 REQUEST_SET_PACKET_STATUS(handle, NEXSTAR_REQUEST_PENDING); 00652 return 0; 00653 } 00654 } 00655 return 0; 00656 } 00657 00658 /** UART2_IRQHandler(void) 00659 * 00660 * The interrupt service routine for the UART2. 00661 */ 00662 extern "C" void UART2_IRQHandler(void) { 00663 char c; 00664 uint32_t iir; 00665 00666 /* Get the interrupt identification register which also resets IIR. */ 00667 iir = LPC_UART2->IIR; 00668 00669 if (iir & 0x0001) { 00670 /* Eh? Then why did we interrupt? */ 00671 return; 00672 } 00673 00674 /* Do we have incoming data? */ 00675 if (iir & UART_ISSET_RDA) { 00676 c = (char)LPC_UART2->RBR; 00677 //debug.printf(" %c", c & 0x7f); 00678 if (nexstar.commsPackets[nexstar.currentRequest].requestStatus != NEXSTAR_REQUEST_IN_PROGRESS) { 00679 return; 00680 } 00681 nexstar.commsPackets[nexstar.currentRequest].buffer[nexstar.commsPackets[nexstar.currentRequest].bufferPointer] = c; 00682 nexstar.commsPackets[nexstar.currentRequest].bufferPointer++; 00683 nexstar.commsPackets[nexstar.currentRequest].bufferPointer &= (NEXSTAR_PACKET_BUFFER_SIZE-1); 00684 if (c == '#' || c == '\r' || c == '\n') { 00685 timeout.stop(); /* Halt the timeout timer. */ 00686 REQUEST_SET_PACKET_STATUS(nexstar.currentRequest, NEXSTAR_REQUEST_COMPLETE); 00687 00688 /* Advance to the next request packet and if pending start it. */ 00689 //NEXSTAR_NEXT_REQUEST(nexstar.currentRequest); 00690 //nexstar_send_request(nexstar.currentRequest); 00691 //debug.printf("\r\n"); 00692 } 00693 } 00694 00695 /* If the THRE goes empty AND the TxFIFO is also empty then a command 00696 was just sent to the Nexstar. Start the serial timeout timer so we 00697 only make a timeout measurement AFTER we have sent our command. 00698 That way we don't include our serial transmit time within the timeout 00699 specified by the timer. */ 00700 if (iir & UART_ISSET_THRE) { 00701 if ((LPC_UART2->FIFOLVL & UART_ISSET_FIFOLVL_TXFULL) == 0) { 00702 timeout.start(nexstar.commsPackets[nexstar.currentRequest].timeout == 0 ? NEXSTAR_SERIAL_TIMEOUT : (uint32_t)nexstar.commsPackets[nexstar.currentRequest].timeout); 00703 } 00704 } 00705 00706 if (iir & UART_ISSET_RLS) { 00707 // Do nothing for now other than read the iir register and clear the interrupt. 00708 } 00709 } 00710 00711 /** Uart2_init 00712 * 00713 * Initialise UART2 to our requirements for Nexstar. 00714 */ 00715 void Uart2_init (void) { 00716 00717 /* Switch on UART2. */ 00718 LPC_SC->PCONP |= UART2_ORMASK_PCONP; 00719 00720 /* Set PCLK == CCLK, 96Mhz */ 00721 LPC_SC->PCLKSEL1 |= UART2_ORMASK_PCLKSEL1; 00722 00723 /* Enable the tx/rx to pins and select pin mode. */ 00724 LPC_PINCON->PINSEL0 |= UART2_ORMASK_PINSEL0; 00725 LPC_PINCON->PINMODE0 |= UART2_ORMASK_PINMODE0; 00726 00727 /* Set the divisor values for 9600 and then set 8,n,1 */ 00728 LPC_UART2->LCR = UART2_SET_LCR_DLAB; 00729 LPC_UART2->DLL = UART2_SET_DLLSB; 00730 LPC_UART2->DLM = UART2_SET_DLMSB; 00731 LPC_UART2->LCR = UART2_SET_LCR; 00732 00733 /* Enable FIFOs and then clear them. */ 00734 LPC_UART2->FCR = UART2_SET_FCR; 00735 LPC_UART2->FCR = UART2_SET_FCR_CLEAR; 00736 00737 /* Enable the RDA and THRE interrupts. */ 00738 LPC_UART2->IER = UART2_SET_IER; 00739 00740 /* Now it's time to do interrupts. */ 00741 NVIC_SetVector(UART2_IRQn, (uint32_t)UART2_IRQHandler); 00742 NVIC_EnableIRQ(UART2_IRQn); 00743 } 00744 00745 /** Uart2_flush_rxfifo 00746 * 00747 * Flush the input RX fifo to make sure it's empty. 00748 */ 00749 void Uart2_flush_rxfifo(void) { 00750 uint8_t c; 00751 while (LPC_UART2->LSR & 0x1) { 00752 c = LPC_UART2->RBR; 00753 } 00754 } 00755 00756 /** Uart2_putc 00757 * 00758 * Put the character given into the TxFIFO. 00759 * By design there should always be room in 00760 * the fifo, but check it to make sure. 00761 * 00762 * @param char The character to write. 00763 * @return int zero on failure, non-zero otherwise. 00764 */ 00765 int Uart2_putc(char c) { 00766 /* Check the TxFIFO is not full. */ 00767 if ((LPC_UART2->FIFOLVL & UART_ISSET_FIFOLVL_TXFULL) != 0) return 0; 00768 LPC_UART2->THR = (uint8_t)c; 00769 return -1; 00770 } 00771 00772 /** Uart2_puts 00773 * 00774 * Put the string given into the TX FIFO. 00775 * By design there should always be room in 00776 * the fifo, but check it to make sure. 00777 * 00778 * @param char *s Pointer The string to write. 00779 * @return int zero on failure, non-zero (number of chars written) otherwise. 00780 */ 00781 int Uart2_puts(char *s, int len) { 00782 int i; 00783 00784 /* Check the FIFO is empty, as it should always be by design. */ 00785 if ((LPC_UART2->FIFOLVL & UART_ISSET_FIFOLVL_TXFULL) == 0) { 00786 for (i = 0; i < len; i++) { 00787 LPC_UART2->THR = (uint8_t)s[i]; 00788 debug.printf("%c", s[i]); 00789 } 00790 debug.printf("\r\n"); 00791 } 00792 else { 00793 return 0; 00794 } 00795 return i; 00796 } 00797 00798 #endif
Generated on Tue Jul 12 2022 18:05:35 by 1.7.2