Subversion Repositories svnkaklik

Compare Revisions

No changes between revisions

Ignore whitespace Rev 507 → Rev 508

/programy/C/avr/LX200/COPYING
0,0 → 1,340
GNU GENERAL PUBLIC LICENSE
Version 2, June 1991
 
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
 
Preamble
 
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
License is intended to guarantee your freedom to share and change free
software--to make sure the software is free for all its users. This
General Public License applies to most of the Free Software
Foundation's software and to any other program whose authors commit to
using it. (Some other Free Software Foundation software is covered by
the GNU Library General Public License instead.) You can apply it to
your programs, too.
 
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
this service if you wish), that you receive source code or can get it
if you want it, that you can change the software or use pieces of it
in new free programs; and that you know you can do these things.
 
To protect your rights, we need to make restrictions that forbid
anyone to deny you these rights or to ask you to surrender the rights.
These restrictions translate to certain responsibilities for you if you
distribute copies of the software, or if you modify it.
 
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must give the recipients all the rights that
you have. You must make sure that they, too, receive or can get the
source code. And you must show them these terms so they know their
rights.
 
We protect your rights with two steps: (1) copyright the software, and
(2) offer you this license which gives you legal permission to copy,
distribute and/or modify the software.
 
Also, for each author's protection and ours, we want to make certain
that everyone understands that there is no warranty for this free
software. If the software is modified by someone else and passed on, we
want its recipients to know that what they have is not the original, so
that any problems introduced by others will not reflect on the original
authors' reputations.
 
Finally, any free program is threatened constantly by software
patents. We wish to avoid the danger that redistributors of a free
program will individually obtain patent licenses, in effect making the
program proprietary. To prevent this, we have made it clear that any
patent must be licensed for everyone's free use or not licensed at all.
 
The precise terms and conditions for copying, distribution and
modification follow.
GNU GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
 
0. This License applies to any program or other work which contains
a notice placed by the copyright holder saying it may be distributed
under the terms of this General Public License. The "Program", below,
refers to any such program or work, and a "work based on the Program"
means either the Program or any derivative work under copyright law:
that is to say, a work containing the Program or a portion of it,
either verbatim or with modifications and/or translated into another
language. (Hereinafter, translation is included without limitation in
the term "modification".) Each licensee is addressed as "you".
 
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running the Program is not restricted, and the output from the Program
is covered only if its contents constitute a work based on the
Program (independent of having been made by running the Program).
Whether that is true depends on what the Program does.
 
1. You may copy and distribute verbatim copies of the Program's
source code as you receive it, in any medium, provided that you
conspicuously and appropriately publish on each copy an appropriate
copyright notice and disclaimer of warranty; keep intact all the
notices that refer to this License and to the absence of any warranty;
and give any other recipients of the Program a copy of this License
along with the Program.
 
You may charge a fee for the physical act of transferring a copy, and
you may at your option offer warranty protection in exchange for a fee.
 
2. You may modify your copy or copies of the Program or any portion
of it, thus forming a work based on the Program, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
 
a) You must cause the modified files to carry prominent notices
stating that you changed the files and the date of any change.
 
b) You must cause any work that you distribute or publish, that in
whole or in part contains or is derived from the Program or any
part thereof, to be licensed as a whole at no charge to all third
parties under the terms of this License.
 
c) If the modified program normally reads commands interactively
when run, you must cause it, when started running for such
interactive use in the most ordinary way, to print or display an
announcement including an appropriate copyright notice and a
notice that there is no warranty (or else, saying that you provide
a warranty) and that users may redistribute the program under
these conditions, and telling the user how to view a copy of this
License. (Exception: if the Program itself is interactive but
does not normally print such an announcement, your work based on
the Program is not required to print an announcement.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Program,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Program, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote it.
 
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Program.
 
In addition, mere aggregation of another work not based on the Program
with the Program (or with a work based on the Program) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
 
3. You may copy and distribute the Program (or a work based on it,
under Section 2) in object code or executable form under the terms of
Sections 1 and 2 above provided that you also do one of the following:
 
a) Accompany it with the complete corresponding machine-readable
source code, which must be distributed under the terms of Sections
1 and 2 above on a medium customarily used for software interchange; or,
 
b) Accompany it with a written offer, valid for at least three
years, to give any third party, for a charge no more than your
cost of physically performing source distribution, a complete
machine-readable copy of the corresponding source code, to be
distributed under the terms of Sections 1 and 2 above on a medium
customarily used for software interchange; or,
 
c) Accompany it with the information you received as to the offer
to distribute corresponding source code. (This alternative is
allowed only for noncommercial distribution and only if you
received the program in object code or executable form with such
an offer, in accord with Subsection b above.)
 
The source code for a work means the preferred form of the work for
making modifications to it. For an executable work, complete source
code means all the source code for all modules it contains, plus any
associated interface definition files, plus the scripts used to
control compilation and installation of the executable. However, as a
special exception, the source code distributed need not include
anything that is normally distributed (in either source or binary
form) with the major components (compiler, kernel, and so on) of the
operating system on which the executable runs, unless that component
itself accompanies the executable.
 
If distribution of executable or object code is made by offering
access to copy from a designated place, then offering equivalent
access to copy the source code from the same place counts as
distribution of the source code, even though third parties are not
compelled to copy the source along with the object code.
4. You may not copy, modify, sublicense, or distribute the Program
except as expressly provided under this License. Any attempt
otherwise to copy, modify, sublicense or distribute the Program is
void, and will automatically terminate your rights under this License.
However, parties who have received copies, or rights, from you under
this License will not have their licenses terminated so long as such
parties remain in full compliance.
 
5. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Program or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Program (or any work based on the
Program), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Program or works based on it.
 
6. Each time you redistribute the Program (or any work based on the
Program), the recipient automatically receives a license from the
original licensor to copy, distribute or modify the Program subject to
these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties to
this License.
 
7. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Program at all. For example, if a patent
license would not permit royalty-free redistribution of the Program by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Program.
 
If any portion of this section is held invalid or unenforceable under
any particular circumstance, the balance of the section is intended to
apply and the section as a whole is intended to apply in other
circumstances.
 
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system, which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
 
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
8. If the distribution and/or use of the Program is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Program under this License
may add an explicit geographical distribution limitation excluding
those countries, so that distribution is permitted only in or among
countries not thus excluded. In such case, this License incorporates
the limitation as if written in the body of this License.
 
9. The Free Software Foundation may publish revised and/or new versions
of the General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
 
Each version is given a distinguishing version number. If the Program
specifies a version number of this License which applies to it and "any
later version", you have the option of following the terms and conditions
either of that version or of any later version published by the Free
Software Foundation. If the Program does not specify a version number of
this License, you may choose any version ever published by the Free Software
Foundation.
 
10. If you wish to incorporate parts of the Program into other free
programs whose distribution conditions are different, write to the author
to ask for permission. For software which is copyrighted by the Free
Software Foundation, write to the Free Software Foundation; we sometimes
make exceptions for this. Our decision will be guided by the two goals
of preserving the free status of all derivatives of our free software and
of promoting the sharing and reuse of software generally.
 
NO WARRANTY
 
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
REPAIR OR CORRECTION.
 
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGES.
 
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
 
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
 
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
convey the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
 
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) 19yy <name of author>
 
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU 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 General Public License for more details.
 
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 
 
Also add information on how to contact you by electronic and paper mail.
 
If the program is interactive, make it output a short notice like this
when it starts in an interactive mode:
 
Gnomovision version 69, Copyright (C) 19yy name of author
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
 
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, the commands you use may
be called something other than `show w' and `show c'; they could even be
mouse-clicks or menu items--whatever suits your program.
 
You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the program, if
necessary. Here is a sample; alter the names:
 
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
`Gnomovision' (which makes passes at compilers) written by James Hacker.
 
<signature of Ty Coon>, 1 April 1989
Ty Coon, President of Vice
 
This General Public License does not permit incorporating your program into
proprietary programs. If your program is a subroutine library, you may
consider it more useful to permit linking proprietary applications with the
library. If this is what you want to do, use the GNU Library General
Public License instead of this License.
/programy/C/avr/LX200/Makefile
0,0 → 1,115
PRG = eq6
OBJ = eq6.o paddle.o combine.o stepper.o driver.o serial.o \
pguide.o sr.o
MCU_TARGET = atmega162
 
OPTIMIZE = -O2
 
DEFS =
LIBS =
 
# You should not have to change anything below here.
 
CC = avr-gcc
 
# Override is only needed by avr-lib build system.
 
override CFLAGS = -g -Wall $(OPTIMIZE) -mmcu=$(MCU_TARGET) $(DEFS)
override LDFLAGS = -Wl,-Map,$(PRG).map
 
OBJCOPY = avr-objcopy
OBJDUMP = avr-objdump
 
all: $(PRG).cof lst text eeprom
 
$(PRG).elf: $(OBJ)
$(CC) $(CFLAGS) $(LDFLAGS) -o $@ $^ $(LIBS)
 
$(PRG).cof: $(PRG).elf
$(OBJCOPY) \
--debugging \
-O coff-ext-avr \
--change-section-address .data-0x800000 \
--change-section-address .bss-0x800000 \
--change-section-address .noinit-0x800000 \
--change-section-address .eeprom-0x810000 \
$(PRG).elf $(PRG).cof
 
 
release:
$(MAKE) clean
$(MAKE) DEFS=-DCLK_RATE=8000000
mv eq6.hex eq6_8MHz.sav
$(MAKE) clean
$(MAKE) DEFS=-DCLK_RATE=16000000
mv eq6.hex eq6_16MHz.sav
$(MAKE) clean
mv eq6_8MHz.sav eq6_8MHz.hex
mv eq6_16MHz.sav eq6_16MHz.hex
 
 
clean:
rm -rf *.o $(PRG).elf *.eps *.png *.pdf *.bak
rm -rf *.lst *.map $(EXTRA_CLEAN_FILES)
 
lst: $(PRG).lst
 
%.lst: %.elf
$(OBJDUMP) -h -S $< > $@
 
# Rules for building the .text rom images
 
text: hex bin srec
 
hex: $(PRG).hex
bin: $(PRG).bin
srec: $(PRG).srec
 
%.hex: %.elf
$(OBJCOPY) -j .text -j .data -O ihex $< $@
 
%.srec: %.elf
$(OBJCOPY) -j .text -j .data -O srec $< $@
 
%.bin: %.elf
$(OBJCOPY) -j .text -j .data -O binary $< $@
 
# Rules for building the .eeprom rom images
 
eeprom: ehex ebin esrec
 
ehex: $(PRG)_eeprom.hex
ebin: $(PRG)_eeprom.bin
esrec: $(PRG)_eeprom.srec
 
%_eeprom.hex: %.elf
$(OBJCOPY) -j .eeprom --change-section-lma .eeprom=0 -O ihex $< $@
 
%_eeprom.srec: %.elf
$(OBJCOPY) -j .eeprom --change-section-lma .eeprom=0 -O srec $< $@
 
%_eeprom.bin: %.elf
$(OBJCOPY) -j .eeprom --change-section-lma .eeprom=0 -O binary $< $@
 
# Every thing below here is used by avr-libc's build system and can be ignored
# by the casual user.
 
FIG2DEV = fig2dev
EXTRA_CLEAN_FILES = *.hex *.bin *.srec
 
dox: eps png pdf
 
eps: $(PRG).eps
png: $(PRG).png
pdf: $(PRG).pdf
 
%.eps: %.fig
$(FIG2DEV) -L eps $< $@
 
%.pdf: %.fig
$(FIG2DEV) -L pdf $< $@
 
%.png: %.fig
$(FIG2DEV) -L png $< $@
 
/programy/C/avr/LX200/combine.c
0,0 → 1,101
/*
* 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 software; see the file COPYING. If not, write to
* the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
* MA 02111-1307, USA.
*
* $Id: combine.c,v 1.5 2004/04/05 06:42:15 dbh Exp $
*/
 
#include <avr/io.h>
#include "combine.h"
#include "stepper.h"
 
/* Instance of rate input/output variables. Normally we would pass these via
* pointers, but this is a small code/data/environment, so they're
* accessed globally
*/
struct rateInput_s rateInput = {SPEED_0_X, SPEED_0_X, SPEED_0_X, SPEED_0_X, SPEED_0_X, SPEED_0_X, SPEED_0_X};
struct rateOutput_s rateOutput = {SPEED_0_X, SPEED_0_X};
 
/* TEST: defeat tracking for testing */
uint8_t noTrack = 0;
 
/* updateMountSpeed() takes the various speed inputs from the paddle,
* serial port, and guiding inputs and determines the actual RA and
* DEC rates
*
* Passed:
* nothing
*
* Returns:
* nothing
*
* Notes:
* Updates rateOutput global structure
*/
void
updateMountSpeed(void)
{
int8_t guideRate;
 
/* Determine the DEC rate. This is the simple one! */
if (rateInput.paddleDecRate != SPEED_0_X)
guideRate = rateInput.paddleDecRate;
else if (rateInput.serialDecRate != SPEED_0_X)
guideRate = rateInput.serialDecRate;
else if (rateInput.guideDecRate != SPEED_0_X)
guideRate = rateInput.guideDecRate;
else
guideRate = SPEED_0_X;
 
rateOutput.decRate = guideRate;
setDecSpeed(rateOutput.decRate);
 
/* Determine the RA rate. This is complicated by the need to perform
* tracking as well as guiding on this axis
*/
if (rateInput.paddleRaRate != SPEED_0_X)
guideRate = rateInput.paddleRaRate;
else if (rateInput.serialRaRate != SPEED_0_X)
guideRate = rateInput.serialRaRate;
else if (rateInput.guideRaRate != SPEED_0_X)
guideRate = rateInput.guideRaRate;
else
guideRate = SPEED_0_X;
 
/* Now we need to add the traking rate to the guiding rate. Fractional
* guiding rates simply adjust the tracking rate, x1 guiding
* doubles/stops the motion, higher tracking rate override the
* guiding rate.
*/
if (noTrack || (guideRate > SPEED_1_X) || (guideRate < -SPEED_1_X))
rateOutput.raRate = guideRate;
else if ((guideRate < SPEED_1_X) && (guideRate > -SPEED_1_X))
rateOutput.raRate = rateInput.siderialRate + guideRate;
else if ((guideRate == SPEED_1_X) && (rateInput.siderialRate == SPEED_1_X))
rateOutput.raRate = SPEED_2_X;
else if ((guideRate == -SPEED_1_X) && (rateInput.siderialRate == -SPEED_1_X))
rateOutput.raRate = -SPEED_2_X;
else
rateOutput.raRate = SPEED_0_X;
 
/* The RA axis needs to turn in the opposite direction of the
* DEC axis. This is the simplest place to do it
*/
setRaSpeed(-rateOutput.raRate);
 
/* All done! */
}
/programy/C/avr/LX200/combine.h
0,0 → 1,77
/*
* 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 software; see the file COPYING. If not, write to
* the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
* MA 02111-1307, USA.
*
* $Id: combine.h,v 1.4 2004/04/05 06:42:15 dbh Exp $
*/
#ifndef _COMBINE_H_
#define _COMBINE_H_
 
#include <inttypes.h>
 
/* This file gives the "public" interface for the "combining" function
* that takes the various inputs (siderial rate, paddle buttons, serial
* input, guider input) to derive speeds for the RA and DEC axis
*/
 
/* Speed definitions */
#define SPEED_0_X 0
#define SPEED_0_33_X 1
#define SPEED_0_67_X 2
#define SPEED_1_X 3
#define SPEED_1_33_X 4
#define SPEED_1_67_X 5
#define SPEED_2_X 6
#define SPEED_4_X 7
#define SPEED_8_X 8
#define SPEED_16_X 9
#define SPEED_SPIN 10
 
#define SPEED_SIDERIAL SPEED_1_X
 
struct rateInput_s
{
int8_t siderialRate;
 
int8_t paddleRaRate;
int8_t paddleDecRate;
 
int8_t serialRaRate;
int8_t serialDecRate;
 
int8_t guideRaRate;
int8_t guideDecRate;
};
 
extern struct rateInput_s rateInput;
 
struct rateOutput_s
{
int8_t raRate;
int8_t decRate;
};
 
extern struct rateOutput_s rateOutput;
 
void updateMountSpeed(void);
 
/* TEST: defeat tracking for testing */
extern uint8_t noTrack;
 
#endif /* _COMBINE_H_ */
 
/programy/C/avr/LX200/driver.c
0,0 → 1,197
/*
* 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 software; see the file COPYING. If not, write to
* the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
* MA 02111-1307, USA.
*
* $Id: driver.c,v 1.4 2004/04/04 06:54:05 dbh Exp $
*/
 
/* This file contains the code that takes the excitation values for each
* coil (determined by the stepper module) and performs a crude PWM
* and generates the output values for the stepper drivers.
*
* This module has it's own timer at a high frequency timer, so efficiency
* is an important issue.
*/
 
#include <avr/io.h>
#include <avr/interrupt.h>
#include <inttypes.h>
 
#include "eq6.h"
#include "stepper.h"
#include "driver.h"
 
/* Like the stepper.h module this one is heavily table-driven. Basically
* each excitation value corresponds to 4, 8 bit lists of values are used
* for 8 clock cycles. This gives a crude PWM system.
*
* The hardware is orginized such that both "ends" of a coil are in
* adjacent bits, so each pair of 8 bits is interleaved into a single
* 16 bit word where the bits are used two at a time.
*
* Note: The high side and low side tables here were different - basically if
* a high side was driven for one coil, the low side should be driven for the
* other.
*
* However the low side bits are reversed because of the bit numbers running
* in the opposite direction for Port A (low side) vs Port C (high side), so
* it turns out that the same table can be used for both!
*
* Of course the bits for the coils are composed in the opposite direction
* too, but that happens below
*/
uint8_t driveTbl[] =
{
[EX_M_1] = 0xaa,
[EX_M_0_67] = 0x2a,
[EX_M_0_4] = 0x22,
[EX_M_0_2] = 0x02,
[EX_0] = 0x00,
[EX_P_0_2] = 0x01,
[EX_P_0_4] = 0x11,
[EX_P_0_67] = 0x15,
[EX_P_1] = 0x55
};
 
#define PWM_RATE 48000 /* PWM update speed */
#define PWM_STEPS 4 /* Steps per PWM cycle */
 
/* driverInit() initializes the port used by the stepper motors and the timer
* used to update the stepper driver state
*
* Passed:
* Nothing
*
* Returns:
* Nothing
*
*/
void
driverInit(void)
{
/* Set up port A and C as outputs and set them to a safe default state
* i.e. no outputs driven
*/
PORTA = 0x00; // Disable high-side drivers
DDRA = 0xff; // Set as outputs
 
PORTC = 0xff; // Disable low-side drivers
DDRC = 0xff; // Set as outputs
 
/* Setup the "magic" relay bit as an output */
 
MAGIC_PORT &= ~_BV(MAGIC_BIT);
MAGIC_DDR |= _BV(MAGIC_BIT);
 
/* Setup timer 0 to generate interrupts for PWM */
OCR0 = (CLK_RATE / PWM_RATE / 8);
TCCR0 = _BV(WGM01) | _BV(CS01); // Divied by 8, CTC mode
 
/* Enable interrupt generation from timer 0 */
TIMSK |= _BV(OCIE0);
}
 
/* driverInt() is called whenever a timer 0 overflow interrupt occurs
*
* Passed:
* Nothing
*
* Returns:
* Nothing
*/
SIGNAL(SIG_OUTPUT_COMPARE0)
{
static uint8_t raCoil1States;
static uint8_t raCoil2States;
static uint8_t decCoil1States;
static uint8_t decCoil2States;
 
static uint8_t ctr = PWM_STEPS - 1;
 
uint8_t highSidePort;
uint8_t lowSidePort;
 
// PORTA = ~excitation.ra;
// PORTC = ~excitation.dec;
 
/* Increment the step count. Reinitialize the states entries
* if the counter wraps around
*/
if (++ctr == PWM_STEPS)
{
uint8_t tmp;
 
ctr = 0;
 
/* Update states */
tmp = _GET_C1(raExcitation.excitation);
raCoil1States = driveTbl[tmp];
 
tmp = _GET_C2(raExcitation.excitation);
raCoil2States = driveTbl[tmp];
 
tmp = _GET_C1(decExcitation.excitation);
decCoil1States = driveTbl[tmp];
 
tmp = _GET_C2(decExcitation.excitation);
decCoil2States = driveTbl[tmp];
 
/* Update magic relay state */
if (raExcitation.useRelay)
MAGIC_PORT &= ~_BV(MAGIC_BIT);
else
MAGIC_PORT |= _BV(MAGIC_BIT);
}
 
/* Build the high_side driver output value */
highSidePort = decCoil2States & 0x3;
highSidePort <<= 2;
 
highSidePort |= decCoil1States & 0x3;
highSidePort <<= 2;
 
highSidePort |= raCoil2States & 0x3;
highSidePort <<= 2;
 
highSidePort |= raCoil1States & 0x3;
 
/* Build the low-side driver states. Note that, due to the
* reverse pin pordering for Port A vs Port C that these are built in
* the opposite direction
*/
lowSidePort = raCoil1States & 0x3;
lowSidePort <<= 2;
raCoil1States >>= 2;
 
lowSidePort |= raCoil2States & 0x3;
lowSidePort <<= 2;
raCoil2States >>= 2;
 
lowSidePort |= decCoil1States & 0x3;
lowSidePort <<= 2;
decCoil1States >>= 2;
 
lowSidePort |= decCoil2States & 0x3;
decCoil2States >>= 2;
 
/* Potential safety check: rev (PortA) & PortC == 0 */
 
/* Write the values to the output ports */
PORTC = highSidePort;
PORTA = ~lowSidePort;
}
/programy/C/avr/LX200/driver.h
0,0 → 1,39
/*
* 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 software; see the file COPYING. If not, write to
* the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
* MA 02111-1307, USA.
*
* $Id: driver.h,v 1.1.1.1 2004/02/22 08:12:42 dbh Exp $
*/
 
#ifndef _DRIVER_H_
#define _DRIVER_H_
 
/* This file contains the interface for the actual stepper motor driver */
 
/* Bit use to connect to the "magic" relay that determines which
* set ot RA coils are connected. This allows low current operation when
* not slewing at high speed
*/
#define MAGIC_PORT PORTB
#define MAGIC_DDR DDRB
#define MAGIC_BIT PB4
 
/* Interface prototypes */
void driverInit(void);
 
#endif /* _DRIVER_H_ */
 
/programy/C/avr/LX200/eq6-mnt.txt
0,0 → 1,156
EQ6 Mount controller analysis (v1 - 10 Jan 2004)
 
Darren Hutchinson
dbh@gbdt.com.au
 
$Id: eq6-mnt.txt,v 1.3 2004/03/07 07:44:59 dbh Exp $
 
Overview:
 
CPU: AT87F51
Clock speed: 3.52 MHz (measured at pin 18 of CPU)
Firmware: MotorDrive DW3505010
 
RA connector
1 RA coil A Driven RA=2,8,16x
2 RA coil C Driven RA=2,8,16x
3 RA coil A Driven RA=1x, 22R to 1, 178R to 4
4 RA coli B Driven RA=Any, 157R to 1, 178R to 3
5 RA coil C Driven RA=1x 173R to 6, 155R to 2
6 RA coil D Driven RA=Any 173R to 5, 22R to 2
 
DEC connector
1 DEC coil A A/B are coil with 16R3 resistance
2 DEC coil B
3 DEC coil C C/D are coil with 16R3 resistance
4 DEC coil D
 
Drive waveforms:
 
RA 0X: Coils not driven
RA 1X: Driven +12V for 114 ms, 0V for 114 ms, not driven for 38ms b/w
driven states, overall time is 302ms [OSC only accurate to 2ms]
 
Each coil driven at 90deg to other coil.
 
Timing correct for half step mode
 
RA 2X: Driven +12V for 75ms, 0V for 76ms, overall time is 151 ms, each coil
at 90deg to other coil
RA 8X: Overall period is 38ms, no undriven time,
coils at 90deg
RA 16X: Overall period is 12.8 ms, no undriven time, coils at 90deg
 
- Timing indicates full step mode
- No evidence of velocity ramp in x2, x8, x16 mode
- RA 1X timinig is correct assuming 180 tooth worm and 1:132 transfer gear
& gearbox reduction ratio
 
DEC 0X: Outputs not driven
DEC 2X: Overall period 151 ms, no undriven time
DEC 8X: Overall period 37.8ms, no undriven time, coils at 90 deg
DEC 16X: Overall period 12.6ms, no undriven time, coils at 90 deg
 
- Timing indicates full step mode
- No evidence of velocity ramp in x16, x8, or x2 mode
 
Drive circuit:
 
The drive circuit is a fairly plain "H" driver with one quirk that may, or
may not, be intentional design from Synta.
 
The half-"H" is built from a pair on PNP/NPN transistors operating in
common-emitter mode. This is somewhat unusual as circuits intended to
drive high currents typically operate in common collector mode.
 
Anyway, the PNP transistor that pulls the output high has a base current of
about 11 mA (depending on the supply voltage). With a transistor hfe of
40 this should give an output current of at least 500 mA.
 
The other part of the bridge is another issue. The identical circuit is used to
drive the base of this NPN transistor, but in this case it will only give
the transistor 1.2 mA, leading to a lower current.
 
The rated hfe of the transistor only guarantees a current of about 50 mA, but
the hfe is typically much higher. In the unit measured the coil current seemed
to be limited to about 250 mA.
 
This may be an attempt to limit the current in fault conditions where
both the NPN and PNP transistors are active, or it may just be bad circuit
design.
 
In any case there are two practical effects:
 
First the transistor may not be saturated, so it will run hot.
Second the coil current is limited, giving less torque.
 
Both of these effect mean that the existing electronics would be
a poor choice as the basis of a GOTO design (but I guess you knew
that ....)
 
MCU Pin Label Use
1 P1.0 1 = RA at 1x, 0 = RA != 1x
2 P1.1 Same as P1.0
3 P1.2 Same as P1.0
4 P1.3 Same as P1.0
5 P1.4 Same as P1.0 but connected to relay (1 = relay off, 0 = on)
6 P1.5 Same as P1.0
7 P1.6 Same as P1.0
8 P1.7 Same as P1.0
9 RST R/C reset circuit, C = 22uF, R = 5K1, active high
10 RXD Data from controller via 1K resistor
11 TXD No data
12 INT0 0V
13 INT1 +5V
14 T0 +5V
15 T1 +5V
16 *WR +5V
17 *RD +5V
18 XTAL xtal out (freq meas point)
19 XTAL Xtal in
20 GND 0V
21 P2.0 1 = RA coil A to +12v, 0 = No effect
22 P2.1 1 = RA coil B to +12v , 0 = No effect
23 P2.2 1 = RA coil C to +12v , 0 = No effect
24 P2.3 1 = RA coil D to +12v, 0 = No effect
25 P2.4 1 = DEC coil A to +12v, 0 = No effect
26 P2.5 1 = DEC coil B to +12v, 0 = No effect
27 P2.6 1 = DEC coil C to +12v, 0 = No effect
28 P2.7 1 = DEC coil D to +12v, 0 = No effect
29 *PSEN +5V
30 ALE Toggle at 602 KHz (high 540 ns, low 1.1 us) [~6 clk / ALE ]
31 *EA +5V
32 P0.7 1 = No effect, 0 = RA coil A to 0V
33 P0.6 1 = No effect, 0 = RA coil B to 0V
34 P0.5 1 = No effect, 0 = RA coil C to 0V
35 P0.4 1 = No effect, 0 = RA coil D to 0V
36 P0.3 1 = No effect, 0 = DEC coil A to 0V
37 P0.2 1 = No effect, 0 = DEC coil B to 0V
38 P0.1 1 = No effect, 0 = DEC coil C to 0V
39 P0.0 1 = No effect, 0 = DEC coil D to 0V
40 Vcc +5V
 
Controller connector port:
 
Pin numbers from RIGHT looking into socket with tab up (as numbered on
controller board)
 
1: Switched +12V from hand controller
2: Ground
3: Data from hand controller via 1K resistor
4: Short to pin 1
5: +12V from source via diode
6: Short to pin 5
 
Notes:
 
- Northern hemisphere selected during measurements
- Relay is 5V, but appears to be driven via a resistor from the 12V supply
- Finder LED has buffering (Q2)
- Controller is series diode protected from reverse power connection
 
Mechanical details:
 
14mm from PCB to inside of cover plate
5mm from PCB to top of MCU socket
9mm from PCB to top of MCU
/programy/C/avr/LX200/eq6-serial.txt
0,0 → 1,125
EQ-6/Atlas handpaddle protocol (v3 - 11 Jan 2004).
 
Darren Hutchinson
dbh@gbdt.com.au
 
$Id: eq6-serial.txt,v 1.3 2004/03/07 07:44:59 dbh Exp $
 
Introduction:
 
The EQ-6/Atlas hand controller is used to control the operation of the
Atlas/EQ-6 mount. The hand controller also acts as a power switch for
the mount.
 
The communication bewteen the controller and the mount is
unidirectional, with data being sent from the controller to the mount
over a single wire. The other wires provide ground, +12V from the mount
to the controller, and switched 12V back to the mount.
 
Cable pinout TBD.
 
Physical format:
 
The signal is a 0/5V signal, with a '1' represented by 5 V. Start bits
are '0', stop bits are '1'
 
Data format:
 
The data is a set of 6 asynchronous words with a format of 1 start bit,
9 data bits, and 1 stop bit. The bits are transmitted at rate of 935
bits per second. The six words are transmitted every 76.2 ms.
 
Note that there is no indication in the data of which word is actually
the first in the set of words. The ordering below is a guess based on
the distribution of extra stop bits in the set of words.
 
The distribution of extra stop bits between the six words depends on
which keys are pressed but it seems unlikely that this is detected or
used by the mount.
 
The six words are divided into two sets of three, one set for RA, the
other for DEC. Each set contains a sync word, a direction word, and a
speed word.
 
All words below are shown with the most significant bit on the left. The
least significant bit is transmitted first, immediately after the start
bit. All RA words have bit 8 set to 0, all DEC words have bit 8 set to 1.
 
Word 1: RA sync
 
This word is always the bit pattern 001111110 (0x07e).
 
B0: Always 0
B1 - B6: Always 1
B7 - B8: Always 0
 
Word 2: RA direction
 
This word determines the rotation direction of the RA axis,
 
B0: 0 = RA left, 1 = RA right.
B1 - Bit 8: Always 0
 
Note: When no keys are pressed Bit 0 is 0 when the controller is set for
southern hemisphere operation, and 1 when set for northern hemisphere
operation.
 
Word 3: RA speed
 
This word determines the speed of the RA axis in multiples of the
sideral rate. There seems to be some logic in the controller for the x2
speed to help with guiding:
 
B3 - 0 Rate
0000 x0 (RA button for opposite direction to hemisphere RA in x2 mode)
0001 x1 (No RA button pressed)
0010 x2 (RA button for same direction to hemisphere RA in x2 mode)
0100 x8
1000 x16
 
B8 to B4: All 0
 
Word 4: DEC sync (?)
 
This word seems to be used to synchronize the start of the DEC
information, but it could be used for something else
 
B0 - B7: All 0
B9: Always '1'
 
Word 5: DEC direction
 
This word determines the direction of DEC axis rotation.
 
B0: 0 = DEC UP, 1 = DEC DOWN
B1 - B7: All 0
B8: Always 1
 
Word 6: DEC speed:
 
This word determines the spped of rotation of the DEC axis.
 
B3 - B0 Speed
0000 x0 (no motion)
0010 x2
0100 x8
1000 x16
 
B7 - B4: All 0
B8: Always 1
 
Notes:
 
- The DEC reverse and RA reverse seem to be inputs to the controller MCU
but only control the interpretation of the buttons and are not sent
directly to the mount.
 
- see eq6-mnt.txt for pinout of cable
 
Further work:
 
- Need to determine correct "first word" in set by monitoring data from
startup
- Need to check for any special startup words by monitoring data from
startup
 
/programy/C/avr/LX200/eq6.c
0,0 → 1,86
/*
* 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 software; see the file COPYING. If not, write to
* the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
* MA 02111-1307, USA.
*
* $Id: eq6.c,v 1.4 2004/04/04 10:32:50 dbh Exp $
*/
 
#include <avr/interrupt.h>
 
#include "eq6.h"
#include "paddle.h"
#include "stepper.h"
#include "driver.h"
#include "serial.h"
#include "pguide.h"
#include "sr.h"
 
volatile uint32_t idleCtr;
 
/* main() is called after the basic system initialization. This
* initialises the program modules (these are, generally, interrupt
* driver), and then waits for the end of civilization as we know it
*
* Passed:
* Nothing
*
* Returns:
* Nothing
*
* Notes:
* There is little to do here but wait.
*/
int
main(void)
{
DDRA = 0xff;
DDRC = 0xff;
PORTA = 0x0;
PORTC = 0x0;
 
/* Initialize the modules */
paddleInit();
stepperInit();
driverInit();
serialInit();
pguideInit();
 
/* Load save data (if any) from the EEPROM */
srLoadState();
setupRateTable(transRatio);
setTrackRate(0);
setTrackRate(trackingRate);
 
/* Enable interrupts */
sei();
 
/* Increment the idle counter to get some idea of the system
* idle time
*/
for (;;)
{
if (doSave)
{
doSave = 0;
srSaveState();
}
}
 
/* NOTREACHED */
return 0;
}
/programy/C/avr/LX200/eq6.h
0,0 → 1,43
/*
* 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 software; see the file COPYING. If not, write to
* the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
* MA 02111-1307, USA.
*
* $Id: eq6.h,v 1.3 2004/04/04 10:32:50 dbh Exp $
*/
 
#ifndef _EQ6_H_
#define _EQ6_H_
 
#include <inttypes.h>
 
/* Define the default clock rate used by the software
* replacement firmware
*/
#define DEF_CLK_RATE (8L * 1000L * 1000L) // 8 MHz
 
#ifndef CLK_RATE
#define CLK_RATE DEF_CLK_RATE
#endif /* CLK_RATE */
 
/* Set the default transmission (gearbox) ratio used by the software. The
* value set via the serial port will override this.
*
* Note: this does not include the worm/worm gear ratio
*/
#define DEF_TRANS_RATIO 132
 
#endif /* _EQ6_H_ */
/programy/C/avr/LX200/eq6_cof.aps
0,0 → 1,0
<AVRStudio><MANAGEMENT><ProjectName>eq6_cof</ProjectName><Created>22-Feb-2004 13:09:53</Created><LastEdit>10-Apr-2004 17:56:42</LastEdit><ICON>Object.bmp</ICON><ProjectType>1</ProjectType><Created>22-Feb-2004 13:09:53</Created><Version>4</Version><Build>310</Build><ProjectTypeName>Atmel AVR Assembler</ProjectTypeName></MANAGEMENT><CODE_CREATION><ObjectFile>H:\atlas\eq6_ver1\eq6.cof</ObjectFile><EntryFile></EntryFile><SaveFolder>H:\atlas\eq6_ver1\</SaveFolder></CODE_CREATION><DEBUG_TARGET><CURRENT_TARGET>AVR Simulator</CURRENT_TARGET><CURRENT_PART>ATmega162</CURRENT_PART><BREAKPOINTS></BREAKPOINTS><IO_EXPAND><Item>51</Item><Item>636</Item><Item>547</Item><Item>34</Item><HIDE>false</HIDE></IO_EXPAND><REGISTERNAMES><Register>R00</Register><Register>R01</Register><Register>R02</Register><Register>R03</Register><Register>R04</Register><Register>R05</Register><Register>R06</Register><Register>R07</Register><Register>R08</Register><Register>R09</Register><Register>R10</Register><Register>R11</Register><Register>R12</Register><Register>R13</Register><Register>R14</Register><Register>R15</Register><Register>R16</Register><Register>R17</Register><Register>R18</Register><Register>R19</Register><Register>R20</Register><Register>R21</Register><Register>R22</Register><Register>R23</Register><Register>R24</Register><Register>R25</Register><Register>R26</Register><Register>R27</Register><Register>R28</Register><Register>R29</Register><Register>R30</Register><Register>R31</Register></REGISTERNAMES><COM>Auto</COM><COMType>0</COMType><WATCHNUM>0</WATCHNUM><WATCHNAMES><Pane0><Variables>pEntry</Variables></Pane0><Pane1></Pane1><Pane2></Pane2><Pane3></Pane3></WATCHNAMES><BreakOnTrcaeFull>0</BreakOnTrcaeFull></DEBUG_TARGET><FilesInProject><Object><OpenString>Object File (*.hex)|*.hex;|AllFiles(*.*)|*.*</OpenString><File>H:\atlas\eq6_ver1\eq6.cof</File></Object></FilesInProject><Files><File00000><FileId>00000</FileId><Path>h:\atlas\eq6_ver1/</Path><Name>eq6.c</Name><Status>259</Status></File00000><File00001><FileId>00001</FileId><Path>h:\atlas\eq6_ver1/</Path><Name>paddle.c</Name><Status>258</Status></File00001><File00002><FileId>00002</FileId><Path>h:\atlas\eq6_ver1/</Path><Name>combine.c</Name><Status>258</Status></File00002><File00003><FileId>00003</FileId><Path>h:\atlas\eq6_ver1/</Path><Name>stepper.c</Name><Status>259</Status></File00003><File00004><FileId>00004</FileId><Path>h:\atlas\eq6_ver1/</Path><Name>driver.c</Name><Status>258</Status></File00004><File00005><FileId>00005</FileId><Path>h:\atlas\eq6_ver1/</Path><Name>serial.c</Name><Status>258</Status></File00005><File00006><FileId>00006</FileId><Path>h:\atlas\eq6_ver1/</Path><Name>pguide.c</Name><Status>258</Status></File00006><File00007><FileId>00007</FileId><Path>h:\atlas\eq6_ver1/</Path><Name>sr.c</Name><Status>258</Status></File00007><File00008><FileId>00008</FileId><Path>H:\atlas\eq6_ver1\</Path><Name>&lt;built-in&gt;</Name><Status>258</Status></File00008></Files><Workspace><File00000><Position>3407 3085 3905 3329</Position><LineCol>47 0</LineCol></File00000><File00003><Position>3429 3107 4004 3420</Position><LineCol>0 0</LineCol></File00003></Workspace><Events><Breakpoints><File00000></File00000><File00001></File00001><File00002></File00002><File00003><B0><Line>325</Line><Value>}</Value><Enabeled>TRUE</Enabeled></B0></File00003><File00004></File00004><File00005></File00005><File00006></File00006><File00007></File00007><File00008></File00008></Breakpoints><Tracepoints><File00000></File00000><File00001></File00001><File00002></File00002><File00003></File00003><File00004></File00004><File00005></File00005><File00006></File00006><File00007></File00007><File00008></File00008></Tracepoints><Bookmarks></Bookmarks></Events><Trace><Filters></Filters></Trace></AVRStudio>
/programy/C/avr/LX200/lx200.kontrollerlab
0,0 → 1,70
<!DOCTYPE KontrollerLab>
<PROJECT VERSION="0.8.0-beta1" >
<FILES>
<FILE SHOWN="FALSE" NAME="combine.c" />
<FILE SHOWN="FALSE" NAME="combine.h" />
<FILE SHOWN="FALSE" NAME="driver.c" />
<FILE SHOWN="FALSE" NAME="driver.h" />
<FILE SHOWN="FALSE" NAME="eq6.c" />
<FILE SHOWN="FALSE" NAME="eq6.h" />
<FILE SHOWN="FALSE" NAME="paddle.c" />
<FILE SHOWN="FALSE" NAME="paddle.h" />
<FILE SHOWN="FALSE" NAME="pguide.c" />
<FILE SHOWN="FALSE" NAME="pguide.h" />
<FILE SHOWN="FALSE" NAME="serial.c" />
<FILE SHOWN="FALSE" NAME="serial.h" />
<FILE SHOWN="FALSE" NAME="sr.c" />
<FILE SHOWN="FALSE" NAME="sr.h" />
<FILE VIEWS="0,0,1024,445,5," SHOWN="TRUE" NAME="stepper.c" />
<FILE SHOWN="FALSE" NAME="stepper.h" />
</FILES>
<SETTINGS>
<ASSEMBLER_COMMAND VALUE="avr-gcc" />
<BUILD_SYSTEM VALUE="BUILT_IN_BUILD" />
<CLOCK VALUE="8e+06" />
<COMPILER_CALL_PROLOGUES VALUE="FALSE" />
<COMPILER_COMMAND VALUE="avr-gcc" />
<COMPILER_F_CPU VALUE="FALSE" />
<COMPILER_GDEBUG VALUE="FALSE" />
<COMPILER_OPT_LEVEL VALUE="s" />
<COMPILER_STRICT_PROTOTYPES VALUE="TRUE" />
<COMPILER_WALL VALUE="TRUE" />
<CPU VALUE="ATMega162" />
<HEX_FILE VALUE="project.hex" />
<LINKER_COMMAND VALUE="avr-gcc" />
<LINKER_FLAGS VALUE="" />
<MAKE_CLEAN_TARGET VALUE="clean" />
<MAKE_COMMAND VALUE="make" />
<MAKE_DEFAULT_TARGET VALUE="all" />
<MAP_FILE VALUE="project.map" />
<OBJCOPY_COMMAND VALUE="avr-objcopy" />
</SETTINGS>
<DEBUGGER_SETTINGS/>
<PROGRAMMERCONFIG>
<AVRDUDE_CONNECTION_PORT VALUE="/dev/parport0" />
<AVRDUDE_COUNT_ERASE VALUE="FALSE" />
<AVRDUDE_DISABLE_AUTO_ERASE VALUE="FALSE" />
<AVRDUDE_OVERRIDE_INVALID_SIGNATURE VALUE="FALSE" />
<AVRDUDE_PROGRAMMER_TYPE VALUE="dapa" />
<AVRDUDE_TEST_MODE VALUE="FALSE" />
<PROGRAMMER_COMMAND VALUE="avrdude" />
<PROGRAMMER_NAME VALUE="AVRDUDE" />
<UISP_PARALLEL_AT89S VALUE="FALSE" />
<UISP_PARALLEL_DISABLE_RETRIES VALUE="FALSE" />
<UISP_PARALLEL_EEPROM_MAX_WRITE_DELAY VALUE="2777" />
<UISP_PARALLEL_FLASH_MAX_WRITE_DELAY VALUE="2777" />
<UISP_PARALLEL_NO_DATA_POLLING VALUE="FALSE" />
<UISP_PARALLEL_PORT VALUE="" />
<UISP_PARALLEL_RESET_HIGH_TIME VALUE="0" />
<UISP_PARALLEL_SCK_HIGH_LOW_TIME VALUE="0" />
<UISP_PARALLEL_VOLTAGE VALUE="0" />
<UISP_PROGRAMMER_TYPE VALUE="" />
<UISP_SERIAL_PORT VALUE="" />
<UISP_SERIAL_SPEED VALUE="9600" />
<UISP_SPECIFY_PART VALUE="FALSE" />
<UISP_STK500_AREF_VOLTAGE VALUE="0" />
<UISP_STK500_OSCILLATOR_FREQUENCY VALUE="14.1" />
<UISP_STK500_USE_HIGH_VOLTAGE VALUE="FALSE" />
<UISP_STK500_VTARGET_VOLTAGE VALUE="0" />
</PROGRAMMERCONFIG>
</PROJECT>
/programy/C/avr/LX200/paddle.c
0,0 → 1,246
/*
* 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: paddle.c,v 1.4 2004/03/03 07:37:11 dbh Exp $
*/
 
/* This file handles the interface to the EQ-6/Atlas hand paddle.
*
* This paddle generates a continuous serial stream containing information
* about the state of the paddle. Unlike many simple paddles the EQ-6 has a
* small microprocessor to handle the various functions (debouncing, switch
* refersal, etc)
*
* See the file eq6-serial.txt for further information on the prototcol
* used by the hand paddle.
*/
#include <avr/io.h>
#include <avr/interrupt.h>
#include <inttypes.h>
 
#include "paddle.h"
#include "eq6.h"
#include "combine.h"
 
uint8_t paddleGuideRate = SPEED_1_X;
 
/* paddleInit() initializes the serial port used for the EQ6/Atlas
* hand paddle. The communication with this port is only in one
* direction (from paddle to mount).
*
* Passed:
* Nothing
*
* Returns:
* Nothing.
*/
void
paddleInit(void)
{
// The handpaddle is connected to UART port #0 (pin 10)
 
// Set serial rate
UBRR0H = (CLK_RATE / PADDLE_RATE / 16 - 1) >> 8;
UBRR0L = (CLK_RATE / PADDLE_RATE / 16 - 1) & 0xff;
 
/* Setup registers
* 9 bits, RX enable
*/
UCSR0B = 0; // Disable all interrupts
UCSR0C = _BV(URSEL0) | _BV(UCSZ01) | _BV(UCSZ00);
UCSR0B = _BV(RXCIE0) | _BV(UCSZ02) | _BV(RXEN0);
}
 
/* paddleInt() is called whenever a character is received on USART0.
* These characters are send by the hand paddle
*
* Passed:
* Nothing
*
* Returns:
* Nothing
*
* Notes:
* This function inplemented a state machine to properly
* synchronize with the incoming character stream.
*
* Interrupts are disabled during processing
*/
SIGNAL(SIG_USART0_RECV)
{
uint8_t lowerByte;
uint8_t b8;
 
static void *pLabel = &&wait_for_sync;
 
static uint8_t raDir = 0;
static uint8_t raSpeed = 0;
static uint8_t decDir = 0;
 
static uint8_t oldRaDir = (uint8_t)-1;
static uint8_t oldRaSpeed = (uint8_t)-1;
static uint8_t oldDecDir = (uint8_t)-1;
static uint8_t oldDecSpeed = (uint8_t)-1;
 
/* Read the nine bits of transferred data. We don't do this
* during initialization as the order is important!
*/
b8 = UCSR0B & _BV(RXB80);
lowerByte = UDR0;
 
/* Jump to the code that handles the current reception system. Note that
* this feature is GCC specific.
*/
goto *pLabel;
 
/* Wait for the RA sync byte
*/
wait_for_sync:
if ((b8 == 0) && (lowerByte == RA_SYNC))
pLabel = &&get_ra_direction;
return;
 
/* Get the RA direction - this will have b8 == 0
*/
get_ra_direction:
if (b8 == 0)
{
raDir = lowerByte & _BV(RA_DIR_BIT);
pLabel = &&get_ra_speed;
}
else
pLabel = &&wait_for_sync;
return;
 
/* Get the RA speed - this will have b8 == 0
*/
get_ra_speed:
if (b8 == 0)
{
raSpeed = lowerByte & RA_SPEED_MASK;
pLabel = &&get_dec_sync;
}
else
pLabel = &&wait_for_sync;
return;
 
/* Get the mystery fourth byte
*/
get_dec_sync:
if (b8 != 0)
{
pLabel = &&get_dec_direction;
}
else
pLabel = &&wait_for_sync;
return;
 
/* Get the DEC direction - this will have b8 != 0
*/
get_dec_direction:
if (b8 != 0)
{
decDir = lowerByte & _BV(DEC_DIR_BIT);
pLabel = &&get_dec_speed;
}
else
pLabel = &&wait_for_sync;
return;
 
/* Get the RA speed - this will have b8 == 0
*/
get_dec_speed:
// We've got all the words - the next state will always be wait for sync
pLabel = &&wait_for_sync;
lowerByte &= DEC_SPEED_MASK;
 
/* If the parity is correct and any of the bytes are different then
* process them
*/
if ( b8 != 0
&& ( (oldRaDir != raDir)
|| (oldRaSpeed != raSpeed)
|| (oldDecDir != decDir)
|| (oldDecSpeed != lowerByte)))
{
/* Update "old" indications */
oldRaDir = raDir;
oldRaSpeed = raSpeed;
oldDecDir = decDir;
oldDecSpeed = lowerByte;
/* Process the data from the paddle
* - if the RA speed is one then setup the siderial speed
* - convert the RA speed/direction into a device independent form
* - convert the DEC speed/direction into a device independent form
*/
if (raSpeed == RA_SPEED_0)
{
rateInput.paddleRaRate = -paddleGuideRate;
/* This is a little trick because the "direction" bit doesn't
* work then the speed is zero. Do a pre-invert if the
* siderial rate is for the northern hemisphere
*/
if (rateInput.siderialRate == SPEED_SIDERIAL)
rateInput.paddleRaRate = -rateInput.paddleRaRate;
}
else if (raSpeed == RA_SPEED_1)
{
rateInput.paddleRaRate = SPEED_0_X;
rateInput.siderialRate = raDir ? SPEED_SIDERIAL : -SPEED_SIDERIAL;
}
else if (raSpeed == RA_SPEED_2)
rateInput.paddleRaRate = paddleGuideRate;
else if (raSpeed == RA_SPEED_8)
rateInput.paddleRaRate = SPEED_8_X;
else if (raSpeed == RA_SPEED_16)
rateInput.paddleRaRate = SPEED_16_X;
 
#if 0
/* The direction of the RA keys is reversed when operating in
* the southern hemisphere, so modify them back
*/
if ((raDir == 0) ^ (rateInput.siderialRate == SPEED_SIDERIAL))
rateInput.paddleRaRate = -rateInput.paddleRaRate;
#else
/* Use the keys as returned by the paddle. These are reversed when
* operating in the southern hemisphere. This ensures that the
* "right" key always increases the RA angle
*/
if (raDir == 0)
rateInput.paddleRaRate = -rateInput.paddleRaRate;
#endif
 
if (lowerByte == DEC_SPEED_0)
rateInput.paddleDecRate = SPEED_0_X;
else if (lowerByte == DEC_SPEED_2)
rateInput.paddleDecRate = paddleGuideRate;
else if (lowerByte == DEC_SPEED_8)
rateInput.paddleDecRate = SPEED_8_X;
else if (lowerByte == DEC_SPEED_16)
rateInput.paddleDecRate = SPEED_16_X;
 
if (decDir != 0)
rateInput.paddleDecRate = -rateInput.paddleDecRate;
 
/* Ok, all parsed. Force an update of the combined speed
*/
updateMountSpeed();
}
}
/programy/C/avr/LX200/paddle.h
0,0 → 1,109
/*
* 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 software; see the file COPYING. If not, write to
* the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
* MA 02111-1307, USA.
*
* $Id: paddle.h,v 1.2 2004/03/03 07:37:11 dbh Exp $
*/
 
#ifndef _PADDLE_H_
#define _PADDLE_H_
 
/* This file describes the data in the EQ6/Atlas hand paddle serial stream.
*
* This is a one-directional serial stream at 935 bits/sec. This is a fairly
* wierd speed that seems to be used to give an overall serial stream time
* of 76.2ms [basically the full-step time for siderial rate, which is
* half of the actual half-step rate].
*
* See the file eq6-serial.txt for further details.
*/
#include <inttypes.h>
 
/* Define the serial rate used by the paddle
*/
#define PADDLE_RATE 935L /* Bit rate for the paddle */
 
/* The serial stream is a set of 6, 9 bit words. The first three words
* are for RA control, the second three words are for DEC control.
*
* Note that the ordering here is arbitary (through reverse engineering), but
* seems sensible.
*
* Word1: RA sync (B8 = 0)
* Word2: RA direction (B8 = 0)
* Word3: RA speed (B8 = 0)
* Word4: ??? (Assumed to be DEC sync) (B8 = 1)
* Word5: DEC direction (B8 = 1)
* Word6: DEC speed (B8 = 1)
*
*/
 
/* Word #1 - RA SYNC
*/
#define RA_SYNC 0x7e
 
/* Word #2 - RA DIRECTION
*/
#define RA_DIR_BIT 0 // RA Direction bit
#define RA_DIR_LEFT 0
#define RA_DIR_RIGHT (1 << RA_DIR_BIT)
 
/* Note: Will be 0 for southern hemispere siderial, 1 for northern siderial
*/
 
 
/* Word #3 - RA SPEED
*/
#define RA_SPEED_MASK 0x0f // Speed bits
#define RA_SPEED_0 0x00 // x2, opposite direction to siderial
#define RA_SPEED_1 0x01 // No RA button pressed
#define RA_SPEED_2 0x02 // x2, same direction as siderial
#define RA_SPEED_8 0x04 // siderial x8
#define RA_SPEED_16 0x08 // siderial x16
 
/* Word #4 - ???. This word always seems to be zero. Assume it's a sync word
* unless we hear something different
*/
#define DEC_SYNC 0x00
 
/* Word #5 - DEC DIRECTION
*/
#define DEC_DIR_BIT 0 // DEC Direction bit
#define DEC_DIR_UP 0
#define DEC_DIR_DOWN (1 << DEC_DIR_BIT)
 
/* Word #6 - DEC SPEED
*/
#define DEC_SPEED_MASK 0x0f // Speed bits
#define DEC_SPEED_0 0x00 // No buttons pressed
#define DEC_SPEED_2 0x02 // siderial x2
#define DEC_SPEED_8 0x04 // siderial x8
#define DEC_SPEED_16 0x08 // siderial x16
 
/* Prototypes for paddle.c functions that can be called from outside
*/
extern void paddleInit(void);
 
extern uint8_t paddleDecRate;
extern uint8_t paddleRaRate;
extern uint8_t siderialRate;
 
/* Configuration variable - sets whether the 2X rate for the paddle should
* be considered as 1X or 0.3X
*/
extern uint8_t paddleGuideRate;
#endif /* _PADDLE_H_ */
/programy/C/avr/LX200/pguide.c
0,0 → 1,125
/*
* 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 software; see the file COPYING. If not, write to
* the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
* MA 02111-1307, USA.
*
* $Id: pguide.c,v 1.1.1.1 2004/02/22 08:12:42 dbh Exp $
*/
 
/* This file contains the code that takes inputs from a parallel output
* guider (such as the SBIG ST-4) and uses them to make guiding
* adjustments.
*/
 
#include <avr/io.h>
#include <avr/interrupt.h>
#include <inttypes.h>
 
#include "eq6.h"
#include "combine.h"
#include "pguide.h"
 
#define GUIDE_BITS (_BV(G_UP) | _BV(G_DN) | _BV(G_RT) | _BV(G_LT))
 
/* This module polls the input bits from the guider, applies some
* crude debouncing, and then applies the requested speed adjustment.
*
* This code assumes that the inputs are active low (i.e. they are connected
* to a relay or optocoupler connecting the "active" input to ground).
*
* The polling rate is generated by a 8-bit timer with /256
*/
 
/* pguideInit() initializes the timer used to poll the parallel guiding
* input bits and sets those bit as inputs.
*
* Passed:
* Nothing
*
* Returns:
* Nothing
*
*/
void
pguideInit(void)
{
/* Set guide bits as inputs with pullups */
GUIDE_DDR &= ~GUIDE_BITS;
GUIDE_PORT |= GUIDE_BITS;
 
/* Setup timer 2 to generate interrupts for PWM to the selected
* rate (in CTC mode)
*/
OCR2 = (CLK_RATE / GUIDE_RATE / 1024);
TCCR2 = _BV(WGM21) | _BV(CS22) | _BV(CS20);
 
/* Enable interrupt generation from timer 2 */
TIMSK |= _BV(OCIE2);
}
 
/* pguideInt() is called whenever a timer 2 overflow interrupt occurs
*
* Passed:
* Nothing
*
* Returns:
* Nothing
*/
SIGNAL(SIG_OUTPUT_COMPARE2)
{
uint8_t guideBits;
 
static uint8_t lastState = GUIDE_BITS;
static uint8_t lastUsed = GUIDE_BITS;
 
/* Get the guide bits */
guideBits = GUIDE_PIN & GUIDE_BITS;
 
/* See if they're the same as the last set. If they are then we
* assume that the guide bits are stable
*/
if (guideBits != lastState)
{
/* Bits are changing */
lastState = guideBits;
}
else if (lastUsed != lastState)
{
/* They're stable and different from the last used set, so
* update the guiding information
*/
 
if ((guideBits & _BV(G_UP)) == 0)
rateInput.guideDecRate = SPEED_0_33_X;
else if ((guideBits & _BV(G_DN)) == 0)
rateInput.guideDecRate = -SPEED_0_33_X;
else
rateInput.guideDecRate = SPEED_0_X;
 
if ((guideBits & _BV(G_RT)) == 0)
rateInput.guideRaRate = SPEED_0_33_X;
else if ((guideBits & _BV(G_LT)) == 0)
rateInput.guideRaRate = -SPEED_0_33_X;
else
rateInput.guideRaRate = SPEED_0_X;
/* Update the overall rate */
updateMountSpeed();
 
/* Update the last used state ('cuz we used it) */
lastUsed = lastState;
}
}
/programy/C/avr/LX200/pguide.h
0,0 → 1,49
/*
* 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 software; see the file COPYING. If not, write to
* the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
* MA 02111-1307, USA.
*
* $Id: pguide.h,v 1.1.1.1 2004/02/22 08:12:42 dbh Exp $
*/
#ifndef _PGUIDE_H_
#define _PGUIDE_H_
 
/* This file has the definitions used to poll the parallel guiding input
* pins.
*
* These pins are pulled high by the internal CPU pullups and should be
* driven low by the guiding input
*/
#define GUIDE_PORT PORTD
#define GUIDE_PIN PIND
#define GUIDE_DDR DDRD
 
#define G_UP PD4
#define G_DN PD5
#define G_RT PD6
#define G_LT PD7
 
/* Define the polling rate (in HZ). For the current software the
* range is 30Hz to 7800Hz @ 8 MHz, and 60Hz to 15KHz @ 16MHz.
*
* A good value would be about 200 Hz (ie. 5ms debounce time)
*/
#define GUIDE_RATE 200
 
/* Prototypes */
void pguideInit(void);
 
#endif /* _PGUIDE_H_ */
/programy/C/avr/LX200/project.hex
0,0 → 1,269
:100000000C9438000C9455000C9455000C94550039
:100010000C9455000C9455000C9455000C9455000C
:100020000C9455000C9455000C9441020C9455000E
:100030000C9455000C944B070C9455000C945500EF
:100040000C94AA000C9455000C9455000C94680173
:100050000C9486020C9455000C9455000C94550099
:100060000C9455000C9455000C9455000C945500BC
:1000700011241FBECFEFD4E0DEBFCDBF11E0A0E062
:10008000B1E0E8E2F0E102C005900D92A039B107BD
:10009000D9F711E0A0E9B1E001C01D92A53FB10779
:1000A000E1F70E9438010C9412080C940000809132
:1000B0009201882331F480919401882311F4809176
:1000C0009601809398010E94FC05909191019923DB
:1000D00031F490919301992311F4909195018091BD
:1000E0009901882359F494304CF49D3F3CF0892FBA
:1000F0008E5F853030F480919001980F9093970136
:1001000014C0933031F480919001833061F486E023
:1001100007C09D3F41F4809190018D3F21F48AEF0B
:100120008093970102C01092970180919701819569
:100130000E94F10508951BBA8FEF8ABB85BB84BB73
:10014000C498BC9A84E181BF8AE083BF89B781608B
:1001500089BF08951F920F920FB60F9211242F930B
:100160003F934F935F936F937F938F939F93AF933F
:10017000BF93EF93FF9380910D018F5F80930D01EB
:10018000843079F510920D01A091ED01EA2FE295EE
:10019000EF70F0E0E050FF4F808180939D01B0E070
:1001A000AF70B070A050BF4F8C9180939C01A09114
:1001B000F101EA2FE295EF70F0E0E050FF4F80810F
:1001C00080939B01B0E0AF70B070A050BF4F8C9196
:1001D00080939A018091EE01882311F0C49801C0A8
:1001E000C49A50919A01E52FE37040919B01742FBE
:1001F00073702E2F220F220F272B30919C01632F1B
:100200006370220F220F262B90919D01220F220F47
:10021000892F8370282B9695969590939D01880F32
:10022000880F862B3695369530939C01880F880F62
:10023000872B4695469540939B01880F880F8E2B00
:100240005695569550939A0125BB80958BBBFF918F
:10025000EF91BF91AF919F918F917F916F915F913E
:100260004F913F912F910F900FBE0F901F901895B7
:100270008FEF8ABB84BB1BBA15BA0E945E010E9435
:10028000F9040E949B000E947D020E9433020E949A
:10029000A204809118010E949C0580E00E94C00584
:1002A0008091B3010E94C00578948091B9018823A0
:1002B000E1F31092B9010E944704F7CF82E080BDBC
:1002C00085E189B91AB886E880BD84E98AB90895BC
:1002D0001F920F920FB60F9211240F931F932F931B
:1002E0003F934F938F939F93EF93FF931AB11270A5
:1002F0000CB1E0911301F09114010994112309F05C
:10030000A4C00E3709F0A1C087E891E007C011230F
:10031000F9F401700093A00183E991E09093140136
:100320008093130192C0112399F40F7000939F01E1
:100330008BE991E0F3CF112359F080EA91E0EECF01
:10034000112331F0017000939E018BEA91E0E6CF1A
:100350008EE791E0E3CF8EE791E0909314018093D4
:100360001301112309F471C0202F2F703091A001C7
:1003700080911201831789F49091110180919F015E
:10038000981759F49091100180919E01981729F4C3
:1003900080910F01821709F458C0309312018091A7
:1003A0009F018093110140919E0140931001209381
:1003B0000F01882369F490910E01892F8195809314
:1003C0009101809190018330E9F4909391011AC0DA
:1003D000813051F410929101332311F48DEF01C05B
:1003E00083E0809390010EC0823019F480910E0159
:1003F00007C0843011F488E003C0883019F489E024
:1004000080939101332329F4809191018195809308
:100410009101222319F4109292010EC0223019F496
:1004200080910E0107C0243011F488E003C0283009
:1004300019F489E080939201442329F0809192017C
:100440008195809392010E945700FF91EF919F91B7
:100450008F914F913F912F911F910F910F900FBE50
:100460000F901F90189581B38F7081BB82B3806FFE
:1004700082BB87E282BD8DE087BD89B7806189BF7D
:1004800008951F920F920FB60F9211242F938F93FE
:100490009F9390B3907F80911601981719F09093D5
:1004A000160123C0809115018917F9F0292F94FDB9
:1004B00002C081E003C095FD04C08FEF80939601D8
:1004C00002C01092960126FD02C081E003C097FD94
:1004D00004C08FEF8093950102C0109295010E9495
:1004E000570080911601809315019F918F912F9154
:1004F0000F900FBE0F901F9018951CBE83E380B91C
:1005000011B886E88CBF88E981B908951F920F92CF
:100510000FB60F9211242F933F934F938F939F9376
:10052000EF93FF9343B18091A101882309F0EEC0BE
:10053000443409F478C0453410F54A3368F4403344
:1005400008F044C0433209F459C04D3209F45DC08B
:10055000463009F064C1D2C04E3309F45DC04F3358
:1005600038F44A3309F4CCC04C3309F058C151C0B7
:10057000423409F46AC0433409F051C10FC1443513
:1005800009F4A5C0453580F44C3409F452C04D340B
:1005900020F4473409F043C190C04D3409F477C0CA
:1005A000423509F03CC142C0473609F49DC0483687
:1005B00030F44535A9F1423609F031C13DC04D3620
:1005C00009F44FC0443709F02AC193C08091B001AB
:1005D0009091B1019C01220F331F220F331F220F74
:1005E000331F880F991F280F391F240F311D2053E7
:1005F00030403093B1012093B00136C11092B10167
:100600001092B0011092AF012FC181E08093AF0131
:100610002BC11092B20128C181E08093B20124C1A4
:100620008091B201AAC08091B201ABC08091B201A9
:10063000ACC08091B201ADC08091B0019091B10188
:100640009093CF018093CE0108C08091B00190912A
:10065000B1019093E0018093DF0181E08093B901C3
:1006600003C11092D0011092D1018091B0019091FC
:10067000B101892B91F38091AF01882321F081E0B2
:100680008093D101EACF81E08093D001E6CF109230
:10069000E1011092E2018091B0019091B101892BAA
:1006A000E1F28091AF01882321F081E08093E201A3
:1006B000D4CF81E08093E101D0CF8091B201882333
:1006C00011F483E001C081E080930E01C6CF8091D8
:1006D000AF01882321F08091B001819502C0809103
:1006E000B0010E94C005B9CF8091B001809318017C
:1006F000B4CF8091B2018093B401B6C080E590C0C0
:1007000081E08093A1011092A201AEC08091A2016C
:10071000433281F0E82FF0E0ED55FE4F40838F5FCC
:100720008093A201883009F09FC08FE383B91092B3
:10073000A1019AC01092A101882309F495C090915B
:10074000A301913549F1923509F44BC09D3409F06C
:1007500066C0823009F088C08091A4018E3661F0B5
:100760008F3624F4853609F057C00EC0833741F028
:10077000873709F051C00CC081E08093AE0182C080
:1007800081E08093AD017EC081E08093AB017AC0AF
:1007900081E08093AC0176C0813039F41092AB01D6
:1007A0001092AC011092AD0110C08230C1F5809161
:1007B000A4018E3651F08F361CF4853669F50BC0D6
:1007C000833731F0873741F509C01092AE015AC026
:1007D0001092AD0157C01092AB0154C01092AC0101
:1007E00051C0823009F040C08091A401873451F09B
:1007F00088341CF4833481F407C08D3439F0833598
:1008000059F408C081E003C083E001C088E0809310
:10081000170138C089E0FBCF8FE383B933C08FE382
:1008200083B922C08091170107C08091AD01882350
:1008300031F08091170181958093940102C010924C
:1008400094018091AB01882319F08091170107C0B2
:100850008091AC01882331F08091170181958093BC
:10086000930102C0109293010E945700FF91EF91F3
:100870009F918F914F913F912F910F900FBE0F90AD
:100880001F9018958091AE01882361F6CECFDF933B
:10089000CF93CDB7DEB72C970FB6F894DEBF0FBE5F
:1008A000CDBFF8948091D00189838091D1018A8352
:1008B0008091CE019091CF019C838B838091E10147
:1008C0008D838091E2018E838091DF019091E00120
:1008D00098878F8380910E0189878091B3018A87E1
:1008E000809118018B87789490E0FE0131969E01EB
:1008F000245F3F4F8191980FE217F307D9F79C8748
:10090000FE0131964E2F54E096E09E01245F3F4F4A
:100910008E2F841BE199FECF1FBA8EBB80818DBBC9
:10092000F8945CBB9CBB7894E217F30711F0319606
:10093000EFCF2C960FB6F894DEBF0FBECDBFCF9190
:10094000DF910895DF93CF93CDB7DEB72C970FB625
:10095000F894DEBF0FBECDBFFE0131964E2F91E061
:100960009E01245F3F4F8E2F841BE199FECF1FBA5B
:100970008EBB9CBB8DB38083E217F30711F03196D9
:10098000F2CF90E0FE0131969E01245F3F4F8191AE
:10099000980FE217F307D9F78C85891709F5898134
:1009A0008093D0018A818093D1018B819C81909327
:1009B000CF018093CE018D818093E1018E81809360
:1009C000E2018F8198859093E0018093DF01898512
:1009D00080930E018A858093B3018B8580931801E3
:1009E0002C960FB6F894DEBF0FBECDBFCF91DF912E
:1009F00008951092ED011092EE018DEE91E090932A
:100A0000CD018093CC011092F10181EF91E09093A0
:100A1000DE018093DD0189B7806489BF08956F92FC
:100A20007F928F929F92AF92BF92CF92DF92EF927E
:100A3000FF920F931F93CF93DF93EC01E62ECA0131
:100A4000B9010E94B6075B016C01FF2400E010E0D1
:100A5000C801B7010E94B6077B018C019595879567
:100A6000779567956A0D7B1D8C1D9D1DA8019701CB
:100A70000E94D507922E832E742E652E622F732F1F
:100A8000842F952FA80197010E94B6079B01AC0106
:100A90002A193B094C095D09C601B5010E94D50719
:100AA00079018A01292D382D472D562DC901DA01EA
:100AB000883E23E0920720E0A20720E0B20724F45A
:100AC00088EE93E0A0E0B0E09983888317FD11C021
:100AD0001C8280E0E81680E0F80681E0080780E0EC
:100AE00018071CF020E030E001C097013B832A8307
:100AF00014C081E08C8321E0E21620E0F2062FEFA3
:100B000002072FEF12071CF480E090E004C0882752
:100B100099278E199F099B838A83DF91CF911F911B
:100B20000F91FF90EF90DF90CF90BF90AF909F908C
:100B30008F907F906F900895FF920F931F93F82EE0
:100B40000AEB11E024E930E541E050E0682FC801EC
:100B50000E940F0520E831E541E050E06F2DC8010B
:100B600005960E940F052DED3CE541E050E06F2D0C
:100B7000C8010A960E940F051F910F91FF900895DA
:100B80008093B30187FF04C081E0809399010895A9
:100B9000833030F510929901992787FD9095FC01DB
:100BA000EE0FFF1FEE0FFF1FE80FF91FE654FE4F79
:100BB000808191819BBD8ABD1DBC1CBC1FBC89E08E
:100BC0008EBD1092F0011092EF018281938190937B
:100BD000F4018093F30184818093C9011092CA01CA
:100BE0000895982F8091DA01882319F481E0809389
:100BF000DA019093CB010895982F8091EB0188231F
:100C000019F481E08093EB019093DC010895E62FC5
:100C1000F0E0EE0FFF1FE758FE4F2081FC01278711
:100C20000895CF93DF93EC0189859A85892B21F470
:100C300087E296E09A8789878D81882329F08E81C3
:100C4000882311F01E821D82E985FA850994888126
:100C5000882381F48E81882309F062C08091790114
:100C60008F87E981FA811082E981FA81118287E216
:100C700096E015C018160CF490C052C088818823E5
:100C800089F48D81882381F4809179018F87E981AE
:100C9000FA811082E981FA8111828EE396E09A87C7
:100CA0008987F6C087FDB2C08B819C81892B79F240
:100CB00020918E011C861B8680918D018F8721FDDE
:100CC00003C089E591E009C08091B401882319F43B
:100CD00089E191E002C089E391E09E878D87E981F7
:100CE000FA812170218387E796E09A878987A98115
:100CF000BA818F81ED85FE85E80FF11D80818C938F
:100D00008F818F5F8F718F838B859C8501969C87E8
:100D10008B872B813C812817390708F498CFB8C0FE
:100D20008B819C81892B09F4A9CF20918E011C868F
:100D30001B8680918D018F8721FD03C089E591E09D
:100D400009C08091B401882319F489E191E002C0BF
:100D500089E391E09E878D87E981FA812170218363
:100D600084EB96E09A878987A981BA818F81ED8586
:100D7000FE85E80FF11D80818C938F8181508F71EA
:100D80008F838B859C8501969C878B872B813C81EB
:100D90002817390708F472CF7BC0E82FFF27E7FD3B
:100DA000F095EE0FFF1FE758FE4F2181E82FF0E08E
:100DB000EE0FFF1FE758FE4F80818F8721FD03C094
:100DC00089E591E009C08091B401882319F489E193
:100DD00091E002C089E391E09E878D87E981FA81E5
:100DE0002170218385EF96E03CC098858881981713
:100DF00009F02DCFA981BA818F81ED85FE85E80F9D
:100E0000F11D80818C938F818F5F40C0E82FFF2779
:100E1000E7FDF095EE0FFF1FF095E195FF4FE758C6
:100E2000FE4F21818195E82FF0E0EE0FFF1FE7587C
:100E3000FE4F80818F8721FD03C089E591E009C0C5
:100E40008091B401882319F489E191E002C089E31B
:100E500091E09E878D87E981FA812170218386E365
:100E600097E09A8789878881888712C098858881CA
:100E7000981709F003CFA981BA818F81ED85FE858E
:100E8000E80FF11D80818C938F8181508F718F834A
:100E9000DF91CF9108951F920F920FB60F921124F8
:100EA0002F933F938F939F932091EF013091F00107
:100EB0002F5F3F4F3093F0012093EF018091C901E4
:100EC0009091CA01892B71F08091F3019091F40106
:100ED000009741F02817390728F01092F00110927E
:100EE000EF013BC09091DA01992369F08091DB0119
:100EF0008F5F8093DB01891730F01092DB018BEC60
:100F000091E00E9411069091EB01992369F0809184
:100F1000EC018F5F8093EC01891730F01092EC01A7
:100F20008CED91E00E9411068091C9019091CA0157
:100F3000892B99F42091F3013091F40121153105A9
:100F400061F08091EF019091F0018217930728F0F2
:100F50001092F0011092EF01C5CF9F918F913F91B8
:100F60002F910F900FBE0F901F901895629FD00188
:100F7000739FF001829FE00DF11D649FE00DF11D54
:100F8000929FF00D839FF00D749FF00D659FF00D03
:100F90009927729FB00DE11DF91F639FB00DE11DF0
:100FA000F91FBD01CF011124089597FB092E0526D5
:100FB0000ED057FD04D014D00AD0001C38F4509540
:100FC0004095309521953F4F4F4F5F4F0895F6F76D
:100FD00090958095709561957F4F8F4F9F4F0895A5
:100FE000A1E21A2EAA1BBB1BFD010DC0AA1FBB1F2D
:100FF000EE1FFF1FA217B307E407F50720F0A21B9F
:10100000B30BE40BF50B661F771F881F991F1A940B
:1010100069F760957095809590959B01AC01BD0135
:08102000CF010895F894FFCF01
:1010280000011115550000000002222AAA0303FF3F
:10103800FFFFFF7E01F0F00184041424344443428E
:101048004140494A4B4C3C2C1C0C9CACBCCCCBCAF8
:10105800C9C0C1C2C3C4B4A4944444444440404039
:10106800404C4C4C4C0C0C0C0CCCCCCCCCC0C0C068
:10107800C0C4C4C4C40404040444444444444444AC
:10108800444C4C4C4C4C4C4C4CCCCCCCCCCCCCCC20
:10109800CCC4C4C4C4C4C4C4C4010290024802304D
:1010A8000224021C0218030C0306030301030000B8
:00000001FF
/programy/C/avr/LX200/project.map
0,0 → 1,460
Archive member included because of file (symbol)
 
/usr/lib/gcc/avr/4.3.0/avr5/libgcc.a(_mulsi3.o)
stepper.o (__mulsi3)
/usr/lib/gcc/avr/4.3.0/avr5/libgcc.a(_divmodsi4.o)
stepper.o (__divmodsi4)
/usr/lib/gcc/avr/4.3.0/avr5/libgcc.a(_exit.o)
/usr/lib/gcc/avr/4.3.0/../../../../avr/lib/avr5/crtm162.o (exit)
/usr/lib/gcc/avr/4.3.0/avr5/libgcc.a(_copy_data.o)
combine.o (__do_copy_data)
/usr/lib/gcc/avr/4.3.0/avr5/libgcc.a(_clear_bss.o)
combine.o (__do_clear_bss)
/usr/lib/gcc/avr/4.3.0/avr5/libgcc.a(_udivmodsi4.o)
/usr/lib/gcc/avr/4.3.0/avr5/libgcc.a(_divmodsi4.o) (__udivmodsi4)
 
Allocating common symbols
Common symbol size file
 
trackRateTable 0xf stepper.o
doSave 0x1 sr.o
doDropInt 0x2 stepper.o
idleCtr 0x4 eq6.o
raState 0x11 stepper.o
decState 0x11 stepper.o
raExcitation 0x2 stepper.o
adjCtr 0x2 stepper.o
decExcitation 0x2 stepper.o
adjLimit 0x2 stepper.o
 
Memory Configuration
 
Name Origin Length Attributes
text 0x00000000 0x00020000 xr
data 0x00800060 0x0000ffa0 rw !x
eeprom 0x00810000 0x00010000 rw !x
fuse 0x00820000 0x00000400 rw !x
lock 0x00830000 0x00000400 rw !x
signature 0x00840000 0x00000400 rw !x
*default* 0x00000000 0xffffffff
 
Linker script and memory map
 
Address of section .data set to 0x800100
LOAD /usr/lib/gcc/avr/4.3.0/../../../../avr/lib/avr5/crtm162.o
LOAD combine.o
LOAD driver.o
LOAD eq6.o
LOAD paddle.o
LOAD pguide.o
LOAD serial.o
LOAD sr.o
LOAD stepper.o
LOAD /usr/lib/gcc/avr/4.3.0/avr5/libgcc.a
LOAD /usr/lib/gcc/avr/4.3.0/../../../../avr/lib/avr5/libc.a
LOAD /usr/lib/gcc/avr/4.3.0/avr5/libgcc.a
 
.hash
*(.hash)
 
.dynsym
*(.dynsym)
 
.dynstr
*(.dynstr)
 
.gnu.version
*(.gnu.version)
 
.gnu.version_d
*(.gnu.version_d)
 
.gnu.version_r
*(.gnu.version_r)
 
.rel.init
*(.rel.init)
 
.rela.init
*(.rela.init)
 
.rel.text
*(.rel.text)
*(.rel.text.*)
*(.rel.gnu.linkonce.t*)
 
.rela.text
*(.rela.text)
*(.rela.text.*)
*(.rela.gnu.linkonce.t*)
 
.rel.fini
*(.rel.fini)
 
.rela.fini
*(.rela.fini)
 
.rel.rodata
*(.rel.rodata)
*(.rel.rodata.*)
*(.rel.gnu.linkonce.r*)
 
.rela.rodata
*(.rela.rodata)
*(.rela.rodata.*)
*(.rela.gnu.linkonce.r*)
 
.rel.data
*(.rel.data)
*(.rel.data.*)
*(.rel.gnu.linkonce.d*)
 
.rela.data
*(.rela.data)
*(.rela.data.*)
*(.rela.gnu.linkonce.d*)
 
.rel.ctors
*(.rel.ctors)
 
.rela.ctors
*(.rela.ctors)
 
.rel.dtors
*(.rel.dtors)
 
.rela.dtors
*(.rela.dtors)
 
.rel.got
*(.rel.got)
 
.rela.got
*(.rela.got)
 
.rel.bss
*(.rel.bss)
 
.rela.bss
*(.rela.bss)
 
.rel.plt
*(.rel.plt)
 
.rela.plt
*(.rela.plt)
 
.text 0x00000000 0x1028
*(.vectors)
.vectors 0x00000000 0x70 /usr/lib/gcc/avr/4.3.0/../../../../avr/lib/avr5/crtm162.o
0x00000000 __vectors
0x00000000 __vector_default
*(.vectors)
*(.progmem.gcc*)
*(.progmem*)
0x00000070 . = ALIGN (0x2)
0x00000070 __trampolines_start = .
*(.trampolines)
.trampolines 0x00000070 0x0 linker stubs
*(.trampolines*)
0x00000070 __trampolines_end = .
*(.jumptables)
*(.jumptables*)
*(.lowtext)
*(.lowtext*)
0x00000070 __ctors_start = .
*(.ctors)
0x00000070 __ctors_end = .
0x00000070 __dtors_start = .
*(.dtors)
0x00000070 __dtors_end = .
SORT(*)(.ctors)
SORT(*)(.dtors)
*(.init0)
.init0 0x00000070 0x0 /usr/lib/gcc/avr/4.3.0/../../../../avr/lib/avr5/crtm162.o
0x00000070 __init
*(.init0)
*(.init1)
*(.init1)
*(.init2)
.init2 0x00000070 0xc /usr/lib/gcc/avr/4.3.0/../../../../avr/lib/avr5/crtm162.o
*(.init2)
*(.init3)
*(.init3)
*(.init4)
.init4 0x0000007c 0x16 /usr/lib/gcc/avr/4.3.0/avr5/libgcc.a(_copy_data.o)
0x0000007c __do_copy_data
.init4 0x00000092 0x10 /usr/lib/gcc/avr/4.3.0/avr5/libgcc.a(_clear_bss.o)
0x00000092 __do_clear_bss
*(.init4)
*(.init5)
*(.init5)
*(.init6)
*(.init6)
*(.init7)
*(.init7)
*(.init8)
*(.init8)
*(.init9)
.init9 0x000000a2 0x8 /usr/lib/gcc/avr/4.3.0/../../../../avr/lib/avr5/crtm162.o
*(.init9)
*(.text)
.text 0x000000aa 0x4 /usr/lib/gcc/avr/4.3.0/../../../../avr/lib/avr5/crtm162.o
0x000000aa __vector_22
0x000000aa __vector_1
0x000000aa __vector_24
0x000000aa __vector_12
0x000000aa __bad_interrupt
0x000000aa __vector_6
0x000000aa __vector_3
0x000000aa __vector_23
0x000000aa __vector_25
0x000000aa __vector_11
0x000000aa __vector_17
0x000000aa __vector_7
0x000000aa __vector_27
0x000000aa __vector_5
0x000000aa __vector_4
0x000000aa __vector_9
0x000000aa __vector_2
0x000000aa __vector_21
0x000000aa __vector_15
0x000000aa __vector_8
0x000000aa __vector_26
0x000000aa __vector_14
0x000000aa __vector_18
.text 0x000000ae 0x88 combine.o
0x000000ae updateMountSpeed
.text 0x00000136 0x13a driver.o
0x00000136 driverInit
0x00000154 __vector_16
.text 0x00000270 0x4c eq6.o
0x00000270 main
.text 0x000002bc 0x1aa paddle.o
0x000002bc paddleInit
0x000002d0 __vector_19
.text 0x00000466 0x94 pguide.o
0x00000466 pguideInit
0x00000482 __vector_10
.text 0x000004fa 0x394 serial.o
0x000004fa serialInit
0x0000050c __vector_20
.text 0x0000088e 0x164 sr.o
0x0000088e srSaveState
0x00000944 srLoadState
.text 0x000009f2 0x57a stepper.o
0x00000b38 setupRateTable
0x00000bf8 setDecSpeed
0x00000c22 stepperProcess
0x00000e96 __vector_13
0x00000b80 setTrackRate
0x00000c0e setTickRate
0x000009f2 stepperInit
0x00000be2 setRaSpeed
.text 0x00000f6c 0x0 /usr/lib/gcc/avr/4.3.0/avr5/libgcc.a(_mulsi3.o)
.text 0x00000f6c 0x0 /usr/lib/gcc/avr/4.3.0/avr5/libgcc.a(_divmodsi4.o)
.text 0x00000f6c 0x0 /usr/lib/gcc/avr/4.3.0/avr5/libgcc.a(_exit.o)
.text 0x00000f6c 0x0 /usr/lib/gcc/avr/4.3.0/avr5/libgcc.a(_copy_data.o)
.text 0x00000f6c 0x0 /usr/lib/gcc/avr/4.3.0/avr5/libgcc.a(_clear_bss.o)
.text 0x00000f6c 0x0 /usr/lib/gcc/avr/4.3.0/avr5/libgcc.a(_udivmodsi4.o)
0x00000f6c . = ALIGN (0x2)
*(.text.*)
.text.libgcc 0x00000f6c 0x3e /usr/lib/gcc/avr/4.3.0/avr5/libgcc.a(_mulsi3.o)
0x00000f6c __mulsi3
.text.libgcc 0x00000faa 0x36 /usr/lib/gcc/avr/4.3.0/avr5/libgcc.a(_divmodsi4.o)
0x00000faa __divmodsi4
.text.libgcc 0x00000fe0 0x0 /usr/lib/gcc/avr/4.3.0/avr5/libgcc.a(_exit.o)
.text.libgcc 0x00000fe0 0x0 /usr/lib/gcc/avr/4.3.0/avr5/libgcc.a(_copy_data.o)
.text.libgcc 0x00000fe0 0x0 /usr/lib/gcc/avr/4.3.0/avr5/libgcc.a(_clear_bss.o)
.text.libgcc 0x00000fe0 0x44 /usr/lib/gcc/avr/4.3.0/avr5/libgcc.a(_udivmodsi4.o)
0x00000fe0 __udivmodsi4
0x00001024 . = ALIGN (0x2)
*(.fini9)
.fini9 0x00001024 0x0 /usr/lib/gcc/avr/4.3.0/avr5/libgcc.a(_exit.o)
0x00001024 exit
0x00001024 _exit
*(.fini9)
*(.fini8)
*(.fini8)
*(.fini7)
*(.fini7)
*(.fini6)
*(.fini6)
*(.fini5)
*(.fini5)
*(.fini4)
*(.fini4)
*(.fini3)
*(.fini3)
*(.fini2)
*(.fini2)
*(.fini1)
*(.fini1)
*(.fini0)
.fini0 0x00001024 0x4 /usr/lib/gcc/avr/4.3.0/avr5/libgcc.a(_exit.o)
*(.fini0)
0x00001028 _etext = .
 
.data 0x00800100 0x90 load address 0x00001028
0x00800100 PROVIDE (__data_start, .)
*(.data)
.data 0x00800100 0x0 /usr/lib/gcc/avr/4.3.0/../../../../avr/lib/avr5/crtm162.o
.data 0x00800100 0x0 combine.o
.data 0x00800100 0xe driver.o
0x00800100 driveTbl
.data 0x0080010e 0x0 eq6.o
.data 0x0080010e 0x7 paddle.o
0x0080010e paddleGuideRate
.data 0x00800115 0x2 pguide.o
.data 0x00800117 0x1 serial.o
.data 0x00800118 0x0 sr.o
.data 0x00800118 0x77 stepper.o
0x00800119 microTable
0x00800179 rateConvert
0x00800139 halfTable
0x00800159 fullTable
0x00800118 transRatio
.data 0x0080018f 0x0 /usr/lib/gcc/avr/4.3.0/avr5/libgcc.a(_mulsi3.o)
.data 0x0080018f 0x0 /usr/lib/gcc/avr/4.3.0/avr5/libgcc.a(_divmodsi4.o)
.data 0x0080018f 0x0 /usr/lib/gcc/avr/4.3.0/avr5/libgcc.a(_exit.o)
.data 0x0080018f 0x0 /usr/lib/gcc/avr/4.3.0/avr5/libgcc.a(_copy_data.o)
.data 0x0080018f 0x0 /usr/lib/gcc/avr/4.3.0/avr5/libgcc.a(_clear_bss.o)
.data 0x0080018f 0x0 /usr/lib/gcc/avr/4.3.0/avr5/libgcc.a(_udivmodsi4.o)
*(.data*)
*(.rodata)
*(.rodata*)
*(.gnu.linkonce.d*)
0x00800190 . = ALIGN (0x2)
*fill* 0x0080018f 0x1 00
0x00800190 _edata = .
0x00800190 PROVIDE (__data_end, .)
 
.bss 0x00800190 0x65 load address 0x000010b8
0x00800190 PROVIDE (__bss_start, .)
*(.bss)
.bss 0x00800190 0x0 /usr/lib/gcc/avr/4.3.0/../../../../avr/lib/avr5/crtm162.o
.bss 0x00800190 0xa combine.o
0x00800197 rateOutput
0x00800190 rateInput
0x00800199 noTrack
.bss 0x0080019a 0x4 driver.o
.bss 0x0080019e 0x0 eq6.o
.bss 0x0080019e 0x3 paddle.o
.bss 0x008001a1 0x0 pguide.o
.bss 0x008001a1 0x12 serial.o
.bss 0x008001b3 0x0 sr.o
.bss 0x008001b3 0x2 stepper.o
0x008001b4 doHalfStep
0x008001b3 trackingRate
.bss 0x008001b5 0x0 /usr/lib/gcc/avr/4.3.0/avr5/libgcc.a(_mulsi3.o)
.bss 0x008001b5 0x0 /usr/lib/gcc/avr/4.3.0/avr5/libgcc.a(_divmodsi4.o)
.bss 0x008001b5 0x0 /usr/lib/gcc/avr/4.3.0/avr5/libgcc.a(_exit.o)
.bss 0x008001b5 0x0 /usr/lib/gcc/avr/4.3.0/avr5/libgcc.a(_copy_data.o)
.bss 0x008001b5 0x0 /usr/lib/gcc/avr/4.3.0/avr5/libgcc.a(_clear_bss.o)
.bss 0x008001b5 0x0 /usr/lib/gcc/avr/4.3.0/avr5/libgcc.a(_udivmodsi4.o)
*(.bss*)
*(COMMON)
COMMON 0x008001b5 0x4 eq6.o
0x008001b5 idleCtr
COMMON 0x008001b9 0x1 sr.o
0x008001b9 doSave
COMMON 0x008001ba 0x3b stepper.o
0x008001ba trackRateTable
0x008001c9 doDropInt
0x008001cb raState
0x008001dc decState
0x008001ed raExcitation
0x008001ef adjCtr
0x008001f1 decExcitation
0x008001f3 adjLimit
0x008001f5 PROVIDE (__bss_end, .)
0x00001028 __data_load_start = LOADADDR (.data)
0x000010b8 __data_load_end = (__data_load_start + SIZEOF (.data))
 
.noinit 0x008001f5 0x0
0x008001f5 PROVIDE (__noinit_start, .)
*(.noinit*)
0x008001f5 PROVIDE (__noinit_end, .)
0x008001f5 _end = .
0x008001f5 PROVIDE (__heap_start, .)
 
.eeprom 0x00810000 0x0
*(.eeprom*)
0x00810000 __eeprom_end = .
 
.fuse
*(.fuse)
*(.lfuse)
*(.hfuse)
*(.efuse)
 
.lock
*(.lock*)
 
.signature
*(.signature*)
 
.stab 0x00000000 0x6b4
*(.stab)
.stab 0x00000000 0x6b4 /usr/lib/gcc/avr/4.3.0/../../../../avr/lib/avr5/crtm162.o
 
.stabstr 0x00000000 0x54
*(.stabstr)
.stabstr 0x00000000 0x54 /usr/lib/gcc/avr/4.3.0/../../../../avr/lib/avr5/crtm162.o
 
.stab.excl
*(.stab.excl)
 
.stab.exclstr
*(.stab.exclstr)
 
.stab.index
*(.stab.index)
 
.stab.indexstr
*(.stab.indexstr)
 
.comment
*(.comment)
 
.debug
*(.debug)
 
.line
*(.line)
 
.debug_srcinfo
*(.debug_srcinfo)
 
.debug_sfnames
*(.debug_sfnames)
 
.debug_aranges
*(.debug_aranges)
 
.debug_pubnames
*(.debug_pubnames)
 
.debug_info
*(.debug_info)
*(.gnu.linkonce.wi.*)
 
.debug_abbrev
*(.debug_abbrev)
 
.debug_line
*(.debug_line)
 
.debug_frame
*(.debug_frame)
 
.debug_str
*(.debug_str)
 
.debug_loc
*(.debug_loc)
 
.debug_macinfo
*(.debug_macinfo)
OUTPUT(project.out elf32-avr)
LOAD linker stubs
/programy/C/avr/LX200/project.out
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes:
Added: svn:executable
+*
\ No newline at end of property
Added: svn:mime-type
+application/octet-stream
\ No newline at end of property
/programy/C/avr/LX200/serial.c
0,0 → 1,416
/*
* 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.
*/
void
serialInit(void)
{
// The serial guider is attached to USART1
 
// Set serial rate
UBRR1H = (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 interrupts
UCSR1C = _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 8
static 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;
else
raState.finPos = 1;
}
doSave = 1;
break;
 
case 'M':
/* Set DEC backlash mode */
decState.finNeg = decState.finPos = 0;
if (accum != 0)
{
if (sign)
decState.finNeg = 1;
else
decState.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 direction
if (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 direction
if (lxPos == 1)
{
// Stop slewing
upFlag = downFlag = leftFlag = rightFlag = 0;
dirChg = 1;
}
else if (lxPos == 2)
{
// Stop slewing is specified direction
switch (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;
} else
UDR1 = '?';
break;
 
case 'R': // Set guiding speed
if (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;
else
rateInput.serialDecRate = SPEED_0_X;
 
if (rightFlag)
rateInput.serialRaRate = guideRate;
else if (leftFlag)
rateInput.serialRaRate = -guideRate;
else
rateInput.serialRaRate = SPEED_0_X;
}
updateMountSpeed();
}
/programy/C/avr/LX200/serial.h
0,0 → 1,33
/*
* 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 software; 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.h,v 1.1.1.1 2004/02/22 08:12:42 dbh Exp $
*/
 
#ifndef _SERIAL_H_
#define _SERIAL_H_
 
/* Define the constants for the guiding input
*/
#define GUIDE_BAUD 9600
 
/* Initialization function */
void serialInit(void);
 
#endif /* _SERIAL_H_ */
 
/programy/C/avr/LX200/sr.c
0,0 → 1,194
/*
* 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 software; see the file COPYING. If not, write to
* the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
* MA 02111-1307, USA.
*
* $Id: sr.c,v 1.4 2004/04/04 10:32:50 dbh Exp $
*/
 
/* This file contains the code to save and restore the "configurable
* parameters" of the program. These are held in the internal EEPROM
*
* These functions are expected to be executed with interrupts enabled and
* will not return until complete.
*/
 
#include <avr/io.h>
#include <inttypes.h>
#include <avr/interrupt.h>
 
#include "stepper.h"
#include "paddle.h"
 
/* Define the staging structure used to save configurable parameters */
struct sr_s
{
uint8_t raFinPos;
uint8_t raFinNeg;
uint16_t raBacklash;
 
uint8_t decFinPos;
uint8_t decFinNeg;
uint16_t decBacklash;
 
uint8_t paddleGuideRate;
 
int8_t trackingRate;
uint8_t transRatio;
 
uint8_t csum; // Two's complement of other fields
};
 
volatile uint8_t doSave;
 
/* srSaveState() collects the configurable parameters from all over the
* system and saves them into the EEPROM
*
* Passed
* Nothing
*
* Returns
* Nothing
*
* Notes:
* This function assumes that the interrupts are enabled on
* entry.
*/
void
srSaveState(void)
{
struct sr_s state;
uint8_t i;
uint8_t *p;
 
/* Turn off the interrupts while we "snapshot" the current
* state
*/
cli();
 
/* Copy the current state */
state.raFinPos = raState.finPos;
state.raFinNeg = raState.finNeg;
state.raBacklash = raState.backlash;
 
state.decFinPos = decState.finPos;
state.decFinNeg = decState.finNeg;
state.decBacklash = decState.backlash;
 
state.paddleGuideRate = paddleGuideRate;
state.trackingRate = trackingRate;
state.transRatio = transRatio;
 
/* Reenable interrupts */
sei();
 
/* Calculate the checksum of the structure */
for (p = (uint8_t *)&state, i = 0 ; p != (uint8_t *)&state.csum ; )
i += *p++;
state.csum = i;
 
/* Write the complete structure into the EEPROM */
for (i = 0, p = (uint8_t *)&state ; i < sizeof(state) ; ++i, ++p)
{
/* Wait for EEWE to become zero (ie. EEPROM not writting) */
while (EECR & _BV(EEWE))
;
/* Setup the address */
EEARH = 0;
EEARL = i;
/* Put the data in place */
EEDR = *p;
 
/* Perform the write */
cli();
EECR = _BV(EEMWE);
EECR = _BV(EEMWE) | _BV(EEWE);
sei();
}
 
/* All done */
}
 
/* srLoadState() reads the configurable parameters from EEPROM and copies
* them to where they need to do.
*
* The data is protected by a checksum calculated when the data was
* saved.
*
* Passed
* Nothing
*
* Returns
* Nothing
*
* Notes:
* This interrupt does not change the interrupt state and does
* not return until all the data is read
*/
void
srLoadState(void)
{
struct sr_s state;
uint8_t i;
uint8_t *p;
 
/* Read the state data from the EEPROM */
for (i = 0, p = (uint8_t *)&state ; i < sizeof(state) ; ++i, ++p)
{
/* Wait for EEWE to become zero (ie. EEPROM not writting) */
while (EECR & _BV(EEWE))
;
/* Setup the address */
EEARH = 0;
EEARL = i;
 
/* Read the data. The device will stall until the data is
* ready
*/
EECR = _BV(EERE);
 
/* Get the data */
*p = EEDR;
}
 
/* Calculate the checksum of the structure. If it doesn't
* match then the data is either corrupt or not initialized
*
* Either way keep the current data
*/
for (p = (uint8_t *)&state, i = 0 ; p != (uint8_t *)&state.csum ; )
i += *p++;
if (state.csum != i)
return;
/* Copy the restored data to the current state */
raState.finPos = state.raFinPos;
raState.finNeg = state.raFinNeg;
raState.backlash = state.raBacklash;
 
decState.finPos = state.decFinPos;
decState.finNeg = state.decFinNeg;
decState.backlash = state.decBacklash;
paddleGuideRate = state.paddleGuideRate;
trackingRate = state.trackingRate;
transRatio = state.transRatio;
 
/* All done */
}
/programy/C/avr/LX200/sr.h
0,0 → 1,31
/*
* 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 software; see the file COPYING. If not, write to
* the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
* MA 02111-1307, USA.
*
* $Id: sr.h,v 1.2 2004/04/04 10:32:50 dbh Exp $
*/
#ifndef _SR_H_
#define _SR_H_
 
void srSaveState(void);
void srLoadState(void);
 
/* Flag to request parameter save */
extern volatile uint8_t doSave;
 
#endif /* _SR_H_ */
 
/programy/C/avr/LX200/stepper.c
0,0 → 1,765
/*
* 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 software; see the file COPYING. If not, write to
* the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
* MA 02111-1307, USA.
*
* $Id: stepper.c,v 1.9 2004/04/05 06:42:15 dbh Exp $
*/
 
/* This file converts the RA and DEC speed indications into drive values for
* the stepper motor coils.
*/
 
#include <inttypes.h>
#include <avr/io.h>
#include <avr/interrupt.h>
 
#include "eq6.h"
#include "combine.h"
 
#include "stepper.h"
 
int8_t trackingRate = 0;
uint8_t transRatio = DEF_TRANS_RATIO;
 
#define STEPS_PER_CYCLE 32L /* Steps per cycle (complete set of phases) */
#define CYCLES_PER_ROTN 12L /* Cycles per stepper motor rotation */
#define SIDERIAL_LCM (long)(3 * 16) /* Divides to give all speeds */
#define WORM_RATIO 180L /* Tooth on worm gear */
 
#define SECS_PER_SDAY 86164L /* 23h, 56m, 4s [Sidereal] */
#define SECS_PER_DAY 86400L /* 24h, 0m, 0s [Solar] */
#define SECS_PER_LDAY 89309L /* 1 + 1/27.3 sidereal days */
 
/* Structure holding information used to generate stepper pulses
* that generate motion at the siderial, solar, and lunar tracking
* rates
*/
struct trackRate_s
{
uint16_t div; // tint
uint16_t adj; // add/drop one int every ....
uint8_t doDropInt; // drop ints if true, add extra ints if false
} trackRateTable[3];
 
/* Define the stepping table. This defines the excitation to be used
* over a complete "cycle" of the stepper motor
*
* These are signed, four bit values. Coil 1 is the LSN, Coil 2 is the MSN
*/
 
#if 1
/* Step table. Values scaled such that one coil is always fully driven.
* Gives lots of torque, but the actual travel is lumpy
*/
uint8_t microTable[STEPS_PER_CYCLE] =
{
_EX_ENTRY(EX_0, EX_P_1), _EX_ENTRY(EX_P_0_2, EX_P_1),
_EX_ENTRY(EX_P_0_4, EX_P_1), _EX_ENTRY(EX_P_0_67, EX_P_1),
_EX_ENTRY(EX_P_1, EX_P_1), _EX_ENTRY(EX_P_1, EX_P_0_67),
_EX_ENTRY(EX_P_1, EX_P_0_4), _EX_ENTRY(EX_P_1, EX_P_0_2),
 
_EX_ENTRY(EX_P_1, EX_0), _EX_ENTRY(EX_P_1, EX_M_0_2),
_EX_ENTRY(EX_P_1, EX_M_0_4), _EX_ENTRY(EX_P_1, EX_M_0_67),
_EX_ENTRY(EX_P_1, EX_M_1), _EX_ENTRY(EX_P_0_67, EX_M_1),
_EX_ENTRY(EX_P_0_4, EX_M_1), _EX_ENTRY(EX_P_0_2, EX_M_1),
 
_EX_ENTRY(EX_0, EX_M_1), _EX_ENTRY(EX_M_0_2, EX_M_1),
_EX_ENTRY(EX_M_0_4, EX_M_1), _EX_ENTRY(EX_M_0_67, EX_M_1),
_EX_ENTRY(EX_M_1, EX_M_1), _EX_ENTRY(EX_M_1, EX_M_0_67),
_EX_ENTRY(EX_M_1, EX_M_0_4), _EX_ENTRY(EX_M_1, EX_M_0_2),
 
_EX_ENTRY(EX_M_1, EX_0), _EX_ENTRY(EX_M_1, EX_P_0_2),
_EX_ENTRY(EX_M_1, EX_P_0_4), _EX_ENTRY(EX_M_1, EX_P_0_67),
_EX_ENTRY(EX_M_1, EX_P_1), _EX_ENTRY(EX_M_0_67, EX_P_1),
_EX_ENTRY(EX_M_0_4, EX_P_1), _EX_ENTRY(EX_M_0_2, EX_P_1),
};
#else
/* Conventional microstep table. Torque vector with magnitude 1. Gives
* less torque that the first table, but the change in smoothness doesn't
* seem to be worth the loss of torque
*/
uint8_t microTable[STEPS_PER_CYCLE] =
{
_EX_ENTRY(EX_0, EX_P_1), _EX_ENTRY(EX_P_0_2, EX_P_1),
_EX_ENTRY(EX_P_0_2, EX_P_1), _EX_ENTRY(EX_P_0_4, EX_P_0_67),
_EX_ENTRY(EX_P_0_67, EX_P_0_67), _EX_ENTRY(EX_P_0_67, EX_P_0_4),
_EX_ENTRY(EX_P_1, EX_P_0_2), _EX_ENTRY(EX_P_1, EX_P_0_2),
 
_EX_ENTRY(EX_P_1, EX_0), _EX_ENTRY(EX_P_1, EX_M_0_2),
_EX_ENTRY(EX_P_1, EX_M_0_2), _EX_ENTRY(EX_P_0_67, EX_M_0_4),
_EX_ENTRY(EX_P_0_67, EX_M_0_67), _EX_ENTRY(EX_P_0_4, EX_M_0_67),
_EX_ENTRY(EX_P_0_2, EX_M_1), _EX_ENTRY(EX_P_0_2, EX_M_1),
 
_EX_ENTRY(EX_0, EX_M_1), _EX_ENTRY(EX_M_0_2, EX_M_1),
_EX_ENTRY(EX_M_0_2, EX_M_1), _EX_ENTRY(EX_M_0_4, EX_M_0_67),
_EX_ENTRY(EX_M_0_67, EX_M_0_67), _EX_ENTRY(EX_M_0_67, EX_M_0_4),
_EX_ENTRY(EX_M_1, EX_M_0_2), _EX_ENTRY(EX_M_1, EX_M_0_2),
 
_EX_ENTRY(EX_M_1, EX_0), _EX_ENTRY(EX_M_1, EX_P_0_2),
_EX_ENTRY(EX_M_1, EX_P_0_2), _EX_ENTRY(EX_M_0_67, EX_P_0_4),
_EX_ENTRY(EX_M_0_67, EX_P_0_67), _EX_ENTRY(EX_M_0_4, EX_P_0_67),
_EX_ENTRY(EX_M_0_2, EX_P_1), _EX_ENTRY(EX_M_0_2, EX_P_1)
};
#endif /* 0 */
 
uint8_t halfTable[STEPS_PER_CYCLE] =
{
_EX_ENTRY(EX_P_1, EX_P_1), _EX_ENTRY(EX_P_1, EX_P_1),
_EX_ENTRY(EX_P_1, EX_P_1), _EX_ENTRY(EX_P_1, EX_P_1),
 
_EX_ENTRY(EX_P_1, EX_0), _EX_ENTRY(EX_P_1, EX_0),
_EX_ENTRY(EX_P_1, EX_0), _EX_ENTRY(EX_P_1, EX_0),
 
_EX_ENTRY(EX_P_1, EX_M_1), _EX_ENTRY(EX_P_1, EX_M_1),
_EX_ENTRY(EX_P_1, EX_M_1), _EX_ENTRY(EX_P_1, EX_M_1),
 
_EX_ENTRY(EX_0, EX_M_1), _EX_ENTRY(EX_0, EX_M_1),
_EX_ENTRY(EX_0, EX_M_1), _EX_ENTRY(EX_0, EX_M_1),
 
_EX_ENTRY(EX_M_1, EX_M_1), _EX_ENTRY(EX_M_1, EX_M_1),
_EX_ENTRY(EX_M_1, EX_M_1), _EX_ENTRY(EX_M_1, EX_M_1),
 
_EX_ENTRY(EX_M_1, EX_0), _EX_ENTRY(EX_M_1, EX_0),
_EX_ENTRY(EX_M_1, EX_0), _EX_ENTRY(EX_M_1, EX_0),
 
_EX_ENTRY(EX_M_1, EX_P_1), _EX_ENTRY(EX_M_1, EX_P_1),
_EX_ENTRY(EX_M_1, EX_P_1), _EX_ENTRY(EX_M_1, EX_P_1),
 
_EX_ENTRY(EX_0, EX_P_1), _EX_ENTRY(EX_0, EX_P_1),
_EX_ENTRY(EX_0, EX_P_1), _EX_ENTRY(EX_0, EX_P_1),
};
 
uint8_t fullTable[STEPS_PER_CYCLE] =
{
_EX_ENTRY(EX_P_1, EX_P_1), _EX_ENTRY(EX_P_1, EX_P_1),
_EX_ENTRY(EX_P_1, EX_P_1), _EX_ENTRY(EX_P_1, EX_P_1),
_EX_ENTRY(EX_P_1, EX_P_1), _EX_ENTRY(EX_P_1, EX_P_1),
_EX_ENTRY(EX_P_1, EX_P_1), _EX_ENTRY(EX_P_1, EX_P_1),
 
_EX_ENTRY(EX_P_1, EX_M_1), _EX_ENTRY(EX_P_1, EX_M_1),
_EX_ENTRY(EX_P_1, EX_M_1), _EX_ENTRY(EX_P_1, EX_M_1),
_EX_ENTRY(EX_P_1, EX_M_1), _EX_ENTRY(EX_P_1, EX_M_1),
_EX_ENTRY(EX_P_1, EX_M_1), _EX_ENTRY(EX_P_1, EX_M_1),
 
_EX_ENTRY(EX_M_1, EX_M_1), _EX_ENTRY(EX_M_1, EX_M_1),
_EX_ENTRY(EX_M_1, EX_M_1), _EX_ENTRY(EX_M_1, EX_M_1),
_EX_ENTRY(EX_M_1, EX_M_1), _EX_ENTRY(EX_M_1, EX_M_1),
_EX_ENTRY(EX_M_1, EX_M_1), _EX_ENTRY(EX_M_1, EX_M_1),
 
_EX_ENTRY(EX_M_1, EX_P_1), _EX_ENTRY(EX_M_1, EX_P_1),
_EX_ENTRY(EX_M_1, EX_P_1), _EX_ENTRY(EX_M_1, EX_P_1),
_EX_ENTRY(EX_M_1, EX_P_1), _EX_ENTRY(EX_M_1, EX_P_1),
_EX_ENTRY(EX_M_1, EX_P_1), _EX_ENTRY(EX_M_1, EX_P_1)
};
 
/* Setup the table of divisors of the siderial interrupt use to
* achieve the required tracking rate.
*/
struct
{
uint8_t divisor; // Siderial interrupts per step
uint8_t flags; // Control flags
#define USE_RELAY 0 // Activate the magic relay [RA only]
#define USE_MICRO 1 // Use the microstep table
} rateConvert[] =
{
[SPEED_0_X] = {1, _BV(USE_MICRO)}, // Special value
[SPEED_0_33_X] = {3 * SIDERIAL_LCM, _BV(USE_MICRO)},
[SPEED_0_67_X] = {(3 * SIDERIAL_LCM) / 2, _BV(USE_MICRO)},
[SPEED_1_X] = {SIDERIAL_LCM, _BV(USE_MICRO)},
[SPEED_1_33_X] = {(3 * SIDERIAL_LCM) / 4, _BV(USE_MICRO)},
[SPEED_1_67_X] = {(3 * SIDERIAL_LCM) / 5, _BV(USE_MICRO)},
[SPEED_2_X] = {SIDERIAL_LCM / 2, _BV(USE_MICRO) | _BV(USE_RELAY)},
[SPEED_4_X] = {SIDERIAL_LCM / 4, _BV(USE_MICRO) | _BV(USE_RELAY)},
[SPEED_8_X] = {SIDERIAL_LCM / 8, _BV(USE_MICRO) | _BV(USE_RELAY)},
[SPEED_16_X] = {SIDERIAL_LCM / 16, _BV(USE_RELAY)},
 
[SPEED_SPIN] = {SIDERIAL_LCM / 16, 0}
};
 
/* Create the instance of the stepper excitation info
*/
struct excitation_s raExcitation;
struct excitation_s decExcitation;
 
/* Define instances of stepper state info
*/
struct stepState_s raState;
struct stepState_s decState;
uint8_t doHalfStep = 0;
 
/* Info for tracking rate correction */
uint16_t adjCtr;
uint16_t adjLimit;
uint16_t doDropInt;
 
/* stepperInit() initializes the state of the stepper code.
*
* The current implementation uses a single 16-bit timer with a fixed
* period shared between RA and DEC.
*
* Passed:
* Nothing
*
* Returns:
* Nothing
*
* Notes:
* An alternate implementation would use a pair of 16 bit timers with
* their timeouts set to the step period. This would minimize the
* number of interrupts, but would take an extra timer.
*
* The current implementation is preferred until we're sure the extra
* timer isn't needed elsewhere or until there is a performance
* problem caused by the extra interrupt load caused by having
* multiple interrupts per step.
*/
void
stepperInit(void)
{
/* Initialize the excitation state */
raExcitation.excitation = EX_0;
raExcitation.useRelay = 0;
raState.pExcite = &raExcitation;
decExcitation.excitation = EX_0;
decState.pExcite = &decExcitation;
 
/* Initialize the siderial rate timer */
 
TIMSK |= _BV(OCIE1A);
}
 
 
/* calculateRateEntry() creates an entry in the rate table
*
* Passed:
* pEntry Pointer to entry
* transRatio Transmission (gearbox) ratio
* secPerDay Seconds per sideral/lunar/solar dat
*
* Returns:
* nothing
*/
static void
calculateRateEntry( struct trackRate_s *pEntry,
uint8_t transRatio,
uint32_t secsPerDay)
{
/* To do this calculation would (without optimization) would need about
* 40 bit arithmetic, which isn't available in this copmiler.
*
* To get the required precision down to below 32 bits the
* numerator and denominator are divided through by 1280.
*
* This gives an exact result for 8/16 MHz with a 180 tooth wormgear
*
* The formula gives the clock divisor for the siderial clock interrupt
* divisor:
*
* (CLK_RATE * SECS_PER_SDAY) / (MECH_DIV * STEPS_PER_CYCLE * SIDERIAL_LCM)
*
* This, by itself, does not give great accuracy because the divisor is
* an integer. With a typical divisor of about 1500 there is a maximum error
* of about 1 / 3000 (0.033%).
*
* For most purposes this should be accurate enough, but the accuracy can
* be improved by adding or dropping the occasional interrupt.
*
* This function calculates both the divisor and how often to
* drop an timer interrupt, or to insert an extra one to improve the
* timer accuracy
*/
#define CLK_FACTOR 1280L // Common divisor for numerator & divisor
#define WORM_CLK_LCM (WORM_RATIO * CYCLES_PER_ROTN * SIDERIAL_LCM)
#define SCALED_CLK (CLK_RATE / CLK_FACTOR)
 
#define MIN_DIV 1000 /* Minimum allowed divisor to avoid
* interrupt saturation
*/
long top;
long bottom;
long div; // Clock divisor for interrupt generation
long adj; // Add/drop adjustment
long adj_denom;
 
top = SCALED_CLK * secsPerDay;
bottom = (WORM_CLK_LCM / CLK_FACTOR) * transRatio * STEPS_PER_CYCLE;
 
/* Calculate divisor, round to nearest integer */
div = (top + (bottom / 2)) / bottom;
 
/* Calculate adjustment */
adj = SCALED_CLK * secsPerDay;
adj_denom = (div * bottom) - (SCALED_CLK * secsPerDay);
 
adj /= adj_denom;
 
/* Fill in the entry */
pEntry->div = (div > MIN_DIV) ? div : MIN_DIV;
if (adj >= 0)
{
pEntry->doDropInt = 0;
pEntry->adj = (adj >= (1L << 16)) ? 0 : adj;
}
else
{
pEntry->doDropInt = 1;
pEntry->adj = (adj <= -(1L << 16)) ? 0 : -adj;
}
}
 
/* setupRateTable() fills the tracking rate table with values
* that are correct for the transmission ratio of the system.
*
* Passed
* transRatio Transmission (gearbox) ratio
*
* Returns
* nothing
*/
void
setupRateTable(uint8_t transRatio)
{
calculateRateEntry(&trackRateTable[0], transRatio, SECS_PER_SDAY);
calculateRateEntry(&trackRateTable[1], transRatio, SECS_PER_DAY);
calculateRateEntry(&trackRateTable[2], transRatio, SECS_PER_LDAY);
}
 
/* setTrackRate() sets the tracking rate used by the stepper module.
*
* Passed:
* rate The tracking rate (index)
*
* Returns:
* Nothing
*
* Note:
* If an illegal rate is entered the current rate will not be changed
*/
void
setTrackRate(int8_t rate)
{
/* If the track rate is <0 then disable siderial rate use in
* combine.c and return, leaving the current clock steup
*/
trackingRate = rate;
 
if (rate < 0)
{
noTrack = 1;
return;
}
 
/* Do nothing if the rate is not supported */
if (rate >= (sizeof(trackRateTable) / sizeof(struct trackRate_s)))
return;
/* Enable tracking */
noTrack = 0;
 
/* Update the tracking rate timer */
OCR1A = trackRateTable[rate].div;
TCNT1 = 0;
TCCR1A = 0;
TCCR1B = _BV(WGM12) | _BV(CS10);
 
/* Update adjustment data */
adjCtr = 0;
adjLimit = trackRateTable[rate].adj;
doDropInt = trackRateTable[rate].doDropInt;
}
 
/* setSpeed() is called by by the combiner to set the requested speed
* for the axis
*
* Passed:
* pState Axis state
* rate Requested rate
*
* Returns:
* Nothing
*
* Notes:
* setRaSpeed() and setDecSpeed() are wrappers used by the combiner
*/
static void
setSpeed(struct stepState_s *pState, int8_t speed)
{
/* If the current speed is zero then start the clock */
if (pState->clkDivRatio == 0)
pState->clkDivRatio = 1; // Almost immediate clock
 
pState->reqSpeed = speed;
}
 
void
setRaSpeed(int8_t speed)
{
setSpeed(&raState, speed);
}
 
void
setDecSpeed(int8_t speed)
{
setSpeed(&decState, speed);
}
 
/* setTickRate() is called by the state machine to set the clock interrupt
* rate.
*
* Passed
* pState The axis state
* tickRate The clock rate to set
*
* Returns
* nothing
*/
void
setTickRate(struct stepState_s *pState, uint8_t tickRate)
{
pState->clkDivRatio = rateConvert[tickRate].divisor;
}
/* stepperProcess is the state machine that makes this whole thing
* work! It is executed each axis interrupt to run the state machine
* that handles operation and backlash processing.
*
* Like the other state machines in the program it takes advantage
* of the GNU computed goto to operate very efficiently.
*
* Passed
* pState The axis state
*
* Returns
* Nothing
*/
#define _GET_TABLE(f) ((f) ? (doHalfStep ? halfTable : microTable) : fullTable)
 
void
stepperProcess(struct stepState_s *pState)
{
// Step up the initial state pointer
if (pState->pState == 0)
pState->pState = &&enter_idle_pos;
 
/* Make sure both finPos and finNeg are not set - that will
* lead to a loop as the code tries to meet both!
*/
if (pState->finPos && pState->finNeg)
pState->finPos = pState->finNeg = 0;
 
// Jump to the current state
goto *pState->pState;
 
/* There are six states in the machine
*
* - idle_pos Idle (last move in positive direction)
* - spin_pos Taking up backlash in positive direction
* - move_pos Moving in the positive direction
*
* There are "negative" versions of these states.
*
* Just to make things simple we use the "idle" state as a central
* decision point.
*/
 
enter_idle_pos:
/* We're about to move into the idle_pos state. We end up here if
* we're stopping or changing direction
*/
if (pState->reqSpeed == SPEED_0_X)
{
/* We're going to stop - if we're in the correct direction then
* stop, else start spinning in the other direction
*/
if (pState->finNeg)
goto enter_spin_neg;
else
{
/* Stop now! */
setTickRate(pState, SPEED_0_X);
pState->pExcite->excitation = EX_0;
pState->pExcite->useRelay = 0;
 
// For this state just call the entry point each interrupt
pState->pState = &&enter_idle_pos;
}
}
else if (pState->reqSpeed > SPEED_0_X)
{
/* We're now moving in the positive direction. As we are
* already engaged in the positive direction we can start
* running
*/
goto enter_move_pos;
}
else
{
/* Must be a negative move direction. Take up the backlash
* in the negative direction
*/
goto enter_spin_neg;
}
 
return;
 
enter_idle_neg:
/* We're about to move into the idle_neg state. We end up here if
* we're stopping or changing direction
*/
if (pState->reqSpeed == SPEED_0_X)
{
/* We're going to stop - if we're in the correct direction then
* stop, else start spinning in the other direction
*/
if (pState->finPos)
goto enter_spin_pos;
else
{
/* Stop now! */
setTickRate(pState, SPEED_0_X);
pState->pExcite->excitation = EX_0;
pState->pExcite->useRelay = 0;
 
// For this state just call the entry point each interrupt
pState->pState = &&enter_idle_neg;
}
}
else if (pState->reqSpeed < SPEED_0_X)
{
/* We're now moving in the negative direction. As we are
* already engaged in the negative direction we can start
* running
*/
goto enter_move_neg;
}
else
{
/* Must be a positive move direction. Take up the backlash
* in the positive direction
*/
goto enter_spin_pos;
}
return;
 
enter_spin_pos:
/* Spin in the positive direction to take up backlash in the
* gear chain
*/
if (pState->backlash == 0)
{
/* No backlash - go to the idle_pos state which will take us
* to the correct place
*/
goto enter_idle_pos;
}
else
{
uint8_t flags = rateConvert[SPEED_SPIN].flags;
/* There is a backlash setting - get ready to spin! */
pState->count = 0;
 
setTickRate(pState, SPEED_SPIN);
pState->pTable = _GET_TABLE(flags & _BV(USE_MICRO));
pState->pExcite->useRelay = flags & _BV(USE_RELAY);
pState->pState = &&run_spin_pos;
// Fall through to run the spin state
}
 
run_spin_pos:
// Update excitation value
pState->pExcite->excitation = pState->pTable[pState->stepCtr];
pState->stepCtr = (pState->stepCtr + 1) & (STEPS_PER_CYCLE - 1);
 
/* Check the count. If we've spun enough then go back to the
* idle_pos state which will send us the right way
*/
if (++pState->count > pState->backlash)
goto enter_idle_pos;
return;
 
enter_spin_neg:
/* Spin in the negative direction to take up backlash in the
* gear chain
*/
if (pState->backlash == 0)
{
/* No backlash - go to the idle_neg state which will take us
* to the correct place
*/
goto enter_idle_neg;
}
else
{
uint8_t flags = rateConvert[SPEED_SPIN].flags;
/* There is a backlash setting - get ready to spin! */
pState->count = 0;
 
setTickRate(pState, SPEED_SPIN);
pState->pTable = _GET_TABLE(flags & _BV(USE_MICRO));
pState->pExcite->useRelay = flags & _BV(USE_RELAY);
pState->pState = &&run_spin_neg;
 
// Fall through to run the spin state
}
 
run_spin_neg:
// Update excitation value
pState->pExcite->excitation = pState->pTable[pState->stepCtr];
pState->stepCtr = (pState->stepCtr - 1) & (STEPS_PER_CYCLE - 1);
 
/* Check the count. If we've spun enough then go back to the
* idle_neg state which will send us the right way
*/
if (++pState->count > pState->backlash)
goto enter_idle_neg;
 
return;
 
enter_move_pos:
/* Start moving in the positive direction. Save the requested
* speed as the current speed so we can detect changes in the
* requested speed
*/
if (pState->reqSpeed > SPEED_0_X)
{
uint8_t flags = rateConvert[pState->reqSpeed].flags;
setTickRate(pState, pState->reqSpeed);
pState->pTable = _GET_TABLE(flags & _BV(USE_MICRO));
pState->pExcite->useRelay = flags & _BV(USE_RELAY);
pState->pState = &&run_move_pos;
pState->curSpeed = pState->reqSpeed;
 
/* Fall through to move action */
}
else
{
/* We're not going in the positive direction any more */
goto enter_idle_pos;
}
return;
 
run_move_pos:
if (pState->curSpeed == pState->reqSpeed)
{
/* We're still moving at the same speed. Do it
*/
pState->pExcite->excitation = pState->pTable[pState->stepCtr];
pState->stepCtr = (pState->stepCtr + 1) & (STEPS_PER_CYCLE - 1);
}
else
{
/* Go baxk to idle_pos that will decide the next state */
goto enter_idle_pos;
}
return;
 
enter_move_neg:
/* Start moving in the negative direction. Save the requested
* speed as the current speed so we can detect changes in the
* requested speed
*/
if (pState->reqSpeed < SPEED_0_X)
{
uint8_t flags = rateConvert[-pState->reqSpeed].flags;
setTickRate(pState, -pState->reqSpeed);
pState->pTable = _GET_TABLE(flags & _BV(USE_MICRO));
pState->pExcite->useRelay = flags & _BV(USE_RELAY);
pState->pState = &&run_move_neg;
pState->curSpeed = pState->reqSpeed;
 
/* Fall through to move action */
}
else
{
/* We're not going in the negative direction any more. Stop and
* continue from there
*/
goto enter_idle_neg;
}
return;
 
run_move_neg:
if (pState->curSpeed == pState->reqSpeed)
{
/* We're still moving at the same speed. Do it
*/
pState->pExcite->excitation = pState->pTable[pState->stepCtr];
pState->stepCtr = (pState->stepCtr - 1) & (STEPS_PER_CYCLE - 1);
}
else
{
/* Go back to the idle_neg. It will determine the next state */
goto enter_idle_neg;
}
return;
}
 
/* stepperInt() is called each siderial interrupt. This is divided down
* in software to derive the actual stepper timing.
*
* Passed:
* Nothing
*
* Returns:
* Nothing
*/
SIGNAL(SIG_OUTPUT_COMPARE1A)
{
/* Update the tracking rate adjustment counter */
++adjCtr;
 
/* If we're dropping then drop if necessary */
if (doDropInt && adjLimit && adjCtr >= adjLimit)
{
/* Drop interrupt */
adjCtr = 0;
return;
}
 
do_again:
/* Run the state machine for the DEC and RA axis */
if (raState.clkDivRatio != 0 && ++raState.divCtr >= raState.clkDivRatio)
{
// Execute the RA state machine
raState.divCtr = 0;
stepperProcess(&raState);
}
 
if (decState.clkDivRatio != 0 && ++decState.divCtr >= decState.clkDivRatio)
{
// Execute the DEC state machine
decState.divCtr = 0;
stepperProcess(&decState);
}
 
/* If we need to "insert" an interrupt do it now */
if (!doDropInt && adjLimit && adjCtr >= adjLimit)
{
adjCtr = 0;
goto do_again;
}
}
/programy/C/avr/LX200/stepper.h
0,0 → 1,103
/*
* 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 software; see the file COPYING. If not, write to
* the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
* MA 02111-1307, USA.
*
* $Id: stepper.h,v 1.7 2004/04/05 06:42:15 dbh Exp $
*/
 
#ifndef _STEPPER_H_
#define _STEPPER_H_
 
/* Define the encoding used to hold the exictation values for each
* stepper coil.
*/
#define _EX_ENTRY(c1, c2) (((c1) << 4) | (c2))
#define _GET_C1(e) ((e) >> 4)
#define _GET_C2(e) ((e) & 0xf)
 
#define EX_0 0x0 // Inactive
#define EX_P_0_2 0x1 // +0.2 active
#define EX_P_0_4 0x2 // +0.4 active
#define EX_P_0_67 0x3 // +0.67 active
#define EX_P_1 0x4 // +Active
 
#define EX_M_0_2 0x9 // -0.2 active
#define EX_M_0_4 0xa // -0.4 active
#define EX_M_0_67 0xb // -0.67 active
#define EX_M_1 0xc // -Active
 
/* Define the struture used to pass excitation information from
* the stepper module to the excitation module
*/
struct excitation_s
{
uint8_t excitation;
uint8_t useRelay;
};
 
extern struct excitation_s raExcitation;
extern struct excitation_s decExcitation;
 
/* Define a structure to hold the current "state" for each axis. This
* allows up to use the same code for both axis, so I don't feel
* tempted to skimp on the features
*/
struct stepState_s
{
// Input (from the combiner)
int8_t reqSpeed; // Rate requested
 
// Output (to the driver)
struct excitation_s *pExcite;
 
// Configuration
uint16_t backlash; // #steps to counteract backlash
uint8_t finPos; // Finish movement in positive direction
uint8_t finNeg; // Finish movement in negative direction
 
// Machine state
uint8_t stepCtr; // Current step in cycle
int8_t curSpeed; // Current rate (when moving after spin)
void *pState; // State pointer
uint16_t count; // Counter used in states
 
uint8_t *pTable; // Current step table
 
// Support function state
uint8_t clkDivRatio; // Current clock div
uint8_t divCtr; // Clock division counter
};
 
/* These are held in stepper.c */
extern struct stepState_s raState;
extern struct stepState_s decState;
extern int8_t trackingRate;
extern uint8_t transRatio;
 
/* Prototypes */
void stepperInit(void);
void setRaSpeed(int8_t speed);
void setDecSpeed(int8_t speed);
 
void setupRateTable(uint8_t transRatio);
void setTrackRate(int8_t rate);
 
/* DEBUG: Uses half step instread of microstep if true */
extern uint8_t doHalfStep;
 
#endif /* _STEPPER_H_ */