diff --git a/AstroEQ5/AstroEQ5.ino b/AstroEQ5/AstroEQ5.ino new file mode 100644 index 0000000000000000000000000000000000000000..8426cd5a6da1a2871b6253cae468b466bbafb6b4 --- /dev/null +++ b/AstroEQ5/AstroEQ5.ino @@ -0,0 +1,746 @@ +/* + 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.0 +*/ +//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); +// +// 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 Mount upgraded with the Dual motor kit (non Goto) +// aVal = 23961600 +// bVal = 172418 +// sVal = 184320 +// scalar = 10 +// +// Other mounts: +// aVal = 64 * motor steps per revolution * ratio +// bVal = 620 * aVal / 86164.0905 (round 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 +//a and s values. Hence below, I have set scalar to 10. + +//This is the initialistation code. If using the excel file, replace this line with what it gives. +// aVal bVal sVal scalar +Synta synta(1281, 13271040, 95493, 16, 92160, 3); + +//Define the two axes (swap the 0 and 1 if R.A. and Dec. motors are reversed) +#define RA 0 +#define DC 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------------------------- +//------------------------------------------------------------- + +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 + +#ifdef USEHIGHSPEEDMODE +#define PULSEWIDTH16F 8 +#define PULSEWIDTH2F 1 +#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 +const char modePins[2][2] = {{16,17},{19,18}}; +//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) +byte distributionWidth[2] = {64,64}; + +#elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) + +//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 +byte distributionWidth[2] = {64,64}; + +#endif + +void setup() +{ + 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 +#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],LOW); //default is low + digitalWrite(modePins[i][1],HIGH); //default is high +#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 + 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) + } //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] - 48)); //Store the current mode for the axis + synta.cmd.dir(synta.axis(),(packetIn[1] - 48)); //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 + + 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 > 64997L){ + rate = 64997L; + } else if (rate < 36L) { + 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(), 320L); + calculateRate(synta.axis()); + motorStart(synta.axis(),20/synta.scalar()); //Begin PWM + } else { + synta.cmd.IVal(synta.axis(), 176L); //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],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; + digitalWrite(modePins[motor][0],LOW); + digitalWrite(modePins[motor][1],HIGH); + if(motor){ + 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);//1 + } 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);//1 + } + } 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);//1 + } 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);//1 + } + } + } +#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 + digitalWrite(modePins[motor][0],HIGH); + digitalWrite(modePins[motor][1],LOW); + if(motor){ + 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); //0 + 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);//1 + } + } 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); //0 + 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);//1 + } + } + } +#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()) < 160000){ + timerCountRate = 200000; + //Set prescaler to F_CPU/8 + TCCR1B &= ~((1<<CS12) | (1<<CS10)); //0x0 + TCCR1B |= (1<<CS11);//1 + TCCR3B &= ~((1<<CS32) | (1<<CS30)); //0x0 + TCCR3B |= (1<<CS31);//1 + 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);//1 + TCCR3B &= ~((1<<CS32) | (1<<CS31));//00x + TCCR3B |= (1<<CS30);//1 + 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/AstroEQ5/Open me first/Driver (Atmega162 Version)/AstroEQ USB-Serial.hex b/AstroEQ5/Open me first/Driver (Atmega162 Version)/AstroEQ USB-Serial.hex new file mode 100644 index 0000000000000000000000000000000000000000..fd671ef1d07744e2b39afbf0d9da48ec4d7890e8 Binary files /dev/null and b/AstroEQ5/Open me first/Driver (Atmega162 Version)/AstroEQ USB-Serial.hex differ diff --git a/AstroEQ5/Open me first/Driver (Atmega162 Version)/mchpcdc.cat b/AstroEQ5/Open me first/Driver (Atmega162 Version)/mchpcdc.cat new file mode 100644 index 0000000000000000000000000000000000000000..14cb5d3d780cdf9d1a6123ccf210ae14893af5b4 Binary files /dev/null and b/AstroEQ5/Open me first/Driver (Atmega162 Version)/mchpcdc.cat differ diff --git a/AstroEQ5/Open me first/Driver (Atmega162 Version)/mchpcdc.inf b/AstroEQ5/Open me first/Driver (Atmega162 Version)/mchpcdc.inf new file mode 100644 index 0000000000000000000000000000000000000000..40fa177504c9aae2e9447f3f02c80aa9528d5bee --- /dev/null +++ b/AstroEQ5/Open me first/Driver (Atmega162 Version)/mchpcdc.inf @@ -0,0 +1,108 @@ + +; Windows USB CDC ACM Setup File +; Copyright (c) 2000 Microsoft Corporation +; Copyright (C) 2007 Microchip Technology Inc. + +[Version] +Signature="$Windows NT$" +Class=Ports +ClassGuid={4D36E978-E325-11CE-BFC1-08002BE10318} +Provider=%MFGNAME% +LayoutFile=layout.inf +CatalogFile=%MFGFILENAME%.cat +DriverVer=03/11/2010,5.1.2600.2 + +[Manufacturer] +%MFGNAME%=DeviceList, NTamd64 + +[DestinationDirs] +DefaultDestDir=12 + + +;------------------------------------------------------------------------------ +; Windows 2000/XP/Server2003/Vista/Server2008/7 - 32bit Sections +;------------------------------------------------------------------------------ + +[DriverInstall.nt] +include=mdmcpq.inf +CopyFiles=DriverCopyFiles.nt +AddReg=DriverInstall.nt.AddReg + +[DriverCopyFiles.nt] +usbser.sys,,,0x20 + +[DriverInstall.nt.AddReg] +HKR,,DevLoader,,*ntkern +HKR,,NTMPDriver,,%DRIVERFILENAME%.sys +HKR,,EnumPropPages32,,"MsPorts.dll,SerialPortPropPageProvider" + +[DriverInstall.nt.Services] +AddService=usbser, 0x00000002, DriverService.nt + +[DriverService.nt] +DisplayName=%SERVICE% +ServiceType=1 +StartType=3 +ErrorControl=1 +ServiceBinary=%12%\%DRIVERFILENAME%.sys + +;------------------------------------------------------------------------------ +; Windows XP/Server2003/Vista/Server2008/7 - 64bit Sections +;------------------------------------------------------------------------------ + +[DriverInstall.NTamd64] +include=mdmcpq.inf +CopyFiles=DriverCopyFiles.NTamd64 +AddReg=DriverInstall.NTamd64.AddReg + +[DriverCopyFiles.NTamd64] +%DRIVERFILENAME%.sys,,,0x20 + +[DriverInstall.NTamd64.AddReg] +HKR,,DevLoader,,*ntkern +HKR,,NTMPDriver,,%DRIVERFILENAME%.sys +HKR,,EnumPropPages32,,"MsPorts.dll,SerialPortPropPageProvider" + +[DriverInstall.NTamd64.Services] +AddService=usbser, 0x00000002, DriverService.NTamd64 + +[DriverService.NTamd64] +DisplayName=%SERVICE% +ServiceType=1 +StartType=3 +ErrorControl=1 +ServiceBinary=%12%\%DRIVERFILENAME%.sys + + +;------------------------------------------------------------------------------ +; Vendor and Product ID Definitions +;------------------------------------------------------------------------------ +; When developing your USB device, the VID and PID used in the PC side +; application program and the firmware on the microcontroller must match. +; Modify the below line to use your VID and PID. Use the format as shown below. +; Note: One INF file can be used for multiple devices with different VID and PIDs. +; For each supported device, append ",USB\VID_xxxx&PID_yyyy" to the end of the line. +;------------------------------------------------------------------------------ +[SourceDisksFiles] +[SourceDisksNames] +[DeviceList] +%DESCRIPTION%=DriverInstall, USB\VID_04D8&PID_000A + +[DeviceList.NTamd64] +%DESCRIPTION%=DriverInstall, USB\VID_04D8&PID_000A + + +;------------------------------------------------------------------------------ +; String Definitions +;------------------------------------------------------------------------------ +;Modify these strings to customize your device +;------------------------------------------------------------------------------ +[Strings] +MFGFILENAME="mchpcdc" +DRIVERFILENAME ="usbser" +MFGNAME="Microchip Technology, Inc." +INSTDISK="Microchip Technology, Inc. Installation Disc" +DESCRIPTION="USB Communications Port" +SERVICE="USB RS-232 Emulation Driver" + + diff --git a/AstroEQ5/Open me first/Initialisation Variable Calculator.xlsx b/AstroEQ5/Open me first/Initialisation Variable Calculator.xlsx new file mode 100644 index 0000000000000000000000000000000000000000..60373fa6e27dbd9489321f9c035fb173aaf3002c Binary files /dev/null and b/AstroEQ5/Open me first/Initialisation Variable Calculator.xlsx differ diff --git a/AstroEQ5/Open me first/README FIRST.txt b/AstroEQ5/Open me first/README FIRST.txt new file mode 100644 index 0000000000000000000000000000000000000000..4edaa9ba0477dd3628e973a31df06c832fd0869d --- /dev/null +++ b/AstroEQ5/Open me first/README FIRST.txt @@ -0,0 +1,36 @@ +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/AstroEQ5/Open me first/hardware/arduino/boards.txt b/AstroEQ5/Open me first/hardware/arduino/boards.txt new file mode 100644 index 0000000000000000000000000000000000000000..98a8611a15cadd3f72225c71234680789c33f27c --- /dev/null +++ b/AstroEQ5/Open me first/hardware/arduino/boards.txt @@ -0,0 +1,497 @@ +############################################################## + +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/AstroEQ5/Open me first/hardware/arduino/bootloaders/optiboot/optiboot_atmega162.hex b/AstroEQ5/Open me first/hardware/arduino/bootloaders/optiboot/optiboot_atmega162.hex new file mode 100644 index 0000000000000000000000000000000000000000..9c2d7e1d356bdb6011d4ae033a07d24aa48e4aa5 Binary files /dev/null and b/AstroEQ5/Open me first/hardware/arduino/bootloaders/optiboot/optiboot_atmega162.hex differ diff --git a/AstroEQ5/Open me first/hardware/arduino/variants/AstroEQ/pins_arduino.h b/AstroEQ5/Open me first/hardware/arduino/variants/AstroEQ/pins_arduino.h new file mode 100644 index 0000000000000000000000000000000000000000..66587c167398485354e0c16d56a988418bf04e33 --- /dev/null +++ b/AstroEQ5/Open me first/hardware/arduino/variants/AstroEQ/pins_arduino.h @@ -0,0 +1,235 @@ +/* + 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). Analog input +// pins are a separate set. + +// 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/AstroEQ5/Open me first/hardware/tools/avr/avr/include/avr/iom162.h b/AstroEQ5/Open me first/hardware/tools/avr/avr/include/avr/iom162.h new file mode 100644 index 0000000000000000000000000000000000000000..0a95150c8228c6f9871b0318dc68c8c624c22f96 --- /dev/null +++ b/AstroEQ5/Open me first/hardware/tools/avr/avr/include/avr/iom162.h @@ -0,0 +1,951 @@ +/* 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/AstroEQ5/commands.cpp b/AstroEQ5/commands.cpp new file mode 100644 index 0000000000000000000000000000000000000000..607cc8c52e635fcbd5cca239d4a735cc6edb1146 --- /dev/null +++ b/AstroEQ5/commands.cpp @@ -0,0 +1,181 @@ +//command Structures --------------------------------------------------------- +// +// Definition of the commands used by the Synta protocol, and variables in which responses +// are stored +// +// Data structure of flag Flag: +// flag = xxxx00ds000g000f where bits: +// x = dont care +// d = dir +// s = stopped +// g = goto +// f = energised +// +// Only dir can be used to set the direction, but stepDir method can be used +// to returns it in a more useful format +// +//---------------------------------------------------------------------------- + +#if ARDUINO >= 100 + #include "Arduino.h" +#else + #include "WProgram.h" +#endif + +#include "commands.h" + +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 + } +} + +const char Commands::command[numberOfCommands][3] = { {'e', 0, 6}, + {'a', 0, 6}, + {'b', 0, 6}, + {'g', 0, 2}, + {'s', 0, 6}, + {'K', 0, 0}, + {'E', 6, 0}, + {'j', 0, 6}, + {'f', 0, 3}, + {'G', 2, 0}, + {'H', 6, 0}, + {'M', 6, 0}, + {'I', 6, 0}, + {'J', 0, 0}, + {'P', 1, 0}, + {'F', 0, 0}, + {'L', 0, 0} }; + +char Commands::getLength(char cmd, boolean sendRecieve){ + for(byte i = 0;i < numberOfCommands;i++){ + if(command[i][0] == cmd){ + if(sendRecieve){ + return command[i][1]; + } else { + return command[i][2]; + } + } + } + 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 + } else { + gotoEn = (_flag[target] >> 4) & 0x01; + } + 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; + } + return FVal; +} + +unsigned long Commands::jVal(byte target, unsigned long jVal){ //Set Method + if(jVal < 0x01000000){ + _jVal[target] = jVal; + } else { + jVal = _jVal[target]; + } + return jVal; +} + +unsigned long Commands::IVal(byte target, unsigned long IVal){ //Set Method + if(IVal < 0x01000000){ + _IVal[target] = IVal; + } else { + IVal = _IVal[target]; + } + return IVal; +} + +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; +} + +unsigned long Commands::eVal(byte target){ + return _eVal[target]; +} + +unsigned long Commands::aVal(byte target){ + return _aVal[target]; +} + +unsigned long Commands::bVal(byte target){ + return _bVal[target]; +} + +byte Commands::gVal(byte target){ + return _gVal[target]; +} + +unsigned long Commands::sVal(byte target){ + return _sVal[target]; +} diff --git a/AstroEQ5/commands.h b/AstroEQ5/commands.h new file mode 100644 index 0000000000000000000000000000000000000000..bd78e968dbd1d205760299f0f22fccf9d3db75ac --- /dev/null +++ b/AstroEQ5/commands.h @@ -0,0 +1,64 @@ +//_fVal Flag get/set callers ------------------------------------------------- +// +//Data structure of _fVal Flag: +// _fVal = xxxx00ds000g000f where bits: +// x = dont care +// d = dir +// s = stopped +// g = goto +// f = energised +// +//Only dir can be used to set the direction, but stepDir method can be used +//to returns it in a more useful format +// +//---------------------------------------------------------------------------- +#ifndef commands_h +#define commands_h + #if ARDUINO >= 100 + #include "Arduino.h" + #else + #include "WProgram.h" + #endif + + #define numberOfCommands 17 + + class Commands{ + public: + void init(unsigned long eVal,unsigned long aVal,unsigned long bVal,byte gVal,unsigned long sVal); + + //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 + + 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 + }; +#endif diff --git a/AstroEQ5/synta.cpp b/AstroEQ5/synta.cpp new file mode 100644 index 0000000000000000000000000000000000000000..e5b19d7c2c36c1d3687f8481a5adb544d999a5e0 --- /dev/null +++ b/AstroEQ5/synta.cpp @@ -0,0 +1,154 @@ + +#include "synta.h" + +Synta::Synta(unsigned long eVal,unsigned long aVal,unsigned long bVal,byte gVal,unsigned long sVal,byte scalar){ + validPacket = 0; + _axis = 0; + commandIndex = 0; + clearBuffer(commandString,sizeof(commandString)); + _scalar = scalar; + cmd.init(eVal, aVal, bVal, gVal, sVal); +} + +const char Synta::startInChar = ':'; +const char Synta::startOutChar = '='; +const char Synta::errorChar = '!'; +const char Synta::endChar = '\r'; + +void Synta::error(char* buf){ + buf[0] = errorChar; + buf[1] = endChar; + buf[2] = 0; +} + +void Synta::clearBuffer(char* buf, byte len){ + strncpy(buf,"",len); +} + +void Synta::success(char* buf, char data[], byte dataLen){ + strcpy(buf + 1,data); + buf[0] = startOutChar; + buf[dataLen] = endChar; + buf[dataLen + 1] = 0; +} + +void Synta::assembleResponse(char* dataPacket, char commandOrError, unsigned long responseData){ + char replyLength = cmd.getLength(commandOrError,0); //get the number of data bytes for response + + char tempStr[11]; + + switch (replyLength){ + case -1: + error(dataPacket); //In otherwords, invalid command, so send error + return; + case 0: + clearBuffer(tempStr,sizeof(tempStr)); //empty temporary string + break; + case 2: + byteToHex(tempStr,responseData); + break; + case 3: + intToHex(tempStr,responseData); + break; + case 6: + longToHex(tempStr,responseData); + break; + } + success(dataPacket,tempStr,replyLength + 1); //compile response + return; +} + +boolean Synta::validateCommand(byte len){ + _command = commandString[0]; //first byte is command + _axis = commandString[1] - 49; //second byte is axis + if(_axis > 1){ + return 0; //incorrect axis + } + char requiredLength = cmd.getLength(_command,1); //get the required length of this command + len -= 3; //Remove the command and axis bytes, aswell as the end char; + if(requiredLength != len){ //If invalid command, or not required length + return 0; + } + + byte i; + for(i = 0;i < len;i++){ + commandString[i] = commandString[i + 2]; + } + commandString[i] = 0; //Null + return 1; +} + +char Synta::recieveCommand(char* dataPacket, char character){ + if(validPacket){ + if (character == startInChar){ + goto error; //new command without old finishing! (dataPacket contains error message) + } + + commandString[commandIndex++] = character; //Add character to current string build + + if(character == endChar){ + if(validateCommand(commandIndex)){ + strcpy(dataPacket,commandString); //Return decoded packet + validPacket = 0; + return 1; //Successful decode (dataPacket contains decoded packet) + } else { + goto error; //Decode Failed (dataPacket contains error message) + } + } else if (commandIndex == sizeof(commandString)){ + goto error; //Message too long! (dataPacket contains error message) + } + } else if (character == startInChar){ + //Begin new command + commandIndex = 0; + validPacket = 1; + clearBuffer(commandString,sizeof(commandString)); + } + return 0; //Decode not finished (dataPacket unchanged) +error: + error(dataPacket); + validPacket = 0; + return -1; +} + +unsigned long Synta::hexToLong(char* hex){ + char *boo; //waste point for strtol + char str[7]; //Destination of rearranged hex + strncpy(str,&hex[4],2); //Lower Byte + strncpy(str+2,&hex[2],2); //Middle Byte + strncpy(str+4,hex,2); //Upper Byte + str[6] = 0; + return strtol(str,&boo,16); //convert hex to long integer +} + +void Synta::longToHex(char* hex, unsigned long data){ + byte bytes[3]; + bytes[0] = (data >> 16) & 0xFF; + bytes[1] = (data >> 8) & 0xFF; + bytes[2] = (data) & 0xFF; + sprintf(hex,"%02X%02X%02X",bytes[2],bytes[1],bytes[0]); +} + +void Synta::intToHex(char* hex, unsigned int data){ + data &= 0xFFF; + sprintf(hex,"%03X",data); +} + +void Synta::byteToHex(char* hex, byte data){ + data &= 0xFF; + sprintf(hex,"%02X",data); +} + +char Synta::command(){ + return _command; +} + +byte Synta::axis(byte axis){ + if(axis < 2){ + _axis = axis; + } + return _axis; +} + +byte Synta::scalar(){ + return _scalar; +} diff --git a/AstroEQ5/synta.h b/AstroEQ5/synta.h new file mode 100644 index 0000000000000000000000000000000000000000..a698025af3cc5da89ba47321dc49dc786557e2ad --- /dev/null +++ b/AstroEQ5/synta.h @@ -0,0 +1,46 @@ + +#ifndef synta_h +#define synta_h + #if ARDUINO >= 100 + #include "Arduino.h" + #else + #include "WProgram.h" + #endif + + #include "commands.h" + + class Synta{ + public: + Synta(unsigned long eVal,unsigned long aVal,unsigned long bVal,byte gVal,unsigned long sVal,byte scalar); + 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); + + private: + void clearBuffer(char* buf, byte len); + void success(char* buf, char data[], byte dataLen); + void error(char* buf); + boolean validateCommand(byte len); + + boolean validPacket; + char commandString[11]; + char commandIndex; + + byte _axis; + char _command; + byte _scalar; + + static const char startInChar; + static const char startOutChar; + static const char errorChar; + static const char endChar; + }; +#endif diff --git a/Hardware V5/README.txt b/Hardware V5/README.txt new file mode 100644 index 0000000000000000000000000000000000000000..6415d9123851e167e57457201a9750fc89ced2a7 --- /dev/null +++ b/Hardware V5/README.txt @@ -0,0 +1,20 @@ +There are two versions of the board: +"Through Hole" uses through-hole components (except for the DRV8824PWP IC's which are only available as an SMD Package) +"SMD" uses all surface mount components and is thus alot smaller. + +The Through Hole board has been fully tested and I know works. +The SMD board I have double checked and looks correct, however I have not had it made, so functionality is not confirmed. + +BOMs can be gotten by using the "Design Link" feature on the schematic. (In Eagle 6, click the "Design Link" on the right from the schematic editor, and then click Schematic. +This will then load the BOM and also Farnell part numbers. All items can be purchased through Farnell, though if you prefer, you can use the BOM to find similar parts from places such as Digikey or RS. + +Please note that the board designs have two types of connector, the RJ11 type for Skywatcher mounts which use that connector, or a set of 8 screw terminals. You can only use one or the other, not both, though both part numbers are in the BOM. + +For the Through Hole board, the DRV8824PWP ICs are to be soldered to the breakout boards on the right. If there is enough interest, I can sell the ICs ready soldered, but only if there are at leasst 5 people who need them. +Also, the IC sockets need to be of this sort: http://www.rshelectronics.co.uk/img/p/607-630-large.jpg +NOT this sort: http://www.westfloridacomponents.com/mm5/graphics/H01/28-pin-machined-ic-socket.jpg +Else the breakout boards cannot be plugged in. Also note that in the BOM, you need twice as many of the 14x1 pin headers as these are used on the breakout boards. (If I do sell the IC's broken out, they will come with the headers attached). + + + +If you have problems with the "Design Link" and retrieving the BOM, please open an issue on the GitHub page. Though I have tested and it should work. \ No newline at end of file diff --git a/Hardware V5/SMD Version (untested)/SyncScan Standalone MK3 SMD.brd b/Hardware V5/SMD Version (untested)/SyncScan Standalone MK3 SMD.brd new file mode 100644 index 0000000000000000000000000000000000000000..c18b212638f68a0a28dce2fda322e952c0e7cb17 Binary files /dev/null and b/Hardware V5/SMD Version (untested)/SyncScan Standalone MK3 SMD.brd differ diff --git a/Hardware V5/SMD Version (untested)/SyncScan Standalone MK3 SMD.sch b/Hardware V5/SMD Version (untested)/SyncScan Standalone MK3 SMD.sch new file mode 100644 index 0000000000000000000000000000000000000000..7178f5e1052f8a3a4b7481d856d789184c74166a Binary files /dev/null and b/Hardware V5/SMD Version (untested)/SyncScan Standalone MK3 SMD.sch differ diff --git a/Hardware V5/Through Hole Version/SyncScan Standalone MK3 PTH.brd b/Hardware V5/Through Hole Version/SyncScan Standalone MK3 PTH.brd new file mode 100644 index 0000000000000000000000000000000000000000..6c31e478e9efbb9ef30f700bddd52cc2afeacc9b Binary files /dev/null and b/Hardware V5/Through Hole Version/SyncScan Standalone MK3 PTH.brd differ diff --git a/Hardware V5/Through Hole Version/SyncScan Standalone MK3 PTH.sch b/Hardware V5/Through Hole Version/SyncScan Standalone MK3 PTH.sch new file mode 100644 index 0000000000000000000000000000000000000000..cdbf0d036ec904b172aa7964250202e3df6e4c16 Binary files /dev/null and b/Hardware V5/Through Hole Version/SyncScan Standalone MK3 PTH.sch differ diff --git a/License.txt b/License.txt index ed25bc32de7eccdc8d31cce0f2191a287db03c94..1f159c961a6987ac0d675e88e7aca8529c27aa0a 100644 --- a/License.txt +++ b/License.txt @@ -1 +1 @@ -The project is completely open source, so feel free to chop and change it as much as you like, as long as any changes you make are published as open source and are not used for any commercial gain. Also, if possible, links back to the orignal code should be included. \ No newline at end of file +The project is completely open source, so feel free to chop and change it as much as you like, as long as any changes you make are published as open source and are not used for any commercial gain. Also, links back to my orignal code and this github page (https://github.com/TCWORLD/AstroEQ) should be included. \ No newline at end of file diff --git a/README b/README index 78d0347ea33a163b217c34d58cffcfee86037dda..67a63844ae8cce8d2beb41639435f7bfc006f070 100644 --- a/README +++ b/README @@ -1,18 +1,18 @@ -Update: 26/06/2012 +Update: 30/06/2012 -In the next couple of weeks, I will be uploading a new version (AstroEQ5). There are still a couple of tweaks to make before release. +In have now uploaded the latest version: AstroEQ5. AstroEQ5 has a completely redesigned set of motor functions and rate calculation making it now far more accurate in its tracking speed. There is also a redesigned set of hardware which no longer requires an Arduino Mega board to work. Instead it is based around an Atmega162 chip. Although this is not officially supported by the Arduino IDE, I have modified the bootloader to suit. -An advantage of this change is that now the board can be built using entirely through hole components, and can be made for much cheaper. +An advantage of this change is that now the board can be built using almost entirely through hole components, and can be made for much cheaper. In order to suit this design, I plan to sell the motor driver IC's, the Atmega162 with Bootloader, and a PIC preprogrammed as a USB-Serial port. The reason for this is that the motor drivers are very fine pitch ICs, not suitable for DIY, however I have designed a board which will break them out to a DIP package. Also the PIC and Atmega need to be initially programmed, which special programmers are needed for. If all goes well, I also plan to make available a kit complete with circuit board, and possibly ready built boards. Currently, with PCB, the estimated cost for a complete board is ~£80. +PLEASE NOTE: In order to do this, there has to be at least 10 people wanting the kits, else it is not economically viable for me to sell them. - -Please note that the new software will still support boards built with the current hardware design (<5.0), so if you have already built one, you can still take advantage of the new software. +Please note that the new software still support boards built with the old hardware design (<5.0), so if you have already built one, you can still take advantage of the new software. ------------------------------------------------------------------------------------- @@ -39,6 +39,6 @@ Also if you have problems getting the numbers to work, open an issue thread and Works with EQ3, EQ5, HEQ5, and EQ6 mounts. Along With custom mounts. - Current Verison: 4.0 + Current Verison: 5.0 --------------------------------------------------------------------------------------- \ No newline at end of file