Satellite Observers Workbench. NOT yet complete, just published for forum posters to \"cherry pick\" pieces of code as requiered as an example.

Dependencies:   mbed

Committer:
AjK
Date:
Mon Oct 11 10:34:55 2010 +0000
Revision:
0:0a841b89d614
Totally Alpha quality as this project isn\t completed. Just publishing it as it answers many questions asked in the forums

Who changed what in which revision?

UserRevisionLine numberNew contents of line
AjK 0:0a841b89d614 1 /****************************************************************************
AjK 0:0a841b89d614 2 * Copyright 2010 Andy Kirkham, Stellar Technologies Ltd
AjK 0:0a841b89d614 3 *
AjK 0:0a841b89d614 4 * This file is part of the Satellite Observers Workbench (SOWB).
AjK 0:0a841b89d614 5 *
AjK 0:0a841b89d614 6 * SOWB is free software: you can redistribute it and/or modify
AjK 0:0a841b89d614 7 * it under the terms of the GNU General Public License as published by
AjK 0:0a841b89d614 8 * the Free Software Foundation, either version 3 of the License, or
AjK 0:0a841b89d614 9 * (at your option) any later version.
AjK 0:0a841b89d614 10 *
AjK 0:0a841b89d614 11 * SOWB is distributed in the hope that it will be useful,
AjK 0:0a841b89d614 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
AjK 0:0a841b89d614 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
AjK 0:0a841b89d614 14 * GNU General Public License for more details.
AjK 0:0a841b89d614 15 *
AjK 0:0a841b89d614 16 * You should have received a copy of the GNU General Public License
AjK 0:0a841b89d614 17 * along with SOWB. If not, see <http://www.gnu.org/licenses/>.
AjK 0:0a841b89d614 18 *
AjK 0:0a841b89d614 19 * $Id: main.cpp 5 2010-07-12 20:51:11Z ajk $
AjK 0:0a841b89d614 20 *
AjK 0:0a841b89d614 21 ***************************************************************************/
AjK 0:0a841b89d614 22
AjK 0:0a841b89d614 23 /*
AjK 0:0a841b89d614 24 Update: This whole module requires refactoring into something much more
AjK 0:0a841b89d614 25 sane. Basically, I "organically" grew the code in this module with trial
AjK 0:0a841b89d614 26 and error using the hardware since getting simple things done proved hard.
AjK 0:0a841b89d614 27 I did design (see below) what I thought reasonable system but the Nexstar
AjK 0:0a841b89d614 28 kept throwing up problems. So I really need to come back to this code and
AjK 0:0a841b89d614 29 sort it out properly.
AjK 0:0a841b89d614 30
AjK 0:0a841b89d614 31 Frustrations: I originally implemented an "intelligent" start-up routine
AjK 0:0a841b89d614 32 that sent echo requests to check the Nexstar was there, then requested
AjK 0:0a841b89d614 33 isAligned and, once aligned, would finally send the Tracking Off command
AjK 0:0a841b89d614 34 and enter operational state. However, that's all out the window.
AjK 0:0a841b89d614 35
AjK 0:0a841b89d614 36 Basically, I have found that if you send anything down the serial cable
AjK 0:0a841b89d614 37 while the Nexstar is powering up it goes dumb and won't responsd to
AjK 0:0a841b89d614 38 anything you send it. How useless, someone needs to educate their
AjK 0:0a841b89d614 39 software engineers to designing robust serial protocols that can
AjK 0:0a841b89d614 40 handle battery/power failure. Really very silly because I now know
AjK 0:0a841b89d614 41 that my software MUST assume the end user has powered on their Nexstar
AjK 0:0a841b89d614 42 before I start sending serial commands! Rubbish design, I like smart
AjK 0:0a841b89d614 43 designs that don't rely on the end user having to do "special things",
AjK 0:0a841b89d614 44 they should just work!
AjK 0:0a841b89d614 45
AjK 0:0a841b89d614 46 Additionally, I have found that, based on documents from TheSky program
AjK 0:0a841b89d614 47 you cannot ask the Nexstar for it's pointing position faster than once
AjK 0:0a841b89d614 48 per second! WTF? Asking too fast can crash the Nexstar hand controller.
AjK 0:0a841b89d614 49 Doh! Since we really need the position at a higher frequency then at the
AjK 0:0a841b89d614 50 subsecond level, the pointing position is calculated from the last position
AjK 0:0a841b89d614 51 known +/- whatever variable speed rates have been sent since then.
AjK 0:0a841b89d614 52
AjK 0:0a841b89d614 53 For the purposes of trying to track a fast moving object (an artificial
AjK 0:0a841b89d614 54 satellite in this case) we end up having to do most of the work ourselves
AjK 0:0a841b89d614 55 and hope the Nexstar tracks it with a sub-standard pointing system.
AjK 0:0a841b89d614 56 Hopefully I'll get it right!
AjK 0:0a841b89d614 57
AjK 0:0a841b89d614 58 Means the serial protocol I develop here is more basic than I would have
AjK 0:0a841b89d614 59 prefered. For example, rather than sending periodic echo requests to
AjK 0:0a841b89d614 60 detect the Nexstar, I'll send just one. If no reply I'll have to prompt
AjK 0:0a841b89d614 61 the user to "Power on the Nexstar and press a key to continue". Doh.
AjK 0:0a841b89d614 62 */
AjK 0:0a841b89d614 63
AjK 0:0a841b89d614 64 #define NEXSTAR_C
AjK 0:0a841b89d614 65
AjK 0:0a841b89d614 66 #include "sowb.h"
AjK 0:0a841b89d614 67 #include "nexstar.h"
AjK 0:0a841b89d614 68 #include "utils.h"
AjK 0:0a841b89d614 69 #include "rit.h"
AjK 0:0a841b89d614 70 #include "user.h"
AjK 0:0a841b89d614 71 #include "osd.h"
AjK 0:0a841b89d614 72 #include "debug.h"
AjK 0:0a841b89d614 73 #include "gpio.h"
AjK 0:0a841b89d614 74 #include "main.h"
AjK 0:0a841b89d614 75
AjK 0:0a841b89d614 76 /* Module global variables. */
AjK 0:0a841b89d614 77 int nexstar_status;
AjK 0:0a841b89d614 78 int nexstar_command;
AjK 0:0a841b89d614 79 int nexstar_command_status;
AjK 0:0a841b89d614 80 char rx_buffer[NEXSTAR_BUFFER_SIZE];
AjK 0:0a841b89d614 81 int rx_buffer_in;
AjK 0:0a841b89d614 82
AjK 0:0a841b89d614 83 bool nexstar_aligned;
AjK 0:0a841b89d614 84
AjK 0:0a841b89d614 85 double last_elevation;
AjK 0:0a841b89d614 86 double last_azmith;
AjK 0:0a841b89d614 87 double virtual_elevation;
AjK 0:0a841b89d614 88 double virtual_azmith;
AjK 0:0a841b89d614 89
AjK 0:0a841b89d614 90 double elevation_rate;
AjK 0:0a841b89d614 91 double elevation_rate_coarse;
AjK 0:0a841b89d614 92 double elevation_rate_fine;
AjK 0:0a841b89d614 93 double elevation_rate_auto;
AjK 0:0a841b89d614 94
AjK 0:0a841b89d614 95 double azmith_rate;
AjK 0:0a841b89d614 96 double azmith_rate_coarse;
AjK 0:0a841b89d614 97 double azmith_rate_fine;
AjK 0:0a841b89d614 98 double azmith_rate_auto;
AjK 0:0a841b89d614 99
AjK 0:0a841b89d614 100 bool nexstar_goto_in_progress;
AjK 0:0a841b89d614 101 char nexstar_goto_elevation[5];
AjK 0:0a841b89d614 102 char nexstar_goto_azmith[5];
AjK 0:0a841b89d614 103
AjK 0:0a841b89d614 104 int virtual_update_counter;
AjK 0:0a841b89d614 105
AjK 0:0a841b89d614 106 /* Local function prototypes. */
AjK 0:0a841b89d614 107 static void Uart2_init(void);
AjK 0:0a841b89d614 108 static inline void Uart2_putc(char c);
AjK 0:0a841b89d614 109 static inline void Uart2_puts(char *s, int len);
AjK 0:0a841b89d614 110
AjK 0:0a841b89d614 111 /** nexstar_process
AjK 0:0a841b89d614 112 *
AjK 0:0a841b89d614 113 * Our system _process function.
AjK 0:0a841b89d614 114 */
AjK 0:0a841b89d614 115 void nexstar_process(void) {
AjK 0:0a841b89d614 116
AjK 0:0a841b89d614 117 if (nexstar_command_status != 0) {
AjK 0:0a841b89d614 118 switch (nexstar_command) {
AjK 0:0a841b89d614 119 case NEXSTAR_IS_ALIGNED:
AjK 0:0a841b89d614 120 nexstar_aligned = rx_buffer[0] == 1 ? true : false;
AjK 0:0a841b89d614 121 nexstar_command = 0;
AjK 0:0a841b89d614 122 nexstar_command_status = 0;
AjK 0:0a841b89d614 123 break;
AjK 0:0a841b89d614 124 case NEXSTAR_GET_AZMALT:
AjK 0:0a841b89d614 125 last_azmith = virtual_azmith = 360.0 * (((double)hex2bin(&rx_buffer[0], 4)) / 65536.0);
AjK 0:0a841b89d614 126 last_elevation = virtual_elevation = 360.0 * (((double)hex2bin(&rx_buffer[5], 4)) / 65536.0);
AjK 0:0a841b89d614 127 nexstar_command = 0;
AjK 0:0a841b89d614 128 nexstar_command_status = 0;
AjK 0:0a841b89d614 129 virtual_update_counter = 0;
AjK 0:0a841b89d614 130 if (nexstar_goto_in_progress) {
AjK 0:0a841b89d614 131 if (!memcmp(&rx_buffer[0], nexstar_goto_azmith, 4) && !memcmp(&rx_buffer[5], nexstar_goto_elevation, 4)) {
AjK 0:0a841b89d614 132 nexstar_goto_in_progress = false;
AjK 0:0a841b89d614 133 osd_clear_line(2);
AjK 0:0a841b89d614 134 osd_clear_line(3);
AjK 0:0a841b89d614 135 _nexstar_set_tracking_mode(0);
AjK 0:0a841b89d614 136 }
AjK 0:0a841b89d614 137 }
AjK 0:0a841b89d614 138 break;
AjK 0:0a841b89d614 139 case NEXSTAR_GET_RADEC:
AjK 0:0a841b89d614 140
AjK 0:0a841b89d614 141 break;
AjK 0:0a841b89d614 142 case NEXSTAR_SET_ELEVATION_RATE:
AjK 0:0a841b89d614 143 case NEXSTAR_SET_AZMITH_RATE:
AjK 0:0a841b89d614 144 nexstar_command = 0;
AjK 0:0a841b89d614 145 nexstar_command_status = 0;
AjK 0:0a841b89d614 146 break;
AjK 0:0a841b89d614 147 case NEXSTAR_GOTO:
AjK 0:0a841b89d614 148 nexstar_command = 0;
AjK 0:0a841b89d614 149 nexstar_command_status = 0;
AjK 0:0a841b89d614 150 break;
AjK 0:0a841b89d614 151 case NEXSTAR_GOTO_AZM_FAST:
AjK 0:0a841b89d614 152 nexstar_command = 0;
AjK 0:0a841b89d614 153 nexstar_command_status = 0;
AjK 0:0a841b89d614 154 break;
AjK 0:0a841b89d614 155 case NEXSTAR_SET_APPROACH:
AjK 0:0a841b89d614 156 nexstar_command = 0;
AjK 0:0a841b89d614 157 nexstar_command_status = 0;
AjK 0:0a841b89d614 158 break;
AjK 0:0a841b89d614 159 case NEXSTAR_SET_TIME:
AjK 0:0a841b89d614 160 nexstar_command = 0;
AjK 0:0a841b89d614 161 nexstar_command_status = 0;
AjK 0:0a841b89d614 162 break;
AjK 0:0a841b89d614 163 case NEXSTAR_SET_LOCATION:
AjK 0:0a841b89d614 164 nexstar_command = 0;
AjK 0:0a841b89d614 165 nexstar_command_status = 0;
AjK 0:0a841b89d614 166 break;
AjK 0:0a841b89d614 167 case NEXSTAR_SYNC:
AjK 0:0a841b89d614 168 nexstar_command = 0;
AjK 0:0a841b89d614 169 nexstar_command_status = 0;
AjK 0:0a841b89d614 170 break;
AjK 0:0a841b89d614 171 }
AjK 0:0a841b89d614 172 }
AjK 0:0a841b89d614 173 }
AjK 0:0a841b89d614 174
AjK 0:0a841b89d614 175 /** nexstar_timeout_callback
AjK 0:0a841b89d614 176 *
AjK 0:0a841b89d614 177 * The generic timer callback handler.
AjK 0:0a841b89d614 178 *
AjK 0:0a841b89d614 179 * @param int index The timer index (handle).
AjK 0:0a841b89d614 180 */
AjK 0:0a841b89d614 181 void _nexstar_timeout_callback(int index) {
AjK 0:0a841b89d614 182 nexstar_status = NEXSTAR_STATE_NOT_CONN;
AjK 0:0a841b89d614 183 }
AjK 0:0a841b89d614 184
AjK 0:0a841b89d614 185 void _nexstar_one_second_timer(int index) {
AjK 0:0a841b89d614 186 _nexstar_get_altazm();
AjK 0:0a841b89d614 187 //_nexstar_get_radec();
AjK 0:0a841b89d614 188 rit_timer_set_counter(RIT_ONESEC_NEXSTAR, 200);
AjK 0:0a841b89d614 189 }
AjK 0:0a841b89d614 190
AjK 0:0a841b89d614 191 double nexstar_get_rate_azm(void) {
AjK 0:0a841b89d614 192 if (nexstar_goto_in_progress) return 0.0;
AjK 0:0a841b89d614 193 return azmith_rate_coarse + azmith_rate_fine + azmith_rate_auto;
AjK 0:0a841b89d614 194 }
AjK 0:0a841b89d614 195
AjK 0:0a841b89d614 196 double nexstar_get_rate_alt(void) {
AjK 0:0a841b89d614 197 if (nexstar_goto_in_progress) return 0.0;
AjK 0:0a841b89d614 198 return elevation_rate_coarse + elevation_rate_fine + elevation_rate_auto;
AjK 0:0a841b89d614 199 }
AjK 0:0a841b89d614 200
AjK 0:0a841b89d614 201 void _nexstar_100th_timer(int index) {
AjK 0:0a841b89d614 202 rit_timer_set_counter(RIT_100TH_NEXSTAR, 100);
AjK 0:0a841b89d614 203 }
AjK 0:0a841b89d614 204
AjK 0:0a841b89d614 205 /** nexstar_init
AjK 0:0a841b89d614 206 *
AjK 0:0a841b89d614 207 * Used to initialise the system.
AjK 0:0a841b89d614 208 */
AjK 0:0a841b89d614 209 void nexstar_init(void) {
AjK 0:0a841b89d614 210
AjK 0:0a841b89d614 211 DEBUG_INIT_START;
AjK 0:0a841b89d614 212
AjK 0:0a841b89d614 213 rit_timer_set_counter(RIT_TIMER_NEXSTAR, 0);
AjK 0:0a841b89d614 214 rit_timer_set_counter(RIT_ONESEC_NEXSTAR, 250);
AjK 0:0a841b89d614 215 rit_timer_set_counter(RIT_100TH_NEXSTAR, 100);
AjK 0:0a841b89d614 216 nexstar_status = NEXSTAR_STATE_IDLE;
AjK 0:0a841b89d614 217 nexstar_command = 0;
AjK 0:0a841b89d614 218 nexstar_command_status = 0;
AjK 0:0a841b89d614 219 last_elevation = 0.0;
AjK 0:0a841b89d614 220 last_azmith = 0.0;
AjK 0:0a841b89d614 221 virtual_elevation = 0.0;
AjK 0:0a841b89d614 222 virtual_azmith = 0.0;
AjK 0:0a841b89d614 223
AjK 0:0a841b89d614 224 elevation_rate = elevation_rate_coarse = elevation_rate_fine = elevation_rate_auto = 0.0;
AjK 0:0a841b89d614 225 azmith_rate = azmith_rate_coarse = azmith_rate_fine = azmith_rate_auto = 0.0;
AjK 0:0a841b89d614 226
AjK 0:0a841b89d614 227 nexstar_goto_in_progress = false;
AjK 0:0a841b89d614 228
AjK 0:0a841b89d614 229 nexstar_aligned = false;
AjK 0:0a841b89d614 230
AjK 0:0a841b89d614 231 rx_buffer_in = 0;
AjK 0:0a841b89d614 232 virtual_update_counter = 0;
AjK 0:0a841b89d614 233
AjK 0:0a841b89d614 234 DEBUG_INIT_END;
AjK 0:0a841b89d614 235
AjK 0:0a841b89d614 236 Uart2_init();
AjK 0:0a841b89d614 237 }
AjK 0:0a841b89d614 238
AjK 0:0a841b89d614 239 /* External API functions. */
AjK 0:0a841b89d614 240 void nexstar_get_elazm(double *el, double *azm) {
AjK 0:0a841b89d614 241 *(el) = last_elevation;
AjK 0:0a841b89d614 242 *(azm) = last_azmith;
AjK 0:0a841b89d614 243 }
AjK 0:0a841b89d614 244
AjK 0:0a841b89d614 245 /* Internal API functions. */
AjK 0:0a841b89d614 246 int _nexstar_set_tracking_mode(int mode) {
AjK 0:0a841b89d614 247 if (nexstar_status == NEXSTAR_STATE_IDLE) {
AjK 0:0a841b89d614 248 nexstar_status = NEXSTAR_STATE_BUSY;
AjK 0:0a841b89d614 249 rx_buffer_in = 0;
AjK 0:0a841b89d614 250 nexstar_command_status = 0;
AjK 0:0a841b89d614 251 nexstar_command = NEXSTAR_SET_TRACKING;
AjK 0:0a841b89d614 252 LPC_UART2->FCR = UART2_SET_FCR_CLEAR;
AjK 0:0a841b89d614 253 Uart2_putc('T');
AjK 0:0a841b89d614 254 Uart2_putc((char)mode);
AjK 0:0a841b89d614 255 rit_timer_set_counter(RIT_TIMER_NEXSTAR, NEXSTAR_SERIAL_TIMEOUT);
AjK 0:0a841b89d614 256 return 1;
AjK 0:0a841b89d614 257 }
AjK 0:0a841b89d614 258 return 0;
AjK 0:0a841b89d614 259 }
AjK 0:0a841b89d614 260
AjK 0:0a841b89d614 261 int _nexstar_get_altazm(void) {
AjK 0:0a841b89d614 262 if (nexstar_status == NEXSTAR_STATE_IDLE) {
AjK 0:0a841b89d614 263 nexstar_status = NEXSTAR_STATE_BUSY;
AjK 0:0a841b89d614 264 rx_buffer_in = 0;
AjK 0:0a841b89d614 265 nexstar_command_status = 0;
AjK 0:0a841b89d614 266 nexstar_command = NEXSTAR_GET_AZMALT;
AjK 0:0a841b89d614 267 LPC_UART2->FCR = UART2_SET_FCR_CLEAR;
AjK 0:0a841b89d614 268 Uart2_putc('Z');
AjK 0:0a841b89d614 269 rit_timer_set_counter(RIT_TIMER_NEXSTAR, NEXSTAR_SERIAL_TIMEOUT);
AjK 0:0a841b89d614 270 return 1;
AjK 0:0a841b89d614 271 }
AjK 0:0a841b89d614 272 return 0;
AjK 0:0a841b89d614 273 }
AjK 0:0a841b89d614 274
AjK 0:0a841b89d614 275 int _nexstar_get_radec(void) {
AjK 0:0a841b89d614 276 if (nexstar_status == NEXSTAR_STATE_IDLE) {
AjK 0:0a841b89d614 277 nexstar_status = NEXSTAR_STATE_BUSY;
AjK 0:0a841b89d614 278 rx_buffer_in = 0;
AjK 0:0a841b89d614 279 nexstar_command_status = 0;
AjK 0:0a841b89d614 280 nexstar_command = NEXSTAR_GET_RADEC;
AjK 0:0a841b89d614 281 LPC_UART2->FCR = UART2_SET_FCR_CLEAR;
AjK 0:0a841b89d614 282 Uart2_putc('E');
AjK 0:0a841b89d614 283 rit_timer_set_counter(RIT_TIMER_NEXSTAR, NEXSTAR_SERIAL_TIMEOUT);
AjK 0:0a841b89d614 284 return 1;
AjK 0:0a841b89d614 285 }
AjK 0:0a841b89d614 286 return 0;
AjK 0:0a841b89d614 287 }
AjK 0:0a841b89d614 288
AjK 0:0a841b89d614 289 void _nexstar_set_elevation_rate_coarse(double rate) {
AjK 0:0a841b89d614 290 elevation_rate_coarse = rate;
AjK 0:0a841b89d614 291 _nexstar_set_elevation_rate();
AjK 0:0a841b89d614 292 }
AjK 0:0a841b89d614 293
AjK 0:0a841b89d614 294 void _nexstar_set_elevation_rate_fine(double rate) {
AjK 0:0a841b89d614 295 elevation_rate_fine = rate;
AjK 0:0a841b89d614 296 _nexstar_set_elevation_rate();
AjK 0:0a841b89d614 297 }
AjK 0:0a841b89d614 298
AjK 0:0a841b89d614 299 void _nexstar_set_elevation_rate_auto(double rate) {
AjK 0:0a841b89d614 300 elevation_rate_auto = rate;
AjK 0:0a841b89d614 301 _nexstar_set_elevation_rate();
AjK 0:0a841b89d614 302 }
AjK 0:0a841b89d614 303
AjK 0:0a841b89d614 304 int _nexstar_set_elevation_rate(void) {
AjK 0:0a841b89d614 305 char dir, high, low, cmd[32];
AjK 0:0a841b89d614 306 double rate;
AjK 0:0a841b89d614 307
AjK 0:0a841b89d614 308 rate = elevation_rate_coarse + elevation_rate_fine + elevation_rate_auto;
AjK 0:0a841b89d614 309
AjK 0:0a841b89d614 310 if (elevation_rate == rate) return 0;
AjK 0:0a841b89d614 311
AjK 0:0a841b89d614 312 if (rate != 0.0) {
AjK 0:0a841b89d614 313 if (nexstar_goto_in_progress || nexstar_status != NEXSTAR_STATE_IDLE) return 0;
AjK 0:0a841b89d614 314 }
AjK 0:0a841b89d614 315
AjK 0:0a841b89d614 316 while (nexstar_status != NEXSTAR_STATE_IDLE) {
AjK 0:0a841b89d614 317 if (nexstar_status == NEXSTAR_STATE_NOT_CONN) return 0;
AjK 0:0a841b89d614 318 user_wait_ms(1);
AjK 0:0a841b89d614 319 };
AjK 0:0a841b89d614 320
AjK 0:0a841b89d614 321 //if (rate >= 0.0) osd_string_xyl(0, 14, cmd, sprintf(cmd, " ALT >> %c%.1f", '+', rate));
AjK 0:0a841b89d614 322 //else osd_string_xyl(0, 14, cmd, sprintf(cmd, " ALT >> %+.1f", rate));
AjK 0:0a841b89d614 323 nexstar_status = NEXSTAR_STATE_BUSY;
AjK 0:0a841b89d614 324 rx_buffer_in = 0;
AjK 0:0a841b89d614 325 nexstar_command_status = 0;
AjK 0:0a841b89d614 326 nexstar_command = NEXSTAR_SET_ELEVATION_RATE;
AjK 0:0a841b89d614 327 LPC_UART2->FCR = UART2_SET_FCR_CLEAR;
AjK 0:0a841b89d614 328 dir = 6;
AjK 0:0a841b89d614 329 if (rate < 0.0) {
AjK 0:0a841b89d614 330 dir = 7;
AjK 0:0a841b89d614 331 rate *= -1;
AjK 0:0a841b89d614 332 }
AjK 0:0a841b89d614 333 high = ((int)(3600.0 * rate * 4.0) / 256) & 0xFF;
AjK 0:0a841b89d614 334 low = ((int)(3600.0 * rate * 4.0) % 256) & 0xFF;
AjK 0:0a841b89d614 335 Uart2_puts(cmd, sprintf(cmd, "P%c%c%c%c%c%c%c", 3, 17, dir, high, low, 0, 0));
AjK 0:0a841b89d614 336 rit_timer_set_counter(RIT_TIMER_NEXSTAR, NEXSTAR_SERIAL_TIMEOUT);
AjK 0:0a841b89d614 337 elevation_rate = rate;
AjK 0:0a841b89d614 338 return 1;
AjK 0:0a841b89d614 339 }
AjK 0:0a841b89d614 340
AjK 0:0a841b89d614 341 void _nexstar_set_azmith_rate_coarse(double rate) {
AjK 0:0a841b89d614 342 azmith_rate_coarse = rate;
AjK 0:0a841b89d614 343 _nexstar_set_azmith_rate();
AjK 0:0a841b89d614 344 }
AjK 0:0a841b89d614 345
AjK 0:0a841b89d614 346 void _nexstar_set_azmith_rate_fine(double rate) {
AjK 0:0a841b89d614 347 azmith_rate_fine = rate;
AjK 0:0a841b89d614 348 _nexstar_set_azmith_rate();
AjK 0:0a841b89d614 349 }
AjK 0:0a841b89d614 350
AjK 0:0a841b89d614 351 void _nexstar_set_azmith_rate_auto(double rate) {
AjK 0:0a841b89d614 352 azmith_rate_auto = rate;
AjK 0:0a841b89d614 353 _nexstar_set_azmith_rate();
AjK 0:0a841b89d614 354 }
AjK 0:0a841b89d614 355
AjK 0:0a841b89d614 356 int _nexstar_set_azmith_rate(void) {
AjK 0:0a841b89d614 357 char dir, high, low, cmd[32];
AjK 0:0a841b89d614 358 double rate;
AjK 0:0a841b89d614 359
AjK 0:0a841b89d614 360 rate = azmith_rate_coarse + azmith_rate_fine + azmith_rate_auto;
AjK 0:0a841b89d614 361
AjK 0:0a841b89d614 362 if (azmith_rate == rate) return 0;
AjK 0:0a841b89d614 363
AjK 0:0a841b89d614 364 if (rate != 0.0) {
AjK 0:0a841b89d614 365 if (nexstar_goto_in_progress || nexstar_status != NEXSTAR_STATE_IDLE) return 0;
AjK 0:0a841b89d614 366 }
AjK 0:0a841b89d614 367
AjK 0:0a841b89d614 368 while (nexstar_status != NEXSTAR_STATE_IDLE) {
AjK 0:0a841b89d614 369 if (nexstar_status == NEXSTAR_STATE_NOT_CONN) return 0;
AjK 0:0a841b89d614 370 user_wait_ms(1);
AjK 0:0a841b89d614 371 };
AjK 0:0a841b89d614 372
AjK 0:0a841b89d614 373 //if (rate >= 0.0) osd_string_xyl(14, 14, cmd, sprintf(cmd, " AZM >> %c%.1f", '+', rate));
AjK 0:0a841b89d614 374 //else osd_string_xyl(14, 14, cmd, sprintf(cmd, " AZM >> %+.1f", rate));
AjK 0:0a841b89d614 375 nexstar_status = NEXSTAR_STATE_BUSY;
AjK 0:0a841b89d614 376 nexstar_status = NEXSTAR_STATE_BUSY;
AjK 0:0a841b89d614 377 rx_buffer_in = 0;
AjK 0:0a841b89d614 378 nexstar_command_status = 0;
AjK 0:0a841b89d614 379 nexstar_command = NEXSTAR_SET_AZMITH_RATE;
AjK 0:0a841b89d614 380 LPC_UART2->FCR = UART2_SET_FCR_CLEAR;
AjK 0:0a841b89d614 381 dir = 6;
AjK 0:0a841b89d614 382 if (rate < 0.0) {
AjK 0:0a841b89d614 383 dir = 7;
AjK 0:0a841b89d614 384 rate *= -1;
AjK 0:0a841b89d614 385 }
AjK 0:0a841b89d614 386 high = ((int)(3600.0 * rate * 4.0) / 256) & 0xFF;
AjK 0:0a841b89d614 387 low = ((int)(3600.0 * rate * 4.0) % 256) & 0xFF;
AjK 0:0a841b89d614 388 Uart2_puts(cmd, sprintf(cmd, "P%c%c%c%c%c%c%c", 3, 16, dir, high, low, 0, 0));
AjK 0:0a841b89d614 389 rit_timer_set_counter(RIT_TIMER_NEXSTAR, NEXSTAR_SERIAL_TIMEOUT);
AjK 0:0a841b89d614 390 azmith_rate = rate;
AjK 0:0a841b89d614 391 return 1;
AjK 0:0a841b89d614 392 }
AjK 0:0a841b89d614 393
AjK 0:0a841b89d614 394 int _nexstar_goto(uint32_t elevation, uint32_t azmith) {
AjK 0:0a841b89d614 395 char cmd[32], buf1[6], buf2[6];
AjK 0:0a841b89d614 396 double azm_target, azm_current;
AjK 0:0a841b89d614 397
AjK 0:0a841b89d614 398 if (nexstar_goto_in_progress) return 0;
AjK 0:0a841b89d614 399
AjK 0:0a841b89d614 400 printDouble_3_2(buf1, 360.0 * ((double)elevation / 65536));
AjK 0:0a841b89d614 401 osd_stringl(2, cmd, sprintf(cmd, " GOTO > %s < ALT", buf1));
AjK 0:0a841b89d614 402 printDouble_3_2(buf2, 360.0 * ((double)azmith / 65536));
AjK 0:0a841b89d614 403 osd_stringl(3, cmd, sprintf(cmd, " > %s < AZM", buf2));
AjK 0:0a841b89d614 404 osd_clear_line(14);
AjK 0:0a841b89d614 405
AjK 0:0a841b89d614 406 /* Adjust the GOTO approach based on where we are pointing now
AjK 0:0a841b89d614 407 comapred to where we want to go. */
AjK 0:0a841b89d614 408 azm_target = 360.0 * ((double)((double)azmith / 65536.0));
AjK 0:0a841b89d614 409 azm_current = last_azmith - azm_target;
AjK 0:0a841b89d614 410
AjK 0:0a841b89d614 411 if (azm_current > 180.) _nexstar_set_azm_approach(1);
AjK 0:0a841b89d614 412 else _nexstar_set_azm_approach(-1);
AjK 0:0a841b89d614 413
AjK 0:0a841b89d614 414 while(nexstar_status != NEXSTAR_STATE_IDLE) {
AjK 0:0a841b89d614 415 if(nexstar_status == NEXSTAR_STATE_NOT_CONN) return 0;
AjK 0:0a841b89d614 416 user_wait_ms(1);
AjK 0:0a841b89d614 417 };
AjK 0:0a841b89d614 418
AjK 0:0a841b89d614 419 nexstar_goto_in_progress = true;
AjK 0:0a841b89d614 420 nexstar_status = NEXSTAR_STATE_BUSY;
AjK 0:0a841b89d614 421 rx_buffer_in = 0;
AjK 0:0a841b89d614 422 nexstar_command_status = 0;
AjK 0:0a841b89d614 423 nexstar_command = NEXSTAR_GOTO;
AjK 0:0a841b89d614 424 LPC_UART2->FCR = UART2_SET_FCR_CLEAR;
AjK 0:0a841b89d614 425 sprintf(nexstar_goto_azmith, "%04X", azmith);
AjK 0:0a841b89d614 426 sprintf(nexstar_goto_elevation, "%04X", elevation);
AjK 0:0a841b89d614 427 Uart2_puts(cmd, sprintf(cmd, "B%s,%s", nexstar_goto_azmith, nexstar_goto_elevation));
AjK 0:0a841b89d614 428 rit_timer_set_counter(RIT_TIMER_NEXSTAR, 60000);
AjK 0:0a841b89d614 429 return 1;
AjK 0:0a841b89d614 430 }
AjK 0:0a841b89d614 431
AjK 0:0a841b89d614 432 int _nexstar_goto_azm_fast(uint32_t azmith) {
AjK 0:0a841b89d614 433 char cmd[16];
AjK 0:0a841b89d614 434
AjK 0:0a841b89d614 435 while(nexstar_status != NEXSTAR_STATE_IDLE) {
AjK 0:0a841b89d614 436 if(nexstar_status == NEXSTAR_STATE_NOT_CONN) return 0;
AjK 0:0a841b89d614 437 user_wait_ms(1);
AjK 0:0a841b89d614 438 };
AjK 0:0a841b89d614 439
AjK 0:0a841b89d614 440 nexstar_status = NEXSTAR_STATE_BUSY;
AjK 0:0a841b89d614 441 rx_buffer_in = 0;
AjK 0:0a841b89d614 442 nexstar_command_status = 0;
AjK 0:0a841b89d614 443 nexstar_command = NEXSTAR_GOTO_AZM_FAST;
AjK 0:0a841b89d614 444 LPC_UART2->FCR = UART2_SET_FCR_CLEAR;
AjK 0:0a841b89d614 445 Uart2_puts(cmd, sprintf(cmd, "P%c%c%c%c%c%c%c", 3, 16, 2, (azmith >> 8) & 0xFF, azmith & 0xFF, 0, 0));
AjK 0:0a841b89d614 446
AjK 0:0a841b89d614 447 rit_timer_set_counter(RIT_TIMER_NEXSTAR, 60000);
AjK 0:0a841b89d614 448 return 1;
AjK 0:0a841b89d614 449 }
AjK 0:0a841b89d614 450
AjK 0:0a841b89d614 451 void _nexstar_set_azm_approach(int approach) {
AjK 0:0a841b89d614 452 char cmd[16];
AjK 0:0a841b89d614 453
AjK 0:0a841b89d614 454 while(nexstar_status != NEXSTAR_STATE_IDLE) {
AjK 0:0a841b89d614 455 if(nexstar_status == NEXSTAR_STATE_NOT_CONN) return;
AjK 0:0a841b89d614 456 user_wait_ms(1);
AjK 0:0a841b89d614 457 };
AjK 0:0a841b89d614 458
AjK 0:0a841b89d614 459 nexstar_command = NEXSTAR_SET_APPROACH;
AjK 0:0a841b89d614 460 nexstar_command_status = 0;
AjK 0:0a841b89d614 461 nexstar_status = NEXSTAR_STATE_BUSY;
AjK 0:0a841b89d614 462 rx_buffer_in = 0;
AjK 0:0a841b89d614 463 LPC_UART2->FCR = UART2_SET_FCR_CLEAR;
AjK 0:0a841b89d614 464 Uart2_puts(cmd, sprintf(cmd, "P%c%c%c%c%c%c%c", 3, 16, 0xFD, approach < 0 ? 1 : 0, 0, 0, 0));
AjK 0:0a841b89d614 465 rit_timer_set_counter(RIT_TIMER_NEXSTAR, NEXSTAR_SERIAL_TIMEOUT);
AjK 0:0a841b89d614 466 }
AjK 0:0a841b89d614 467
AjK 0:0a841b89d614 468 bool _nexstar_is_aligned(void) {
AjK 0:0a841b89d614 469
AjK 0:0a841b89d614 470 while(nexstar_status != NEXSTAR_STATE_IDLE) {
AjK 0:0a841b89d614 471 if(nexstar_status == NEXSTAR_STATE_NOT_CONN) return false;
AjK 0:0a841b89d614 472 user_wait_ms(1);
AjK 0:0a841b89d614 473 };
AjK 0:0a841b89d614 474
AjK 0:0a841b89d614 475 nexstar_command = NEXSTAR_IS_ALIGNED;
AjK 0:0a841b89d614 476 nexstar_command_status = 0;
AjK 0:0a841b89d614 477 nexstar_status = NEXSTAR_STATE_BUSY;
AjK 0:0a841b89d614 478 rx_buffer_in = 0;
AjK 0:0a841b89d614 479 LPC_UART2->FCR = UART2_SET_FCR_CLEAR;
AjK 0:0a841b89d614 480 Uart2_putc('J');
AjK 0:0a841b89d614 481 rit_timer_set_counter(RIT_TIMER_NEXSTAR, NEXSTAR_SERIAL_TIMEOUT);
AjK 0:0a841b89d614 482
AjK 0:0a841b89d614 483 /* This command blocks while we wait for an answer. */
AjK 0:0a841b89d614 484 while(nexstar_status != NEXSTAR_STATE_IDLE) {
AjK 0:0a841b89d614 485 user_wait_ms(10);
AjK 0:0a841b89d614 486 };
AjK 0:0a841b89d614 487
AjK 0:0a841b89d614 488 return nexstar_aligned;
AjK 0:0a841b89d614 489 }
AjK 0:0a841b89d614 490
AjK 0:0a841b89d614 491 void _nexstar_sync(RaDec *radec) {
AjK 0:0a841b89d614 492 char cmd[32];
AjK 0:0a841b89d614 493 uint16_t ra, dec;
AjK 0:0a841b89d614 494
AjK 0:0a841b89d614 495 while(nexstar_status != NEXSTAR_STATE_IDLE) {
AjK 0:0a841b89d614 496 user_wait_ms(1);
AjK 0:0a841b89d614 497 };
AjK 0:0a841b89d614 498
AjK 0:0a841b89d614 499 ra = (uint16_t)((radec->ra / 360.0) * 65536);
AjK 0:0a841b89d614 500 dec = (uint16_t)((radec->dec / 360.0) * 65536);
AjK 0:0a841b89d614 501
AjK 0:0a841b89d614 502 nexstar_command = NEXSTAR_SYNC;
AjK 0:0a841b89d614 503 nexstar_command_status = 0;
AjK 0:0a841b89d614 504 nexstar_status = NEXSTAR_STATE_BUSY;
AjK 0:0a841b89d614 505 rx_buffer_in = 0;
AjK 0:0a841b89d614 506 LPC_UART2->FCR = UART2_SET_FCR_CLEAR;
AjK 0:0a841b89d614 507 Uart2_puts(cmd, sprintf(cmd, "S%02X,%02X", ra, dec));
AjK 0:0a841b89d614 508 rit_timer_set_counter(RIT_TIMER_NEXSTAR, NEXSTAR_SERIAL_TIMEOUT);
AjK 0:0a841b89d614 509
AjK 0:0a841b89d614 510 }
AjK 0:0a841b89d614 511
AjK 0:0a841b89d614 512 void _nexstar_set_time(GPS_TIME *t) {
AjK 0:0a841b89d614 513 char cmd[32];
AjK 0:0a841b89d614 514 GPS_TIME rt;
AjK 0:0a841b89d614 515
AjK 0:0a841b89d614 516 while(nexstar_status != NEXSTAR_STATE_IDLE) {
AjK 0:0a841b89d614 517 user_wait_ms(1);
AjK 0:0a841b89d614 518 };
AjK 0:0a841b89d614 519
AjK 0:0a841b89d614 520 if (t == (GPS_TIME *)NULL) {
AjK 0:0a841b89d614 521 t = &rt;
AjK 0:0a841b89d614 522 gps_get_time(t);
AjK 0:0a841b89d614 523 }
AjK 0:0a841b89d614 524
AjK 0:0a841b89d614 525 nexstar_command = NEXSTAR_SET_TIME;
AjK 0:0a841b89d614 526 nexstar_command_status = 0;
AjK 0:0a841b89d614 527 nexstar_status = NEXSTAR_STATE_BUSY;
AjK 0:0a841b89d614 528 rx_buffer_in = 0;
AjK 0:0a841b89d614 529 LPC_UART2->FCR = UART2_SET_FCR_CLEAR;
AjK 0:0a841b89d614 530 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));
AjK 0:0a841b89d614 531 rit_timer_set_counter(RIT_TIMER_NEXSTAR, NEXSTAR_SERIAL_TIMEOUT);
AjK 0:0a841b89d614 532 }
AjK 0:0a841b89d614 533
AjK 0:0a841b89d614 534 void _nexstar_set_location(GPS_LOCATION_AVERAGE *l) {
AjK 0:0a841b89d614 535 char cmd[32];
AjK 0:0a841b89d614 536 GPS_LOCATION_AVERAGE rl;
AjK 0:0a841b89d614 537 double d, t;
AjK 0:0a841b89d614 538 char lat_degrees, lat_minutes, lat_seconds, lon_degrees, lon_minutes, lon_seconds;
AjK 0:0a841b89d614 539
AjK 0:0a841b89d614 540 while(nexstar_status != NEXSTAR_STATE_IDLE) {
AjK 0:0a841b89d614 541 user_wait_ms(1);
AjK 0:0a841b89d614 542 };
AjK 0:0a841b89d614 543
AjK 0:0a841b89d614 544 if (l == (GPS_LOCATION_AVERAGE *)NULL) {
AjK 0:0a841b89d614 545 l = &rl;
AjK 0:0a841b89d614 546 gps_get_location_average(l);
AjK 0:0a841b89d614 547 }
AjK 0:0a841b89d614 548
AjK 0:0a841b89d614 549 d = l->latitude;
AjK 0:0a841b89d614 550 lat_degrees = (char)d; t = (d - (double)lat_degrees) * 60.0;
AjK 0:0a841b89d614 551 lat_minutes = (char)t;
AjK 0:0a841b89d614 552 lat_seconds = (t - (double)lat_minutes) * 60.0;
AjK 0:0a841b89d614 553 d = l->longitude;
AjK 0:0a841b89d614 554 lon_degrees = (int)d; t = (d - (double)lon_degrees) * 60.0;
AjK 0:0a841b89d614 555 lon_minutes = (int)t;
AjK 0:0a841b89d614 556 lon_seconds = (t - (double)lon_minutes) * 60.0;
AjK 0:0a841b89d614 557
AjK 0:0a841b89d614 558 nexstar_command = NEXSTAR_SET_LOCATION;
AjK 0:0a841b89d614 559 nexstar_command_status = 0;
AjK 0:0a841b89d614 560 nexstar_status = NEXSTAR_STATE_BUSY;
AjK 0:0a841b89d614 561 rx_buffer_in = 0;
AjK 0:0a841b89d614 562 LPC_UART2->FCR = UART2_SET_FCR_CLEAR;
AjK 0:0a841b89d614 563 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));
AjK 0:0a841b89d614 564 rit_timer_set_counter(RIT_TIMER_NEXSTAR, NEXSTAR_SERIAL_TIMEOUT);
AjK 0:0a841b89d614 565 }
AjK 0:0a841b89d614 566
AjK 0:0a841b89d614 567 /** UART2_IRQHandler(void)
AjK 0:0a841b89d614 568 *
AjK 0:0a841b89d614 569 * The interrupt service routine for the UART2.
AjK 0:0a841b89d614 570 */
AjK 0:0a841b89d614 571 extern "C" void UART2_IRQHandler(void) __irq {
AjK 0:0a841b89d614 572 volatile uint32_t iir;
AjK 0:0a841b89d614 573 char c;
AjK 0:0a841b89d614 574
AjK 0:0a841b89d614 575 /* Get the interrupt identification register which also resets IIR. */
AjK 0:0a841b89d614 576 iir = LPC_UART2->IIR;
AjK 0:0a841b89d614 577
AjK 0:0a841b89d614 578 if (iir & 0x1) return;
AjK 0:0a841b89d614 579
AjK 0:0a841b89d614 580 iir = (iir >> 1) & 0x3;
AjK 0:0a841b89d614 581
AjK 0:0a841b89d614 582 /* Handle the incoming character. */
AjK 0:0a841b89d614 583 if (iir == 2) {
AjK 0:0a841b89d614 584 c = LPC_UART2->RBR;
AjK 0:0a841b89d614 585 //Uart0_putc(c);
AjK 0:0a841b89d614 586 rit_timer_set_counter(RIT_TIMER_NEXSTAR, NEXSTAR_SERIAL_TIMEOUT);
AjK 0:0a841b89d614 587 rx_buffer[rx_buffer_in] = c;
AjK 0:0a841b89d614 588 rx_buffer_in++;
AjK 0:0a841b89d614 589 if (rx_buffer_in >= NEXSTAR_BUFFER_SIZE) {
AjK 0:0a841b89d614 590 rx_buffer_in = 0;
AjK 0:0a841b89d614 591 }
AjK 0:0a841b89d614 592 if (c == '#') {
AjK 0:0a841b89d614 593 rit_timer_set_counter(RIT_TIMER_NEXSTAR, 0);
AjK 0:0a841b89d614 594 nexstar_command_status = 1;
AjK 0:0a841b89d614 595 nexstar_status = NEXSTAR_STATE_IDLE;
AjK 0:0a841b89d614 596 }
AjK 0:0a841b89d614 597 }
AjK 0:0a841b89d614 598 }
AjK 0:0a841b89d614 599
AjK 0:0a841b89d614 600 /** Uart2_init
AjK 0:0a841b89d614 601 *
AjK 0:0a841b89d614 602 * Initialise UART2 to our requirements for Nexstar.
AjK 0:0a841b89d614 603 */
AjK 0:0a841b89d614 604 static void Uart2_init (void) {
AjK 0:0a841b89d614 605 volatile char c __attribute__((unused));
AjK 0:0a841b89d614 606
AjK 0:0a841b89d614 607 DEBUG_INIT_START;
AjK 0:0a841b89d614 608
AjK 0:0a841b89d614 609 LPC_SC->PCONP |= (1UL << 24);
AjK 0:0a841b89d614 610 LPC_SC->PCLKSEL1 &= ~(3UL << 16);
AjK 0:0a841b89d614 611 LPC_SC->PCLKSEL1 |= (1UL << 16);
AjK 0:0a841b89d614 612 LPC_PINCON->PINSEL0 |= ((1UL << 20) | (1UL << 22));
AjK 0:0a841b89d614 613 LPC_UART2->LCR = 0x80;
AjK 0:0a841b89d614 614 LPC_UART2->DLM = 0x2; // 115200 baud, for 9600 use 0x2;
AjK 0:0a841b89d614 615 LPC_UART2->DLL = 0x71; // 115200 baud, for 9600 use 0x71;
AjK 0:0a841b89d614 616 LPC_UART2->LCR = 0x3;
AjK 0:0a841b89d614 617 LPC_UART2->FCR = 0x1;
AjK 0:0a841b89d614 618
AjK 0:0a841b89d614 619 /* Ensure the FIFO is empty. */
AjK 0:0a841b89d614 620 while (LPC_UART2->LSR & 0x1) c = (char)LPC_UART2->RBR;
AjK 0:0a841b89d614 621
AjK 0:0a841b89d614 622 NVIC_SetVector(UART2_IRQn, (uint32_t)UART2_IRQHandler);
AjK 0:0a841b89d614 623 NVIC_EnableIRQ(UART2_IRQn);
AjK 0:0a841b89d614 624
AjK 0:0a841b89d614 625 /* Enable UART0 RX interrupt only. */
AjK 0:0a841b89d614 626 LPC_UART2->IER = 0x1;
AjK 0:0a841b89d614 627
AjK 0:0a841b89d614 628 DEBUG_INIT_END;
AjK 0:0a841b89d614 629 }
AjK 0:0a841b89d614 630
AjK 0:0a841b89d614 631 static inline void Uart2_putc(char c) {
AjK 0:0a841b89d614 632 //Uart0_putc(c);
AjK 0:0a841b89d614 633 LPC_UART2->THR = (uint32_t)(c & 0xFF);
AjK 0:0a841b89d614 634 }
AjK 0:0a841b89d614 635
AjK 0:0a841b89d614 636 static inline void Uart2_puts(char *s, int len) {
AjK 0:0a841b89d614 637 int i;
AjK 0:0a841b89d614 638 if (len > 0) for (i = 0; len; i++, len--) Uart2_putc(s[i]);
AjK 0:0a841b89d614 639 }
AjK 0:0a841b89d614 640