Blame | Last modification | View Log | Download
/** Copyright (C) 2004 Darren Hutchinson (dbh@gbdt.com.au)** This program is free software; you can redistribute it and/or modify* it under the terms of the GNU Library General Public License as published by* the Free Software Foundation; either version 2 of the License, or (at your* option) any later version.** This program is distributed in the hope that it will be useful, but* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public* License for more details.** You should have received a copy of the GNU Library General Public License* along with this program; see the file COPYING. If not, write to* the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,* MA 02111-1307, USA.** $Id: serial.c,v 1.10 2004/04/04 10:32:50 dbh Exp $*/#include <inttypes.h>#include <avr/io.h>#include "eq6.h"#include "serial.h"#include "combine.h"#include "stepper.h"#include "paddle.h"#include "sr.h"/* This file accepts serial data from a serial guider and performs the* requested guiding operation.** This interface is also is designed to support future mount management* operations via the same serial interface** The current protocol is:** [0-9] Add the number to the "accumulator"* - Denote accumulator as negative* # Clear the accumulator and flag* < Clear the flag* > Set the flag* U Copy flag state to the DEC UP key* D Copy flag state to the DEC DOWN key* L Copy flag state to the RA left key* R Copy flag state to the RA right key* C Release all keys** B Set DEC backlash to accum* M Set DEC backlash mode (+ = finish pos, 0 = none, - = finish neg)* b Set RA backlash to accum* m Set RA backlash mode (see DEC backlash)** G Set 2X paddle to guiding speed (0.3x) if flag set, 1X if clear** t Use halfStep for slow step if flag set, microStep if clear (TEST)** T Set the tracking rate as-per the accumulator* -1 = No tracking (Terrestial)* 0 = Sidereal* 1 = Solar / Planetary* 2 = Lunar** g Set transmission (gearbox) ratio** The '#' and accumulator support future value-based entries** A subset of LX200 commands are supported for compatibility* with various autoguiding programs.** :Me# :Mw# :Ms# :Mn# Start slewing East(right), West(left),* North (up), South (down)* :Qe# :Qw# :Qs# :Qn# :Q# Halt selected or all slews* :RG# :RC# :RM# :RS# Set guiding rate for LX200 motions* G = 0.3x* C = 1x* M = 8x* S = 16x** ACK Returns alignment mode (always 'P' polar)*/#include <avr/interrupt.h>#include <inttypes.h>#include "paddle.h"#include "eq6.h"#include "combine.h"/* serialInit() initializes the serial port used for the* serial guider input.** Passed:* Nothing** Returns:* Nothing.*/voidserialInit(void){// The serial guider is attached to USART1// Set serial rateUBRR1H = (CLK_RATE / GUIDE_BAUD / 16 - 1) >> 8;UBRR1L = (CLK_RATE / GUIDE_BAUD / 16 - 1) & 0xff;/* Setup registers* 8 bits, no parity, RX enable, TX enable. Only the Rx interrupts are* enabled at this point.*/UCSR1B = 0; // Disable all interruptsUCSR1C = _BV(URSEL1) | _BV(UCSZ11) | _BV(UCSZ10);UCSR1B = _BV(RXCIE1) | _BV(RXEN1) | _BV(TXEN1);}/* serialInt() is called whenever a character is received on USART1.* These characters are send by the serial guider** Passed:* Nothing** Returns:* Nothing** Notes:* Interrupts are disabled during processing*/SIGNAL(SIG_USART1_RECV){/* Variables for flags/accumulator */static uint8_t flag = 0;static uint16_t accum = 0;static uint8_t sign = 0;/* Variable holding current guiding rate */static int8_t guideRate = SPEED_0_33_X;/* Flags holding current requested slewing directions */static uint8_t upFlag;static uint8_t downFlag;static uint8_t leftFlag;static uint8_t rightFlag;/* LX200 command state */#define LX200_CMD_LEN 8static char lxCmd[LX200_CMD_LEN];static uint8_t lxPos;uint8_t ch;uint8_t dirChg;static uint8_t lxMode;/* Get the character from the port. This will dismiss the interrupt*/dirChg = 0;ch = UDR1;/* UDR1 = ch; /* Echo for debugging *//* This code processes commands when a LX200 command is not currently* being processed.*/if (lxMode == 0){switch(ch){case '0' ... '9':/* Add it to the accumulator */accum = (accum * 10) + ch - '0';break;case '#':/* Clear the accumulator */accum = 0;sign = 0;break;case '-':/* Set the sign of the accumulator to negative */sign = 1;break;case '<':/* Clear the flag */flag = 0;break;case '>':/* Set the flag */flag = 1;break;case 'U':/* Guide UP (DEC) */upFlag = flag;dirChg = 1;break;case 'D':/* Guide DOWN (DEC) */downFlag = flag;dirChg = 1;break;case 'R':/* Guide RIGHT (RA) */rightFlag = flag;dirChg = 1;break;case 'L':/* Guide LEFT (RA) */leftFlag = flag;dirChg = 1;break;case 'C':/* Clear all keys */upFlag = downFlag = leftFlag = rightFlag = 0;dirChg = 1;break;case 'b':/* Set RA backlash steps */raState.backlash = accum;doSave = 1;break;case 'B':/* Set DEC backlash steps */decState.backlash = accum;doSave = 1;break;case 'm':/* Set RA backlash mode */raState.finNeg = raState.finPos = 0;if (accum != 0){if (sign)raState.finNeg = 1;elseraState.finPos = 1;}doSave = 1;break;case 'M':/* Set DEC backlash mode */decState.finNeg = decState.finPos = 0;if (accum != 0){if (sign)decState.finNeg = 1;elsedecState.finPos = 1;}doSave = 1;break;case 'G':/* Set the speed for the 2x paddle button. This has* no effect on the rate used for serial commands*/paddleGuideRate = flag ? SPEED_0_33_X : SPEED_1_X;doSave = 1;break;case 'T':/* Set the tracking speed */setTrackRate(sign ? -accum : accum);doSave = 1;break;case 'g': /* Set transmission (gearbox) ratio */transRatio = accum;doSave = 1;break;case 't':/* *TEST* Allow half step table to be specified instead of* the microstep table*/doHalfStep = flag;break;case '\006': /* LX200: ACK */UDR1 = 'P';break;case ':': /* LX200: Start command *//* This indicates the start of a LX200 command */lxMode = 1;lxPos = 0;break;default:/* OK, now we're confused .... */UDR1 = '?';break;}}else{/* This section of code supports the LX200 commands. They* have a fundimentally different syntax to the existing* commands, so they are implemented in this code seperately* for clarity.*/if (ch != '#'){/* Add this to the command characters so far */lxCmd[lxPos++] = ch;if (lxPos == LX200_CMD_LEN){/* Too much data for any command */UDR1 = '?';lxMode = 0;}}else{/* We are going back to native mode after this */lxMode = 0;if (lxPos >= 1){/* We have a complete LX200 command (without the delimiters).* Do what it asks*/switch(lxCmd[0]){case 'M': // Start guiding in specified directionif (lxPos == 2){// We have the right number of chars */switch (lxCmd[1]){case 'n': upFlag = 1; break;case 's': downFlag = 1; break;case 'e': rightFlag = 1; break;case 'w': leftFlag = 1; break;default: UDR1 = '?'; break;}dirChg = 1;}break;case 'Q': // Stop guiding in specified directionif (lxPos == 1){// Stop slewingupFlag = downFlag = leftFlag = rightFlag = 0;dirChg = 1;}else if (lxPos == 2){// Stop slewing is specified directionswitch (lxCmd[1]){case 'n': upFlag = 0; break;case 's': downFlag = 0; break;case 'e': rightFlag = 0; break;case 'w': leftFlag = 0; break;default: UDR1 = '?'; break;}dirChg = 1;} elseUDR1 = '?';break;case 'R': // Set guiding speedif (lxPos == 2){switch (lxCmd[1]){case 'G': guideRate = SPEED_0_33_X; break;case 'C': guideRate = SPEED_1_X; break;case 'M': guideRate = SPEED_8_X; break;case 'S': guideRate = SPEED_16_X; break;default: UDR1 = '?'; break;}dirChg = 1;}break;default:UDR1 = '?';}}}}/* Update the serial guiding rate data if it has changed */if (dirChg){if (upFlag)rateInput.serialDecRate = guideRate;else if (downFlag)rateInput.serialDecRate = -guideRate;elserateInput.serialDecRate = SPEED_0_X;if (rightFlag)rateInput.serialRaRate = guideRate;else if (leftFlag)rateInput.serialRaRate = -guideRate;elserateInput.serialRaRate = SPEED_0_X;}updateMountSpeed();}