diff --git a/AstroEQ-Firmware/AstroEQ5.ino b/AstroEQ-Firmware/AstroEQ5.ino deleted file mode 100644 index 819445c9d28e96d1d69b57ca667dc1d24bc8deda..0000000000000000000000000000000000000000 --- a/AstroEQ-Firmware/AstroEQ5.ino +++ /dev/null @@ -1,934 +0,0 @@ -/* - Code written by Thomas Carpenter 2012 - - With thanks Chris over at the EQMOD Yahoo group for explaining the Skywatcher protocol - - - Equatorial mount tracking system for integration with EQMOD using the Skywatcher/Syntia - communication protocol. - - Works with EQ5, HEQ5, and EQ6 mounts (Not EQ3-2, they have a different gear ratio) - - Current Verison: 5.4 -*/ - -//Only works with ATmega162, and Arduino Mega boards (1280 and 2560) -#if defined(__AVR_ATmega162__) || defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) -//Just in case it was defined somewhere else, we cant be having that. -#ifdef USEHIGHSPEEDMODE -#undef USEHIGHSPEEDMODE -#endif - -#include "synta.h" //Synta Communications Protocol. - - -//The system needs to be configured to suit your mount. -//Either use the instructions below and calculate the values yourself, -//or use the "Initialisation Variable Calculator.xlsx" file. -// -// The line to configure the mount follows these instructions! -// -// -// Format: -// -//Synta synta( e [1281], a, b, g [16], s, scalar); //same ratio for each axis -//Synta synta( e [1281], a RA, a DEC, b RA, b DEC, g [16], s RA, s DEC, scalar); //different ratio for each axis -// -// e = version number (this doesnt need chaning) -// -// a = number of steps per complete axis revolution. -// aVal = 64 * motor steps per revolution * ratio -// where ratio is the gear ratio from motor to axis. E.g. for an HEQ5 mount, this is 705 -// and motor steps is how many steps per one revolution of the motor. E.g. a 1.8degree stepper has 200 steps/revolution -// -// b = sidereal rate. This again depends on number of microsteps per step. -// bVal = 620 * aVal / 86164.0905 (round UP to nearest integer) -// -// g = high speed multiplyer. This is the EQMOD recommended default. In highspeed mode, the step rate will be 16 times larger. -// -// s = steps per worm revolution -// sVal = aVal / Worm Gear Teeth -// where worm gear teeth is how many teeth on the main worm gear. E.g. for an HEQ5 this is 135 -// -// scalar = reduces the number reported to EQMOD, whilst not affecting mount behavior. -// This is such that: aVal/scalar < 10000000 (ten million). The max allowed is 15. If a number larger than this is required, let me know and I will see what can be done. -// -// -// Examples: -// -// mount specifics can be found here: http://tech.groups.yahoo.com/group/EQMOD/database?method=reportRows&tbl=5 -// -// Summary of mounts (Untested): -// -// HEQ5 Pro/Syntrek/SynscanUpgrade: -// aVal = 9024000 -// bVal = 64933 -// sVal = 66845 -// scalar = 1 -// -// EQ6 Pro/Syntrek/SynscanUpgrade: -// aVal = 9024000 -// bVal = 64933 -// sVal = 50133 -// scalar = 1 -// -// EQ5 Synscan/SynscanUpgrade: -// aVal = 9011200 -// bVal = 64841 -// sVal = 31289 -// scalar = 1 -// -// EQ4/5 Mount upgraded with the Dual motor kit (non Goto) -- This is the only one I have tested, the others are theoretical -// aVal = 26542080 -// bVal = 190985 -// sVal = 184320 -// scalar = 10 -// -// EQ3-2 Mount upgraded with the Dual motor kit (non Goto) -// aVal1 = 23961600 -// aVal2 = 11980800 -// bVal1 = 172417 -// bVal2 = 86209 -// sVal1 = 184320 -// sVal2 = 184320 -// scalar = 10 //scales aVal and sVal with no error -// -// Other mounts: -// aVal = 64 * motor steps per revolution * ratio -// bVal = 620 * aVal / 86164.0905 (round UP to nearest whole number) -// sVal = aVal / Worm Gear Teeth (round to nearest whole number) -// scalar = depends on aVal, see notes below -// -//Create an instance of the mount -//If aVal is roughly greater than 10000000 (ten million), the number needs to be scaled down by some factor -//to make it smaller than that limit. In my case I have chosen 10 as it nicely scales the - - -//------------------------------------------------------------- -//INITIALISATION CODE ----------------------------------------- -//------------------------------------------------------------- - -//This is the initialistation code. If using the excel file, replace this line with what it gives. - -//Example for same ratio per axis -//Synta synta(1281, 9011200, 64841, 16, 31289, 1); -//Example for different ratio per axis (see excel file). -//Synta synta(1281, 23961600, 11980800, 172417, 86209, 184320, 184320, 16, 10); -Synta synta(1281, 1664000, 832000, 11974, 5987, 12800, 12800, 16, 1); - - -//------------------------------------------------------------- -//USER CONFIGURATION ------------------------------------------ -//------------------------------------------------------------- - -//This is for HARDWARE versions prior to 4.0. This includes all versions using Arduino Mega board. -//#define LEGACY_MODE 1 - -//These allow you to configure the speed at which the mount moves when executing goto commands. (Lower is faster) -//It can be calculated from the value given for speed how fast the mount will move: -//seconds per revolution = speed * aVal / bVal -//Or in terms of how many times the sidereal rate it will move -//ratio = 620 / speed -// -//When changing the speed, change the number below, ensuring to suffix it with the letter 'L' -#define NORMALGGOTOSPEED 320L //This is defined as Speed with the letter 'L' appended -#define FASTGOTOSPEED 176L -//Normally, 'fast' should be the fastest you want the mount to move, and 'normal' should be around half that. - -//This needs to be uncommented for those using the Pololu A4983 Driver board. Otherwise DRV8824 will be assumed. -//#define POLOLU_A498x 1 - -//Define the two axes (change 0 to 1 if R.A. and Dec. motors are swapped - i.e. RA moves instead of DEC and vice versa) -#define RA 0 -#define DC (1 - RA) //dont change this one. If RA=0, then DEC=(1-0)=1. If RA=1, then DEC=(1-1)=0 - -//If motors turn in the wrong direction - i.e. a West slew moves East, and a North slew moves South, uncomment the line for the motors to be reversed: -//#define REVERSEDIRECTION_RA 1 -//#define REVERSEDIRECTION_DEC 1 - -//Uncomment the following #define to use a Beta function which increases motor torque when moving at highspeed by switching from 16th ustep to half stepping. -//Note, this is very much a Beta, and requires mode pins M2 and M0 of the DRV8824 chips to be connected to the arduino. -//It seems to work, but it isn't fully tested, so is turned off by default. - -//#define USEHIGHSPEEDMODE 1 - - - -//------------------------------------------------------------- -//DO NOT EDIT ANYTHING BELOW THIS LINE------------------------- -//------------------------------------------------------------- - -//#define DEBUG 1 - -unsigned long gotoPosn[2] = {0,0}; //where to slew to -unsigned int timerOVF[2][64]; //Clock section of each of the 64 microsteps -unsigned long timerCountRate; -unsigned long maxTimerOVF; //Minimum allowable clock count - -#define PULSEWIDTH16 64 -#define PULSEWIDTH2 8 -#define PULSEWIDTH_25 1 - -#ifdef USEHIGHSPEEDMODE -#define PULSEWIDTH16F 8 -#define PULSEWIDTH2F 1 -#define PULSEWIDTH_25F 1 -#endif - -#ifdef REVERSEDIRECTION_DEC -#define DEC_REVERSE HIGH -#define DEC_FORWARD LOW -#else -#define DEC_REVERSE LOW -#define DEC_FORWARD HIGH -#endif -#ifdef REVERSEDIRECTION_RA -#define RA_REVERSE HIGH -#define RA_FORWARD LOW -#else -#define RA_REVERSE LOW -#define RA_FORWARD HIGH -#endif - -#if (RA == 0) -#define ENCODE_DIRECTION_INIT() {{RA_REVERSE,RA_FORWARD},{DEC_REVERSE,DEC_FORWARD}} -#else -#define ENCODE_DIRECTION_INIT() {{DEC_REVERSE,DEC_FORWARD},{RA_REVERSE,RA_FORWARD}} -#endif - -#if defined(__AVR_ATmega162__) - -//Pins -const char statusPin = 13; -const char resetPin[2] = {15,14}; -const char errorPin[2] = {2,6}; -const char dirPin[2] = {3,7}; -const char enablePin[2] = {4,8}; -const char stepPin[2] = {5,30}; -const char oldStepPin1 = 9; //Note this has changed due to a mistake I had made originally. The original will be set as an input so hardware can be corrected by shorting with new pin -#ifdef LEGACY_MODE -const char modePins[2][2] = {{16,17},{19,18}}; -#else -const char modePins[2][3] = {{6,16,17},{10,19,18}}; -#endif -//Used for direct port register write. Also determines which hardware -//#define STEP1PORT PORTD -//#define _STEP1_HIGH 0b00010000 -//#define _STEP1_LOW 0b11101111 -//#define STEP2PORT PORTE -//#define _STEP2_HIGH 0b00000100 -//#define _STEP2_LOW 0b11111011 - -boolean highSpeed[2] = {false,false}; //whether number of microsteps is dropped to 8 due to high speed (to increase Torque) - -#elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) -#ifndef LEGACY_MODE -#define LEGACY_MODE 1 -#endif -//Pins -const char statusPin = 13; -const char resetPin[2] = {A1,A0}; -const char errorPin[2] = {2,6}; -const char dirPin[2] = {3,7}; -const char enablePin[2] = {4,8}; -const char stepPin[2] = {5,12}; -const char oldStepPin1 = 9; //Note this has changed due to a mistake I had made originally. The original will be set as an input so hardware can be corrected by shorting with new pin -//Used for direct port register write. Also determines which hardware -//#define STEP1PORT PORTE -//#define _STEP1_HIGH 0b00001000 -//#define _STEP1_LOW 0b11110111 -//#define STEP2PORT PORTB -//#define _STEP2_HIGH 0b01000000 -//#define _STEP2_LOW 0b10111111 - -#ifdef USEHIGHSPEEDMODE -const char modePins[2][2] = {{16,17},{19,18}}; // {RA{Mode0,Mode2}, DEC{Mode0,Mode2}} Modepins, Mode1=leave unconnected. -boolean highSpeed[2] = {false,false}; //whether number of microsteps is dropped to 8 due to high speed (to increase Torque) - - //This is only available on Atmega162 as not included with original hardware. - //If you want to use it, uncomment the line: '#define USEHIGHSPEEDMODE 1' - //and connect the mode pins of the DRV8824PWP chips to the pins shown -#endif - -#endif -const boolean encodeDirection[2][2] = ENCODE_DIRECTION_INIT(); -byte distributionWidth[2] = {64,64}; - -volatile byte* _STEP1_PORT; -byte _STEP1_HIGH; -byte _STEP1_LOW; -#define STEP1PORT *_STEP1_PORT -volatile byte* _STEP2_PORT; -byte _STEP2_HIGH; -byte _STEP2_LOW; -#define STEP2PORT *_STEP2_PORT - -//In order to support both the DRV8824 and A4983 carrier boards from Pololu, the mode positions had to be changed and thus this is different: -#ifdef LEGACY_MODE - -#ifdef POLOLU_A498x -#define MODE0STATE16 HIGH -#define MODE0STATE2 LOW -#else -#define MODE0STATE16 LOW -#define MODE0STATE2 HIGH -#endif -#define MODE2STATE16 HIGH -#define MODE2STATE2 LOW - -#else - -#ifdef POLOLU_A498x -#define MODE0STATE16 HIGH -#define MODE0STATE2 HIGH -#define MODE1STATE16 HIGH -#define MODE1STATE2 LOW -#define MODE2STATE16 HIGH -#define MODE2STATE2 LOW -#else -#define MODE0STATE16 LOW -#define MODE0STATE2 HIGH -#define MODE1STATE16 LOW -#define MODE1STATE2 LOW -#define MODE2STATE16 HIGH -#define MODE2STATE2 LOW -#endif - -#endif - - -void setup() -{ - unsigned char STEP1 = digitalPinToPort(stepPin[0]); - unsigned char STEP2 = digitalPinToPort(stepPin[1]); - _STEP1_PORT = portOutputRegister(STEP1); - _STEP2_PORT = portOutputRegister(STEP2); - _STEP1_HIGH = digitalPinToBitMask(stepPin[0]); - _STEP2_HIGH = digitalPinToBitMask(stepPin[1]); - _STEP1_LOW = ~_STEP1_HIGH; - _STEP2_LOW = ~_STEP2_HIGH; - -#ifdef DEBUG - Serial1.begin(115200); -#endif - - pinMode(oldStepPin1,INPUT); //Set to input for ease of hardware change - digitalWrite(oldStepPin1,LOW); //disable internal pullup - pinMode(statusPin,OUTPUT); - for(byte i = 0;i < 2;i++){ //for each motor... - pinMode(errorPin[i],INPUT); //enable the Error pin - pinMode(enablePin[i],OUTPUT); //enable the Enable pin - digitalWrite(enablePin[i],HIGH); //IC disabled - pinMode(stepPin[i],OUTPUT); //enable the step pin - digitalWrite(stepPin[i],LOW); //default is low - pinMode(dirPin[i],OUTPUT); //enable the direction pin - digitalWrite(dirPin[i],LOW); //default is low -#ifdef LEGACY_MODE -#if defined(__AVR_ATmega162__) || defined(USEHIGHSPEEDMODE) - pinMode(modePins[i][0],OUTPUT); //enable the mode pins - pinMode(modePins[i][1],OUTPUT); //enable the mode pins - digitalWrite(modePins[i][0],MODE0STATE16); //default is low - digitalWrite(modePins[i][1],MODE2STATE16); //default is high -#endif -#else -#if defined(__AVR_ATmega162__) - pinMode(modePins[i][0],OUTPUT); //enable the mode pins - pinMode(modePins[i][1],OUTPUT); //enable the mode pins - pinMode(modePins[i][2],OUTPUT); //enable the mode pins - digitalWrite(modePins[i][0],MODE0STATE16); //default is low - digitalWrite(modePins[i][1],MODE1STATE16); //default is high - digitalWrite(modePins[i][2],MODE2STATE16); //default is high -#endif -#endif - pinMode(resetPin[i],OUTPUT); //enable the reset pin - digitalWrite(resetPin[i],LOW); //active low reset - delay(1); //allow ic to reset - digitalWrite(resetPin[i],HIGH); //complete reset - } - - // start Serial port: - Serial.begin(9600); //SyncScan runs at 9600Baud, use a serial port of your choice - while(Serial.available()){ - Serial.read(); //Clear the buffer - } - - configureTimer(); //setup the motor pulse timers. -} - -void loop(){ - static unsigned long lastMillis = millis(); - static boolean isLedOn = false; - char decodedPacket[11]; //temporary store for completed command ready to be processed - if (Serial.available()) { //is there a byte in buffer - digitalWrite(statusPin,HIGH); //Turn on the LED to indicate activity. - char recievedChar = Serial.read(); //get the next character in buffer -#ifdef DEBUG - Serial1.write(recievedChar); -#endif - char decoded = synta.recieveCommand(decodedPacket,recievedChar); //once full command packet recieved, decodedPacket returns either error packet, or valid packet - if (decoded == 1){ //Valid Packet - decodeCommand(synta.command(),decodedPacket); //decode the valid packet - } else if (decoded == -1){ //Error - Serial.print(decodedPacket); //send the error packet (recieveCommand() already generated the error packet, so just need to send it) -#ifdef DEBUG - Serial1.print(" ->Res:"); - Serial1.println(decodedPacket); -#endif - } //otherwise command not yet fully recieved, so wait for next byte - lastMillis = millis(); - isLedOn = true; - } - if (isLedOn && (millis() > lastMillis + 20)){ - isLedOn = false; - digitalWrite(statusPin,LOW); //Turn LED back off after a short delay. - } -} - -void decodeCommand(char command, char* packetIn){ //each command is axis specific. The axis being modified can be retrieved by calling synta.axis() - char response[11]; //generated response string - unsigned long responseData; //data for response - - switch(command){ - case 'e': //readonly, return the eVal (version number) - responseData = synta.cmd.eVal(synta.axis()); //response to the e command is stored in the eVal function for that axis. - break; - case 'a': //readonly, return the aVal (steps per axis) - responseData = synta.cmd.aVal(synta.axis()); //response to the a command is stored in the aVal function for that axis. - responseData /= synta.scalar(); - break; - case 'b': //readonly, return the bVal (sidereal rate) - responseData = synta.cmd.bVal(synta.axis()); //response to the b command is stored in the bVal function for that axis. - responseData /= synta.scalar(); - if (synta.cmd.bVal(synta.axis()) % synta.scalar()){ - responseData++; //round up - } - break; - case 'g': //readonly, return the gVal (high speed multiplier) - responseData = synta.cmd.gVal(synta.axis()); //response to the g command is stored in the gVal function for that axis. - break; - case 's': //readonly, return the sVal (steps per worm rotation) - responseData = synta.cmd.sVal(synta.axis()); //response to the s command is stored in the sVal function for that axis. - responseData /= synta.scalar(); - break; - case 'f': //readonly, return the fVal (axis status) - responseData = synta.cmd.fVal(synta.axis()); //response to the f command is stored in the fVal function for that axis. - break; - case 'j': //readonly, return the jVal (current position) - responseData = synta.cmd.jVal(synta.axis()); //response to the j command is stored in the jVal function for that axis. - break; - case 'K': //stop the motor, return empty response - - - motorStop(synta.axis()); //No specific response, just stop the motor (Feel free to customise motorStop function to suit your needs - - - responseData = 0; - break; - case 'G': //set mode and direction, return empty response - synta.cmd.GVal(synta.axis(), (packetIn[0] - '0')); //Store the current mode for the axis - synta.cmd.dir(synta.axis(), (packetIn[1] - '0')); //Store the current direction for that axis - responseData = 0; - break; - case 'H': //set goto position, return empty response (this sets the number of steps to move from cuurent position if in goto mode) - synta.cmd.HVal(synta.axis(), synta.hexToLong(packetIn)); //set the goto position container (convert string to long first) - responseData = 0; - break; - case 'I': //set slew speed, return empty response (this sets the speed to move at if in slew mode) - responseData = synta.hexToLong(packetIn); - if (responseData > 650L){ - responseData = 650; //minimum speed to prevent timer overrun - } - synta.cmd.IVal(synta.axis(), responseData); //set the speed container (convert string to long first) - - //This will be different if you use a different motor code - calculateRate(synta.axis()); //Used to convert speed into the number of 0.5usecs per step. Result is stored in TimerOVF - - - responseData = 0; - break; - case 'E': //set the current position, return empty response - synta.cmd.jVal(synta.axis(), synta.hexToLong(packetIn)); //set the current position (used to sync to what EQMOD thinks is the current position at startup - responseData = 0; - break; - case 'F': //Enable the motor driver, return empty response - - - motorEnable(); //This enables the motors - gives the motor driver board power - - - responseData = 0; - break; - default: //Return empty response (deals with commands that don't do anything before the response sent (i.e 'J'), or do nothing at all (e.g. 'M', 'L') ) - responseData = 0; - break; - } - - synta.assembleResponse(response, command, responseData); //generate correct response (this is required as is) - Serial.print(response); //send response to the serial port -#ifdef DEBUG - Serial1.print(" ->Res:"); - Serial1.println(response); -#endif - - if(command == 'J'){ //J tells - if(synta.cmd.GVal(synta.axis()) & 1){ - - //This is the funtion that enables a slew type move. - slewMode(); //Slew type - - - } else { - - //This is the function for goto mode. You may need to customise it for a different motor driver - gotoMode(); //Goto Mode - - - } - } -} - - - -//Calculates the rate based on the recieved I value -void calculateRate(byte motor){ - - //seconds per step = IVal / BVal; for lowspeed move - //or seconds per step = IVal / (BVal * gVal); for highspeed move - // - //whether to use highspeed move or not is determined by the GVal; - // - //clocks per step = timerCountRate * seconds per step - - unsigned long rate; - unsigned long remainder; - float floatRemainder; - unsigned long divisor = synta.cmd.bVal(motor); - if((synta.cmd.GVal(motor) == 2)||(synta.cmd.GVal(motor) == 1)){ //Normal Speed -#if defined(USEHIGHSPEEDMODE) - //check if at very high speed - if (synta.cmd.IVal(motor) < 30){ - highSpeed[motor] = true; - distributionWidth[motor] = 8; //There are 8 times fewer steps over which to distribute extra clock cycles - } else { - highSpeed[motor] = false; - distributionWidth[motor] = 64; - } -#endif - } else if ((synta.cmd.GVal(motor) == 0)||(synta.cmd.GVal(motor) == 3)){ //High Speed - divisor *= synta.cmd.gVal(motor); -#if defined(USEHIGHSPEEDMODE) - //check if at very high speed - if (synta.cmd.IVal(motor) < (30 * synta.cmd.gVal(motor))){ - highSpeed[motor] = true; - distributionWidth[motor] = 8; //There are 8 times fewer steps over which to distribute extra clock cycles - } else { - highSpeed[motor] = false; - distributionWidth[motor] = 64; - } -#endif - } - rate = timerCountRate * synta.cmd.IVal(motor); - //When dividing a very large number by a much smaller on, float accuracy is abismal. So firstly we use integer math to split the division into quotient and remainder - remainder = rate % divisor; //Calculate the remainder - rate /= divisor; //Calculate the quotient - //Then convert the remainder into a decimal number (division of a small number by a larger one, improving accuracy) - floatRemainder = (float)remainder/(float)divisor; //Convert the remainder to a decimal. - - rate *= 10; //corrects for timer count rate being set to 1/10th of the required to prevent numbers getting too big for an unsigned long. - floatRemainder *= 10; - - //If there is now any integer part of the remainder after the multiplication by 10, it needs to be added back on to the rate and removed from the remainder. - remainder = (unsigned long)floatRemainder; //first work out how much to be added - //Then add it to the rate, and remove it from the decimal remainder - rate += remainder; - floatRemainder -= (float)remainder; - - //Multiply the remainder by distributionWidth to work out an approximate number of extra clocks needed per full step (each step is 'distributionWidth' microsteps) - floatRemainder *= (float)distributionWidth[motor]; - //This many extra microseconds are needed: - remainder = (unsigned long)floatRemainder; - - //Now truncate to an unsigned int with a sensible max value (the int is to avoid register issues with the 16 bit timer) - if(rate > 64997UL){ - rate = 64997UL; - } else if (rate < 36UL) { - rate = 36L; - } - for (int i = 0; i < distributionWidth[motor]; i++){ - timerOVF[motor][i] = rate - 1; //Subtract 1 as timer is 0 indexed. - } - - //evenly distribute the required number of extra clocks over the full step. - for (int i = 0; i < remainder; i++){ - float distn = i; - distn *= (float)distributionWidth[motor]; - distn /= (float)remainder; - byte index = (byte)ceil(distn); - timerOVF[motor][index] += 1; - } -} - -void motorEnable(){ - digitalWrite(enablePin[synta.axis()],LOW); - synta.cmd.FVal(synta.axis(),1); -} - -void slewMode(){ - motorStart(synta.axis(), 30/synta.scalar()); //Begin PWM -} - -void gotoMode(){ - if (synta.cmd.HVal(synta.axis()) < (140/synta.scalar())){ - if (synta.cmd.HVal(synta.axis()) < 2){ - synta.cmd.HVal(synta.axis(),2); - } - //To short of a goto to use the timers, so do it manually - accellerate( (synta.cmd.HVal(synta.axis()) / 2) * synta.scalar(), synta.axis()); - decellerate( (synta.cmd.HVal(synta.axis()) / 2) * synta.scalar(), synta.axis()); - - synta.cmd.jVal(synta.axis(), (synta.cmd.jVal(synta.axis()) + (synta.cmd.stepDir(synta.axis()) * synta.cmd.HVal(synta.axis())) ) ); - } else { - gotoPosn[synta.axis()] = synta.cmd.jVal(synta.axis()) + (synta.cmd.stepDir(synta.axis()) * synta.cmd.HVal(synta.axis())); //current position + distance to travel - - if (synta.cmd.HVal(synta.axis()) < (200/synta.scalar())){ - synta.cmd.IVal(synta.axis(), NORMALGGOTOSPEED); - calculateRate(synta.axis()); - motorStart(synta.axis(),20/synta.scalar()); //Begin PWM - } else { - synta.cmd.IVal(synta.axis(), FASTGOTOSPEED); //Higher speed goto - calculateRate(synta.axis()); - motorStart(synta.axis(),60/synta.scalar()); //Begin PWM - } - synta.cmd.gotoEn(synta.axis(),1); - } -} - -void motorStart(byte motor, byte steps){ - digitalWrite(dirPin[motor],encodeDirection[motor][synta.cmd.dir(motor)]); //set the direction - synta.cmd.stopped(motor, 0); - accellerate(steps * synta.scalar(),motor); //accellerate to calculated rate in given number of steps steps - synta.cmd.jVal(motor, (synta.cmd.jVal(motor) + (synta.cmd.stepDir(motor) * steps) ) ); //update position to account for accelleration - if(motor){ - ICR1 = timerOVF[motor][0]; - TCNT1 = 0; - TCCR1A |= (1<<COM1B1); //Set port operation to fast PWM -#if defined(__AVR_ATmega162__) - TIMSK |= (1<<TOIE1); //Enable timer interrupt -#elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) - TIMSK1 |= (1<<TOIE1); //Enable timer interrupt -#endif - } else { - ICR3 = timerOVF[motor][0]; - TCNT3 = 0; - TCCR3A |= (1<<COM3A1); //Set port operation to fast PWM -#if defined(__AVR_ATmega162__) - ETIMSK |= (1<<TOIE3); //Enable timer interrupt -#elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) - TIMSK3 |= (1<<TOIE3); //Enable timer interrupt -#endif - } -} - -void motorStop(byte motor){ - motorStop(motor, 60/synta.scalar()); //Default number of steps. Replaces function prototype from Version < 5.0 -} - -void motorStop(byte motor, byte steps){ - if (!synta.cmd.stopped(motor)){ - if(motor){ - TCCR1A &= ~(1<<COM1B1); //Set port operation to Normal -#if defined(__AVR_ATmega162__) - TIMSK &= ~(1<<TOIE1); //Disable timer interrupt -#elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) - TIMSK1 &= ~(1<<TOIE1); //Disable timer interrupt -#endif - } else { - TCCR3A &= ~(1<<COM3A1); //Set port operation to Normal -#if defined(__AVR_ATmega162__) - ETIMSK &= ~(1<<TOIE3); //Disable timer interrupt -#elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) - TIMSK3 &= ~(1<<TOIE3); //Disable timer interrupt -#endif - } - //Only decellerate if not already stopped - for some reason EQMOD stops both axis when slewing, even if one isn't currently moving? - if (synta.cmd.gotoEn(motor)){ - synta.cmd.gotoEn(motor,0); //Cancel goto mode - } - decellerate(steps * synta.scalar(),motor); - synta.cmd.jVal(motor, (synta.cmd.jVal(motor) + (synta.cmd.stepDir(motor) * steps) ) ); - synta.cmd.stopped(motor,1); //mark as stopped - } -} - -void decellerate(byte decellerateSteps, byte motor){ -#if defined(USEHIGHSPEEDMODE) - if(highSpeed[motor]){ - //Disable Highspeed mode - highSpeed[motor] = false; -#ifdef LEGACY_MODE - digitalWrite(modePins[motor][0],MODE0STATE16); - digitalWrite(modePins[motor][1],MODE2STATE16); -#else - digitalWrite(modePins[motor][0],MODE0STATE16); //default is low - digitalWrite(modePins[motor][1],MODE1STATE16); //default is high - digitalWrite(modePins[motor][2],MODE2STATE16); //default is high -#endif - if(motor){ - if (synta.cmd.bVal(synta.axis()) < 20000){ - OCR1B = PULSEWIDTH_25; //Width of step pulse (equates to ~4uS. DRV8824PWP specifies absolute minimum as ~2uS) - //Set prescaler to F_CPU/64 - TCCR1B &= ~(1<<CS12); //0xx - TCCR1B |= ((1<<CS11) | (1<<CS10));//x11 - } else if (synta.cmd.bVal(synta.axis()) < 160000){ - OCR1B = PULSEWIDTH2; //Width of step pulse (equates to ~4uS. DRV8824PWP specifies absolute minimum as ~2uS) - //Set prescaler to F_CPU/8 - TCCR1B &= ~((1<<CS12) | (1<<CS10)); //0x0 - TCCR1B |= (1<<CS11);//x1x - } else { - OCR1B = PULSEWIDTH16; //Width of step pulse (equates to ~4uS. DRV8824PWP specifies absolute minimum as ~2uS) - //Set prescaler to F_CPU/1 - TCCR1B &= ~((1<<CS12) | (1<<CS11));//00x - TCCR1B |= (1<<CS10);//xx1 - } - } else { - if (synta.cmd.bVal(synta.axis()) < 20000){ - OCR3A = PULSEWIDTH_25; //Width of step pulse (equates to ~4uS. DRV8824PWP specifies absolute minimum as ~2uS) - //Set prescaler to F_CPU/64 - TCCR3B &= ~(1<<CS32); //0xx - TCCR3B |= ((1<<CS31) | (1<<CS30));//x11 - } else if (synta.cmd.bVal(synta.axis()) < 160000){ - OCR3A = PULSEWIDTH2; //Width of step pulse (equates to ~4uS. DRV8824PWP specifies absolute minimum as ~2uS) - //Set prescaler to F_CPU/8 - TCCR3B &= ~((1<<CS32) | (1<<CS30)); //0x0 - TCCR3B |= (1<<CS31);//x1x - } else { - OCR3A = PULSEWIDTH16; //Width of step pulse (equates to ~4uS. DRV8824PWP specifies absolute minimum as ~2uS) - //Set prescaler to F_CPU/1 - TCCR3B &= ~((1<<CS32) | (1<<CS31));//00x - TCCR3B |= (1<<CS30);//xx1 - } - } - } -#endif - //x steps to slow down to maxTimerOVF - speedCurve(timerOVF[motor][0], 1, decellerateSteps, motor); - //Now at minimum speed, so safe to stop. -} - -void accellerate(byte accellerateSteps, byte motor){ - //x steps to speed up to timerOVF[synta.axis()] - speedCurve(maxTimerOVF, -1, accellerateSteps, motor); - //Now at speed, so check highspeed mode and then return. Timers will be used from now on. -#if defined(USEHIGHSPEEDMODE) - if(highSpeed[motor]){ - //Enable Highspeed mode -#ifdef LEGACY_MODE - digitalWrite(modePins[motor][0],MODE0STATE2); - digitalWrite(modePins[motor][1],MODE2STATE2); -#else - digitalWrite(modePins[motor][0],MODE0STATE2); //default is low - digitalWrite(modePins[motor][1],MODE1STATE2); //default is high - digitalWrite(modePins[motor][2],MODE2STATE2); //default is high -#endif - if(motor){ - if (synta.cmd.bVal(synta.axis()) < 20000){ - OCR1B = PULSEWIDTH_25F; //Width of step pulse (equates to ~32uS. DRV8824PWP specifies absolute minimum as ~2uS) - //Set prescaler to F_CPU/256 - TCCR1B |= (1<<CS12); //1xx - TCCR1B &= ~((1<<CS11) | (1<<CS10));//x00 - } else if (synta.cmd.bVal(synta.axis()) < 160000){ - OCR1B = PULSEWIDTH2F; //Width of step pulse (equates to ~4uS. DRV8824PWP specifies absolute minimum as ~2uS) - //Set prescaler to F_CPU/64 - TCCR1B &= ~(1<<CS12); //0xx - TCCR1B |= ((1<<CS11) | (1<<CS10));//x11 - } else { - OCR1B = PULSEWIDTH16F; //Width of step pulse (equates to ~4uS. DRV8824PWP specifies absolute minimum as ~2uS) - //Set prescaler to F_CPU/8 - TCCR1B &= ~((1<<CS12) | (1<<CS10)); //0x0 - TCCR1B |= (1<<CS11);//x1x - } - } else { - if (synta.cmd.bVal(synta.axis()) < 20000){ - OCR1B = PULSEWIDTH_25F; //Width of step pulse (equates to ~32uS. DRV8824PWP specifies absolute minimum as ~2uS) - //Set prescaler to F_CPU/256 - TCCR3B |= (1<<CS32); //1xx - TCCR3B &= ~((1<<CS31) | (1<<CS30));//x00 - } else if (synta.cmd.bVal(synta.axis()) < 160000){ - OCR3A = PULSEWIDTH2F; //Width of step pulse (equates to ~4uS. DRV8824PWP specifies absolute minimum as ~2uS) - //Set prescaler to F_CPU/64 - TCCR3B &= ~(1<<CS32); //0xx - TCCR3B |= ((1<<CS31) | (1<<CS30));//x11 - } else { - OCR3A = PULSEWIDTH16F; //Width of step pulse (equates to ~4uS. DRV8824PWP specifies absolute minimum as ~2uS) - //Set prescaler to F_CPU/8 - TCCR3B &= ~((1<<CS32) | (1<<CS30)); //0x0 - TCCR3B |= (1<<CS31);//x1x - } - } - } -#endif -} - -void speedCurve(unsigned long currentSpeed, char dir, byte steps, byte motor){ //dir = -1 or +1. - means accellerate - unsigned long speedPerStep = (maxTimerOVF - timerOVF[motor][0]); //maxTimerOVF is always largest - speedPerStep /= steps; - if (synta.cmd.bVal(motor) < 160000){//convert the number of clock cycles into uS. - speedPerStep >>= 1; - } else { - speedPerStep >>= 4; - } - if (speedPerStep == 0){ - speedPerStep = 1; //just in case - prevents rounding from resulting in delay of 0. - } - unsigned int microDelay; - if (synta.cmd.bVal(motor) < 160000){ - microDelay = currentSpeed >> 1; //number of uS to wait for speed (rate is in 1/2ths of a microsecond) - } else { - microDelay = currentSpeed >> 4; //number of uS to wait for speed (rate is in 1/16ths of a microsecond) - } - for(int i = 0;i < steps;i++){ - delayMicroseconds(microDelay); - if(motor){ //Step - writeSTEP2(HIGH); - delayMicroseconds(5); - writeSTEP2(LOW); - } else { - writeSTEP1(HIGH); - delayMicroseconds(5); - writeSTEP1(LOW); - } - microDelay += (dir * speedPerStep); - } -} - -//Timer Interrupt----------------------------------------------------------------------------- -void configureTimer(){ -#if defined(__AVR_ATmega162__) - TIMSK &= ~(1<<TOIE1); //disable timer so it can be configured - ETIMSK &= ~(1<<TOIE3); //disable timer so it can be configured - //Disable compare interrupt (only interested in overflow) - TIMSK &= ~((1<<OCIE1A) | (1<<OCIE1B)); - ETIMSK &= ~((1<<OCIE3A) | (1<<OCIE3B)); -#elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) - TIMSK1 &= ~(1<<TOIE1); //disable timer so it can be configured - TIMSK3 &= ~(1<<TOIE3); //disable timer so it can be configured - //Disable compare interrupt (only interested in overflow) - TIMSK1 &= ~((1<<OCIE1A) | (1<<OCIE1B) | (1<<OCIE1C)); - TIMSK3 &= ~((1<<OCIE3A) | (1<<OCIE3B) | (1<<OCIE3C)); -#endif - //set to fast PWM mode (1110) - TCCR1A |= ((1<<WGM11)); - TCCR1A &= ~((1<<WGM10)); - TCCR1B |= ((1<<WGM13) | (1<<WGM12)); - TCCR3A |= ((1<<WGM31)); - TCCR3A &= ~((1<<WGM30)); - TCCR3B |= ((1<<WGM33) | (1<<WGM32)); - if (synta.cmd.bVal(synta.axis()) < 20000){ - timerCountRate = 25000; - //Set prescaler to F_CPU/64 - TCCR1B &= ~(1<<CS12); //0xx - TCCR1B |= ((1<<CS11) | (1<<CS10));//x11 - TCCR3B &= ~(1<<CS32); //0x0 - TCCR3B |= ((1<<CS31) | (1<<CS30));//x11 - OCR1B = PULSEWIDTH_25; //Width of step pulse (equates to ~4uS. DRV8824PWP specifies absolute minimum as ~2uS) - OCR3A = PULSEWIDTH_25; - } else if (synta.cmd.bVal(synta.axis()) < 160000){ - timerCountRate = 200000; - //Set prescaler to F_CPU/8 - TCCR1B &= ~((1<<CS12) | (1<<CS10)); //0x0 - TCCR1B |= (1<<CS11);//x1x - TCCR3B &= ~((1<<CS32) | (1<<CS30)); //0x0 - TCCR3B |= (1<<CS31);//x1x - OCR1B = PULSEWIDTH2; //Width of step pulse (equates to ~4uS. DRV8824PWP specifies absolute minimum as ~2uS) - OCR3A = PULSEWIDTH2; - } else { - timerCountRate = 1600000; - //Set prescaler to F_CPU/1 - TCCR1B &= ~((1<<CS12) | (1<<CS11));//00x - TCCR1B |= (1<<CS10);//xx1 - TCCR3B &= ~((1<<CS32) | (1<<CS31));//00x - TCCR3B |= (1<<CS30);//xx1 - OCR1B = PULSEWIDTH16; //Width of step pulse (equates to ~4uS. DRV8824PWP specifies absolute minimum as ~2uS) - OCR3A = PULSEWIDTH16; - } - unsigned long rate = timerCountRate * 650L; //min rate of just under the sidereal rate - rate /= synta.cmd.bVal(synta.axis()); - maxTimerOVF = 10 * rate; //corrects for timer count rate being set to 1/10th of the required to prevent numbers getting too big for an unsigned long. -} - -/*Timer Interrupt Vector*/ -ISR(TIMER3_OVF_vect) { - static byte timeSegment = 0; - ICR3 = timerOVF[RA][timeSegment++]; //move to next pwm period - if (timeSegment == distributionWidth[RA]){ - timeSegment = 0; - } - motorStep(RA); -} - -/*Timer Interrupt Vector*/ -ISR(TIMER1_OVF_vect) { - static byte timeSegment = 0; - ICR1 = timerOVF[DC][timeSegment++]; //move to next pwm period - if (timeSegment == distributionWidth[DC]){ - timeSegment = 0; - } - motorStep(DC); -} - -void motorStep(byte motor){ - static char divider[2] = {0}; - - divider[motor] += synta.cmd.stepDir(motor); - if(synta.cmd.stepDir(motor) < 0){ - if (divider[motor] < 0){ - divider[motor] = synta.scalar() - 1; - checkIfDone(motor); - } - } else { - if (divider[motor] >= synta.scalar()){ - divider[motor] = 0; - checkIfDone(motor); - } - } -} - -void checkIfDone(byte motor){ -#if defined(USEHIGHSPEEDMODE) - if(highSpeed[motor]){ - synta.cmd.jVal(motor, (synta.cmd.jVal(motor) + (8 * synta.cmd.stepDir(motor)))); - } else { -#else - if(1){ //Always do the next line. Here to account for the extra close brace - //} -> this one is supposed to be commented out! (keeps the IDE happy) -#endif - synta.cmd.jVal(motor, (synta.cmd.jVal(motor) + synta.cmd.stepDir(motor))); - } - if(synta.cmd.gotoEn(motor)){ - long stepsLeft = gotoPosn[motor] - synta.cmd.jVal(motor); - stepsLeft *= synta.cmd.stepDir(motor); - if(stepsLeft <= (120/synta.scalar())){ - motorStop(motor, stepsLeft); //will decellerate the rest of the way. - } - } -} - -void writeSTEP1(boolean bitValue){ - if (bitValue){ - STEP1PORT |= _STEP1_HIGH; - } else { - STEP1PORT &= _STEP1_LOW; - } -} - -void writeSTEP2(boolean bitValue){ - if (bitValue){ - STEP2PORT |= _STEP2_HIGH; - } else { - STEP2PORT &= _STEP2_LOW; - } -} -//------------------------------------------------------------------------------------------- -#else -#error Unsupported Part! Please use an Arduino Mega, or ATMega162 -#endif - diff --git a/AstroEQ-Firmware/AstroEQ6.ino b/AstroEQ-Firmware/AstroEQ6.ino new file mode 100644 index 0000000000000000000000000000000000000000..3b81c3ddeae8b276bb60f8b0b0e2423c866ef6b7 --- /dev/null +++ b/AstroEQ-Firmware/AstroEQ6.ino @@ -0,0 +1,839 @@ +/* + Code written by Thomas Carpenter 2012 + + With thanks Chris over at the EQMOD Yahoo group for explaining the Skywatcher protocol + + + Equatorial mount tracking system for integration with EQMOD using the Skywatcher/Syntia + communication protocol. + + Works with EQ5, HEQ5, and EQ6 mounts (Not EQ3-2, they have a different gear ratio) + + Current Verison: 6 +*/ + +//Only works with ATmega162, and Arduino Mega boards (1280 and 2560) +#if defined(__AVR_ATmega162__) || defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) + +#include "synta.h" //Synta Communications Protocol. +#include "PinMappings.h" //Read Pin Mappings +#include "EEPROMReader.h" //Read config file +#include "EEPROMAddresses.h" //Config file addresses + + +//------------------------------------------------------------- +//DO NOT EDIT ANYTHING BELOW THIS LINE------------------------- +//------------------------------------------------------------- + +Synta synta = Synta::getInstance(1281); //create a mount instance, specify version! + +#define RA 0 //Right Ascension is AstroEQ axis 0 (Synta axis '1') +#define DC 1 //Declination is AstroEQ axis 1 (Synta axis '2') + +//#define DEBUG 1 +unsigned int normalGotoSpeed[2]; +unsigned int gotoFactor; +unsigned int minSpeed[2]; + +unsigned long gotoPosn[2] = {0UL,0UL}; //where to slew to + +#define timerCountRate 8000000 + +#define NormalDistnWidth 32 +#define HighspeedDistnWidth 4 +unsigned int timerOVF[2][max(HighspeedDistnWidth,NormalDistnWidth)]; +boolean highSpeed[2] = {false,false}; +byte distributionWidth[2] = {NormalDistnWidth,NormalDistnWidth}; +#define distributionSegment(m) (m ? GPIOR1 : GPIOR0) +#define decelerationSteps(m) (m ? DDRC : PORTC) +#define currentMotorSpeed(m) (m ? OCR3A : OCR3B) +#define interruptCount(m) (m ? OCR1A : OCR1B) +#define interruptOVFCount(m) (m ? ICR3 : ICR1) +#define interruptControlRegister(m) (m ? TIMSK3 : TIMSK1) +#define interruptControlBitMask(m) (m ? _BV(ICIE3) : _BV(ICIE1)) +#define timerCountRegister(m) (m ? TCNT3 : TCNT1) +#define timerPrescalarRegister(m) (m ? TCCR3B : TCCR1B) + +//Pins +const byte statusPin = statusPin_Define; +const byte resetPin[2] = {resetPin_0_Define,resetPin_1_Define}; +const byte errorPin[2] = {errorPin_0_Define,errorPin_1_Define}; +const byte dirPin[2] = {dirPin_0_Define,dirPin_1_Define}; +const byte enablePin[2] = {enablePin_0_Define,enablePin_1_Define}; +const byte stepPin[2] = {stepPin_0_Define,stepPin_1_Define}; + +#ifdef LEGACY_MODE +const byte modePins[2][2] = {{modePins0_0_Define,modePins2_0_Define},{modePins0_1_Define,modePins2_1_Define}}; +#else +const byte modePins[2][3] = {{modePins0_0_Define,modePins1_0_Define,modePins2_0_Define},{modePins0_1_Define,modePins1_1_Define,modePins2_1_Define}}; +#endif + + +byte encodeDirection[2]; + +#define _STEP0_HIGH _BV(digitalPinToBit(stepPin[RA])) +#define _STEP0_LOW (~_STEP0_HIGH) +#define STEP0PORT *digitalPinToPortReg(stepPin[RA]) +#define _STEP1_HIGH _BV(digitalPinToBit(stepPin[DC])) +#define _STEP1_LOW (~_STEP1_HIGH) +#define STEP1PORT *digitalPinToPortReg(stepPin[DC]) +#define stepPort(m) (m ? STEP1PORT : STEP0PORT) +#define stepHigh(m) (m ? _STEP1_HIGH : _STEP0_HIGH) +#define stepLow(m) (m ? _STEP1_LOW : _STEP0_LOW) + +#ifdef LEGACY_MODE +byte modeState[2][2] = {{HIGH,HIGH},{LOW,LOW}}; +#define MODE0 0 +#define MODE2 1 +#define STATE16 0 +#define STATE2 1 + +#else +byte modeState[2][3] = {{HIGH,HIGH,HIGH},{HIGH,LOW,LOW}}; +#define MODE0 0 +#define MODE1 1 +#define MODE2 2 +#define STATE16 0 +#define STATE2 1 + +#endif + +boolean checkEEPROM(){ + char temp[9] = {0}; + EEPROM.readString(temp,8,AstroEQID_Address); + return !(strncmp(temp,"AstroEQ",8)); +} + +void systemInitialiser(){ + encodeDirection[RA] = EEPROM.readByte(RAReverse_Address); //reverse the right ascension if 1 + encodeDirection[DC] = EEPROM.readByte(DECReverse_Address); //reverse the declination if 1 + + +#ifdef LEGACY_MODE + modeState[STATE16][MODE0] = !EEPROM.readByte(Driver_Address); + modeState[STATE2][MODE0] = !modeState[STATE16][MODE0]; +#else + modeState[STATE16][MODE0] = !EEPROM.readByte(Driver_Address); + modeState[STATE16][MODE1] = modeState[STATE16][MODE0]; +#endif + + gotoFactor = EEPROM.readInt(NormalGoto_Address); + normalGotoSpeed[RA] = synta.cmd.stepIncrement[RA] * gotoFactor + 1; + normalGotoSpeed[DC] = synta.cmd.stepIncrement[DC] * gotoFactor + 1; + + minSpeed[RA] = synta.cmd.siderealIVal[RA] + ((unsigned int)synta.cmd.stepIncrement[RA] << 2); + minSpeed[DC] = synta.cmd.siderealIVal[DC] + ((unsigned int)synta.cmd.stepIncrement[DC] << 2); + +#ifdef DEBUG + Serial1.println(); + Serial1.println(minSpeed[RA]); + Serial1.println(minSpeed[DC]); + Serial1.println(); + Serial1.println(normalGotoSpeed[RA]); + Serial1.println(normalGotoSpeed[DC]); + Serial1.println(); + Serial1.println(synta.cmd.stepIncrement[RA]); + Serial1.println(synta.cmd.stepIncrement[DC]); + Serial1.println(); +#endif + if(!checkEEPROM()){ + while(1); //prevent AstroEQ startup if EEPROM is blank. + } +} + +void setup() +{ +#ifdef DEBUG + Serial1.begin(115200); +#endif + systemInitialiser(); + +#if defined(__AVR_ATmega162__) + //Timer 2 registers are being used as general purpose data storage for high efficency interrupt routines. So timer must be fully disabled. + TCCR2 = 0; + ASSR=0; +#endif + + pinMode(statusPin,OUTPUT); + for(byte i = 0;i < 2;i++){ //for each motor... + pinMode(errorPin[i],INPUT); //enable the Error pin + pinMode(enablePin[i],OUTPUT); //enable the Enable pin + digitalWrite(enablePin[i],HIGH); //IC disabled + pinMode(stepPin[i],OUTPUT); //enable the step pin + digitalWrite(stepPin[i],LOW); //default is low + pinMode(dirPin[i],OUTPUT); //enable the direction pin + digitalWrite(dirPin[i],LOW); //default is low +#ifdef LEGACY_MODE + pinMode(modePins[i][0],OUTPUT); //enable the mode pins + pinMode(modePins[i][1],OUTPUT); //enable the mode pins + for( byte j = 0; j < 2; j++){ + digitalWrite(modePins[i][j],modeState[0][j]); + } +#else + pinMode(modePins[i][0],OUTPUT); //enable the mode pins + pinMode(modePins[i][1],OUTPUT); //enable the mode pins + pinMode(modePins[i][2],OUTPUT); //enable the mode pins + for( byte j = 0; j < 3; j++){ + digitalWrite(modePins[i][j],modeState[0][j]); + } +#endif + pinMode(resetPin[i],OUTPUT); //enable the reset pin + digitalWrite(resetPin[i],LOW); //active low reset + delay(1); //allow ic to reset + digitalWrite(resetPin[i],HIGH); //complete reset + } + + // start Serial port: + Serial.begin(9600); //SyncScan runs at 9600Baud, use a serial port of your choice + while(Serial.available()){ + Serial.read(); //Clear the buffer + } + + + configureTimer(); //setup the motor pulse timers. +} + +void loop(){ + static unsigned long lastMillis = millis(); + static boolean isLedOn = false; + char decodedPacket[11]; //temporary store for completed command ready to be processed + if (Serial.available()) { //is there a byte in buffer + digitalWrite(statusPin,HIGH); //Turn on the LED to indicate activity. + char recievedChar = Serial.read(); //get the next character in buffer +#ifdef DEBUG + Serial1.write(recievedChar); +#endif + char decoded = synta.recieveCommand(decodedPacket,recievedChar); //once full command packet recieved, decodedPacket returns either error packet, or valid packet + if (decoded == 1){ //Valid Packet + decodeCommand(synta.command(),decodedPacket); //decode the valid packet + } else if (decoded == -1){ //Error + Serial.print(decodedPacket); //send the error packet (recieveCommand() already generated the error packet, so just need to send it) +#ifdef DEBUG + Serial1.print(F(" ->Res:")); + Serial1.println(decodedPacket); +#endif + } //otherwise command not yet fully recieved, so wait for next byte + lastMillis = millis(); + isLedOn = true; + } + if (isLedOn && (millis() > lastMillis + 20)){ + isLedOn = false; + digitalWrite(statusPin,LOW); //Turn LED back off after a short delay. + } +#ifdef DEBUG + if (Serial1.available()) { //is there a byte in buffer + Serial1.println(); + Serial1.println(currentMotorSpeed(RA)); + Serial1.println(currentMotorSpeed(DC)); + Serial1.println(interruptOVFCount(RA)); + Serial1.println(interruptOVFCount(DC)); + Serial1.println(); + Serial1.read(); + } +#endif +} + +void decodeCommand(char command, char* packetIn){ //each command is axis specific. The axis being modified can be retrieved by calling synta.axis() + char response[11]; //generated response string + unsigned long responseData = 0; //data for response + byte axis = synta.axis(); + unsigned int correction; + //byte scalar = synta.scalar[axis]+1; + switch(command){ + case 'e': //readonly, return the eVal (version number) + responseData = synta.cmd.eVal[axis]; //response to the e command is stored in the eVal function for that axis. + break; + case 'a': //readonly, return the aVal (steps per axis) + responseData = synta.cmd.aVal[axis]; //response to the a command is stored in the aVal function for that axis. + break; + case 'b': //readonly, return the bVal (sidereal step rate) + responseData = synta.cmd.bVal[axis]; //response to the b command is stored in the bVal function for that axis. + correction = (synta.cmd.siderealIVal[axis] << 1); + responseData = (responseData * (correction+1))/correction; //account for rounding inside Skywatcher DLL. + break; + case 'g': //readonly, return the gVal (high speed multiplier) + responseData = synta.cmd.gVal[axis]; //response to the g command is stored in the gVal function for that axis. + break; + case 's': //readonly, return the sVal (steps per worm rotation) + responseData = synta.cmd.sVal[axis]; //response to the s command is stored in the sVal function for that axis. + break; + case 'f': //readonly, return the fVal (axis status) + responseData = synta.cmd.fVal(axis); //response to the f command is stored in the fVal function for that axis. + break; + case 'j': //readonly, return the jVal (current position) + responseData = synta.cmd.jVal[axis]; //response to the j command is stored in the jVal function for that axis. + break; + case 'K': //stop the motor, return empty response + motorStop(axis,0); //normal ISR based decelleration trigger. + break; + case 'L': + motorStop(axis,1); //emergency axis stop. + motorDisable(axis); //shutdown driver power. + break; + case 'G': //set mode and direction, return empty response + if (packetIn[0] == '0'){ + packetIn[0] = '2'; //don't allow a high torque goto. But do allow a high torque slew. + } + synta.cmd.setGVal(axis, (packetIn[0] - '0')); //Store the current mode for the axis + synta.cmd.setDir(axis, (packetIn[1] - '0')); //Store the current direction for that axis + break; + case 'H': //set goto position, return empty response (this sets the number of steps to move from cuurent position if in goto mode) + synta.cmd.setHVal(axis, synta.hexToLong(packetIn)); //set the goto position container (convert string to long first) + break; + case 'I': //set slew speed, return empty response (this sets the speed to move at if in slew mode) + responseData = synta.hexToLong(packetIn); + if (responseData > minSpeed[axis]){ + responseData = minSpeed[axis]; //minimum speed + } + synta.cmd.setIVal(axis, responseData); //set the speed container (convert string to long first) + + //This will be different if you use a different motor code + calculateRate(axis); //Used to convert speed into the number of 0.5usecs per step. Result is stored in TimerOVF + + + responseData = 0; + break; + case 'E': //set the current position, return empty response + synta.cmd.setjVal(axis, synta.hexToLong(packetIn)); //set the current position (used to sync to what EQMOD thinks is the current position at startup + break; + case 'F': //Enable the motor driver, return empty response + motorEnable(axis); //This enables the motors - gives the motor driver board power + break; + default: //Return empty response (deals with commands that don't do anything before the response sent (i.e 'J'), or do nothing at all (e.g. 'M', 'L') ) + break; + } + + synta.assembleResponse(response, command, responseData); //generate correct response (this is required as is) + Serial.print(response); //send response to the serial port +#ifdef DEBUG + Serial1.print(F(" ->Res:")); + Serial1.println(response); +#endif + + if(command == 'J'){ //J tells + if(synta.cmd.GVal[axis] & 1){ + + //This is the funtion that enables a slew type move. + slewMode(axis); //Slew type + + + } else { + + //This is the function for goto mode. You may need to customise it for a different motor driver + gotoMode(axis); //Goto Mode + + + } + } +} + + + +//Calculates the rate based on the recieved I value +void calculateRate(byte motor){ + + unsigned long rate; + unsigned long remainder; + float floatRemainder; + unsigned long divisor = synta.cmd.bVal[motor]; + byte GVal = synta.cmd.GVal[motor]; + if((GVal == 2)||(GVal == 1)){ //Normal Speed + highSpeed[motor] = false; + distributionWidth[motor] = NormalDistnWidth; + } else { //High Speed + highSpeed[motor] = true; + distributionWidth[motor] = HighspeedDistnWidth; //There are 8 times fewer steps over which to distribute extra clock cycles + } + + //When dividing a very large number by a much smaller on, float accuracy is abismal. So firstly we use integer math to split the division into quotient and remainder + rate = timerCountRate / divisor; //Calculate the quotient + remainder = timerCountRate % divisor; //Calculate the remainder + + //Then convert the remainder into a decimal number (division of a small number by a larger one, improving accuracy) + floatRemainder = (float)remainder/(float)divisor; //Convert the remainder to a decimal. + + //Multiply the remainder by distributionWidth to work out an approximate number of extra clocks needed per full step (each step is 'distributionWidth' microsteps) + floatRemainder *= (float)distributionWidth[motor]; + //This many extra cycles are needed: + remainder = (unsigned long)round(floatRemainder); + + //Now truncate to an unsigned int with a sensible max value (the int is to avoid register issues with the 16 bit timer) + if(rate > 65535UL){ + rate = 65535UL; + } else if (rate < 128UL) { + rate = 128UL; + } +#if defined(__AVR_ATmega162__) + rate--; +#endif + + for (byte i = 0; i < distributionWidth[motor]; i++){ +#if defined(__AVR_ATmega162__) + timerOVF[motor][i] = rate; //Subtract 1 as timer is 0 indexed. +#else + timerOVF[motor][i] = rate; //Hmm, for some reason this one doesn't need 1 subtracting??? +#endif + } + + //evenly distribute the required number of extra clocks over the full step. + for (unsigned long i = 0; i < remainder; i++){ + float distn = i; + distn *= (float)distributionWidth[motor]; + distn /= (float)remainder; + byte index = (byte)ceil(distn); + timerOVF[motor][index] += 1; + } + +#ifdef DEBUG + Serial1.println(); + Serial1.println(rate); + Serial1.println(); +#endif + + distributionWidth[motor]--; //decrement to get its bitmask. (distnWidth is always a power of 2) +} + +void motorEnable(byte axis){ + digitalWrite(enablePin[axis],LOW); + synta.cmd.setFVal(axis,1); +} + +void motorDisable(byte axis){ + digitalWrite(enablePin[axis],LOW); + synta.cmd.setFVal(axis,0); +} + +void slewMode(byte axis){ + motorStart(axis,1/*decellerateStepsFactor[axis]*/); //Begin PWM +} + +void gotoMode(byte axis){ + if (synta.cmd.HVal[axis] < 2){ + synta.cmd.setHVal(axis,2); + } + unsigned long HVal = synta.cmd.HVal[axis]; + unsigned long halfHVal = HVal >> 1; + unsigned int gotoSpeed = normalGotoSpeed[axis]; + byte decelerationLength; + if (halfHVal < 80) { + decelerationLength = (byte)halfHVal; + if (gotoFactor < 4) { + gotoSpeed += synta.cmd.stepIncrement[axis]; + } + if (gotoFactor < 8) { + gotoSpeed += synta.cmd.stepIncrement[axis]; //for short goto's when goto speed is very high, use a slower target speed. + } + } else { + decelerationLength = 80; + } + //byte decelerationLength = (byte)min(halfHVal,80); +#ifdef DEBUG + Serial1.println(); + Serial1.println(decelerationLength); + Serial1.println(synta.cmd.jVal[axis]); +#endif + gotoPosn[axis] = synta.cmd.jVal[axis] + (synta.cmd.stepDir[axis] * (synta.cmd.HVal[axis] - (unsigned long)decelerationLength)); //current position + relative change - decelleration region + +#ifdef DEBUG + Serial1.println(gotoPosn[axis]); + Serial1.println(); +#endif + synta.cmd.setIVal(axis, gotoSpeed); + calculateRate(axis); + motorStart(axis,decelerationLength/*decellerateStepsFactor[axis]*/); //Begin PWM + synta.cmd.setGotoEn(axis,1); + //} +} +/* +void normalTorqueTimerEnable(byte motor) { +// if(motor){ +// TCCR1B &= ~((1<<CS12) | (1<<CS11));//00x +// TCCR1B |= (1<<CS10);//xx1 +// } else { +// TCCR3B &= ~((1<<CS32) | (1<<CS31));//00x +// TCCR3B |= (1<<CS30);//xx1 +// } + //set normal speed mode + synta.cmd.setStepLength(motor, 1); +#ifdef LEGACY_MODE + for( byte j = 0; j < 2; j++){ + digitalWrite(modePins[motor][j],modeState[0][j]); + } +#else + for( byte j = 0; j < 3; j++){ + digitalWrite(modePins[motor][j],modeState[0][j]); + } +#endif +}*/ + +void timerEnable(byte motor, byte mode) { + if (mode){ + //FCPU/8 + timerPrescalarRegister(motor) &= ~((1<<CSn2) | (1<<CSn0)); //0x0 + timerPrescalarRegister(motor) |= (1<<CSn1);//x1x + } else { + //FCPU/1 + timerPrescalarRegister(motor) &= ~((1<<CSn2) | (1<<CSn1));//00x + timerPrescalarRegister(motor) |= (1<<CSn0);//xx1 + } + synta.cmd.setStepLength(motor, (mode ? synta.cmd.gVal[motor] : 1)); +#ifdef LEGACY_MODE + for( byte j = 0; j < 2; j++){ + digitalWrite(modePins[motor][j],modeState[mode][j]); + } +#else + for( byte j = 0; j < 3; j++){ + digitalWrite(modePins[motor][j],modeState[mode][j]); + } +#endif +// if(motor){ +// TCCR1B &= ~((1<<CS12) | (1<<CS10)); //0x0 +// TCCR1B |= (1<<CS11);//x1x +// } else { +// TCCR3B &= ~((1<<CS32) | (1<<CS30)); //0x0 +// TCCR3B |= (1<<CS31);//x1x +// } + //Enable Highspeed mode +// synta.cmd.setStepLength(motor, synta.cmd.gVal[motor]); +//#ifdef LEGACY_MODE +// for( byte j = 0; j < 2; j++){ +// digitalWrite(modePins[motor][j],modeState[1][j]); +// } +//#else +// for( byte j = 0; j < 3; j++){ +// digitalWrite(modePins[motor][j],modeState[1][j]); +// } +//#endif +} + +inline void timerDisable(byte motor) { + interruptControlRegister(motor) &= ~interruptControlBitMask(motor); //Disable timer interrupt + timerPrescalarRegister(motor) &= ~((1<<CSn2) | (1<<CSn1) | (1<<CSn0));//00x +} + +void motorStart(byte motor, byte gotoDeceleration){ + digitalWrite(dirPin[motor],encodeDirection[motor]^synta.cmd.dir[motor]); //set the direction + synta.cmd.setStopped(motor, 0); + +#ifdef DEBUG + Serial1.println(); + Serial1.println(synta.cmd.IVal[motor]); + Serial1.println(); +#endif + +// if(!highSpeed[motor]){ //Normal Speed +// normalTorqueTimerEnable(motor); +// } else { +// highTorqueTimerEnable(motor); +// } + + interruptCount(motor) = 1; + currentMotorSpeed(motor) = minSpeed[motor]; + distributionSegment(motor) = 0; + decelerationSteps(motor) = -gotoDeceleration; + timerCountRegister(motor) = 0; + interruptControlRegister(motor) |= interruptControlBitMask(motor); + interruptOVFCount(motor) = timerOVF[motor][0]; + timerEnable(motor,highSpeed[motor]); +// if(motor == DC){ +// ICR1 = timerOVF[motor][0]; +// interruptCount(DC) = 1;//synta.cmd.IVal[motor]; +// currentMotorSpeed(DC) = 640;//synta.cmd.IVal[motor]; +// TCNT1 = 0; +// distributionSegment(DC) = 0; +// decelerationSteps(DC) = -gotoDeceleration; //inform goto of how many decelleration steps to use (ignored if slew) +// TCCR1A |= (1<<COM1B1); //Set port operation to fast PWM +//#if defined(__AVR_ATmega162__) +// TIMSK |= (1<<TICIE1); //Enable timer interrupt +//#elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) +// TIMSK1 |= (1<<ICIE1); //Enable timer interrupt +//#endif +// } else { +// ICR3 = timerOVF[motor][0]; +// OCR1B = 1;//synta.cmd.IVal[motor]; +// OCR3B = 640;//synta.cmd.IVal[motor]; +// TCNT3 = 0; +// distributionSegment(RA) = 0; +// PORTC = -gotoDeceleration; //inform goto of how many decelleration steps to use (ignored if slew) +// TCCR3A |= (1<<COM3A1); //Set port operation to fast PWM +//#if defined(__AVR_ATmega162__) +// ETIMSK |= (1<<TICIE3); //Enable timer interrupt +//#elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) +// TIMSK3 |= (1<<ICIE3); //Enable timer interrupt +//#endif +// } +} + +void motorStop(byte motor, byte emergency){ + if (emergency) { + //trigger instant shutdown of the motor in an emergency. + //interruptControlRegister(motor) &= ~interruptControlBitMask(motor); +// if(motor){ +//#if defined(__AVR_ATmega162__) +// TIMSK &= ~(1<<TICIE1); //Disable timer interrupt +//#elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) +// TIMSK1 &= ~(1<<ICIE1); //Disable timer interrupt +//#endif +// } else { +//#if defined(__AVR_ATmega162__) +// ETIMSK &= ~(1<<TICIE3); //Disable timer interrupt +//#elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) +// TIMSK3 &= ~(1<<ICIE3); //Disable timer interrupt +//#endif +// } + synta.cmd.setGotoEn(motor,0); //Not in goto mode. + synta.cmd.setStopped(motor,1); //mark as stopped + timerDisable(motor); + + } else if (!synta.cmd.stopped[motor]){ //Only stop if not already stopped - for some reason EQMOD stops both axis when slewing, even if one isn't currently moving? + //trigger ISR based decelleration + synta.cmd.IVal[motor] = minSpeed[motor] + synta.cmd.stepIncrement[motor]; + } +} + +//Timer Interrupt----------------------------------------------------------------------------- +void configureTimer(){ + interruptControlRegister(DC) = 0; //disable all timer interrupts. +#if defined(__AVR_ATmega162__) + interruptControlRegister(RA) &= 0b00000011; //for 162, the lower 2 bits of the declination register control another timer, so leave them alone. +#else + interruptControlRegister(RA) = 0; +#endif +//#if defined(__AVR_ATmega162__) +// TIMSK &= ~(1<<TOIE1); //disable timer so it can be configured +// ETIMSK &= ~(1<<TOIE3); //disable timer so it can be configured +// TIMSK &= ~((1<<OCIE1A) | (1<<OCIE1B)); +// ETIMSK &= ~((1<<OCIE3A) | (1<<OCIE3B)); +//#elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) +// TIMSK1 &= ~(1<<TOIE1); //disable timer so it can be configured +// TIMSK3 &= ~(1<<TOIE3); //disable timer so it can be configured +// TIMSK1 &= ~((1<<OCIE1A) | (1<<OCIE1B) | (1<<OCIE1C)); +// TIMSK3 &= ~((1<<OCIE3A) | (1<<OCIE3B) | (1<<OCIE3C)); +//#endif + //set to ctc mode (0100) + TCCR1A = 0;//~((1<<WGM11) | (1<<WGM10)); + TCCR1B = ((1<<WGM12) | (1<<WGM13)); + TCCR3A = 0;//~((1<<WGM31) | (1<<WGM30)); + TCCR3B = ((1<<WGM32) | (1<<WGM33)); +} + + + +/*Timer Interrupt Vector*/ +ISR(TIMER3_CAPT_vect) { + byte timeSegment = distributionSegment(DC); + byte index = (distributionWidth[DC] << 1) & timeSegment; + interruptOVFCount(DC) = *(int*)((byte*)timerOVF[DC] + index); //move to next pwm period + distributionSegment(DC) = timeSegment + 1; + + unsigned int count = interruptCount(DC)-1; //OCR1B is used as it is an unused register which affords us quick access. + if (count == 0) { + register byte port asm("r18") = stepPort(DC); + register unsigned int startVal asm("r24") = currentMotorSpeed(DC); + //byte port = STEP0PORT; + //unsigned int startVal = currentMotorSpeed(DC); + interruptCount(DC) = startVal; //start val is used for specifying how many interrupts between steps. This tends to IVal after acceleration + if (port & stepHigh(DC)){ + stepPort(DC) = port & stepLow(DC); + unsigned long jVal = synta.cmd.jVal[DC]; + jVal = jVal + synta.cmd.stepDir[DC]; + synta.cmd.jVal[DC] = jVal; + if(synta.cmd.gotoEn[DC]){ + if (gotoPosn[DC] == jVal){ //reached the decelleration marker. Note that this line loads gotoPosn[] into r24:r27 + //will decellerate the rest of the way. So first move gotoPosn[] to end point. + if (decelerationSteps(DC) & _BV(7)) { + /* + unsigned long gotoPos = gotoPosn[DC]; + if (synta.cmd.stepDir[DC] < 0){ + gotoPosn[DC] = gotoPos + decelerationSteps(DC); + } else { + gotoPosn[DC] = gotoPos - decelerationSteps(DC); + } + */ + //--- This is a heavily optimised version of the code commented out just above ------------ + //During compare of jVal and gotoPosn[], gotoPosn[] was loaded into r24 to r27 + register char stepDir asm("r19") = synta.cmd.stepDir[DC]; + asm volatile( + "in %A0, %2 \n\t" + "cp %1, __zero_reg__ \n\t" + "brlt .+4 \n\t" + "neg %A0 \n\t" + "eor %B0, %B0 \n\t" + "mov %C0, %B0 \n\t" + "mov %D0, %B0 \n\t" + "add %A0, r24 \n\t" //add previously loaded gotoPosn[] registers to new gotoPosn[] registers. + "adc %B0, r25 \n\t" + "adc %C0, r26 \n\t" + "adc %D0, r27 \n\t" + : "=a" (gotoPosn[DC]) //goto selects r18:r21. This adds sts commands for all 4 bytes + : "r" (stepDir),"I" (_SFR_IO_ADDR(decelerationSteps(DC))) //stepDir is in r19 to match second byte of goto. + : + ); + //----------------------------------------------------------------------------------------- + decelerationSteps(DC) = 0; //say we are stopping + synta.cmd.IVal[DC] = minSpeed[DC]; //decellerate to min speed. This is possible in at most 80 steps. + } else { + goto stopMotorISR3; + } + } + } + if (currentMotorSpeed(DC) > minSpeed[DC]) { +stopMotorISR3: + synta.cmd.gotoEn[DC] = 0; //Not in goto mode. + synta.cmd.stopped[DC] = 1; //mark as stopped + timerDisable(DC); + } + } else { + stepPort(DC) = port | stepHigh(DC); + register unsigned int iVal asm("r20") = synta.cmd.IVal[DC]; + //unsigned int iVal = synta.cmd.IVal[RA]; + register byte increment asm("r0") = synta.cmd.stepIncrement[DC]; + asm volatile( + "movw r18, %0 \n\t" + "sub %A0, %2 \n\t" + "sbc %B0, __zero_reg__ \n\t" + "cp %A0, %A1 \n\t" + "cpc %B0, %B1 \n\t" + "brge 1f \n\t" //branch if iVal <= (startVal-increment) + "movw %0, r18 \n\t" + "add %A0, %2 \n\t" + "adc %B0, __zero_reg__ \n\t" + "cp %A1, %A0 \n\t" + "cpc %B1, %B0 \n\t" + "brge 1f \n\t" //branch if (startVal+increment) <= iVal + "movw %0, %1 \n\t" //copy iVal to startVal + "1: \n\t" + : "=&w" (startVal) //startVal is in r24:25 + : "a" (iVal), "t" (increment) //iVal is in r20:21 + : + ); + currentMotorSpeed(DC) = startVal; //store startVal + /* + if (startVal - increment >= iVal) { // if (iVal <= startVal-increment) + startVal = startVal - increment; + } else if (startVal + increment <= iVal){ + startVal = startVal + increment; + } else { + startVal = iVal; + } + currentMotorSpeed(DC) = startVal; + */ + } + } else { + interruptCount(DC) = count; + } +} + +/*Timer Interrupt Vector*/ +ISR(TIMER1_CAPT_vect) { + byte timeSegment = distributionSegment(RA); + byte index = (distributionWidth[RA] << 1) & timeSegment; + +#if defined(__AVR_ATmega162__) + asm("nop"); //ICR1 is two clocks faster to write to than ICR3, so account for that + asm("nop"); +#endif + interruptOVFCount(RA) = *(int*)((byte*)timerOVF[RA] + index); //move to next pwm period + distributionSegment(RA) = timeSegment + 1; + + unsigned int count = interruptCount(RA)-1; + if (count == 0) { + register byte port asm("r18") = stepPort(RA); + register unsigned int startVal asm("r24") = currentMotorSpeed(RA); + //byte port = STEP1PORT; + //unsigned int startVal = currentMotorSpeed(RA); + interruptCount(RA) = startVal; //start val is used for specifying how many interrupts between steps. This tends to IVal after acceleration + if (port & stepHigh(RA)){ + stepPort(RA) = port & stepLow(RA); + unsigned long jVal = synta.cmd.jVal[RA]; + jVal = jVal + synta.cmd.stepDir[RA]; + synta.cmd.jVal[RA] = jVal; + if(synta.cmd.gotoEn[RA]){ + if (jVal == gotoPosn[RA]){ //reached the decelleration marker + //will decellerate the rest of the way. So first move gotoPosn[] to end point. + if (decelerationSteps(RA) & _BV(7)) { + /* + unsigned long gotoPos = gotoPosn[RA]; + if (synta.cmd.stepDir[RA] < 0){ + gotoPosn[RA] = gotoPos + decelerationSteps(RA); + } else { + gotoPosn[RA] = gotoPos - decelerationSteps(RA); + } + */ + //--- This is a heavily optimised version of the code commented out just above ------------ + register char temp asm("r19") = synta.cmd.stepDir[RA]; + asm volatile( + "in %A0, %2 \n\t" + "cp %1, __zero_reg__ \n\t" + "brlt .+4 \n\t" + "neg %A0 \n\t" + "eor %B0, %B0 \n\t" + "mov %C0, %B0 \n\t" + "mov %D0, %B0 \n\t" + "add %A0, r24 \n\t" + "adc %B0, r25 \n\t" + "adc %C0, r26 \n\t" + "adc %D0, r27 \n\t" + : "=a" (gotoPosn[RA]) //goto selects r18:r21. This adds sts commands for all 4 bytes + : "r" (temp),"I" (_SFR_IO_ADDR(decelerationSteps(RA))) //temp is in r19 to match second byte of goto. + : + ); + decelerationSteps(RA) = 0; //say we are stopping + synta.cmd.IVal[RA] = minSpeed[RA]; //decellerate to min speed. This is possible in at most 80 steps. + } else { + goto stopMotorISR1; + } + } + } + if (currentMotorSpeed(RA) > minSpeed[RA]) { +stopMotorISR1: + //interruptControlRegister(RA) &= ~interruptControlBitMask(RA); + synta.cmd.gotoEn[RA] = 0; //Not in goto mode. + synta.cmd.stopped[RA] = 1; //mark as stopped + timerDisable(RA); + } + } else { + stepPort(RA) = port | stepHigh(RA); + register unsigned int iVal asm("r20") = synta.cmd.IVal[RA]; + //unsigned int iVal = synta.cmd.IVal[RA]; + register byte increment asm("r0") = synta.cmd.stepIncrement[RA]; + asm volatile( + "movw r18, %0 \n\t" + "sub %A0, %2 \n\t" + "sbc %B0, __zero_reg__ \n\t" + "cp %A0, %A1 \n\t" + "cpc %B0, %B1 \n\t" + "brge 1f \n\t" //branch if iVal <= (startVal-increment) + "movw %0, r18 \n\t" + "add %A0, %2 \n\t" + "adc %B0, __zero_reg__ \n\t" + "cp %A1, %A0 \n\t" + "cpc %B1, %B0 \n\t" + "brge 1f \n\t" //branch if (startVal+increment) <= iVal + "movw %0, %1 \n\t" //copy iVal to startVal + "1: \n\t" + : "=&w" (startVal) //startVal is in r24:25 + : "a" (iVal), "t" (increment) //iVal is in r20:21 + : + ); + currentMotorSpeed(RA) = startVal; //store startVal + /* + if (startVal - increment >= iVal) { // if (iVal <= startVal-increment) + startVal = startVal - increment; + } else if (startVal + increment <= iVal){ + startVal = startVal + increment; + } else { + startVal = iVal; + } + currentMotorSpeed(RA) = startVal; + */ + } + } else { + interruptCount(RA) = count; + } +} + +#else +#error Unsupported Part! Please use an Arduino Mega, or ATMega162 +#endif + diff --git a/AstroEQ-Firmware/EEPROMAddresses.h b/AstroEQ-Firmware/EEPROMAddresses.h new file mode 100644 index 0000000000000000000000000000000000000000..dccbeb835a2277a9e2bcd8fba247119eb1dcf5e1 --- /dev/null +++ b/AstroEQ-Firmware/EEPROMAddresses.h @@ -0,0 +1,16 @@ + +#define EEPROMStart_Address ( 0 ) +#define AstroEQID_Address (EEPROMStart_Address + 0 ) +//#define AstroEQVer_Address (EEPROMStart_Address + 8 ) +#define RAReverse_Address (EEPROMStart_Address + 9 ) +#define DECReverse_Address (EEPROMStart_Address + 10) +#define Driver_Address (EEPROMStart_Address + 11) +#define NormalGoto_Address (EEPROMStart_Address + 12) //and 13 +#define aVal1_Address (EEPROMStart_Address + 14) //steps/axis +#define aVal2_Address (EEPROMStart_Address + 18) //steps/axis +#define bVal1_Address (EEPROMStart_Address + 22) //sidereal rate +#define bVal2_Address (EEPROMStart_Address + 26) //sidereal rate +#define sVal1_Address (EEPROMStart_Address + 30) //steps/worm rotation +#define sVal2_Address (EEPROMStart_Address + 34) //steps/worm rotation +#define IVal1_Address (EEPROMStart_Address + 38) //steps/worm rotation +#define IVal2_Address (EEPROMStart_Address + 40) //steps/worm rotation diff --git a/AstroEQ-Firmware/EEPROMReader.cpp b/AstroEQ-Firmware/EEPROMReader.cpp new file mode 100644 index 0000000000000000000000000000000000000000..9e5fb8315181c01505317e59b8742123a30a5341 --- /dev/null +++ b/AstroEQ-Firmware/EEPROMReader.cpp @@ -0,0 +1,58 @@ + +#include <avr/eeprom.h> +#include "Arduino.h" +#include "EEPROMReader.h" + +uint8_t EEPROMReader::readByte(byte address) +{ + return eeprom_read_byte((unsigned char *) address); +} + +uint16_t EEPROMReader::readInt(byte address) +{ + TwoBytes fetcher; + fetcher.array[0] = readByte(address); + fetcher.array[1] = readByte(address+1); + return fetcher.integer; +} +uint32_t EEPROMReader::readLong(byte address) +{ + FourBytes fetcher; + fetcher.array[0] = readInt(address); + fetcher.array[1] = readInt(address+2); + return fetcher.integer; +} + +void EEPROMReader::readString(char* string, byte len, byte address) +{ + for(byte i = 0; i < len; i++) { + string[i] = readByte(address++); + } +} + +void EEPROMReader::writeByte(uint8_t val, byte address) +{ + return eeprom_write_byte((unsigned char *) address, val); +} + +void EEPROMReader::writeInt(uint16_t val, byte address) +{ + TwoBytes storer = {val}; + writeByte(storer.array[0], address); + writeByte(storer.array[1], address+1); +} +void EEPROMReader::writeLong(uint32_t val, byte address) +{ + FourBytes storer = {val}; + writeInt(storer.array[0], address); + writeInt(storer.array[1], address+2); +} +void EEPROMReader::writeString(const char* string, byte len, byte address) +{ + for(byte i = 0; i < len; i++) { + writeByte(string[i], address+i); + } +} + +EEPROMReader EEPROM; + diff --git a/AstroEQ-Firmware/EEPROMReader.h b/AstroEQ-Firmware/EEPROMReader.h new file mode 100644 index 0000000000000000000000000000000000000000..4d64c7febff794b6820360aa05001f86707111a7 --- /dev/null +++ b/AstroEQ-Firmware/EEPROMReader.h @@ -0,0 +1,33 @@ +#ifndef EEPROM_h +#define EEPROM_h + +#include "Arduino.h" +#include <inttypes.h> + +typedef union { + uint16_t integer; + uint8_t array[2]; +} TwoBytes; + +typedef union { + uint32_t integer; + uint16_t array[2]; + uint8_t bytes[4]; +} FourBytes; + +class EEPROMReader +{ + public: + uint8_t readByte(byte); + uint16_t readInt(byte); + uint32_t readLong(byte); + void readString(char* string, byte len, byte address); + void writeByte(uint8_t,byte); + void writeInt(uint16_t,byte); + void writeLong(uint32_t,byte); + void writeString(const char* string, byte len, byte address); +}; + +extern EEPROMReader EEPROM; + +#endif diff --git a/AstroEQ-Firmware/Open me first/Initialisation Variable Calculator.xlsx b/AstroEQ-Firmware/Open me first/Initialisation Variable Calculator.xlsx deleted file mode 100644 index dfa249e90d2ff8b6799b0d42bda504a305cb15c4..0000000000000000000000000000000000000000 Binary files a/AstroEQ-Firmware/Open me first/Initialisation Variable Calculator.xlsx and /dev/null differ diff --git a/AstroEQ-Firmware/Open me first/README FIRST.txt b/AstroEQ-Firmware/Open me first/README FIRST.txt deleted file mode 100644 index 4edaa9ba0477dd3628e973a31df06c832fd0869d..0000000000000000000000000000000000000000 --- a/AstroEQ-Firmware/Open me first/README FIRST.txt +++ /dev/null @@ -1,36 +0,0 @@ -There are 5 steps to setup AstroEQ for the first time. - -(1) There is a folder named 'hardware'. ----> This needs to be copied into the arduino install dirctory. When asked, merge folders with existing ones, replacing files. ----> This will add support to the arduino IDE for AstroEQ. -[NOTE: If you plan to use the old Arduino Mega hardware, you can skip step (1)] - -(2) In the 'Driver' folder is contained a .inf Windows compatible driver for the AstroEQ USB-Serial port. ----> When you connect AstroEQ, Windows will try to install the board automatically. ----> If Windows Update fails to find a driver, use the Add Hardware... wizard and specify to look in this folder. ----> If you have a Mac or use Linux it should install automatically, but I haven't tested this (I don't have a Mac or Linux) -[NOTE: If you plan to use the old Arduino Mega hardware, you can skip step (2)] - -(3) The "Initialisation Variable Calculator" file will allow you to enter specifics about your mount. ----> It will generate a line of text: Synta synta(...stuff here...); ----> This is the initialisation call for your mount. More about this in step 4. - -(4) In the AstroEQ5 folder, open AstroEQ5.ino with the Arduino IDE. ----> There is some introductary text which you can read if you want to understand more. ----> If not, move to the end of the text and find the line "Synta synta(1281, 26542080, 190985, 16, 184320, 10);" - Approx. line 101 ----> Replace this line with the one generated in step (3). - -(5) Finally you need to download the program. In arduino IDE do the following: ----> (a) Select 'Tools->Board->AstroEQ w/ Atmega162' if you have the new hardware, or 'Tools->Board->Arduino Mega' for the old hardware. -[NOTE: If you use the old hardware there are two versions of an Arduino Mega: 1280 or 2560. Select the one you have] ----> (b) Select 'Tools->Serial Port->//your port//' ----> (c) Select Upload (File->Upload, or the second round button) - -You should now be up and running. Setup EQMOD and connect. If all goes well AstroEQ is now setup and it will be just plug and play from now on. - -If you have any problems, open an issue on the github repository and I will do my best to help. - - - -As a sidenote, If you purchased either a kit, or the IC pack from me, the Atmega162 will come with its bootloader and USB-Serial IC will come ready programmed. -If you buy these IC's yourself, you will need a PIC programmer to burn the .hex file in the Driver folder to the USB-Serial IC, and Atmel programmer to burn the bootloader to the Atmega162 (Tools->Burn Bootloader in Arduino IDE). \ No newline at end of file diff --git a/AstroEQ-Firmware/Open me first/hardware/arduino/boards.txt b/AstroEQ-Firmware/Open me first/hardware/arduino/boards.txt deleted file mode 100644 index 98a8611a15cadd3f72225c71234680789c33f27c..0000000000000000000000000000000000000000 --- a/AstroEQ-Firmware/Open me first/hardware/arduino/boards.txt +++ /dev/null @@ -1,497 +0,0 @@ -############################################################## - -uno.name=Arduino Uno -uno.upload.protocol=arduino -uno.upload.maximum_size=32256 -uno.upload.speed=115200 -uno.bootloader.low_fuses=0xff -uno.bootloader.high_fuses=0xde -uno.bootloader.extended_fuses=0x05 -uno.bootloader.path=optiboot -uno.bootloader.file=optiboot_atmega328.hex -uno.bootloader.unlock_bits=0x3F -uno.bootloader.lock_bits=0x0F -uno.build.mcu=atmega328p -uno.build.f_cpu=16000000L -uno.build.core=arduino -uno.build.variant=standard - -############################################################## - -atmega328.name=Arduino Duemilanove w/ ATmega328 - -atmega328.upload.protocol=arduino -atmega328.upload.maximum_size=30720 -atmega328.upload.speed=57600 - -atmega328.bootloader.low_fuses=0xFF -atmega328.bootloader.high_fuses=0xDA -atmega328.bootloader.extended_fuses=0x05 -atmega328.bootloader.path=atmega -atmega328.bootloader.file=ATmegaBOOT_168_atmega328.hex -atmega328.bootloader.unlock_bits=0x3F -atmega328.bootloader.lock_bits=0x0F - -atmega328.build.mcu=atmega328p -atmega328.build.f_cpu=16000000L -atmega328.build.core=arduino -atmega328.build.variant=standard - -############################################################## - -diecimila.name=Arduino Diecimila or Duemilanove w/ ATmega168 - -diecimila.upload.protocol=arduino -diecimila.upload.maximum_size=14336 -diecimila.upload.speed=19200 - -diecimila.bootloader.low_fuses=0xff -diecimila.bootloader.high_fuses=0xdd -diecimila.bootloader.extended_fuses=0x00 -diecimila.bootloader.path=atmega -diecimila.bootloader.file=ATmegaBOOT_168_diecimila.hex -diecimila.bootloader.unlock_bits=0x3F -diecimila.bootloader.lock_bits=0x0F - -diecimila.build.mcu=atmega168 -diecimila.build.f_cpu=16000000L -diecimila.build.core=arduino -diecimila.build.variant=standard - -############################################################## - -nano328.name=Arduino Nano w/ ATmega328 - -nano328.upload.protocol=arduino -nano328.upload.maximum_size=30720 -nano328.upload.speed=57600 - -nano328.bootloader.low_fuses=0xFF -nano328.bootloader.high_fuses=0xDA -nano328.bootloader.extended_fuses=0x05 -nano328.bootloader.path=atmega -nano328.bootloader.file=ATmegaBOOT_168_atmega328.hex -nano328.bootloader.unlock_bits=0x3F -nano328.bootloader.lock_bits=0x0F - -nano328.build.mcu=atmega328p -nano328.build.f_cpu=16000000L -nano328.build.core=arduino -nano328.build.variant=eightanaloginputs - -############################################################## - -nano.name=Arduino Nano w/ ATmega168 - -nano.upload.protocol=arduino -nano.upload.maximum_size=14336 -nano.upload.speed=19200 - -nano.bootloader.low_fuses=0xff -nano.bootloader.high_fuses=0xdd -nano.bootloader.extended_fuses=0x00 -nano.bootloader.path=atmega -nano.bootloader.file=ATmegaBOOT_168_diecimila.hex -nano.bootloader.unlock_bits=0x3F -nano.bootloader.lock_bits=0x0F - -nano.build.mcu=atmega168 -nano.build.f_cpu=16000000L -nano.build.core=arduino -nano.build.variant=eightanaloginputs - -############################################################## - -mega2560.name=Arduino Mega 2560 or Mega ADK - -mega2560.upload.protocol=stk500v2 -mega2560.upload.maximum_size=258048 -mega2560.upload.speed=115200 - -mega2560.bootloader.low_fuses=0xFF -mega2560.bootloader.high_fuses=0xD8 -mega2560.bootloader.extended_fuses=0xFD -mega2560.bootloader.path=stk500v2 -mega2560.bootloader.file=stk500boot_v2_mega2560.hex -mega2560.bootloader.unlock_bits=0x3F -mega2560.bootloader.lock_bits=0x0F - -mega2560.build.mcu=atmega2560 -mega2560.build.f_cpu=16000000L -mega2560.build.core=arduino -mega2560.build.variant=mega - -############################################################## - -mega.name=Arduino Mega (ATmega1280) - -mega.upload.protocol=arduino -mega.upload.maximum_size=126976 -mega.upload.speed=57600 - -mega.bootloader.low_fuses=0xFF -mega.bootloader.high_fuses=0xDA -mega.bootloader.extended_fuses=0xF5 -mega.bootloader.path=atmega -mega.bootloader.file=ATmegaBOOT_168_atmega1280.hex -mega.bootloader.unlock_bits=0x3F -mega.bootloader.lock_bits=0x0F - -mega.build.mcu=atmega1280 -mega.build.f_cpu=16000000L -mega.build.core=arduino -mega.build.variant=mega - -############################################################## - -#leonardo.name=Arduino Leonardo -#leonardo.upload.protocol=arduino -#leonardo.upload.maximum_size=28672 -#leonardo.upload.speed=1200 -#leonardo.bootloader.low_fuses=0xde -#leonardo.bootloader.high_fuses=0xd8 -#leonardo.bootloader.extended_fuses=0xcb -#leonardo.bootloader.path=diskloader -#leonardo.bootloader.file=DiskLoader-Leonardo.hex -#leonardo.bootloader.unlock_bits=0x3F -#leonardo.bootloader.lock_bits=0x2F -#leonardo.build.mcu=atmega32u4 -#leonardo.build.f_cpu=16000000L -#leonardo.build.core=arduino -#leonardo.build.variant=leonardo - -############################################################## - -#micro.name=Arduino Micro -#micro.upload.protocol=arduino -#micro.upload.maximum_size=30720 -#micro.upload.speed=1200 -#micro.bootloader.low_fuses=0xde -#micro.bootloader.high_fuses=0xda -#micro.bootloader.extended_fuses=0xcb -#micro.bootloader.path=diskloader -#micro.bootloader.file=DiskLoader-Micro.hex -#micro.bootloader.unlock_bits=0x3F -#micro.bootloader.lock_bits=0x2F -#micro.build.mcu=atmega32u4 -#micro.build.f_cpu=16000000L -#micro.build.core=arduino -#micro.build.variant=micro - -############################################################## - -mini328.name=Arduino Mini w/ ATmega328 - -mini328.upload.protocol=stk500 -mini328.upload.maximum_size=28672 -mini328.upload.speed=115200 - -mini328.bootloader.low_fuses=0xff -mini328.bootloader.high_fuses=0xd8 -mini328.bootloader.extended_fuses=0x05 -mini328.bootloader.path=optiboot -mini328.bootloader.file=optiboot_atmega328-Mini.hex -mini328.bootloader.unlock_bits=0x3F -mini328.bootloader.lock_bits=0x0F - -mini328.build.mcu=atmega328p -mini328.build.f_cpu=16000000L -mini328.build.core=arduino -mini328.build.variant=eightanaloginputs - -############################################################## - -mini.name=Arduino Mini w/ ATmega168 - -mini.upload.protocol=arduino -mini.upload.maximum_size=14336 -mini.upload.speed=19200 - -mini.bootloader.low_fuses=0xff -mini.bootloader.high_fuses=0xdd -mini.bootloader.extended_fuses=0x00 -mini.bootloader.path=atmega -mini.bootloader.file=ATmegaBOOT_168_ng.hex -mini.bootloader.unlock_bits=0x3F -mini.bootloader.lock_bits=0x0F - -mini.build.mcu=atmega168 -mini.build.f_cpu=16000000L -mini.build.core=arduino -mini.build.variant=eightanaloginputs - -############################################################## - -ethernet.name=Arduino Ethernet - -ethernet.upload.protocol=arduino -ethernet.upload.maximum_size=32256 -ethernet.upload.speed=115200 - -ethernet.bootloader.low_fuses=0xff -ethernet.bootloader.high_fuses=0xde -ethernet.bootloader.extended_fuses=0x05 -ethernet.bootloader.path=optiboot -ethernet.bootloader.file=optiboot_atmega328.hex -ethernet.bootloader.unlock_bits=0x3F -ethernet.bootloader.lock_bits=0x0F - -ethernet.build.variant=standard -ethernet.build.mcu=atmega328p -ethernet.build.f_cpu=16000000L -ethernet.build.core=arduino - -############################################################## - -fio.name=Arduino Fio - -fio.upload.protocol=arduino -fio.upload.maximum_size=30720 -fio.upload.speed=57600 - -fio.bootloader.low_fuses=0xFF -fio.bootloader.high_fuses=0xDA -fio.bootloader.extended_fuses=0x05 -fio.bootloader.path=arduino:atmega -fio.bootloader.file=ATmegaBOOT_168_atmega328_pro_8MHz.hex -fio.bootloader.unlock_bits=0x3F -fio.bootloader.lock_bits=0x0F - -fio.build.mcu=atmega328p -fio.build.f_cpu=8000000L -fio.build.core=arduino -fio.build.variant=eightanaloginputs - -############################################################## - -bt328.name=Arduino BT w/ ATmega328 - -bt328.upload.protocol=arduino -bt328.upload.maximum_size=28672 -bt328.upload.speed=19200 -bt328.upload.disable_flushing=true - -bt328.bootloader.low_fuses=0xff -bt328.bootloader.high_fuses=0xd8 -bt328.bootloader.extended_fuses=0x05 -bt328.bootloader.path=bt -bt328.bootloader.file=ATmegaBOOT_168_atmega328_bt.hex -bt328.bootloader.unlock_bits=0x3F -bt328.bootloader.lock_bits=0x0F - -bt328.build.mcu=atmega328p -bt328.build.f_cpu=16000000L -bt328.build.core=arduino -bt328.build.variant=eightanaloginputs - -############################################################## - -bt.name=Arduino BT w/ ATmega168 - -bt.upload.protocol=arduino -bt.upload.maximum_size=14336 -bt.upload.speed=19200 -bt.upload.disable_flushing=true - -bt.bootloader.low_fuses=0xff -bt.bootloader.high_fuses=0xdd -bt.bootloader.extended_fuses=0x00 -bt.bootloader.path=bt -bt.bootloader.file=ATmegaBOOT_168.hex -bt.bootloader.unlock_bits=0x3F -bt.bootloader.lock_bits=0x0F - -bt.build.mcu=atmega168 -bt.build.f_cpu=16000000L -bt.build.core=arduino -bt.build.variant=eightanaloginputs - -############################################################## - -lilypad328.name=LilyPad Arduino w/ ATmega328 - -lilypad328.upload.protocol=arduino -lilypad328.upload.maximum_size=30720 -lilypad328.upload.speed=57600 - -lilypad328.bootloader.low_fuses=0xFF -lilypad328.bootloader.high_fuses=0xDA -lilypad328.bootloader.extended_fuses=0x05 -lilypad328.bootloader.path=atmega -lilypad328.bootloader.file=ATmegaBOOT_168_atmega328_pro_8MHz.hex -lilypad328.bootloader.unlock_bits=0x3F -lilypad328.bootloader.lock_bits=0x0F - -lilypad328.build.mcu=atmega328p -lilypad328.build.f_cpu=8000000L -lilypad328.build.core=arduino -lilypad328.build.variant=standard - -############################################################## - -lilypad.name=LilyPad Arduino w/ ATmega168 - -lilypad.upload.protocol=arduino -lilypad.upload.maximum_size=14336 -lilypad.upload.speed=19200 - -lilypad.bootloader.low_fuses=0xe2 -lilypad.bootloader.high_fuses=0xdd -lilypad.bootloader.extended_fuses=0x00 -lilypad.bootloader.path=lilypad -lilypad.bootloader.file=LilyPadBOOT_168.hex -lilypad.bootloader.unlock_bits=0x3F -lilypad.bootloader.lock_bits=0x0F - -lilypad.build.mcu=atmega168 -lilypad.build.f_cpu=8000000L -lilypad.build.core=arduino -lilypad.build.variant=standard - -############################################################## - -pro5v328.name=Arduino Pro or Pro Mini (5V, 16 MHz) w/ ATmega328 - -pro5v328.upload.protocol=arduino -pro5v328.upload.maximum_size=30720 -pro5v328.upload.speed=57600 - -pro5v328.bootloader.low_fuses=0xFF -pro5v328.bootloader.high_fuses=0xDA -pro5v328.bootloader.extended_fuses=0x05 -pro5v328.bootloader.path=atmega -pro5v328.bootloader.file=ATmegaBOOT_168_atmega328.hex -pro5v328.bootloader.unlock_bits=0x3F -pro5v328.bootloader.lock_bits=0x0F - -pro5v328.build.mcu=atmega328p -pro5v328.build.f_cpu=16000000L -pro5v328.build.core=arduino -pro5v328.build.variant=standard - -############################################################## - -pro5v.name=Arduino Pro or Pro Mini (5V, 16 MHz) w/ ATmega168 - -pro5v.upload.protocol=arduino -pro5v.upload.maximum_size=14336 -pro5v.upload.speed=19200 - -pro5v.bootloader.low_fuses=0xff -pro5v.bootloader.high_fuses=0xdd -pro5v.bootloader.extended_fuses=0x00 -pro5v.bootloader.path=atmega -pro5v.bootloader.file=ATmegaBOOT_168_diecimila.hex -pro5v.bootloader.unlock_bits=0x3F -pro5v.bootloader.lock_bits=0x0F - -pro5v.build.mcu=atmega168 -pro5v.build.f_cpu=16000000L -pro5v.build.core=arduino -pro5v.build.variant=standard - -############################################################## - -pro328.name=Arduino Pro or Pro Mini (3.3V, 8 MHz) w/ ATmega328 - -pro328.upload.protocol=arduino -pro328.upload.maximum_size=30720 -pro328.upload.speed=57600 - -pro328.bootloader.low_fuses=0xFF -pro328.bootloader.high_fuses=0xDA -pro328.bootloader.extended_fuses=0x05 -pro328.bootloader.path=atmega -pro328.bootloader.file=ATmegaBOOT_168_atmega328_pro_8MHz.hex -pro328.bootloader.unlock_bits=0x3F -pro328.bootloader.lock_bits=0x0F - -pro328.build.mcu=atmega328p -pro328.build.f_cpu=8000000L -pro328.build.core=arduino -pro328.build.variant=standard - -############################################################## - -pro.name=Arduino Pro or Pro Mini (3.3V, 8 MHz) w/ ATmega168 - -pro.upload.protocol=arduino -pro.upload.maximum_size=14336 -pro.upload.speed=19200 - -pro.bootloader.low_fuses=0xc6 -pro.bootloader.high_fuses=0xdd -pro.bootloader.extended_fuses=0x00 -pro.bootloader.path=atmega -pro.bootloader.file=ATmegaBOOT_168_pro_8MHz.hex -pro.bootloader.unlock_bits=0x3F -pro.bootloader.lock_bits=0x0F - -pro.build.mcu=atmega168 -pro.build.f_cpu=8000000L -pro.build.core=arduino -pro.build.variant=standard - -############################################################## - -atmega168.name=Arduino NG or older w/ ATmega168 - -atmega168.upload.protocol=arduino -atmega168.upload.maximum_size=14336 -atmega168.upload.speed=19200 - -atmega168.bootloader.low_fuses=0xff -atmega168.bootloader.high_fuses=0xdd -atmega168.bootloader.extended_fuses=0x00 -atmega168.bootloader.path=atmega -atmega168.bootloader.file=ATmegaBOOT_168_ng.hex -atmega168.bootloader.unlock_bits=0x3F -atmega168.bootloader.lock_bits=0x0F - -atmega168.build.mcu=atmega168 -atmega168.build.f_cpu=16000000L -atmega168.build.core=arduino -atmega168.build.variant=standard - -############################################################## - -atmega8.name=Arduino NG or older w/ ATmega8 - -atmega8.upload.protocol=arduino -atmega8.upload.maximum_size=7168 -atmega8.upload.speed=19200 - -atmega8.bootloader.low_fuses=0xdf -atmega8.bootloader.high_fuses=0xca -atmega8.bootloader.path=atmega8 -atmega8.bootloader.file=ATmegaBOOT.hex -atmega8.bootloader.unlock_bits=0x3F -atmega8.bootloader.lock_bits=0x0F - -atmega8.build.mcu=atmega8 -atmega8.build.f_cpu=16000000L -atmega8.build.core=arduino -atmega8.build.variant=standard - -############################################################## - -atmega162.name=AstroEQ w/ ATmega162 - -atmega162.upload.protocol=arduino -atmega162.upload.maximum_size=14336 -atmega162.upload.speed=57600 - -atmega162.bootloader.low_fuses=0xFF -atmega162.bootloader.high_fuses=0xD8 -atmega162.bootloader.extended_fuses=0xFB -atmega162.bootloader.path=optiboot -atmega162.bootloader.file=optiboot_atmega162.hex -atmega162.bootloader.unlock_bits=0x3F -atmega162.bootloader.lock_bits=0x0F - -atmega162.build.mcu=atmega162 -atmega162.build.f_cpu=16000000L -atmega162.build.core=arduino -atmega162.build.variant=AstroEQ - -############################################################## \ No newline at end of file diff --git a/AstroEQ-Firmware/Open me first/hardware/arduino/bootloaders/optiboot/optiboot_atmega162.hex b/AstroEQ-Firmware/Open me first/hardware/arduino/bootloaders/optiboot/optiboot_atmega162.hex deleted file mode 100644 index 9c2d7e1d356bdb6011d4ae033a07d24aa48e4aa5..0000000000000000000000000000000000000000 Binary files a/AstroEQ-Firmware/Open me first/hardware/arduino/bootloaders/optiboot/optiboot_atmega162.hex and /dev/null differ diff --git a/AstroEQ-Firmware/Open me first/hardware/arduino/variants/AstroEQ/pins_arduino.h b/AstroEQ-Firmware/Open me first/hardware/arduino/variants/AstroEQ/pins_arduino.h deleted file mode 100644 index a8994b2ba8b073373c45fb913969a0ca09b69a28..0000000000000000000000000000000000000000 --- a/AstroEQ-Firmware/Open me first/hardware/arduino/variants/AstroEQ/pins_arduino.h +++ /dev/null @@ -1,234 +0,0 @@ -/* - pins_arduino.h - Pin definition functions for Arduino - Part of Arduino - http://www.arduino.cc/ - - Copyright (c) 2007 David A. Mellis - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library 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 - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General - Public License along with this library; if not, write to the - Free Software Foundation, Inc., 59 Temple Place, Suite 330, - Boston, MA 02111-1307 USA - - $Id: wiring.h 249 2007-02-03 16:52:51Z mellis $ -*/ - -#ifndef Pins_Arduino_h -#define Pins_Arduino_h - -#include <avr/pgmspace.h> - -#define NUM_DIGITAL_PINS 35 -#define NUM_ANALOG_INPUTS 0 -#define analogInputToDigitalPin(p) (-1) - -#define digitalPinHasPWM(p) ((p) == 5 || (p) == 6 || (p) == 8 || (p) == 9 || (p) == 10 || (p) == 30) - -const static uint8_t SS = 10; -const static uint8_t MOSI = 11; -const static uint8_t MISO = 12; -const static uint8_t SCK = 13; - -const static uint8_t LED_BUILTIN = 13; - -#define digitalPinToPCICR(p) ( (((p) >= 14) && ((p) <= 17)) || \ - (((p) >= 20) && ((p) <= 27)) || \ - (((p) >= 31) && ((p) <= 34)) ? (&PCICR) : ((uint8_t *)0) ) - -#define digitalPinToPCICRbit(p) ( (((p) >= 20) && ((p) <= 27)) ? 0 : 1 ) - -#define digitalPinToPCMSK(p) ( (((p) >= 20) && ((p) <= 27)) ? (&PCMSK0) : \ - (((p) >= 14) && ((p) <= 17)) || \ - (((p) >= 31) && ((p) <= 34)) ? (&PCMSK1) : ((uint8_t *)0) ) - -#define digitalPinToPCMSKbit(p) ( (((p) >= 20) && ((p) <= 27)) ? ((p) - 20) : \ - (((p) >= 14) && ((p) <= 17)) ? ((p) - 14) : ((p) - 27) ) - -#ifdef ARDUINO_MAIN - -// On the Arduino board, digital pins are also used -// for the analog output (software PWM). - -// ATMEL ATMEGA162 / ARDUINO -// -// +-\/-+ -// PWM(0) (D 8) PB0 1| |40 VCC -// PWM(2) (D 9) PB1 2| |39 PA0 (D14) -// (D19) PB2 3| |38 PA1 (D15) -// (D18) PB3 4| |37 PA2 (D16) -// PWM(3B) (D10) PB4 5| |36 PA3 (D17) -// (D11) PB5 6| |35 PA4 (D31) -// (D12) PB6 7| |34 PA5 (D32) -// (D13) PB7 8| |33 PA6 (D33) -// RST 9| |32 PA7 (D34) -// (D 0) PD0 10| |31 PE0 (D28) -// (D 1) PD1 11| |30 PE1 (D29) -// (D 2) PD2 12| |29 PE2 (D30) PWM(1B) -// (D 3) PD3 13| |28 PC7 (D27) -// PWM(3A) (D 5) PD4 14| |27 PC6 (D26) -// PWM(1A) (D 6) PD5 15| |26 PC5 (D25) -// (D 4) PD6 16| |25 PC4 (D24) -// (D 7) PD7 17| |24 PC3 (D23) -// XT2 18| |23 PC2 (D22) -// XT1 19| |22 PC1 (D21) -// GND 20| |21 PC0 (D20) -// +----+ -// - - -// these arrays map port names (e.g. port B) to the -// appropriate addresses for various functions (e.g. reading -// and writing) -const uint16_t PROGMEM port_to_mode_PGM[] = { - NOT_A_PORT, - (uint16_t) &DDRA, - (uint16_t) &DDRB, - (uint16_t) &DDRC, - (uint16_t) &DDRD, - (uint16_t) &DDRE, -}; - -const uint16_t PROGMEM port_to_output_PGM[] = { - NOT_A_PORT, - (uint16_t) &PORTA, - (uint16_t) &PORTB, - (uint16_t) &PORTC, - (uint16_t) &PORTD, - (uint16_t) &PORTE, -}; - -const uint16_t PROGMEM port_to_input_PGM[] = { - NOT_A_PORT, - (uint16_t) &PINA, - (uint16_t) &PINB, - (uint16_t) &PINC, - (uint16_t) &PIND, - (uint16_t) &PINE, -}; - -const uint8_t PROGMEM digital_pin_to_port_PGM[] = { - PD, /* 0 */ - PD, - PD, - PD, - PD, - PD, - PD, - PD, - PB, /* 8 */ - PB, - PB, - PB, - PB, - PB, - PA, /* 14 */ - PA, - PA, - PA, - PB, /* 18 */ - PB, - PC, /* 20 */ - PC, - PC, - PC, - PC, - PC, - PC, - PC, - PE, /* 28 */ - PE, - PE, - PA, /* 31 */ - PA, - PA, - PA, -}; - -const uint8_t PROGMEM digital_pin_to_bit_mask_PGM[] = { - _BV(0), /* 0, port D */ - _BV(1), - _BV(2), - _BV(3), - _BV(6), - _BV(4), - _BV(5), - _BV(7), - _BV(0), /* 8, port B */ - _BV(1), - _BV(4), - _BV(5), - _BV(6), - _BV(7), - _BV(0), /* 14, port A */ - _BV(1), - _BV(2), - _BV(3), - _BV(3), /* 18, port B */ - _BV(2), - _BV(0), /* 20, port C */ - _BV(1), - _BV(2), - _BV(3), - _BV(4), - _BV(5), - _BV(6), - _BV(7), - _BV(0), /* 28, port E */ - _BV(1), - _BV(2), - _BV(4), /* 31, port A */ - _BV(5), - _BV(6), - _BV(7), -}; - -const uint8_t PROGMEM digital_pin_to_timer_PGM[] = { - NOT_ON_TIMER, /* 0 - port D */ - NOT_ON_TIMER, - NOT_ON_TIMER, - NOT_ON_TIMER, - NOT_ON_TIMER, - TIMER3A, - TIMER1A, - NOT_ON_TIMER, - TIMER0A, /* 8 - port B */ - TIMER2A, - TIMER3B, - NOT_ON_TIMER, - NOT_ON_TIMER, - NOT_ON_TIMER, - NOT_ON_TIMER,/* 14, port A */ - NOT_ON_TIMER, - NOT_ON_TIMER, - NOT_ON_TIMER, - NOT_ON_TIMER, /* 18, port B */ - NOT_ON_TIMER, - NOT_ON_TIMER, /* 20, port C */ - NOT_ON_TIMER, - NOT_ON_TIMER, - NOT_ON_TIMER, - NOT_ON_TIMER, - NOT_ON_TIMER, - NOT_ON_TIMER, - NOT_ON_TIMER, - NOT_ON_TIMER, /* 28, port E */ - NOT_ON_TIMER, - TIMER1B, - NOT_ON_TIMER, /* 31, port A */ - NOT_ON_TIMER, - NOT_ON_TIMER, - NOT_ON_TIMER, -}; - -#endif - -#endif \ No newline at end of file diff --git a/AstroEQ-Firmware/Open me first/hardware/tools/avr/avr/include/avr/iom162.h b/AstroEQ-Firmware/Open me first/hardware/tools/avr/avr/include/avr/iom162.h deleted file mode 100644 index 0a95150c8228c6f9871b0318dc68c8c624c22f96..0000000000000000000000000000000000000000 --- a/AstroEQ-Firmware/Open me first/hardware/tools/avr/avr/include/avr/iom162.h +++ /dev/null @@ -1,951 +0,0 @@ -/* Copyright (c) 2002, Nils Kristian Strom <nilsst@omegav.ntnu.no> - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the - distribution. - - * Neither the name of the copyright holders nor the names of - contributors may be used to endorse or promote products derived - from this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - POSSIBILITY OF SUCH DAMAGE. */ - -/* $Id: iom162.h,v 1.13.2.5 2008/10/17 23:27:47 arcanum Exp $ */ - -/* iom162.h - definitions for ATmega162 */ - -#ifndef _AVR_IOM162_H_ -#define _AVR_IOM162_H_ 1 - -/* This file should only be included from <avr/io.h>, never directly. */ - -#ifndef _AVR_IO_H_ -# error "Include <avr/io.h> instead of this file." -#endif - -#ifndef _AVR_IOXXX_H_ -# define _AVR_IOXXX_H_ "iom162.h" -#else -# error "Attempt to include more than one <avr/ioXXX.h> file." -#endif - -/* Memory mapped I/O registers */ - -/* Timer/Counter3 Control Register A */ -#define TCCR3A _SFR_MEM8(0x8B) - -/* Timer/Counter3 Control Register B */ -#define TCCR3B _SFR_MEM8(0x8A) - -/* Timer/Counter3 - Counter Register */ -#define TCNT3H _SFR_MEM8(0x89) -#define TCNT3L _SFR_MEM8(0x88) -#define TCNT3 _SFR_MEM16(0x88) - -/* Timer/Counter3 - Output Compare Register A */ -#define OCR3AH _SFR_MEM8(0x87) -#define OCR3AL _SFR_MEM8(0x86) -#define OCR3A _SFR_MEM16(0x86) - -/* Timer/Counter3 - Output Compare Register B */ -#define OCR3BH _SFR_MEM8(0x85) -#define OCR3BL _SFR_MEM8(0x84) -#define OCR3B _SFR_MEM16(0x84) - -/* Timer/Counter3 - Input Capture Register */ -#define ICR3H _SFR_MEM8(0x81) -#define ICR3L _SFR_MEM8(0x80) -#define ICR3 _SFR_MEM16(0x80) - -/* Extended Timer/Counter Interrupt Mask */ -#define ETIMSK _SFR_MEM8(0x7D) - -/* Extended Timer/Counter Interrupt Flag Register */ -#define ETIFR _SFR_MEM8(0x7C) - -/* Pin Change Mask Register 1 */ -#define PCMSK1 _SFR_MEM8(0x6C) - -/* Pin Change Mask Register 0 */ -#define PCMSK0 _SFR_MEM8(0x6B) - -/* Clock PRescale */ -#define CLKPR _SFR_MEM8(0x61) - - -/* Standard I/O registers */ - -/* 0x3F SREG */ -/* 0x3D..0x3E SP */ -#define UBRR1H _SFR_IO8(0x3C) /* USART 1 Baud Rate Register High Byte, Shared with UCSR1C */ -#define UCSR1C _SFR_IO8(0x3C) /* USART 1 Control and Status Register, Shared with UBRR1H */ -#define GICR _SFR_IO8(0x3B) /* General Interrupt Control Register */ -#define GIFR _SFR_IO8(0x3A) /* General Interrupt Flag Register */ -#define TIMSK _SFR_IO8(0x39) /* Timer Interrupt Mask */ -#define TIFR _SFR_IO8(0x38) /* Timer Interrupt Flag Register */ -#define SPMCR _SFR_IO8(0x37) /* Store Program Memory Control Register */ -#define EMCUCR _SFR_IO8(0x36) /* Extended MCU Control Register */ -#define MCUCR _SFR_IO8(0x35) /* MCU Control Register */ -#define MCUCSR _SFR_IO8(0x34) /* MCU Control and Status Register */ -#define TCCR0 _SFR_IO8(0x33) /* Timer/Counter 0 Control Register */ -#define TCNT0 _SFR_IO8(0x32) /* TImer/Counter 0 */ -#define OCR0 _SFR_IO8(0x31) /* Output Compare Register 0 */ -#define SFIOR _SFR_IO8(0x30) /* Special Function I/O Register */ -#define TCCR1A _SFR_IO8(0x2F) /* Timer/Counter 1 Control Register A */ -#define TCCR1B _SFR_IO8(0x2E) /* Timer/Counter 1 Control Register A */ -#define TCNT1H _SFR_IO8(0x2D) /* Timer/Counter 1 High Byte */ -#define TCNT1L _SFR_IO8(0x2C) /* Timer/Counter 1 Low Byte */ -#define TCNT1 _SFR_IO16(0x2C) /* Timer/Counter 1 */ -#define OCR1AH _SFR_IO8(0x2B) /* Timer/Counter 1 Output Compare Register A High Byte */ -#define OCR1AL _SFR_IO8(0x2A) /* Timer/Counter 1 Output Compare Register A Low Byte */ -#define OCR1A _SFR_IO16(0x2A) /* Timer/Counter 1 Output Compare Register A */ -#define OCR1BH _SFR_IO8(0x29) /* Timer/Counter 1 Output Compare Register B High Byte */ -#define OCR1BL _SFR_IO8(0x28) /* Timer/Counter 1 Output Compare Register B Low Byte */ -#define OCR1B _SFR_IO16(0x28) /* Timer/Counter 1 Output Compare Register B */ -#define TCCR2 _SFR_IO8(0x27) /* Timer/Counter 2 Control Register */ -#define ASSR _SFR_IO8(0x26) /* Asynchronous Status Register */ -#define ICR1H _SFR_IO8(0x25) /* Input Capture Register 1 High Byte */ -#define ICR1L _SFR_IO8(0x24) /* Input Capture Register 1 Low Byte */ -#define ICR1 _SFR_IO16(0x24) /* Input Capture Register 1 */ -#define TCNT2 _SFR_IO8(0x23) /* Timer/Counter 2 */ -#define OCR2 _SFR_IO8(0x22) /* Timer/Counter 2 Output Compare Register */ -#define WDTCR _SFR_IO8(0x21) /* Watchdow Timer Control Register */ -#define UBRR0H _SFR_IO8(0x20) /* USART 0 Baud-Rate Register High Byte, Shared with UCSR0C */ -#define UCSR0C _SFR_IO8(0x20) /* USART 0 Control and Status Register C, Shared with UBRR0H */ -#define EEARH _SFR_IO8(0x1F) /* EEPROM Address Register High Byte */ -#define EEARL _SFR_IO8(0x1E) /* EEPROM Address Register Low Byte */ -#define EEAR _SFR_IO16(0x1E) /* EEPROM Address Register */ -#define EEDR _SFR_IO8(0x1D) /* EEPROM Data Register */ -#define EECR _SFR_IO8(0x1C) /* EEPROM Control Register */ -#define PORTA _SFR_IO8(0x1B) /* Port A */ -#define DDRA _SFR_IO8(0x1A) /* Port A Data Direction Register */ -#define PINA _SFR_IO8(0x19) /* Port A Pin Register */ -#define PORTB _SFR_IO8(0x18) /* Port B */ -#define DDRB _SFR_IO8(0x17) /* Port B Data Direction Register */ -#define PINB _SFR_IO8(0x16) /* Port B Pin Register */ -#define PORTC _SFR_IO8(0x15) /* Port C */ -#define DDRC _SFR_IO8(0x14) /* Port C Data Direction Register */ -#define PINC _SFR_IO8(0x13) /* Port C Pin Register */ -#define PORTD _SFR_IO8(0x12) /* Port D */ -#define DDRD _SFR_IO8(0x11) /* Port D Data Direction Register */ -#define PIND _SFR_IO8(0x10) /* Port D Pin Register */ -#define SPDR _SFR_IO8(0x0F) /* SPI Data Register */ -#define SPSR _SFR_IO8(0x0E) /* SPI Status Register */ -#define SPCR _SFR_IO8(0x0D) /* SPI Control Register */ -#define UDR0 _SFR_IO8(0x0C) /* USART 0 Data Register */ -#define UCSR0A _SFR_IO8(0x0B) /* USART 0 Control and Status Register A */ -#define UCSR0B _SFR_IO8(0x0A) /* USART 0 Control and Status Register B */ -#define UBRR0L _SFR_IO8(0x09) /* USART 0 Baud-Rate Register Low Byte */ -#define ACSR _SFR_IO8(0x08) /* Analog Comparator Status Register */ -#define PORTE _SFR_IO8(0x07) /* Port E */ -#define DDRE _SFR_IO8(0x06) /* Port E Data Direction Register */ -#define PINE _SFR_IO8(0x05) /* Port E Pin Register */ -#define OSCCAL _SFR_IO8(0x04) /* Oscillator Calibration, Shared with OCDR */ -#define OCDR _SFR_IO8(0x04) /* On-Chip Debug Register, Shared with OSCCAL */ -#define UDR1 _SFR_IO8(0x03) /* USART 1 Data Register */ -#define UCSR1A _SFR_IO8(0x02) /* USART 1 Control and Status Register A */ -#define UCSR1B _SFR_IO8(0x01) /* USART 1 Control and Status Register B */ -#define UBRR1L _SFR_IO8(0x00) /* USART 0 Baud Rate Register High Byte */ - - -/* Interrupt vectors (byte addresses) */ - -/* External Interrupt Request 0 */ -#define INT0_vect _VECTOR(1) -#define SIG_INTERRUPT0 _VECTOR(1) - -/* External Interrupt Request 1 */ -#define INT1_vect _VECTOR(2) -#define SIG_INTERRUPT1 _VECTOR(2) - -/* External Interrupt Request 2 */ -#define INT2_vect _VECTOR(3) -#define SIG_INTERRUPT2 _VECTOR(3) - -/* Pin Change Interrupt Request 0 */ -#define PCINT0_vect _VECTOR(4) -#define SIG_PIN_CHANGE0 _VECTOR(4) - -/* Pin Change Interrupt Request 1 */ -#define PCINT1_vect _VECTOR(5) -#define SIG_PIN_CHANGE1 _VECTOR(5) - -/* Timer/Counter3 Capture Event */ -#define TIMER3_CAPT_vect _VECTOR(6) -#define SIG_INPUT_CAPTURE3 _VECTOR(6) - -/* Timer/Counter3 Compare Match A */ -#define TIMER3_COMPA_vect _VECTOR(7) -#define SIG_OUTPUT_COMPARE3A _VECTOR(7) - -/* Timer/Counter3 Compare Match B */ -#define TIMER3_COMPB_vect _VECTOR(8) -#define SIG_OUTPUT_COMPARE3B _VECTOR(8) - -/* Timer/Counter3 Overflow */ -#define TIMER3_OVF_vect _VECTOR(9) -#define SIG_OVERFLOW3 _VECTOR(9) - -/* Timer/Counter2 Compare Match */ -#define TIMER2_COMP_vect _VECTOR(10) -#define SIG_OUTPUT_COMPARE2 _VECTOR(10) - -/* Timer/Counter2 Overflow */ -#define TIMER2_OVF_vect _VECTOR(11) -#define SIG_OVERFLOW2 _VECTOR(11) - -/* Timer/Counter1 Capture Event */ -#define TIMER1_CAPT_vect _VECTOR(12) -#define SIG_INPUT_CAPTURE1 _VECTOR(12) - -/* Timer/Counter1 Compare Match A */ -#define TIMER1_COMPA_vect _VECTOR(13) -#define SIG_OUTPUT_COMPARE1A _VECTOR(13) - -/* Timer/Counter Compare Match B */ -#define TIMER1_COMPB_vect _VECTOR(14) -#define SIG_OUTPUT_COMPARE1B _VECTOR(14) - -/* Timer/Counter1 Overflow */ -#define TIMER1_OVF_vect _VECTOR(15) -#define SIG_OVERFLOW1 _VECTOR(15) - -/* Timer/Counter0 Compare Match */ -#define TIMER0_COMP_vect _VECTOR(16) -#define SIG_OUTPUT_COMPARE0 _VECTOR(16) - -/* Timer/Counter0 Overflow */ -#define TIMER0_OVF_vect _VECTOR(17) -#define SIG_OVERFLOW0 _VECTOR(17) - -/* SPI Serial Transfer Complete */ -#define SPI_STC_vect _VECTOR(18) -#define SIG_SPI _VECTOR(18) - -/* USART0, Rx Complete */ -#define USART0_RX_vect _VECTOR(19) -#define SIG_USART0_RECV _VECTOR(19) - -/* USART1, Rx Complete */ -#define USART1_RX_vect _VECTOR(20) -#define SIG_USART1_RECV _VECTOR(20) - -/* USART0 Data register Empty */ -#define USART0_UDRE_vect _VECTOR(21) -#define SIG_USART0_DATA _VECTOR(21) - -/* USART1, Data register Empty */ -#define USART1_UDRE_vect _VECTOR(22) -#define SIG_USART1_DATA _VECTOR(22) - -/* USART0, Tx Complete */ -#define USART0_TX_vect _VECTOR(23) -#define SIG_USART0_TRANS _VECTOR(23) - -/* USART1, Tx Complete */ -#define USART1_TX_vect _VECTOR(24) -#define SIG_USART1_TRANS _VECTOR(24) - -/* EEPROM Ready */ -#define EE_RDY_vect _VECTOR(25) -#define SIG_EEPROM_READY _VECTOR(25) - -/* Analog Comparator */ -#define ANA_COMP_vect _VECTOR(26) -#define SIG_COMPARATOR _VECTOR(26) - -/* Store Program Memory Read */ -#define SPM_RDY_vect _VECTOR(27) -#define SIG_SPM_READY _VECTOR(27) - -#define _VECTORS_SIZE 112 /* = (num vec+1) * 4 */ - - - - - -/* TCCR3B bit definitions, memory mapped I/O */ - -#define ICNC3 7 -#define ICES3 6 -#define WGM33 4 -#define WGM32 3 -#define CS32 2 -#define CS31 1 -#define CS30 0 - - - -/* TCCR3A bit definitions, memory mapped I/O */ - -#define COM3A1 7 -#define COM3A0 6 -#define COM3B1 5 -#define COM3B0 4 -#define FOC3A 3 -#define FOC3B 2 -#define WGM31 1 -#define WGM30 0 - - - -/* ETIMSK bit definitions, memory mapped I/O */ - -#define TICIE3 5 -#define OCIE3A 4 -#define OCIE3B 3 -#define TOIE3 2 - - - -/* ETIFR bit definitions, memory mapped I/O */ - -#define ICF3 5 -#define OCF3A 4 -#define OCF3B 3 -#define TOV3 2 - - - -/* PCMSK1 bit definitions, memory mapped I/O */ -#define PCINT15 7 -#define PCINT14 6 -#define PCINT13 5 -#define PCINT12 4 -#define PCINT11 3 -#define PCINT10 2 -#define PCINT9 1 -#define PCINT8 0 - - - -/* PCMSK0 bit definitions, memory mapped I/O */ - -#define PCINT7 7 -#define PCINT6 6 -#define PCINT5 5 -#define PCINT4 4 -#define PCINT3 3 -#define PCINT2 2 -#define PCINT1 1 -#define PCINT0 0 - - - -/* CLKPR bit definitions, memory mapped I/O */ - -#define CLKPCE 7 -#define CLKPS3 3 -#define CLKPS2 2 -#define CLKPS1 1 -#define CLKPS0 0 - - - -/* SPH bit definitions */ - -#define SP15 15 -#define SP14 14 -#define SP13 13 -#define SP12 12 -#define SP11 11 -#define SP10 10 -#define SP9 9 -#define SP8 8 - - - -/* SPL bit definitions */ - -#define SP7 7 -#define SP6 6 -#define SP5 5 -#define SP4 4 -#define SP3 3 -#define SP2 2 -#define SP1 1 -#define SP0 0 - - - -/* UBRR1H bit definitions */ - -#define URSEL1 7 -#define UBRR111 3 -#define UBRR110 2 -#define UBRR19 1 -#define UBRR18 0 - - - -/* UCSR1C bit definitions */ - -#define URSEL1 7 -#define UMSEL1 6 -#define UPM11 5 -#define UPM10 4 -#define USBS1 3 -#define UCSZ11 2 -#define UCSZ10 1 -#define UCPOL1 0 - - - -/* GICR bit definitions */ - -#define INT1 7 -#define INT0 6 -#define INT2 5 -#define PCIE1 4 -#define PCIE0 3 -#define IVSEL 1 -#define IVCE 0 - - - -/* GIFR bit definitions */ - -#define INTF1 7 -#define INTF0 6 -#define INTF2 5 -#define PCIF1 4 -#define PCIF0 3 - - - -/* TIMSK bit definitions */ - -#define TOIE1 7 -#define OCIE1A 6 -#define OCIE1B 5 -#define OCIE2 4 -#define TICIE1 3 -#define TOIE2 2 -#define TOIE0 1 -#define OCIE0 0 - - - -/* TIFR bit definitions */ - -#define TOV1 7 -#define OCF1A 6 -#define OCF1B 5 -#define OCF2 4 -#define ICF1 3 -#define TOV2 2 -#define TOV0 1 -#define OCF0 0 - - - -/* SPMCR bit definitions */ - -#define SPMIE 7 -#define RWWSB 6 -#define RWWSRE 4 -#define BLBSET 3 -#define PGWRT 2 -#define PGERS 1 -#define SPMEN 0 - - - -/* EMCUCR bit definitions */ - -#define SM0 7 -#define SRL2 6 -#define SRL1 5 -#define SRL0 4 -#define SRW01 3 -#define SRW00 2 -#define SRW11 1 -#define ISC2 0 - - - -/* MCUCR bit definitions */ - -#define SRE 7 -#define SRW10 6 -#define SE 5 -#define SM1 4 -#define ISC11 3 -#define ISC10 2 -#define ISC01 1 -#define ISC00 0 - - - -/* MCUCSR bit definitions */ - -#define JTD 7 -#define SM2 5 -#define JTRF 4 -#define WDRF 3 -#define BORF 2 -#define EXTRF 1 -#define PORF 0 - - - -/* TCCR0 bit definitions */ - -#define FOC0 7 -#define WGM00 6 -#define COM01 5 -#define COM00 4 -#define WGM01 3 -#define CS02 2 -#define CS01 1 -#define CS00 0 - - - -/* SFIOR bit definitions */ - -#define TSM 7 -#define XMBK 6 -#define XMM2 5 -#define XMM1 4 -#define XMM0 3 -#define PUD 2 -#define PSR2 1 -#define PSR310 0 - - - -/* TCCR1A bit definitions */ - -#define COM1A1 7 -#define COM1A0 6 -#define COM1B1 5 -#define COM1B0 4 -#define FOC1A 3 -#define FOC1B 2 -#define WGM11 1 -#define WGM10 0 - - - - -/* TCCR1B bit definitions */ - -#define ICNC1 7 /* Input Capture Noise Canceler */ -#define ICES1 6 /* Input Capture Edge Select */ -#define WGM13 4 /* Waveform Generation Mode 3 */ -#define WGM12 3 /* Waveform Generation Mode 2 */ -#define CS12 2 /* Clock Select 2 */ -#define CS11 1 /* Clock Select 1 */ -#define CS10 0 /* Clock Select 0 */ - - - -/* TCCR2 bit definitions */ - -#define FOC2 7 -#define WGM20 6 -#define COM21 5 -#define COM20 4 -#define WGM21 3 -#define CS22 2 -#define CS21 1 -#define CS20 0 - - - -/* ASSR bit definitions */ - -#define AS2 3 -#define TCON2UB 2 -#define OCR2UB 1 -#define TCR2UB 0 - - - -/* WDTCR bit definitions */ - -#define WDCE 4 -#define WDE 3 -#define WDP2 2 -#define WDP1 1 -#define WDP0 0 - - - -/* UBRR0H bif definitions */ - -#define URSEL0 7 -#define UBRR011 3 -#define UBRR010 2 -#define UBRR09 1 -#define UBRR08 0 - - - -/* UCSR0C bit definitions */ - -#define URSEL0 7 -#define UMSEL0 6 -#define UPM01 5 -#define UPM00 4 -#define USBS0 3 -#define UCSZ01 2 -#define UCSZ00 1 -#define UCPOL0 0 - - - -/* EEARH bit definitions */ - -#define EEAR8 0 - - - -/* EECR bit definitions */ - -#define EERIE 3 -#define EEMWE 2 -#define EEWE 1 -#define EERE 0 - - - -/* PORTA bit definitions */ - -#define PA7 7 -#define PA6 6 -#define PA5 5 -#define PA4 4 -#define PA3 3 -#define PA2 2 -#define PA1 1 -#define PA0 0 - - - -/* DDRA bit definitions */ - -#define DDA7 7 -#define DDA6 6 -#define DDA5 5 -#define DDA4 4 -#define DDA3 3 -#define DDA2 2 -#define DDA1 1 -#define DDA0 0 - - - -/* PINA bit definitions */ - -#define PINA7 7 -#define PINA6 6 -#define PINA5 5 -#define PINA4 4 -#define PINA3 3 -#define PINA2 2 -#define PINA1 1 -#define PINA0 0 - - -/* PORTB bit definitions */ - -#define PB7 7 -#define PB6 6 -#define PB5 5 -#define PB4 4 -#define PB3 3 -#define PB2 2 -#define PB1 1 -#define PB0 0 - - - -/* DDRB bit definitions */ - -#define DDB7 7 -#define DDB6 6 -#define DDB5 5 -#define DDB4 4 -#define DDB3 3 -#define DDB2 2 -#define DDB1 1 -#define DDB0 0 - - - -/* PINB bit definitions */ - -#define PINB7 7 -#define PINB6 6 -#define PINB5 5 -#define PINB4 4 -#define PINB3 3 -#define PINB2 2 -#define PINB1 1 -#define PINB0 0 - - - -/* PORTC bit definitions */ - -#define PC7 7 -#define PC6 6 -#define PC5 5 -#define PC4 4 -#define PC3 3 -#define PC2 2 -#define PC1 1 -#define PC0 0 - - - -/* DDRC bit definitions */ - -#define DDC7 7 -#define DDC6 6 -#define DDC5 5 -#define DDC4 4 -#define DDC3 3 -#define DDC2 2 -#define DDC1 1 -#define DDC0 0 - - - -/* PINC bit definitions */ - -#define PINC7 7 -#define PINC6 6 -#define PINC5 5 -#define PINC4 4 -#define PINC3 3 -#define PINC2 2 -#define PINC1 1 -#define PINC0 0 - - - -/* PORTD bit definitions */ - -#define PD7 7 -#define PD6 6 -#define PD5 5 -#define PD4 4 -#define PD3 3 -#define PD2 2 -#define PD1 1 -#define PD0 0 - - - -/* DDRD bit definitions */ - -#define DDD7 7 -#define DDD6 6 -#define DDD5 5 -#define DDD4 4 -#define DDD3 3 -#define DDD2 2 -#define DDD1 1 -#define DDD0 0 - - - -/* PIND bit definitions */ - -#define PIND7 7 -#define PIND6 6 -#define PIND5 5 -#define PIND4 4 -#define PIND3 3 -#define PIND2 2 -#define PIND1 1 -#define PIND0 0 - - - -/* SPSR bit definitions */ - -#define SPIF 7 -#define WCOL 6 -#define SPI2X 0 - - - -/* SPCR bit definitions */ - -#define SPIE 7 -#define SPE 6 -#define DORD 5 -#define MSTR 4 -#define CPOL 3 -#define CPHA 2 -#define SPR1 1 -#define SPR0 0 - - - -/* UCSR0A bit definitions */ - -#define RXC0 7 -#define TXC0 6 -#define UDRE0 5 -#define FE0 4 -#define DOR0 3 -#define UPE0 2 -#define U2X0 1 -#define MPCM0 0 - - - -/* UCSR0B bit definitions */ - -#define RXCIE0 7 -#define TXCIE0 6 -#define UDRIE0 5 -#define RXEN0 4 -#define TXEN0 3 -#define UCSZ02 2 -#define RXB80 1 -#define TXB80 0 - - - -/* ACSR bit definitions */ - -#define ACD 7 -#define ACBG 6 -#define ACO 5 -#define ACI 4 -#define ACIE 3 -#define ACIC 2 -#define ACIS1 1 -#define ACIS0 0 - - - -/* PORTE bit definitions */ - -#define PE2 2 -#define PE1 1 -#define PE0 0 - - - -/* DDRE bit definitions */ - -#define DDE2 2 -#define DDE1 1 -#define DDE0 0 - - - -/* PINE bit definitions */ - -#define PINE2 2 -#define PINE1 1 -#define PINE0 0 - - - -/* UCSR1A bit definitions */ - -#define RXC1 7 -#define TXC1 6 -#define UDRE1 5 -#define FE1 4 -#define DOR1 3 -#define UPE1 2 -#define U2X1 1 -#define MPCM1 0 - - - -/* UCSR1B bit definitions */ - -#define RXCIE1 7 -#define TXCIE1 6 -#define UDRIE1 5 -#define RXEN1 4 -#define TXEN1 3 -#define UCSZ12 2 -#define RXB81 1 -#define TXB81 0 - - -/* Constants */ -#define SPM_PAGESIZE 128 -#define RAMEND 0x4FF -#define XRAMEND 0xFFFF -#define E2END 0x1FF -#define E2PAGESIZE 4 -#define FLASHEND 0x3FFF - - -/* Fuses */ - -#define FUSE_MEMORY_SIZE 3 - -/* Low Fuse Byte */ -#define FUSE_CKSEL0 (unsigned char)~_BV(0) -#define FUSE_CKSEL1 (unsigned char)~_BV(1) -#define FUSE_CKSEL2 (unsigned char)~_BV(2) -#define FUSE_CKSEL3 (unsigned char)~_BV(3) -#define FUSE_SUT0 (unsigned char)~_BV(4) -#define FUSE_SUT1 (unsigned char)~_BV(5) -#define FUSE_CKOUT (unsigned char)~_BV(6) -#define FUSE_CKDIV8 (unsigned char)~_BV(7) -#define LFUSE_DEFAULT (FUSE_CKSEL0 & FUSE_CKSEL2 & FUSE_CKSEL3 & FUSE_SUT0 & FUSE_CKDIV8) - -/* High Fuse Byte */ -#define FUSE_BOOTRST (unsigned char)~_BV(0) -#define FUSE_BOOTSZ0 (unsigned char)~_BV(1) -#define FUSE_BOOTSZ1 (unsigned char)~_BV(2) -#define FUSE_EESAVE (unsigned char)~_BV(3) -#define FUSE_WDTON (unsigned char)~_BV(4) -#define FUSE_SPIEN (unsigned char)~_BV(5) -#define FUSE_JTAGEN (unsigned char)~_BV(6) -#define FUSE_OCDEN (unsigned char)~_BV(7) -#define HFUSE_DEFAULT (FUSE_BOOTSZ0 & FUSE_BOOTSZ1 & FUSE_SPIEN & FUSE_JTAGEN) - -/* Extended Fuse Byte */ -#define FUSE_BODLEVEL0 (unsigned char)~_BV(1) -#define FUSE_BODLEVEL1 (unsigned char)~_BV(2) -#define FUSE_BODLEVEL2 (unsigned char)~_BV(3) -#define FUSE_M161C (unsigned char)~_BV(4) -#define EFUSE_DEFAULT (0xFF) - - -/* Lock Bits */ -#define __LOCK_BITS_EXIST -#define __BOOT_LOCK_BITS_0_EXIST -#define __BOOT_LOCK_BITS_1_EXIST - - -/* Signature */ -#define SIGNATURE_0 0x1E -#define SIGNATURE_1 0x94 -#define SIGNATURE_2 0x04 - - -#endif /* _AVR_IOM162_H_ */ diff --git a/AstroEQ-Firmware/PinMappings.h b/AstroEQ-Firmware/PinMappings.h new file mode 100644 index 0000000000000000000000000000000000000000..d3f61beffe79693f0bcc206349689b667224f8b4 --- /dev/null +++ b/AstroEQ-Firmware/PinMappings.h @@ -0,0 +1,163 @@ + +#if defined(__AVR_ATmega162__) + +//This is for HARDWARE versions prior to 4.0. This includes all versions using Arduino Mega board. +//#define LEGACY_MODE 1 + +//----- User Configurable Pin Definitions for ATMega162 Variants ----- +//Warning: D20 to D27 inclusive are NOT allowed +#define statusPin_Define 13 + +#define resetPin_0_Define 15 +#define resetPin_1_Define 14 + +#define errorPin_0_Define 2 +#define errorPin_1_Define 6 + +#define dirPin_0_Define 3 +#define dirPin_1_Define 7 + +#define enablePin_0_Define 4 +#define enablePin_1_Define 8 + +#define stepPin_0_Define 5 +#define stepPin_1_Define 30 + +#ifdef LEGACY_MODE +#define modePins0_0_Define 16 +#define modePins2_0_Define 17 +#define modePins0_1_Define 19 +#define modePins2_1_Define 18 +#else +#define modePins0_0_Define 6 +#define modePins1_0_Define 17 +#define modePins2_0_Define 16 +#define modePins0_1_Define 10 +#define modePins1_1_Define 18 +#define modePins2_1_Define 19 +#endif + + +#elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) + +//---- User Configurable Pin Definitions for ATMegaXXX0 Variants ----- +//Warning: D30 to D37 inclusive are NOT allowed +#define statusPin_Define 13 + +#define resetPin_0_Define A1 +#define resetPin_1_Define A0 + +#define errorPin_0_Define 2 +#define errorPin_1_Define 6 + +#define dirPin_0_Define 3 +#define dirPin_1_Define 7 + +#define enablePin_0_Define 4 +#define enablePin_1_Define 8 + +#define stepPin_0_Define 5 +#define stepPin_1_Define 12 + +#define modePins0_0_Define 16 +#define modePins2_0_Define 17 +#define modePins0_1_Define 19 +#define modePins2_1_Define 18 + + + +#endif + + + + + + + + +// Do not modify anything below this line! --------------------------------------- + + +#if (CS10 != CS30) || (CS11 != CS31) || (CS12 != CS32) +#error incorrect assumption about prescale bits being equal between timer 1 and 3. +#endif +#define CSn0 CS10 +#define CSn1 CS11 +#define CSn2 CS12 + + + +#if defined(__AVR_ATmega162__) + +#define GPIOR0 TCNT2 +#define GPIOR1 OCR2 +#ifndef TIMSK3 +#define TIMSK3 ETIMSK +#endif +#ifndef TIMSK1 +#define TIMSK1 TIMSK +#endif +#ifndef ICIE3 +#define ICIE3 TICIE3 +#endif +#ifndef ICIE1 +#define ICIE1 TICIE1 +#endif + +#define digitalPinToPortReg(P) \ +((((P) >= 14 && (P) <= 17) || ((P) >= 31 && (P) <= 34)) ? &PORTA : \ +((((P) >= 8 && (P) <= 13) || ((P) >= 18 && (P) <= 19)) ? &PORTB : \ +((((P) >= 20 && (P) <= 27)) ? &PORTC : \ +((((P) <= 7)) ? &PORTD : &PORTE )))) + +#define digitalPinToBit(P) \ +(((P) >= 0 && (P) <= 3) ? (P) : \ +(((P) >= 10 && (P) <= 13) ? (P) - 6 : \ +(((P) >= 8 && (P) <= 9) ? (P) - 8 : \ +(((P) >= 18 && (P) <= 19) ? 21 - (P) : \ +(((P) >= 20 && (P) <= 27) ? (P) - 20 : \ +(((P) >= 28 && (P) <= 30) ? (P) - 28 : \ +(((P) >= 31 && (P) <= 34) ? (P) - 27 : \ +(((P) >= 14 && (P) <= 17) ? (P) - 14 : \ +(((P) >= 5 && (P) <= 6) ? (P) - 1 : \ +(((P) == 7) ? 7 : 6 )))))))))) + + +#elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) + +#ifndef LEGACY_MODE +#define LEGACY_MODE 1 +#endif + +#define digitalPinToPortReg(P) \ +(((P) >= 22 && (P) <= 29) ? &PORTA : \ +((((P) >= 10 && (P) <= 13) || ((P) >= 50 && (P) <= 53)) ? &PORTB : \ +(((P) >= 30 && (P) <= 37) ? &PORTC : \ +((((P) >= 18 && (P) <= 21) || (P) == 38) ? &PORTD : \ +((((P) >= 0 && (P) <= 3) || (P) == 5) ? &PORTE : \ +(((P) >= 54 && (P) <= 61) ? &PORTF : \ +((((P) >= 39 && (P) <= 41) || (P) == 4) ? &PORTG : \ +((((P) >= 6 && (P) <= 9) || (P) == 16 || (P) == 17) ? &PORTH : \ +(((P) == 14 || (P) == 15) ? &PORTJ : \ +(((P) >= 62 && (P) <= 69) ? &PORTK : &PORTL)))))))))) + +#define digitalPinToBit(P) \ +(((P) >= 7 && (P) <= 9) ? (P) - 3 : \ +(((P) >= 10 && (P) <= 13) ? (P) - 6 : \ +(((P) >= 22 && (P) <= 29) ? (P) - 22 : \ +(((P) >= 30 && (P) <= 37) ? 37 - (P) : \ +(((P) >= 39 && (P) <= 41) ? 41 - (P) : \ +(((P) >= 42 && (P) <= 49) ? 49 - (P) : \ +(((P) >= 50 && (P) <= 53) ? 53 - (P) : \ +(((P) >= 54 && (P) <= 61) ? (P) - 54 : \ +(((P) >= 62 && (P) <= 69) ? (P) - 62 : \ +(((P) == 0 || (P) == 15 || (P) == 17 || (P) == 21) ? 0 : \ +(((P) == 1 || (P) == 14 || (P) == 16 || (P) == 20) ? 1 : \ +(((P) == 19) ? 2 : \ +(((P) == 5 || (P) == 6 || (P) == 18) ? 3 : \ +(((P) == 2) ? 4 : \ +(((P) == 3 || (P) == 4) ? 5 : 7))))))))))))))) + + + +#endif diff --git a/AstroEQ-Firmware/commands.cpp b/AstroEQ-Firmware/commands.cpp index 9a582d31ecc28e8148d564e5d151539b11a1c050..a78f4651a4e13e336f2e60f11446cae0f7013495 100644 --- a/AstroEQ-Firmware/commands.cpp +++ b/AstroEQ-Firmware/commands.cpp @@ -23,36 +23,28 @@ #endif #include "commands.h" -void Commands::init(unsigned long eVal,unsigned long aVal1,unsigned long aVal2,unsigned long bVal1,unsigned long bVal2,unsigned long sVal1,unsigned long sVal2,byte gVal){ +void Commands::init(unsigned long _eVal, byte _gVal){ + aVal[0] = EEPROM.readLong(aVal1_Address); //steps/axis + aVal[1] = EEPROM.readLong(aVal2_Address); //steps/axis + bVal[0] = EEPROM.readLong(bVal1_Address); //sidereal rate + bVal[1] = EEPROM.readLong(bVal2_Address); //sidereal rate + sVal[0] = EEPROM.readLong(sVal1_Address); //steps/worm rotation + sVal[1] = EEPROM.readLong(sVal2_Address); //steps/worm rotation + siderealIVal[0] = EEPROM.readInt(IVal1_Address); //steps/worm rotation + siderealIVal[1] = EEPROM.readInt(IVal2_Address); //steps/worm rotation for(byte i = 0;i < 2;i++){ - _flag[i] = 0x100; - _jVal[i] = 0x800000; //Current position, 0x800000 is the centre - _IVal[i] = 0; //Recieved Speed - _GVal[i] = 0; //Mode recieved from :G command - _HVal[i] = 0; //Value recieved from :H command - _eVal[i] = eVal; //version number - _gVal[i] = gVal; //High speed scalar - } - _aVal[0] = aVal1; //steps/axis - _aVal[1] = aVal2; //steps/axis - _bVal[0] = bVal1; //sidereal rate - _bVal[1] = bVal2; //sidereal rate - _sVal[0] = sVal1; //steps/worm rotation - _sVal[1] = sVal2; //steps/worm rotation -} - -void Commands::init(unsigned long eVal,unsigned long aVal,unsigned long bVal,byte gVal,unsigned long sVal){ - for(byte i = 0;i < 2;i++){ - _flag[i] = 0x100; - _jVal[i] = 0x800000; //Current position, 0x800000 is the centre - _IVal[i] = 0; //Recieved Speed - _GVal[i] = 0; //Mode recieved from :G command - _HVal[i] = 0; //Value recieved from :H command - _eVal[i] = eVal; //version number - _aVal[i] = aVal; //steps/axis - _bVal[i] = bVal; //sidereal rate - _gVal[i] = gVal; //High speed scalar - _sVal[i] = sVal; //steps/worm rotation + dir[i] = 0; + stopped[i] = 1; + gotoEn[i] = 0; + FVal[i] = 0; + jVal[i] = 0x800000; //Current position, 0x800000 is the centre + IVal[i] = 0; //Recieved Speed + GVal[i] = 0; //Mode recieved from :G command + HVal[i] = 0; //Value recieved from :H command + eVal[i] = _eVal; //version number + gVal[i] = _gVal; //High speed scalar + + stepIncrement[i] = map(siderealIVal[i],300,1200,4,16);//((aVal[i] < 5600000UL) ? ((aVal[i] < 2800000UL) ? 16 : 8) : 4); } } @@ -72,7 +64,10 @@ const char Commands::command[numberOfCommands][3] = { {'e', 0, 6}, {'J', 0, 0}, {'P', 1, 0}, {'F', 0, 0}, - {'L', 0, 0} }; + {'L', 0, 0}, + {'A', 6, 0}, + {'B', 6, 0}, + {'S', 6, 0} }; char Commands::getLength(char cmd, boolean sendRecieve){ for(byte i = 0;i < numberOfCommands;i++){ @@ -87,112 +82,54 @@ char Commands::getLength(char cmd, boolean sendRecieve){ return -1; } -unsigned int Commands::fVal(byte target){ - return _flag[target]; -} - -char Commands::stepDir(byte target){ //Get Method - char stepDir = 1 - ((_flag[target] >> 8) & 0x02); //get step direction - return stepDir; -} - -byte Commands::dir(byte target, char dir){ //Set Method - if(dir == 1){ - //set direction - _flag[target] |= (1 << 9); //set bit - } else if (dir == 0){ - _flag[target] &= ~(1 << 9); //unset bit - } else { - dir = (_flag[target] >> 9) & 0x01; //get direction - } - return dir; -} - -byte Commands::stopped(byte target, byte stopped){ //Set Method - if(stopped == 1){ - _flag[target] |= (1 << 8); //set bit - } else if (stopped == 0){ - _flag[target] &= ~(1 << 8); //unset bit - } else { - stopped = (_flag[target] >> 8) & 0x01; - } - return stopped; -} - -byte Commands::gotoEn(byte target, byte gotoEn){ //Set Method - if(gotoEn == 1){ - _flag[target] |= (1 << 4); //set bit - } else if (gotoEn == 0){ - _flag[target] &= ~(1 << 4); //unset bit +void Commands::setStepLength(byte target, byte stepLength) { + if (stepDir[target] > 0) { + stepDir[target] = stepLength; } else { - gotoEn = (_flag[target] >> 4) & 0x01; + stepDir[target] = -stepLength; } - return gotoEn; } -byte Commands::FVal(byte target, byte FVal){ //Set Method - if(FVal == 1){ - _flag[target] |= (1 << 0); //set bit - } else if (FVal == 0){ - _flag[target] &= ~(1 << 0); //unset bit - } else { - FVal = (_flag[target] >> 0) & 0x01; +void Commands::setDir(byte target, byte _dir){ //Set Method + _dir &= 1; + //byte sign = _dir ^ target; + //if (sign & 1){ + if(_dir){ + stepDir[target] = -1; //set step direction + } else {//if (dir == 0){} + stepDir[target] = 1; //set step direction } - return FVal; + dir[target] = _dir & 1; //set direction } -unsigned long Commands::jVal(byte target, unsigned long jVal){ //Set Method - if(jVal < 0x01000000){ - _jVal[target] = jVal; - } else { - jVal = _jVal[target]; - } - return jVal; +void Commands::setStopped(byte target, byte _stopped){ //Set Method + stopped[target] = _stopped & 1; } -unsigned long Commands::IVal(byte target, unsigned long IVal){ //Set Method - if(IVal < 0x01000000){ - _IVal[target] = IVal; - } else { - IVal = _IVal[target]; - } - return IVal; +void Commands::setGotoEn(byte target, byte _gotoEn){ //Set Method + gotoEn[target] = _gotoEn & 1; } -byte Commands::GVal(byte target, byte GVal){ //Set Method - if(GVal < 4){ - _GVal[target] = GVal; - } else { - GVal = _GVal[target]; - } - return GVal; -} - -unsigned long Commands::HVal(byte target, unsigned long HVal){ //Set Method - if(HVal < 0x01000000){ - _HVal[target] = HVal; - } else { - HVal = _HVal[target]; - } - return HVal; +void Commands::setFVal(byte target, byte _FVal){ //Set Method + FVal[target] = _FVal & 1; } -unsigned long Commands::eVal(byte target){ - return _eVal[target]; +unsigned int Commands::fVal(byte target){ //_fVal: 00ds000g000f + return ((dir[target] << 9)|(stopped[target] << 8)|(gotoEn[target] << 4)|(FVal[target] << 0)); } -unsigned long Commands::aVal(byte target){ - return _aVal[target]; +void Commands::setjVal(byte target, unsigned long _jVal){ //Set Method + jVal[target] = _jVal; } -unsigned long Commands::bVal(byte target){ - return _bVal[target]; +void Commands::setIVal(byte target, unsigned int _IVal){ //Set Method + IVal[target] = _IVal; } -byte Commands::gVal(byte target){ - return _gVal[target]; +void Commands::setHVal(byte target, unsigned long _HVal){ //Set Method + HVal[target] = _HVal; } -unsigned long Commands::sVal(byte target){ - return _sVal[target]; +void Commands::setGVal(byte target, byte _GVal){ //Set Method + GVal[target] = _GVal; } diff --git a/AstroEQ-Firmware/commands.h b/AstroEQ-Firmware/commands.h index 8dc127f857fb66c998ab69d5276f7360354d90ab..c0b9aad912fc0d3942169eddff66f11f07343297 100644 --- a/AstroEQ-Firmware/commands.h +++ b/AstroEQ-Firmware/commands.h @@ -14,52 +14,58 @@ //---------------------------------------------------------------------------- #ifndef commands_h #define commands_h + #if ARDUINO >= 100 #include "Arduino.h" #else #include "WProgram.h" #endif - #define numberOfCommands 17 + #include "EEPROMReader.h" + #include "EEPROMAddresses.h" + #define numberOfCommands 20 + class Commands{ public: - void init(unsigned long eVal,unsigned long aVal1,unsigned long aVal2,unsigned long bVal1,unsigned long bVal2,unsigned long sVal1,unsigned long sVal2,byte gVal); - void init(unsigned long eVal,unsigned long aVal,unsigned long bVal,byte gVal,unsigned long sVal); + + void init(unsigned long _eVal, byte _gVal); //Command definitions static const char command[numberOfCommands][3]; //Methods for accessing class variables - char stepDir(byte target); //Get Method - byte dir(byte target, char dir = 2); //Get Method - byte stopped(byte target, byte stopped = 2); //Get Method - byte gotoEn(byte target, byte gotoEn = 2); //Get Method - byte FVal(byte target, byte FVal = 2); //Get Method - unsigned int fVal(byte target); //return the flag to main program - unsigned long jVal(byte target, unsigned long jVal = 0x01000000); //Get Method - unsigned long IVal(byte target, unsigned long IVal = 0x01000000); //Get Method - byte GVal(byte target, byte GVal = 4); //Get Method - unsigned long HVal(byte target, unsigned long HVal = 0x01000000); //Get Method - unsigned long eVal(byte target); //Get Method - unsigned long aVal(byte target); //Get Method - unsigned long bVal(byte target); //Get Method - byte gVal(byte target); //Get Method - unsigned long sVal(byte target); //Get Method + void setStepLength(byte target, byte stepLength); //in highspeed mode, one step is gVal increments of the jVal. + void setDir(byte target, byte _dir); //Get Method + void setStopped(byte target, byte _stopped); //Get Method + void setGotoEn(byte target, byte _gotoEn); //Set Method + void setFVal(byte target, byte _FVal); //Get Method + void setjVal(byte target, unsigned long _jVal); //set Method + void setIVal(byte target, unsigned int _IVal); //set Method + void setHVal(byte target, unsigned long _HVal); //set Method + void setGVal(byte target, byte _GVal); //Get Method char getLength(char cmd, boolean sendRecieve); - private: //class variables - unsigned long _jVal[2]; //_jVal: Current position - unsigned long _IVal[2]; //_IVal: speed to move if in slew mode - byte _GVal[2]; //_GVal: slew/goto mode - unsigned long _HVal[2]; //_HVal: steps to move if in goto mode - unsigned int _flag[2]; //_fVal: 00ds000g000f; d = dir, s = stopped, g = goto, f = energised - unsigned long _eVal[2]; //_eVal: Version number - unsigned long _aVal[2]; //_aVal: Steps per axis revolution - unsigned long _bVal[2]; //_bVal: Sidereal Rate of axis - byte _gVal[2]; //_gVal: Speed scalar for highspeed slew - unsigned long _sVal[2]; //_sVal: Steps per worm gear revolution + unsigned long jVal[2]; //_jVal: Current position + unsigned int IVal[2]; //_IVal: speed to move if in slew mode + unsigned int motorSpeed[2]; //speed at which moving. Accelerates to IVal. + byte GVal[2]; //_GVal: slew/goto mode + unsigned long HVal[2]; //_HVal: steps to move if in goto mode + unsigned int fVal(byte target); //_fVal: 00ds000g000f; d = dir, s = stopped, g = goto, f = energised + volatile char stepDir[2]; + byte dir[2]; + byte FVal[2]; + byte gotoEn[2]; + byte stopped[2]; + unsigned long eVal[2]; //_eVal: Version number + unsigned long aVal[2]; //_aVal: Steps per axis revolution + unsigned long bVal[2]; //_bVal: Sidereal Rate of axis + byte gVal[2]; //_gVal: Speed scalar for highspeed slew + unsigned long sVal[2]; //_sVal: Steps per worm gear revolution + byte stepIncrement[2]; + unsigned int siderealIVal[2]; //_IVal: at sidereal rate + }; #endif diff --git a/AstroEQ-Firmware/synta.cpp b/AstroEQ-Firmware/synta.cpp index 95c3d3be91618be96b4d996956d392c950688228..33b510665be3937a6ac54838ca03b90f5b62bb25 100644 --- a/AstroEQ-Firmware/synta.cpp +++ b/AstroEQ-Firmware/synta.cpp @@ -1,22 +1,14 @@ #include "synta.h" -Synta::Synta(unsigned long eVal,unsigned long aVal,unsigned long bVal,byte gVal,unsigned long sVal,byte scalar){ +void Synta::initialise(unsigned long eVal){ validPacket = 0; _axis = 0; commandIndex = 0; clearBuffer(commandString,sizeof(commandString)); - _scalar = scalar; - cmd.init(eVal, aVal, bVal, gVal, sVal); -} - -Synta::Synta(unsigned long eVal,unsigned long aVal1,unsigned long aVal2,unsigned long bVal1,unsigned long bVal2,unsigned long sVal1,unsigned long sVal2,byte gVal,byte scalar){ - validPacket = 0; - _axis = 0; - commandIndex = 0; - clearBuffer(commandString,sizeof(commandString)); - _scalar = scalar; - cmd.init(eVal, aVal1, aVal2, bVal1, bVal2, sVal1, sVal2, gVal); + //scalar[0] = EEPROM.readByte(scalar1_Address) - 1; + //scalar[1] = EEPROM.readByte(scalar2_Address) - 1; + cmd.init(eVal, 8); } const char Synta::startInChar = ':'; @@ -157,7 +149,3 @@ byte Synta::axis(byte axis){ } return _axis; } - -byte Synta::scalar(){ - return _scalar; -} diff --git a/AstroEQ-Firmware/synta.h b/AstroEQ-Firmware/synta.h index 8d12d90c5d30e4f1bdaa96f7feb82fe3e63d9124..d4ff08ad1a670bb00c0c85670e1df805cbbdda7e 100644 --- a/AstroEQ-Firmware/synta.h +++ b/AstroEQ-Firmware/synta.h @@ -11,21 +11,36 @@ class Synta{ public: - Synta(unsigned long eVal,unsigned long aVal,unsigned long bVal,byte gVal,unsigned long sVal,byte scalar); - Synta(unsigned long eVal,unsigned long aVal1,unsigned long aVal2,unsigned long bVal1,unsigned long bVal2,unsigned long sVal1,unsigned long sVal2,byte gVal,byte scalar); + + static Synta& getInstance(unsigned long version) + { + static Synta singleton = Synta(version); + return singleton; + } + Commands cmd; void assembleResponse(char* dataPacket, char commandOrError, unsigned long responseData); char recieveCommand(char* dataPacket, char character); byte axis(byte axis = 2); //make target readonly to outside world. - byte scalar(); char command(); //make current command readonly to outside world. unsigned long hexToLong(char* hex); void longToHex(char* hex, unsigned long data); void intToHex(char* hex, unsigned int data); void byteToHex(char* hex, byte data); + + //byte scalar[2]; private: + Synta(unsigned long version) { + initialise(version); + }; + //Synta(Synta const&); + void operator=(Synta const&); + + void initialise(unsigned long eVal); + + void clearBuffer(char* buf, byte len); void success(char* buf, char data[], byte dataLen); void error(char* buf); @@ -33,11 +48,10 @@ boolean validPacket; char commandString[11]; - char commandIndex; + byte commandIndex; byte _axis; char _command; - byte _scalar; static const char startInChar; static const char startOutChar; diff --git a/AstroEQ-Hardware/PTH/AstroEQ PTH MK2.brd b/AstroEQ-Hardware/PTH/AstroEQ PTH MK2.brd index a520b26ec586695e5b61966962d3a74f26235d95..a0b2eef65ac183858fbe6fdd44fbee2392ec45ce 100644 Binary files a/AstroEQ-Hardware/PTH/AstroEQ PTH MK2.brd and b/AstroEQ-Hardware/PTH/AstroEQ PTH MK2.brd differ diff --git a/AstroEQ-Hardware/PTH/AstroEQ PTH MK2.sch b/AstroEQ-Hardware/PTH/AstroEQ PTH MK2.sch index 14fd992eb1d31dc4492bd3961c70d89b3830b677..53f0b7a99d9da7eda770ab67f9343a0e74778c39 100644 Binary files a/AstroEQ-Hardware/PTH/AstroEQ PTH MK2.sch and b/AstroEQ-Hardware/PTH/AstroEQ PTH MK2.sch differ diff --git a/AstroEQ-Hardware/PTH/AstroEQ-PTH-Gerber.zip b/AstroEQ-Hardware/PTH/AstroEQ-PTH-Gerber.zip index 500444ddf51a48bd994462ad0dbb931a0ddac39b..13c5e38a39835f07bd15e362a1e60928b31b22b8 100644 Binary files a/AstroEQ-Hardware/PTH/AstroEQ-PTH-Gerber.zip and b/AstroEQ-Hardware/PTH/AstroEQ-PTH-Gerber.zip differ diff --git a/Downloads/AstroEQ-Hardware.zip b/Downloads/AstroEQ-Hardware.zip index 017ceb91f31ea0ac5dab02cadfb56d08d8964377..03fc1b022e5c7c38568af8158488c78de803865c 100644 Binary files a/Downloads/AstroEQ-Hardware.zip and b/Downloads/AstroEQ-Hardware.zip differ diff --git a/Downloads/AstroEQ5-Software.zip b/Downloads/AstroEQ5-Software.zip deleted file mode 100644 index a9da126676ad89e1ed56c63f0068abfd231e4a12..0000000000000000000000000000000000000000 Binary files a/Downloads/AstroEQ5-Software.zip and /dev/null differ diff --git a/Downloads/AstroEQ6-ConfigUtility.zip b/Downloads/AstroEQ6-ConfigUtility.zip new file mode 100644 index 0000000000000000000000000000000000000000..7ec7f851dba1ea4590fcf52c5347b280f1fcc92f Binary files /dev/null and b/Downloads/AstroEQ6-ConfigUtility.zip differ diff --git a/Downloads/AstroEQ6-Firmware.zip b/Downloads/AstroEQ6-Firmware.zip new file mode 100644 index 0000000000000000000000000000000000000000..dab868141eedc7bc5f39d4de8835d3fa3ed26b1d Binary files /dev/null and b/Downloads/AstroEQ6-Firmware.zip differ diff --git a/WikiFiles/AstroEQ5.jpg b/WikiFiles/AstroEQ5.jpg deleted file mode 100644 index 0e3292a94b1c885315e5e059c3acf8fa71318289..0000000000000000000000000000000000000000 Binary files a/WikiFiles/AstroEQ5.jpg and /dev/null differ diff --git a/WikiFiles/Bottom.jpg b/WikiFiles/Bottom.jpg deleted file mode 100644 index 7cbcfb146b87c2e09cf7f6e463392296fefc96b1..0000000000000000000000000000000000000000 Binary files a/WikiFiles/Bottom.jpg and /dev/null differ diff --git a/WikiFiles/Config Screen.JPG b/WikiFiles/Config Screen.JPG new file mode 100644 index 0000000000000000000000000000000000000000..84635cb78b5e5a73f62ac70dda3d6926b37da3fb Binary files /dev/null and b/WikiFiles/Config Screen.JPG differ diff --git a/WikiFiles/EQMOD Loaded.JPG b/WikiFiles/EQMOD Loaded.JPG new file mode 100644 index 0000000000000000000000000000000000000000..430ef36398a71f6639f9d860e56c393b06677283 Binary files /dev/null and b/WikiFiles/EQMOD Loaded.JPG differ diff --git a/WikiFiles/EQMOD TestRun.JPG b/WikiFiles/EQMOD TestRun.JPG new file mode 100644 index 0000000000000000000000000000000000000000..61fd79c87d490300ba9efbb4648d6f542abd2924 Binary files /dev/null and b/WikiFiles/EQMOD TestRun.JPG differ diff --git a/WikiFiles/Home.JPG b/WikiFiles/Home.JPG new file mode 100644 index 0000000000000000000000000000000000000000..eda7e376e3a0debea4387e9cbc8529e6a1f45a64 Binary files /dev/null and b/WikiFiles/Home.JPG differ diff --git a/WikiFiles/Programmer.JPG b/WikiFiles/Programmer.JPG new file mode 100644 index 0000000000000000000000000000000000000000..6720fa62da816808f148d83ca9658988cb2d3901 Binary files /dev/null and b/WikiFiles/Programmer.JPG differ diff --git a/WikiFiles/Read Succeeded.JPG b/WikiFiles/Read Succeeded.JPG new file mode 100644 index 0000000000000000000000000000000000000000..17ce85827c9e8224b9e483be6ed24b8f2ab1098d Binary files /dev/null and b/WikiFiles/Read Succeeded.JPG differ diff --git a/WikiFiles/Reading Stored Values.JPG b/WikiFiles/Reading Stored Values.JPG new file mode 100644 index 0000000000000000000000000000000000000000..83f8314b50eaef7c401373c879b6b9f82ee7fa0f Binary files /dev/null and b/WikiFiles/Reading Stored Values.JPG differ diff --git a/WikiFiles/Splash.JPG b/WikiFiles/Splash.JPG new file mode 100644 index 0000000000000000000000000000000000000000..4550e4da92ab568ecc88c3428c8dd4ddfc7476b9 Binary files /dev/null and b/WikiFiles/Splash.JPG differ diff --git a/WikiFiles/Stored Config.JPG b/WikiFiles/Stored Config.JPG new file mode 100644 index 0000000000000000000000000000000000000000..73667c1ac3fe4a09c0064324ed6915389ac60e3c Binary files /dev/null and b/WikiFiles/Stored Config.JPG differ diff --git a/WikiFiles/Storing Config.JPG b/WikiFiles/Storing Config.JPG new file mode 100644 index 0000000000000000000000000000000000000000..772e5e40d2ac33b344780a50f90810d4dffe5b1c Binary files /dev/null and b/WikiFiles/Storing Config.JPG differ diff --git a/WikiFiles/Top.jpg b/WikiFiles/Top.jpg deleted file mode 100644 index 76db757d6890c30eacf85786b64edab308585362..0000000000000000000000000000000000000000 Binary files a/WikiFiles/Top.jpg and /dev/null differ diff --git a/WikiFiles/Update Complete.JPG b/WikiFiles/Update Complete.JPG new file mode 100644 index 0000000000000000000000000000000000000000..10686ca737e3e7cb8833362447eb487a89f5c943 Binary files /dev/null and b/WikiFiles/Update Complete.JPG differ diff --git a/WikiFiles/Upload Successful.JPG b/WikiFiles/Upload Successful.JPG new file mode 100644 index 0000000000000000000000000000000000000000..a483cbf1a64180401cb4c11efa3e148b963f50b7 Binary files /dev/null and b/WikiFiles/Upload Successful.JPG differ diff --git a/WikiFiles/Uploading AstroEQ.JPG b/WikiFiles/Uploading AstroEQ.JPG new file mode 100644 index 0000000000000000000000000000000000000000..39f84ced053b445ae22a8253136adfa51ee1c1fd Binary files /dev/null and b/WikiFiles/Uploading AstroEQ.JPG differ diff --git a/WikiFiles/calculator.jpg b/WikiFiles/calculator.jpg deleted file mode 100644 index a5920e127d85d890e40cee3c26c3d6e6986b1b77..0000000000000000000000000000000000000000 Binary files a/WikiFiles/calculator.jpg and /dev/null differ diff --git a/WikiFiles/initCode.jpg b/WikiFiles/initCode.jpg deleted file mode 100644 index 839f7b2ed49d0851bd2e9040d7c7b0473a111a6d..0000000000000000000000000000000000000000 Binary files a/WikiFiles/initCode.jpg and /dev/null differ diff --git a/WikiFiles/openMeFirst.jpg b/WikiFiles/openMeFirst.jpg deleted file mode 100644 index a139811d90f64a6041bad2f3826edf058224e609..0000000000000000000000000000000000000000 Binary files a/WikiFiles/openMeFirst.jpg and /dev/null differ diff --git a/WikiFiles/selectBoard.jpg b/WikiFiles/selectBoard.jpg deleted file mode 100644 index c5e9a876dfd08a500b0de2ecc78dfb7b0b39e680..0000000000000000000000000000000000000000 Binary files a/WikiFiles/selectBoard.jpg and /dev/null differ diff --git a/WikiFiles/sketchbook.jpg b/WikiFiles/sketchbook.jpg deleted file mode 100644 index 8bf94f76ce287282df532bd0fad7370c4e8d21b4..0000000000000000000000000000000000000000 Binary files a/WikiFiles/sketchbook.jpg and /dev/null differ