diff --git a/AstroEQ-ConfigUtility/AstroEQ.exe b/AstroEQ-ConfigUtility/AstroEQ.exe index 5950a6b5c54997904dcd8e152411405a1d658517..d1451f3fdc04343d777e7125161659408ea9cc0b 100644 Binary files a/AstroEQ-ConfigUtility/AstroEQ.exe and b/AstroEQ-ConfigUtility/AstroEQ.exe differ diff --git a/AstroEQ-ConfigUtility/hex/AstroEQATMega162Based(Legacy).7.hex b/AstroEQ-ConfigUtility/hex/AstroEQATMega162Based(Legacy).7.hex deleted file mode 100644 index 3dc1909ddff704d2c7456a8f4af67799ac5f7cb5..0000000000000000000000000000000000000000 Binary files a/AstroEQ-ConfigUtility/hex/AstroEQATMega162Based(Legacy).7.hex and /dev/null differ diff --git a/AstroEQ-ConfigUtility/hex/AstroEQATMega162Based(Legacy).hex b/AstroEQ-ConfigUtility/hex/AstroEQATMega162Based(Legacy).hex deleted file mode 100644 index 7bc538bfd3fc40340b00f928908d7421c4d95c7d..0000000000000000000000000000000000000000 Binary files a/AstroEQ-ConfigUtility/hex/AstroEQATMega162Based(Legacy).hex and /dev/null differ diff --git a/AstroEQ-ConfigUtility/hex/AstroEQATMega162Based(Legacy)EEPROMReader.hex b/AstroEQ-ConfigUtility/hex/AstroEQATMega162Based(Legacy)EEPROMReader.hex deleted file mode 100644 index ad1aa4fd6481b2b39821f41790272b81eeccf6be..0000000000000000000000000000000000000000 Binary files a/AstroEQ-ConfigUtility/hex/AstroEQATMega162Based(Legacy)EEPROMReader.hex and /dev/null differ diff --git a/AstroEQ-ConfigUtility/hex/AstroEQArduinoMega1280(Legacy).7.hex b/AstroEQ-ConfigUtility/hex/AstroEQArduinoMega1280(Legacy).7.hex deleted file mode 100644 index a60ef4ca0f950f31042d355ff88a5143a9d29392..0000000000000000000000000000000000000000 Binary files a/AstroEQ-ConfigUtility/hex/AstroEQArduinoMega1280(Legacy).7.hex and /dev/null differ diff --git a/AstroEQ-ConfigUtility/hex/AstroEQArduinoMega1280(Legacy).hex b/AstroEQ-ConfigUtility/hex/AstroEQArduinoMega1280(Legacy).hex deleted file mode 100644 index 029ff92d6d341464af5f280ba9601059d2b1d173..0000000000000000000000000000000000000000 Binary files a/AstroEQ-ConfigUtility/hex/AstroEQArduinoMega1280(Legacy).hex and /dev/null differ diff --git a/AstroEQ-ConfigUtility/hex/AstroEQArduinoMega1280(Legacy)EEPROMReader.hex b/AstroEQ-ConfigUtility/hex/AstroEQArduinoMega1280(Legacy)EEPROMReader.hex deleted file mode 100644 index 273c0e8c51f2b3c33c65976bd72a9ed8eaca7084..0000000000000000000000000000000000000000 Binary files a/AstroEQ-ConfigUtility/hex/AstroEQArduinoMega1280(Legacy)EEPROMReader.hex and /dev/null differ diff --git a/AstroEQ-ConfigUtility/hex/AstroEQArduinoMega1280.hex b/AstroEQ-ConfigUtility/hex/AstroEQArduinoMega1280.hex new file mode 100644 index 0000000000000000000000000000000000000000..2f9f56765aa58e9e49d460cbec723b968a30073a Binary files /dev/null and b/AstroEQ-ConfigUtility/hex/AstroEQArduinoMega1280.hex differ diff --git a/AstroEQ-ConfigUtility/hex/AstroEQArduinoMega2560(Legacy).7.hex b/AstroEQ-ConfigUtility/hex/AstroEQArduinoMega2560(Legacy).7.hex deleted file mode 100644 index ded9b903c072dd9cb4ece93cda0b11ffea92f528..0000000000000000000000000000000000000000 Binary files a/AstroEQ-ConfigUtility/hex/AstroEQArduinoMega2560(Legacy).7.hex and /dev/null differ diff --git a/AstroEQ-ConfigUtility/hex/AstroEQArduinoMega2560(Legacy).hex b/AstroEQ-ConfigUtility/hex/AstroEQArduinoMega2560(Legacy).hex deleted file mode 100644 index 5cadeaeefe83c7a64624b7a72f720aa88ae2506b..0000000000000000000000000000000000000000 Binary files a/AstroEQ-ConfigUtility/hex/AstroEQArduinoMega2560(Legacy).hex and /dev/null differ diff --git a/AstroEQ-ConfigUtility/hex/AstroEQArduinoMega2560(Legacy)EEPROMReader.hex b/AstroEQ-ConfigUtility/hex/AstroEQArduinoMega2560(Legacy)EEPROMReader.hex deleted file mode 100644 index c1b2e6bc93255890eca6d762f2e9ea81b69343f6..0000000000000000000000000000000000000000 Binary files a/AstroEQ-ConfigUtility/hex/AstroEQArduinoMega2560(Legacy)EEPROMReader.hex and /dev/null differ diff --git a/AstroEQ-ConfigUtility/hex/AstroEQArduinoMega2560.hex b/AstroEQ-ConfigUtility/hex/AstroEQArduinoMega2560.hex new file mode 100644 index 0000000000000000000000000000000000000000..9be646901c389d99bfec06500025270f62993fa5 Binary files /dev/null and b/AstroEQ-ConfigUtility/hex/AstroEQArduinoMega2560.hex differ diff --git a/AstroEQ-ConfigUtility/hex/AstroEQV4-DIYBoard(includingKits).7.hex b/AstroEQ-ConfigUtility/hex/AstroEQV4-DIYBoard(includingKits).7.hex deleted file mode 100644 index a4fb1f68ae9e2105d18add3343b401614eedd1b2..0000000000000000000000000000000000000000 Binary files a/AstroEQ-ConfigUtility/hex/AstroEQV4-DIYBoard(includingKits).7.hex and /dev/null differ diff --git a/AstroEQ-ConfigUtility/hex/AstroEQV4-DIYBoard(includingKits).hex b/AstroEQ-ConfigUtility/hex/AstroEQV4-DIYBoard(includingKits).hex index e5c85febe1e647d0dacbcb7b8f097b625cc76ac5..cae6b706c64bcba283f2eac04f65378666d5d6b2 100644 Binary files a/AstroEQ-ConfigUtility/hex/AstroEQV4-DIYBoard(includingKits).hex and b/AstroEQ-ConfigUtility/hex/AstroEQV4-DIYBoard(includingKits).hex differ diff --git a/AstroEQ-ConfigUtility/hex/AstroEQV4-DIYBoard(includingKits)EEPROMReader.hex b/AstroEQ-ConfigUtility/hex/AstroEQV4-DIYBoard(includingKits)EEPROMReader.hex deleted file mode 100644 index 54b66465cccc252cc7b9abff1dc20f90bd6f485b..0000000000000000000000000000000000000000 Binary files a/AstroEQ-ConfigUtility/hex/AstroEQV4-DIYBoard(includingKits)EEPROMReader.hex and /dev/null differ diff --git a/AstroEQ-ConfigUtility/hex/AstroEQV4-EQ5Board.7.hex b/AstroEQ-ConfigUtility/hex/AstroEQV4-EQ5Board.7.hex deleted file mode 100644 index a4fb1f68ae9e2105d18add3343b401614eedd1b2..0000000000000000000000000000000000000000 Binary files a/AstroEQ-ConfigUtility/hex/AstroEQV4-EQ5Board.7.hex and /dev/null differ diff --git a/AstroEQ-ConfigUtility/hex/AstroEQV4-EQ5Board.hex b/AstroEQ-ConfigUtility/hex/AstroEQV4-EQ5Board.hex index e5c85febe1e647d0dacbcb7b8f097b625cc76ac5..cae6b706c64bcba283f2eac04f65378666d5d6b2 100644 Binary files a/AstroEQ-ConfigUtility/hex/AstroEQV4-EQ5Board.hex and b/AstroEQ-ConfigUtility/hex/AstroEQV4-EQ5Board.hex differ diff --git a/AstroEQ-ConfigUtility/hex/AstroEQV4-EQ5BoardEEPROMReader.hex b/AstroEQ-ConfigUtility/hex/AstroEQV4-EQ5BoardEEPROMReader.hex deleted file mode 100644 index 54b66465cccc252cc7b9abff1dc20f90bd6f485b..0000000000000000000000000000000000000000 Binary files a/AstroEQ-ConfigUtility/hex/AstroEQV4-EQ5BoardEEPROMReader.hex and /dev/null differ diff --git a/AstroEQ-ConfigUtility/hex/hexNames.txt b/AstroEQ-ConfigUtility/hex/hexNames.txt deleted file mode 100644 index edcb6353e709358c40bf0dfbacfe2a0b7b6c87c1..0000000000000000000000000000000000000000 --- a/AstroEQ-ConfigUtility/hex/hexNames.txt +++ /dev/null @@ -1,10 +0,0 @@ -AstroEQArduinoMega1280(Legacy) 6.8 7.0 -AstroEQArduinoMega2560(Legacy) 6.8 7.0 -AstroEQATMega162Based(Legacy) 6.8 7.0 -AstroEQV4-EQ5Board 6.8 7.0 -AstroEQV4-DIYBoard(includingKits) 6.8 7.0 -AstroEQArduinoMega1280(Legacy)EEPROMReader 1.2 1.2 -AstroEQArduinoMega2560(Legacy)EEPROMReader 1.2 1.2 -AstroEQATMega162Based(Legacy)EEPROMReader 1.2 1.2 -AstroEQV4-EQ5BoardEEPROMReader 1.2 1.2 -AstroEQV4-DIYBoard(includingKits)EEPROMReader 1.2 1.2 \ No newline at end of file diff --git a/AstroEQ-ConfigUtility/hex/versions.txt b/AstroEQ-ConfigUtility/hex/versions.txt new file mode 100644 index 0000000000000000000000000000000000000000..ee390ab09077a69609b1609120e5cec1d422f6d8 --- /dev/null +++ b/AstroEQ-ConfigUtility/hex/versions.txt @@ -0,0 +1,5 @@ +AstroEQUploaderUtility 3.2 +AstroEQArduinoMega1280 7.3 +AstroEQArduinoMega2560 7.3 +AstroEQV4-EQ5Board 7.3 +AstroEQV4-DIYBoard(includingKits) 7.3 \ No newline at end of file diff --git a/AstroEQ-ConfigUtility/mounts/Blank.conf b/AstroEQ-ConfigUtility/mounts/Blank.conf new file mode 100644 index 0000000000000000000000000000000000000000..3d29b6d6176241314560555c2d0fdd03e7265af6 --- /dev/null +++ b/AstroEQ-ConfigUtility/mounts/Blank.conf @@ -0,0 +1,20 @@ +:a1 +:b1 +:s1 +:n1 +:a2 +:b2 +:s2 +:n2 +:c10 +:c20 +:d11 +:d24 +:z1null +:z2null +:V1 +:V2 +:U1 +:U2 +:W1 +:W2 diff --git a/AstroEQ-ConfigUtility/mounts/EQ3-2-Skywatcher-Type1.conf b/AstroEQ-ConfigUtility/mounts/EQ3-2-Skywatcher-Type1.conf new file mode 100644 index 0000000000000000000000000000000000000000..b7703b67c4c1c625e515c1ce0919ce6f59f39094 --- /dev/null +++ b/AstroEQ-ConfigUtility/mounts/EQ3-2-Skywatcher-Type1.conf @@ -0,0 +1,20 @@ +:a12995200 +:b114739 +:s123040 +:n1424 +:a2998400 +:b28053 +:s215360 +:n2695 +:c10 +:c20 +:d11 +:d24 +:z19 +:z215 +:V17.5 +:V27.5 +:U1120 +:U280 +:W1130 +:W265 diff --git a/AstroEQ-ConfigUtility/mounts/EQ3-2-Skywatcher-Type2.conf b/AstroEQ-ConfigUtility/mounts/EQ3-2-Skywatcher-Type2.conf new file mode 100644 index 0000000000000000000000000000000000000000..ef20b726e0a4fb9422f15df33d45dfc69f3cda0b --- /dev/null +++ b/AstroEQ-ConfigUtility/mounts/EQ3-2-Skywatcher-Type2.conf @@ -0,0 +1,20 @@ +:a12995200 +:b114739 +:s123040 +:n1424 +:a2988416 +:b29246 +:s215206 +:n2806 +:c10 +:c20 +:d11 +:d24 +:z19 +:z217 +:V17.5 +:V27.5 +:U1120 +:U279.2 +:W1130 +:W265 diff --git a/AstroEQ-ConfigUtility/mounts/EQ5-Custom-Pulley.conf b/AstroEQ-ConfigUtility/mounts/EQ5-Custom-Pulley.conf new file mode 100644 index 0000000000000000000000000000000000000000..b4f847a6b532b59f56678e17447050ad6eb2b048 --- /dev/null +++ b/AstroEQ-ConfigUtility/mounts/EQ5-Custom-Pulley.conf @@ -0,0 +1,20 @@ +:a12457601 +:b114461 +:s117067 +:n1507 +:a22457601 +:b214461 +:s217067 +:n2507 +:c10 +:c20 +:d11 +:d232 +:z15 +:z25 +:V11.8 +:V21.8 +:U12.666666667 +:U22.666666667 +:W1144 +:W2144 diff --git a/AstroEQ-ConfigUtility/mounts/EQ5-Skywatcher.conf b/AstroEQ-ConfigUtility/mounts/EQ5-Skywatcher.conf new file mode 100644 index 0000000000000000000000000000000000000000..9ec6bdf8a7b8069c2a0d283b7f7af45d2818d17d --- /dev/null +++ b/AstroEQ-ConfigUtility/mounts/EQ5-Skywatcher.conf @@ -0,0 +1,20 @@ +:a13317760 +:b114863 +:s123040 +:n1386 +:a23317760 +:b214863 +:s223040 +:n2386 +:c10 +:c20 +:d11 +:d24 +:z19 +:z29 +:V17.5 +:V27.5 +:U1120 +:U2120 +:W1144 +:W2144 diff --git a/AstroEQ-ConfigUtility/mounts/HEQ5-Syntrek.conf b/AstroEQ-ConfigUtility/mounts/HEQ5-Syntrek.conf new file mode 100644 index 0000000000000000000000000000000000000000..fdac6248db19cc4ba7350339d99195d1ada7e775 --- /dev/null +++ b/AstroEQ-ConfigUtility/mounts/HEQ5-Syntrek.conf @@ -0,0 +1,20 @@ +:a14512000 +:b116390 +:s133422 +:n1313 +:a24512000 +:b216390 +:s233422 +:n2313 +:c10 +:c20 +:d11 +:d232 +:z126 +:z226 +:V11.8 +:V21.8 +:U15.222222222 +:U25.222222222 +:W1135 +:W2135 diff --git a/AstroEQ-Firmware/AstroEQ6.ino b/AstroEQ-Firmware/AstroEQ.cpp similarity index 52% rename from AstroEQ-Firmware/AstroEQ6.ino rename to AstroEQ-Firmware/AstroEQ.cpp index 6e47f8dd8cbc58b628c023134ffe25379f86f2bf..6c9edfc2cce35228d4c118113e617884cc56cba8 100644 --- a/AstroEQ-Firmware/AstroEQ6.ino +++ b/AstroEQ-Firmware/AstroEQ.cpp @@ -9,27 +9,23 @@ Works with EQ5, HEQ5, and EQ6 mounts - Current Verison: 7.0 + Current Verison: 7.3 */ //Only works with ATmega162, and Arduino Mega boards (1280 and 2560) #if defined(__AVR_ATmega162__) || defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) -#include "synta.h" //Synta Communications Protocol. -#include "PinMappings.h" //Read Pin Mappings -#include "EEPROMReader.h" //Read config file -#include "EEPROMAddresses.h" //Config file addresses -#include <util/delay.h> - -Synta synta = Synta::getInstance(1281); //create a mount instance, specify version! +#include "AstroEQ.h" -#define RA 0 //Right Ascension is AstroEQ axis 0 (Synta axis '1') -#define DC 1 //Declination is AstroEQ axis 1 (Synta axis '2') +#include "EEPROMReader.h" //Read config file +#include "SerialLink.h" //Serial Port +#include "UnionHelpers.h" +#include "synta.h" //Synta Communications Protocol. +#include <util/delay.h> +#include <avr/wdt.h> -//#define DEBUG 1 byte stepIncrement[2]; unsigned int normalGotoSpeed[2]; -unsigned int gotoFactor[2]; unsigned int minSpeed[2]; unsigned int stopSpeed[2]; byte readyToGo[2] = {0,0}; @@ -38,11 +34,9 @@ unsigned long gotoPosn[2] = {0UL,0UL}; //where to slew to #define timerCountRate 8000000 -#define NormalDistnWidth 32 -#define HighspeedDistnWidth 4 -unsigned int timerOVF[2][max(HighspeedDistnWidth,NormalDistnWidth)]; -boolean highSpeed[2] = {false,false}; -byte distributionWidth[2] = {NormalDistnWidth,NormalDistnWidth}; +#define DecimalDistnWidth 32 +unsigned int timerOVF[2][DecimalDistnWidth]; +bool canJumpToHighspeed = false; byte stepIncrementRepeat[2] = {0,0}; unsigned int gotoDecelerationLength[2]; #define distributionSegment(m) (m ? GPIOR1 : GPIOR0) @@ -55,6 +49,8 @@ unsigned int gotoDecelerationLength[2]; #define interruptControlBitMask(m) (m ? _BV(ICIE3) : _BV(ICIE1)) #define timerCountRegister(m) (m ? TCNT3 : TCNT1) #define timerPrescalarRegister(m) (m ? TCCR3B : TCCR1B) +#define gotoCompleteBitMask(m) (m ? _BV(3) : _BV(2)) +#define gotoCompleteRegister GPIOR2 //Pins const byte statusPin = statusPin_Define; @@ -64,11 +60,7 @@ const byte enablePin[2] = {enablePin_0_Define,enablePin_1_Define}; const byte stepPin[2] = {stepPin_0_Define,stepPin_1_Define}; const byte st4Pin[2][2] = {{ST4AddPin_0_Define,ST4SubPin_0_Define},{ST4AddPin_1_Define,ST4SubPin_1_Define}}; -#ifdef LEGACY_MODE -const byte modePins[2][2] = {{modePins0_0_Define,modePins2_0_Define},{modePins0_1_Define,modePins2_1_Define}}; -#else const byte modePins[2][3] = {{modePins0_0_Define,modePins1_0_Define,modePins2_0_Define},{modePins0_1_Define,modePins1_1_Define,modePins2_1_Define}}; -#endif byte encodeDirection[2]; @@ -83,13 +75,6 @@ byte encodeDirection[2]; #define stepHigh(m) (m ? _STEP1_HIGH : _STEP0_HIGH) #define stepLow(m) (m ? _STEP1_LOW : _STEP0_LOW) -#ifdef LEGACY_MODE -byte modeState[2][2] = {{HIGH,HIGH},{LOW,LOW}}; -#define MODE0 0 -#define MODE2 1 -#define STATE16 0 -#define STATE2 1 -#else byte modeState[2][3] = {{HIGH,HIGH,HIGH},{HIGH,LOW,LOW}}; #define MODE0 0 #define MODE1 1 @@ -97,60 +82,116 @@ byte modeState[2][3] = {{HIGH,HIGH,HIGH},{HIGH,LOW,LOW}}; #define STATE16 0 #define STATE2 1 -#endif +void buildModeMapping(byte microsteps, bool driverVersion){ + if (microsteps < 8){ + microsteps *= 8; + } + if (microsteps <16){ + modeState[STATE16][MODE0] = HIGH; + modeState[STATE16][MODE1] = HIGH; + modeState[STATE16][MODE2] = LOW; + modeState[STATE2][MODE0] = LOW; + modeState[STATE2][MODE1] = LOW; + modeState[STATE2][MODE2] = LOW; + } else if (microsteps > 16){ + modeState[STATE16][MODE0] = HIGH; + modeState[STATE16][MODE1] = HIGH; + modeState[STATE16][MODE2] = HIGH; + modeState[STATE2][MODE0] = LOW; + modeState[STATE2][MODE1] = HIGH; + modeState[STATE2][MODE2] = LOW; + } else { + modeState[STATE16][MODE0] = driverVersion ? LOW : HIGH; + modeState[STATE16][MODE1] = driverVersion ? LOW : HIGH; + modeState[STATE16][MODE2] = HIGH; + modeState[STATE2][MODE0] = HIGH; + modeState[STATE2][MODE1] = LOW; + modeState[STATE2][MODE2] = LOW; + } +} + + + + -boolean checkEEPROM(){ +byte progMode = 0; //MODES: 0 = Normal Ops (EQMOD). 1 = Validate EEPROM. 2 = Store to EEPROM. 3 = Rebuild EEPROM +byte microstepConf; +byte driverVersion; + +bool checkEEPROM(){ char temp[9] = {0}; - EEPROM.readString(temp,8,AstroEQID_Address); - return !(strncmp(temp,"AstroEQ",8)); + EEPROM_readString(temp,8,AstroEQID_Address); + if(strncmp(temp,"AstroEQ",8)){ + return false; + } + if ((encodeDirection[RA] > 1) || (encodeDirection[DC] > 1)){ + return false; //invalid value. + } + if (driverVersion > 1){ + return false; //invalid value. + } + if (driverVersion && microstepConf > 32){ + return false; //invalid value. + } else if (!driverVersion && microstepConf > 16){ + return false; //invalid value. + } + if ((cmd.siderealIVal[RA] > 1200) || (cmd.siderealIVal[RA] < 300)) { + return false; //invalid value. + } + if ((cmd.siderealIVal[DC] > 1200) || (cmd.siderealIVal[DC] < 300)) { + return false; //invalid value. + } + if(normalGotoSpeed[RA] == 0){ + return false; //invalid value. + } + if(normalGotoSpeed[DC] == 0){ + return false; //invalid value. + } + return true; +} + +void buildEEPROM(){ + EEPROM_writeString("AstroEQ",8,AstroEQID_Address); +} + +void storeEEPROM(){ + EEPROM_writeLong(cmd.aVal[RA],aVal1_Address); + EEPROM_writeLong(cmd.aVal[DC],aVal2_Address); + EEPROM_writeLong(cmd.bVal[RA],bVal1_Address); + EEPROM_writeLong(cmd.bVal[DC],bVal2_Address); + EEPROM_writeLong(cmd.sVal[RA],sVal1_Address); + EEPROM_writeLong(cmd.sVal[DC],sVal2_Address); + EEPROM_writeByte(encodeDirection[RA],RAReverse_Address); + EEPROM_writeByte(encodeDirection[DC],DECReverse_Address); + EEPROM_writeByte(driverVersion,Driver_Address); + EEPROM_writeByte(microstepConf,Microstep_Address); + EEPROM_writeByte(normalGotoSpeed[RA],RAGoto_Address); + EEPROM_writeByte(normalGotoSpeed[DC],DECGoto_Address); + EEPROM_writeInt(cmd.siderealIVal[RA],IVal1_Address); + EEPROM_writeInt(cmd.siderealIVal[DC],IVal2_Address); } void systemInitialiser(){ - encodeDirection[RA] = EEPROM.readByte(RAReverse_Address); //reverse the right ascension if 1 - encodeDirection[DC] = EEPROM.readByte(DECReverse_Address); //reverse the declination if 1 + synta_initialise(1281); //initialise mount instance, specify version! - -#ifdef LEGACY_MODE - //modeState[STATE2][MODE0] = EEPROM.readByte(Driver_Address); - //modeState[STATE16][MODE0] = !modeState[STATE2][MODE0]; - modeState[STATE2][MODE0] = EEPROM.readByte(Driver_Address); -#else - //modeState[STATE16][MODE1] = !EEPROM.readByte(Driver_Address); - //modeState[STATE16][MODE0] = modeState[STATE16][MODE1]; - modeState[STATE16][MODE0] = !EEPROM.readByte(Driver_Address); - modeState[STATE2][MODE0] = modeState[STATE16][MODE0]; - modeState[STATE2][MODE1] = !modeState[STATE16][MODE0]; -#endif + encodeDirection[RA] = EEPROM_readByte(RAReverse_Address); //reverse the right ascension if 1 + encodeDirection[DC] = EEPROM_readByte(DECReverse_Address); //reverse the declination if 1 - unsigned int multiplierRA = synta.cmd.siderealIVal[RA]/75; - unsigned int multiplierDC = synta.cmd.siderealIVal[DC]/75; - gotoFactor[RA] = EEPROM.readByte(RAGoto_Address); - normalGotoSpeed[RA] = multiplierRA * gotoFactor[RA] + 1; - gotoFactor[DC] = EEPROM.readByte(DECGoto_Address); - normalGotoSpeed[DC] = multiplierDC * gotoFactor[DC] + 1; + driverVersion = EEPROM_readByte(Driver_Address); - highSpeed[RA] = !EEPROM.readByte(Microstep_Address); - highSpeed[DC] = highSpeed[RA]; - distributionWidth[RA] = highSpeed[RA] ? HighspeedDistnWidth : NormalDistnWidth; - distributionWidth[DC] = highSpeed[DC] ? HighspeedDistnWidth : NormalDistnWidth; + normalGotoSpeed[RA] = EEPROM_readByte(RAGoto_Address); + normalGotoSpeed[DC] = EEPROM_readByte(DECGoto_Address); + + microstepConf = EEPROM_readByte(Microstep_Address); + buildModeMapping(microstepConf, driverVersion); + + canJumpToHighspeed = microstepConf>4; -#ifdef DEBUG - Serial1.println(); - Serial1.println(minSpeed[RA]); - Serial1.println(minSpeed[DC]); - Serial1.println(); - Serial1.println(normalGotoSpeed[RA]); - Serial1.println(normalGotoSpeed[DC]); - Serial1.println(); - Serial1.println(multiplierRA); - Serial1.println(multiplierDC); - Serial1.println(); -#endif if(!checkEEPROM()){ - while(1); //prevent AstroEQ startup if EEPROM is blank. + progMode = 1; //prevent AstroEQ startup if EEPROM is blank. } - minSpeed[RA] = synta.cmd.siderealIVal[RA]>>1;//2x sidereal rate. - minSpeed[DC] = synta.cmd.siderealIVal[DC]>>1;//[minspeed is the point at which acceleration curves are enabled] + minSpeed[RA] = cmd.siderealIVal[RA]>>1;//2x sidereal rate. + minSpeed[DC] = cmd.siderealIVal[DC]>>1;//[minspeed is the point at which acceleration curves are enabled] calculateRate(RA); //Initialise the interrupt speed table. This now only has to be done once at the beginning. calculateRate(DC); //Initialise the interrupt speed table. This now only has to be done once at the beginning. gotoDecelerationLength[RA] = calculateDecelerationLength(RA); @@ -160,67 +201,109 @@ void systemInitialiser(){ unsigned int calculateDecelerationLength (byte axis){ unsigned int currentSpeed = normalGotoSpeed[axis]; unsigned int stoppingSpeed = minSpeed[axis]; - unsigned int stepRepeat = synta.cmd.stepRepeat[axis] + 1; + unsigned int stepRepeat = cmd.stepRepeat[axis] + 1; unsigned int numberOfSteps = 0; while(currentSpeed < stoppingSpeed) { currentSpeed += (currentSpeed >> 5) + 1; //work through the decelleration formula. numberOfSteps += stepRepeat; //n more steps } //number of steps now contains how many steps required to slow to a stop. - if (!(numberOfSteps & 0xFF)) { - numberOfSteps++; //If it is a multiple of 16, an assumption in the ISR calculations won't hold true. So add an extra step. - } return numberOfSteps; } int main(void) { sei(); -#ifdef DEBUG - Serial1.begin(115200); -#endif systemInitialiser(); - #if defined(__AVR_ATmega162__) - //Timer 2 registers are being used as general purpose data storage for high efficency interrupt routines. So timer must be fully disabled. + //Timer 0 and 2 registers are being used as general purpose data storage for high efficency interrupt routines. So timer must be fully disabled. TCCR2 = 0; ASSR=0; -#endif - - pinMode(statusPin,OUTPUT); - for(byte i = 0;i < 2;i++){ //for each motor... - pinMode(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 - const byte* modePin = modePins[i]; - const byte* state = modeState[highSpeed[i]]; -#ifdef LEGACY_MODE - for(byte j = 0; j < 2; j++){ - pinMode(modePin[j],OUTPUT); - digitalWrite(modePin[j],state[j]); - } + GPIOR2 = 0; + TIMSK &= ~(_BV(TOIE0) | _BV(OCIE0)); + TCCR0 = 0; #else - for(byte j = 0; j < 3; j++){ - pinMode(modePin[j],OUTPUT); - digitalWrite(modePin[j],state[j]); - } + //Timer 0 registers are being used as general purpuse data storage. Timer must be fully disabled. + TCCR0A = 0; + TCCR0B = 0; + TIMSK0 = 0; #endif - pinMode(resetPin[i],OUTPUT); //enable the reset pin - digitalWrite(resetPin[i],LOW); //active low reset - _delay_ms(1); //allow ic to reset - digitalWrite(resetPin[i],HIGH); //complete reset - - pinMode(st4Pin[i][0],INPUT_PULLUP); - pinMode(st4Pin[i][1],INPUT_PULLUP); + //Status pins to output + *digitalPinToDirectionReg(statusPin) |= _BV(digitalPinToBit(statusPin)); + //Reset pins to output + *digitalPinToDirectionReg(resetPin[RA]) |= _BV(digitalPinToBit(resetPin[RA])); + *digitalPinToPortReg(resetPin[RA]) &= ~_BV(digitalPinToBit(resetPin[RA])); + *digitalPinToDirectionReg(resetPin[DC]) |= _BV(digitalPinToBit(resetPin[DC])); + *digitalPinToPortReg(resetPin[DC]) &= ~_BV(digitalPinToBit(resetPin[DC])); + //Enable pins to output + *digitalPinToDirectionReg(enablePin[RA]) |= _BV(digitalPinToBit(enablePin[RA])); + *digitalPinToPortReg(enablePin[RA]) |= _BV(digitalPinToBit(enablePin[RA])); //IC disabled + *digitalPinToDirectionReg(enablePin[DC]) |= _BV(digitalPinToBit(enablePin[DC])); + *digitalPinToPortReg(enablePin[DC]) |= _BV(digitalPinToBit(enablePin[DC])); //IC disabled + //Step pins to output + *digitalPinToDirectionReg(stepPin[RA]) |= _BV(digitalPinToBit(stepPin[RA])); + *digitalPinToPortReg(stepPin[RA]) &= ~_BV(digitalPinToBit(stepPin[RA])); + *digitalPinToDirectionReg(stepPin[DC]) |= _BV(digitalPinToBit(stepPin[DC])); + *digitalPinToPortReg(stepPin[DC]) &= ~_BV(digitalPinToBit(stepPin[DC])); + //Direction pins to output + *digitalPinToDirectionReg(dirPin[RA]) |= _BV(digitalPinToBit(dirPin[RA])); + *digitalPinToPortReg(dirPin[RA]) &= ~_BV(digitalPinToBit(dirPin[RA])); + *digitalPinToDirectionReg(dirPin[DC]) |= _BV(digitalPinToBit(dirPin[DC])); + *digitalPinToPortReg(dirPin[DC]) &= ~_BV(digitalPinToBit(dirPin[DC])); + + //Mode pins to output. + *digitalPinToDirectionReg(modePins[RA][MODE0]) |= _BV(digitalPinToBit(modePins[RA][MODE0])); + *digitalPinToDirectionReg(modePins[RA][MODE1]) |= _BV(digitalPinToBit(modePins[RA][MODE1])); + *digitalPinToDirectionReg(modePins[RA][MODE2]) |= _BV(digitalPinToBit(modePins[RA][MODE2])); + *digitalPinToDirectionReg(modePins[DC][MODE0]) |= _BV(digitalPinToBit(modePins[DC][MODE0])); + *digitalPinToDirectionReg(modePins[DC][MODE1]) |= _BV(digitalPinToBit(modePins[DC][MODE1])); + *digitalPinToDirectionReg(modePins[DC][MODE2]) |= _BV(digitalPinToBit(modePins[DC][MODE2])); + const byte * state; + if (!canJumpToHighspeed) { + state = modeState[STATE2]; + } else { + state = modeState[STATE16]; } - + if (state[MODE0]) { + *digitalPinToPortReg(modePins[RA][MODE0]) |= _BV(digitalPinToBit(modePins[RA][MODE0])); + *digitalPinToPortReg(modePins[DC][MODE0]) |= _BV(digitalPinToBit(modePins[DC][MODE0])); + } else { + *digitalPinToPortReg(modePins[RA][MODE0]) &= ~_BV(digitalPinToBit(modePins[RA][MODE0])); + *digitalPinToPortReg(modePins[DC][MODE0]) &= ~_BV(digitalPinToBit(modePins[DC][MODE0])); + } + if (state[MODE1]) { + *digitalPinToPortReg(modePins[RA][MODE1]) |= _BV(digitalPinToBit(modePins[RA][MODE1])); + *digitalPinToPortReg(modePins[DC][MODE1]) |= _BV(digitalPinToBit(modePins[DC][MODE1])); + } else { + *digitalPinToPortReg(modePins[RA][MODE1]) &= ~_BV(digitalPinToBit(modePins[RA][MODE1])); + *digitalPinToPortReg(modePins[DC][MODE1]) &= ~_BV(digitalPinToBit(modePins[DC][MODE1])); + } + if (state[MODE2]) { + *digitalPinToPortReg(modePins[RA][MODE2]) |= _BV(digitalPinToBit(modePins[RA][MODE2])); + *digitalPinToPortReg(modePins[DC][MODE2]) |= _BV(digitalPinToBit(modePins[DC][MODE2])); + } else { + *digitalPinToPortReg(modePins[RA][MODE2]) &= ~_BV(digitalPinToBit(modePins[RA][MODE2])); + *digitalPinToPortReg(modePins[DC][MODE2]) &= ~_BV(digitalPinToBit(modePins[DC][MODE2])); + } + + _delay_ms(1); //allow ic to reset + *digitalPinToPortReg(resetPin[RA]) |= _BV(digitalPinToBit(resetPin[RA])); + *digitalPinToPortReg(resetPin[DC]) |= _BV(digitalPinToBit(resetPin[DC])); + + //ST4 pins to input with pullup + *digitalPinToDirectionReg(st4Pin[RA][0]) &= ~_BV(digitalPinToBit(st4Pin[RA][0])); + *digitalPinToPortReg(st4Pin[RA][0]) |= _BV(digitalPinToBit(st4Pin[RA][0])); + *digitalPinToDirectionReg(st4Pin[RA][1]) &= ~_BV(digitalPinToBit(st4Pin[RA][1])); + *digitalPinToPortReg(st4Pin[RA][1]) |= _BV(digitalPinToBit(st4Pin[RA][1])); + *digitalPinToDirectionReg(st4Pin[DC][0]) &= ~_BV(digitalPinToBit(st4Pin[DC][0])); + *digitalPinToPortReg(st4Pin[DC][0]) |= _BV(digitalPinToBit(st4Pin[DC][0])); + *digitalPinToDirectionReg(st4Pin[DC][1]) &= ~_BV(digitalPinToBit(st4Pin[DC][1])); + *digitalPinToPortReg(st4Pin[DC][1]) |= _BV(digitalPinToBit(st4Pin[DC][1])); + // 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 + Serial_initialise(9600); //SyncScan runs at 9600Baud, use a serial port of your choice + while(Serial_available()){ + Serial_read(); //Clear the buffer } //setup interrupt for ST4 connection @@ -233,109 +316,150 @@ int main(void) #endif PCICR &= ~_BV(PCIE1); //disable PCInt[8..15] vector PCICR |= _BV(PCIE0); //enable PCInt[0..7] vector - + char recievedChar = 0; + signed char decoded = 0; for(;;){ //loop //static unsigned long lastMillis = millis(); //static boolean isLedOn = false; char decodedPacket[11]; //temporary store for completed command ready to be processed //*digitalPinToPortReg(statusPin) &= ~_BV(digitalPinToBit(statusPin)); - if (Serial.available()) { //is there a byte in buffer - *digitalPinToPortReg(statusPin) ^= _BV(digitalPinToBit(statusPin)); - //digitalWrite(statusPin,HIGH); //Turn on the LED to indicate activity. - char recievedChar = Serial.read(); //get the next character in buffer - #ifdef DEBUG - Serial1.write(recievedChar); - #endif - char decoded = synta.recieveCommand(decodedPacket,recievedChar); //once full command packet recieved, decodedPacket returns either error packet, or valid packet - if (decoded == 1){ //Valid Packet - decodeCommand(synta.command(),decodedPacket); //decode the valid packet - } else if (decoded == -1){ //Error - Serial.print(decodedPacket); //send the error packet (recieveCommand() already generated the error packet, so just need to send it) - #ifdef DEBUG - Serial1.print(F(" ->Res:")); - Serial1.println(decodedPacket); - #endif + if ((decoded == -2) || Serial_available()) { //is there a byte in buffer + *digitalPinToPortReg(statusPin) ^= _BV(digitalPinToBit(statusPin)); //Toggle on the LED to indicate activity. + if (decoded != -2) { + recievedChar = Serial_read(); //get the next character in buffer + } //else try to parse the last character again. + decoded = synta_recieveCommand(decodedPacket,recievedChar); //once full command packet recieved, decodedPacket returns either error packet, or valid packet + if (decoded > 0){ //Valid Packet + decodeCommand(synta_command(),decodedPacket); //decode the valid packet + } else if (decoded < 0){ //Error + Serial_writeStr(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. } - for(byte axis = 0; axis < 2; axis++){ - if(readyToGo[axis]==1){ - /*byte currentDir; - if(synta.cmd.stepDir[axis] > 0){ - currentDir = 0; - } else { - currentDir = 1; - } //convert step direction back to synta direction. - - //If directions are the same, we can just continue and decellerate to target speed. - */ - //if motor is stopped, then we can accelerate to target speed. - //Otherwise don't start the next movement until we have stopped. - if(/*(currentDir == synta.cmd.dir[axis]) || */(synta.cmd.stopped[axis])){ - synta.cmd.updateStepDir(axis); - if(synta.cmd.GVal[axis] & 1){ - //This is the funtion that enables a slew type move. - slewMode(axis); //Slew type - readyToGo[axis] = 2; + + //Check both axes - loop unravelled for speed efficiency - lots of Flash available. + if(readyToGo[RA]==1){ + //if motor is stopped, then we can accelerate to target speed. + //Otherwise don't start the next movement until we have stopped. + if((cmd.stopped[RA])){ + signed char GVal = cmd.GVal[RA]; + if (canJumpToHighspeed){ + const byte* state; + if ((GVal == 0) || (GVal == 3)) { + state = modeState[STATE2]; + cmd_updateStepDir(RA,8); + } else { + state = modeState[STATE16]; + cmd_updateStepDir(RA,1); + } + if (state[0]) { + *digitalPinToPortReg(modePins[RA][0]) |= _BV(digitalPinToBit(modePins[RA][0])); + } else { + *digitalPinToPortReg(modePins[RA][0]) &= ~_BV(digitalPinToBit(modePins[RA][0])); + } + if (state[1]) { + *digitalPinToPortReg(modePins[RA][1]) |= _BV(digitalPinToBit(modePins[RA][1])); + } else { + *digitalPinToPortReg(modePins[RA][1]) &= ~_BV(digitalPinToBit(modePins[RA][1])); + } + if (state[2]) { + *digitalPinToPortReg(modePins[RA][2]) |= _BV(digitalPinToBit(modePins[RA][2])); } else { - //This is the function for goto mode. You may need to customise it for a different motor driver - gotoMode(axis); //Goto Mode - readyToGo[axis] = 0; + *digitalPinToPortReg(modePins[RA][2]) &= ~_BV(digitalPinToBit(modePins[RA][2])); } + } else { + cmd_updateStepDir(RA,1); + } + if(GVal & 1){ + //This is the funtion that enables a slew type move. + slewMode(RA); //Slew type + readyToGo[RA] = 2; + } else { + //This is the function for goto mode. You may need to customise it for a different motor driver + gotoMode(RA); //Goto Mode + readyToGo[RA] = 0; } } } - #ifdef DEBUG - if (Serial1.available()) { //is there a byte in buffer - Serial1.println(); - Serial1.println(currentMotorSpeed(RA)); - Serial1.println(currentMotorSpeed(DC)); - Serial1.println(interruptOVFCount(RA)); - Serial1.println(interruptOVFCount(DC)); - Serial1.println(); - Serial1.read(); + if(readyToGo[DC]==1){ + //if motor is stopped, then we can accelerate to target speed. + //Otherwise don't start the next movement until we have stopped. + if((cmd.stopped[DC])){ + signed char GVal = cmd.GVal[DC]; + if (canJumpToHighspeed){ //for those using microstepping, disable microstepping for high speed slews + const byte* state; + if ((GVal == 0) || (GVal == 3)) { + state = modeState[STATE2]; + cmd_updateStepDir(DC,8); + } else { + state = modeState[STATE16]; + cmd_updateStepDir(DC,1); + } + if (state[0]) { + *digitalPinToPortReg(modePins[DC][0]) |= _BV(digitalPinToBit(modePins[DC][0])); + } else { + *digitalPinToPortReg(modePins[DC][0]) &= ~_BV(digitalPinToBit(modePins[DC][0])); + } + if (state[1]) { + *digitalPinToPortReg(modePins[DC][1]) |= _BV(digitalPinToBit(modePins[DC][1])); + } else { + *digitalPinToPortReg(modePins[DC][1]) &= ~_BV(digitalPinToBit(modePins[DC][1])); + } + if (state[2]) { + *digitalPinToPortReg(modePins[DC][2]) |= _BV(digitalPinToBit(modePins[DC][2])); + } else { + *digitalPinToPortReg(modePins[DC][2]) &= ~_BV(digitalPinToBit(modePins[DC][2])); + } + } else { + cmd_updateStepDir(DC,1); + } + if(GVal & 1){ + //This is the funtion that enables a slew type move. + slewMode(DC); //Slew type + readyToGo[DC] = 2; + } else { + //This is the function for goto mode. You may need to customise it for a different motor driver + gotoMode(DC); //Goto Mode + readyToGo[DC] = 0; + } + } } - #endif } } -void decodeCommand(char command, char* packetIn){ //each command is axis specific. The axis being modified can be retrieved by calling synta.axis() +void decodeCommand(char command, char* packetIn){ //each command is axis specific. The axis being modified can be retrieved by calling synta_axis() char response[11]; //generated response string unsigned long responseData = 0; //data for response - byte axis = synta.axis(); + byte axis = synta_axis(); unsigned int correction; - //byte scalar = synta.scalar[axis]+1; + //byte scalar = scalar[axis]+1; uint8_t oldSREG; switch(command){ case 'e': //readonly, return the eVal (version number) - responseData = synta.cmd.eVal[axis]; //response to the e command is stored in the eVal function for that axis. + responseData = cmd.eVal[axis]; //response to the e command is stored in the eVal function for that axis. break; case 'a': //readonly, return the aVal (steps per axis) - responseData = synta.cmd.aVal[axis]; //response to the a command is stored in the aVal function for that axis. + responseData = cmd.aVal[axis]; //response to the a command is stored in the aVal function for that axis. break; case 'b': //readonly, return the bVal (sidereal step rate) - responseData = synta.cmd.bVal[axis]; //response to the b command is stored in the bVal function for that axis. - correction = (synta.cmd.siderealIVal[axis] << 1); - responseData = (responseData * (correction+1))/correction; //account for rounding inside Skywatcher DLL. + responseData = cmd.bVal[axis]; //response to the b command is stored in the bVal function for that axis. + if (progMode == 0){ + correction = (cmd.siderealIVal[axis] << 1); + responseData = (responseData * (correction+1))/correction; //account for rounding inside Skywatcher DLL. + } break; case 'g': //readonly, return the gVal (high speed multiplier) - responseData = synta.cmd.gVal[axis]; //response to the g command is stored in the gVal function for that axis. + responseData = cmd.gVal[axis]; //response to the g command is stored in the gVal function for that axis. break; case 's': //readonly, return the sVal (steps per worm rotation) - responseData = synta.cmd.sVal[axis]; //response to the s command is stored in the sVal function for that axis. + responseData = cmd.sVal[axis]; //response to the s command is stored in the sVal function for that axis. break; case 'f': //readonly, return the fVal (axis status) - responseData = synta.cmd.fVal(axis); //response to the f command is stored in the fVal function for that axis. + responseData = cmd_fVal(axis); //response to the f command is stored in the fVal function for that axis. break; case 'j': //readonly, return the jVal (current position) oldSREG = SREG; cli(); //The next bit needs to be atomic, just in case the motors are running - responseData = synta.cmd.jVal[axis]; //response to the j command is stored in the jVal function for that axis. + responseData = cmd.jVal[axis]; //response to the j command is stored in the jVal function for that axis. SREG = oldSREG; break; case 'K': //stop the motor, return empty response @@ -347,26 +471,29 @@ void decodeCommand(char command, char* packetIn){ //each command is axis specifi motorDisable(axis); //shutdown driver power. break; case 'G': //set mode and direction, return empty response - if (packetIn[0] == '0'){ + /*if (packetIn[0] == '0'){ packetIn[0] = '2'; //don't allow a high torque goto. But do allow a high torque slew. - } - synta.cmd.setGVal(axis, (packetIn[0] - '0')); //Store the current mode for the axis - synta.cmd.setDir(axis, (packetIn[1] - '0')); //Store the current direction for that axis + }*/ + cmd_setGVal(axis, (packetIn[0] - '0')); //Store the current mode for the axis + cmd_setDir(axis, (packetIn[1] - '0')); //Store the current direction for that axis readyToGo[axis] = 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.setHVal(axis, synta.hexToLong(packetIn)); //set the goto position container (convert string to long first) + cmd_setHVal(axis, synta_hexToLong(packetIn)); //set the goto position container (convert string to long first) readyToGo[axis] = 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); + responseData = synta_hexToLong(packetIn); //if (responseData > minSpeed[axis]){ // responseData = minSpeed[axis]; //minimum speed limit <- if it is slower than this, there will be no acelleration. //} - synta.cmd.setIVal(axis, responseData); //set the speed container (convert string to long first) + if (responseData == 0){ + responseData = 1; //limit IVal to minimum of 1. + } + cmd_setIVal(axis, responseData); //set the speed container (convert string to long first) responseData = 0; if (readyToGo[axis] == 2){ - motorStart(axis,1); //Update Speed. + motorStart(axis,cmd.stepDir[axis]); //Update Speed. } else { readyToGo[axis] = 0; } @@ -374,61 +501,115 @@ void decodeCommand(char command, char* packetIn){ //each command is axis specifi case 'E': //set the current position, return empty response oldSREG = SREG; cli(); //The next bit needs to be atomic, just in case the motors are running - synta.cmd.setjVal(axis, synta.hexToLong(packetIn)); //set the current position (used to sync to what EQMOD thinks is the current position at startup + cmd_setjVal(axis, synta_hexToLong(packetIn)); //set the current position (used to sync to what EQMOD thinks is the current position at startup SREG = oldSREG; break; case 'F': //Enable the motor driver, return empty response - motorEnable(axis); //This enables the motors - gives the motor driver board power + if (progMode == 0){ //only allow motors to be enabled outside of programming mode. + motorEnable(axis); //This enables the motors - gives the motor driver board power + } else { + command = 0; //force sending of error packet!. + } + break; + + + //The following are used for configuration ---------- + case 'A': //store the aVal (steps per axis) + cmd_setaVal(axis, synta_hexToLong(packetIn)); //store aVal for that axis. 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') ) + case 'B': //store the bVal (sidereal rate) + cmd_setbVal(axis, synta_hexToLong(packetIn)); //store bVal for that axis. + break; + case 'S': //store the sVal (steps per worm rotation) + cmd_setsVal(axis, synta_hexToLong(packetIn)); //store sVal for that axis. + break; + case 'n': //return the IVal (EQMOD Speed at sidereal) + responseData = cmd.siderealIVal[axis]; + break; + case 'N': //store the IVal (EQMOD Speed at sidereal) + cmd_setsideIVal(axis, synta_hexToLong(packetIn)); //store sVal for that axis. + break; + case 'd': //return the driver version or step mode + if (axis) { + responseData = microstepConf; + } else { + responseData = driverVersion; + } + break; + case 'D': //store the driver verison and step modes + if (axis) { + microstepConf = synta_hexToByte(packetIn); //store step mode. + canJumpToHighspeed = microstepConf > 4; + } else { + driverVersion = synta_hexToByte(packetIn); //store driver version. + } + break; + case 'z': //return the Goto speed + responseData = normalGotoSpeed[axis]; + break; + case 'Z': //return the Goto speed factor + normalGotoSpeed[axis] = synta_hexToByte(packetIn); //store the goto speed factor + break; + case 'c': //return the axisDirectionReverse + responseData = encodeDirection[axis]; + break; + case 'C': //store the axisDirectionReverse + encodeDirection[axis] = packetIn[0] - '0'; //store sVal for that axis. + break; + case 'O': //set the programming mode. + progMode = packetIn[0] - '0'; //MODES: 0 = Normal Ops (EQMOD). 1 = Validate EEPROM. 2 = Store to EEPROM. 3 = Rebuild EEPROM + if (progMode != 0){ + motorStop(RA,1); //emergency axis stop. + motorDisable(RA); //shutdown driver power. + motorStop(DC,1); //emergency axis stop. + motorDisable(DC); //shutdown driver power. + readyToGo[RA] = 0; + readyToGo[DC] = 0; + } + break; + case 'T': //set mode, return empty response + if(progMode & 2){ + //proceed with eeprom write + if (progMode & 1) { + buildEEPROM(); + } else { + storeEEPROM(); + } + } else if (progMode & 1){ + if(!checkEEPROM()){ //check if EEPROM contains valid data. + command = 0; //force sending of an error packet. + } + } + break; + //--------------------------------------------------- + default: //Return empty response (deals with commands that don't do anything before the response sent (i.e 'J', 'R'), or do nothing at all (e.g. 'M', 'L') ) break; } - synta.assembleResponse(response, command, responseData); //generate correct response (this is required as is) - Serial.print(response); //send response to the serial port -#ifdef DEBUG - -#if DEBUG == 2 - if (command != 'j') -#endif - { - Serial1.print(F(" ->Res:")); - Serial1.println(response); - } -#if DEBUG == 2 - else { - Serial.println(); - } -#endif -#endif + synta_assembleResponse(response, command, responseData); //generate correct response (this is required as is) + Serial_writeStr(response); //send response to the serial port - if(command == 'J'){ //J tells us we are ready to begin the requested movement. So signal we are ready to go and when the last movement complets this one will execute. + if ((command == 'R') && (response[0] == '=')){ //reset the uC + wdt_enable(WDTO_15MS); + exit(0); + } + if((command == 'J') && (progMode == 0)){ //J tells us we are ready to begin the requested movement. So signal we are ready to go and when the last movement complets this one will execute. readyToGo[axis] = 1; - if (!(synta.cmd.GVal[axis] & 1)){ - synta.cmd.setGotoEn(axis,1); + if (!(cmd.GVal[axis] & 1)){ + cmd_setGotoEn(axis,1); } } } -//Calculates the rate based on the recieved I value void calculateRate(byte motor){ unsigned long rate; unsigned long remainder; float floatRemainder; - unsigned long divisor = synta.cmd.bVal[motor]; - byte distWidth; - // byte GVal = synta.cmd.GVal[motor]; - //if((GVal == 2)||(GVal == 1)){ //Normal Speed} - if(!highSpeed[motor]){ //Normal Speed - // highSpeed[motor] = false; - distWidth = NormalDistnWidth; - } else { //High Speed - // highSpeed[motor] = true; - distWidth = HighspeedDistnWidth; //There are 8 times fewer steps over which to distribute extra clock cycles - } + unsigned long divisor = cmd.bVal[motor]; + byte distWidth = DecimalDistnWidth; //When dividing a very large number by a much smaller on, float accuracy is abismal. So firstly we use integer math to split the division into quotient and remainder rate = timerCountRate / divisor; //Calculate the quotient @@ -440,10 +621,10 @@ void calculateRate(byte motor){ //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)distWidth; //This many extra cycles are needed: - remainder = (unsigned long)round(floatRemainder); + remainder = (unsigned long)(floatRemainder+0.5f); //Now truncate to an unsigned int with a sensible max value (the int is to avoid register issues with the 16 bit timer) - if(rate > 65535UL){ + if(((Inter)rate).highByter.integer){ rate = 65535UL; } else if (rate < 128UL) { rate = 128UL; @@ -468,100 +649,81 @@ void calculateRate(byte motor){ byte index = (byte)ceil(distn); timerOVF[motor][index] += 1; } - -#ifdef DEBUG - Serial1.println(); - Serial1.println(rate); - Serial1.println(); -#endif - - distributionWidth[motor] = distWidth - 1; //decrement to get its bitmask. (distnWidth is always a power of 2) - - byte x = synta.cmd.siderealIVal[motor]>>3; + + byte x = cmd.siderealIVal[motor]>>3; byte y = ((unsigned int)rate)>>3; unsigned int divisior = x * y; - synta.cmd.stepRepeat[motor] = (byte)((18750+(divisior>>1))/divisior)-1; //note that we are rounding to neareast so we add half the divisor. -#ifdef DEBUG - Serial1.println(); - Serial1.println(synta.cmd.stepRepeat[motor] ); - Serial1.println(); -#endif + cmd.stepRepeat[motor] = (byte)((18750+(divisior>>1))/divisior)-1; //note that we are rounding to neareast so we add half the divisor. } void motorEnable(byte axis){ - digitalWrite(enablePin[axis],LOW); - synta.cmd.setFVal(axis,1); + if (axis == RA){ + *digitalPinToPortReg(enablePin[RA]) &= ~_BV(digitalPinToBit(enablePin[RA])); //IC enabled + } else { + *digitalPinToPortReg(enablePin[DC]) &= ~_BV(digitalPinToBit(enablePin[DC])); //IC enabled + } + cmd_setFVal(axis,1); configureTimer(); //setup the motor pulse timers. } void motorDisable(byte axis){ - digitalWrite(enablePin[axis],LOW); - synta.cmd.setFVal(axis,0); + if (axis == RA){ + *digitalPinToPortReg(enablePin[RA]) |= _BV(digitalPinToBit(enablePin[RA])); //IC disabled + } else { + *digitalPinToPortReg(enablePin[DC]) |= _BV(digitalPinToBit(enablePin[DC])); //IC disabled + } + cmd_setFVal(axis,0); } void slewMode(byte axis){ - motorStart(axis,1); //Begin PWM + motorStart(axis,cmd.stepDir[axis]); //Begin PWM } void gotoMode(byte axis){ unsigned int decelerationLength = gotoDecelerationLength[axis]; + byte dirMagnitude = abs(cmd.stepDir[axis]); + char sign = cmd.dir[axis] ? -1 : 1; if (axis == RA){ - if (synta.cmd.HVal[axis] < (decelerationLength>>1)){ - synta.cmd.setHVal(axis,(decelerationLength>>1)); + if (cmd.HVal[axis] < (decelerationLength>>1)){ + cmd_setHVal(axis,(decelerationLength>>1)); //fudge factor to account for star movement during decelleration. } } else { - if (synta.cmd.HVal[axis] < 10){ - synta.cmd.setHVal(axis,10); + if (cmd.HVal[axis] < 16){ + cmd_setHVal(axis,16); } } - unsigned long HVal = synta.cmd.HVal[axis]; - unsigned long halfHVal = (HVal >> 1) + 1; //make decel slightly longer than accel + decelerationLength = decelerationLength * dirMagnitude; + //decelleration length is here a multiple of stepDir. + unsigned long HVal = cmd.HVal[axis]; + unsigned long halfHVal = (HVal >> 1) + 1; //make deceleration slightly longer than acceleration unsigned int gotoSpeed = normalGotoSpeed[axis]; + if(dirMagnitude == 8){ + HVal &= 0xFFFFFFF8; //clear the lower bits to avoid overshoot. + } + if(dirMagnitude == 8){ + halfHVal &= 0xFFFFFFF8; //clear the lower bits to avoid overshoot. + } + //HVal and halfHVal are here a multiple of stepDir if (halfHVal < decelerationLength) { decelerationLength = halfHVal; } -#ifdef DEBUG - Serial1.println(); - Serial1.println(decelerationLength); - Serial1.println(synta.cmd.jVal[axis]); -#endif HVal -= decelerationLength; /*if (axis == RA){ HVal += (decelerationLength>>2); }*/ - gotoPosn[axis] = synta.cmd.jVal[axis] + (synta.cmd.stepDir[axis] * HVal); //current position + relative change - decelleration region - -#ifdef DEBUG - Serial1.println(gotoPosn[axis]); - Serial1.println(); -#endif - synta.cmd.setIVal(axis, gotoSpeed); - //calculateRate(axis); + gotoPosn[axis] = cmd.jVal[axis] + (sign * HVal); //current position + relative change - decelleration region + cmd_setIVal(axis, gotoSpeed); + //calculateRate(axis); + gotoCompleteRegister |= gotoCompleteBitMask(axis); + decelerationLength = sign * decelerationLength; motorStart(axis,decelerationLength); //Begin PWM gotoRunning[axis] = 1; //start the goto. } -inline void timerEnable(byte motor, byte mode) { - //if (mode){ - //FCPU/8 - // timerPrescalarRegister(motor) &= ~((1<<CSn2) | (1<<CSn0)); //0x0 - // timerPrescalarRegister(motor) |= (1<<CSn1);//x1x - //} else { - //FCPU/1 +inline void timerEnable(byte motor) { timerPrescalarRegister(motor) &= ~((1<<CSn2) | (1<<CSn1));//00x timerPrescalarRegister(motor) |= (1<<CSn0);//xx1 - //} - //synta.cmd.setStepLength(motor, 1);//(mode ? synta.cmd.gVal[motor] : 1)); -/*#ifdef LEGACY_MODE - for( byte j = 0; j < 2; j++){ - digitalWrite(modePins[motor][j],modeState[mode][j]); - } -#else - for( byte j = 0; j < 3; j++){ - digitalWrite(modePins[motor][j],modeState[mode][j]); - } -#endif*/ } inline void timerDisable(byte motor) { @@ -570,24 +732,19 @@ inline void timerDisable(byte motor) { } //As there is plenty of FLASH left, then to improve speed, I have created two motorStart functions (one for RA and one for DEC) -void motorStart(byte motor, unsigned int gotoDeceleration){ +void motorStart(byte motor, signed int gotoDeceleration){ if (motor == RA) { motorStartRA(gotoDeceleration); } else { motorStartDC(gotoDeceleration); } } -void motorStartRA(unsigned int gotoDeceleration){ - unsigned int IVal = synta.cmd.IVal[RA]; +void motorStartRA(signed int gotoDeceleration){ + unsigned int IVal = cmd.IVal[RA]; unsigned int currentIVal; interruptControlRegister(RA) &= ~interruptControlBitMask(RA); //Disable timer interrupt currentIVal = currentMotorSpeed(RA); interruptControlRegister(RA) |= interruptControlBitMask(RA); //enable timer interrupt -#ifdef DEBUG - Serial1.println(F("IVal:")); - Serial1.println(IVal); - Serial1.println(); -#endif unsigned int startSpeed; unsigned int stoppingSpeed; if (IVal > minSpeed[RA]){ @@ -595,7 +752,7 @@ void motorStartRA(unsigned int gotoDeceleration){ } else { stoppingSpeed = minSpeed[RA]; } - if(synta.cmd.stopped[RA]) { + if(cmd.stopped[RA]) { startSpeed = stoppingSpeed; } else { if (currentIVal < minSpeed[RA]) { @@ -606,45 +763,35 @@ void motorStartRA(unsigned int gotoDeceleration){ } interruptControlRegister(RA) &= ~interruptControlBitMask(RA); //Disable timer interrupt - synta.cmd.currentIVal[RA] = synta.cmd.IVal[RA]; + cmd.currentIVal[RA] = cmd.IVal[RA]; currentMotorSpeed(RA) = startSpeed; stopSpeed[RA] = stoppingSpeed; interruptCount(RA) = 1; - if (encodeDirection[RA]^synta.cmd.dir[RA]) { + if (encodeDirection[RA]^cmd.dir[RA]) { *digitalPinToPortReg(dirPin[RA]) |= _BV(digitalPinToBit(dirPin[RA])); } else { *digitalPinToPortReg(dirPin[RA]) &= ~_BV(digitalPinToBit(dirPin[RA])); } - if(synta.cmd.stopped[RA]) { //if stopped, configure timers - //digitalWrite(dirPin[RA],encodeDirection[RA]^synta.cmd.dir[RA]); //set the direction + if(cmd.stopped[RA]) { //if stopped, configure timers stepIncrementRepeat[RA] = 0; distributionSegment(RA) = 0; int* decelerationSteps = (int*)&decelerationStepsLow(RA); //low and high are in sequential registers so we can treat them as an int in the sram. - *decelerationSteps = -gotoDeceleration; + *decelerationSteps = gotoDeceleration; timerCountRegister(RA) = 0; interruptOVFCount(RA) = timerOVF[RA][0]; - timerEnable(RA,highSpeed[RA]); - synta.cmd.setStopped(RA, 0); + timerEnable(RA); + cmd_setStopped(RA, 0); } interruptControlRegister(RA) |= interruptControlBitMask(RA); //enable timer interrupt -#ifdef DEBUG - Serial1.println(F("StartSpeed:")); - Serial1.println(startSpeed); - Serial1.println(); -#endif } -void motorStartDC(unsigned int gotoDeceleration){ - unsigned int IVal = synta.cmd.IVal[DC]; +void motorStartDC(signed int gotoDeceleration){ + unsigned int IVal = cmd.IVal[DC]; unsigned int currentIVal; interruptControlRegister(DC) &= ~interruptControlBitMask(DC); //Disable timer interrupt currentIVal = currentMotorSpeed(DC); interruptControlRegister(DC) |= interruptControlBitMask(DC); //enable timer interrupt -#ifdef DEBUG - Serial1.println(F("IVal:")); - Serial1.println(IVal); - Serial1.println(); -#endif + unsigned int startSpeed; unsigned int stoppingSpeed; if (IVal > minSpeed[DC]){ @@ -652,7 +799,7 @@ void motorStartDC(unsigned int gotoDeceleration){ } else { stoppingSpeed = minSpeed[DC]; } - if(synta.cmd.stopped[DC]) { + if(cmd.stopped[DC]) { startSpeed = stoppingSpeed; } else { if (currentIVal < minSpeed[DC]) { @@ -663,32 +810,26 @@ void motorStartDC(unsigned int gotoDeceleration){ } interruptControlRegister(DC) &= ~interruptControlBitMask(DC); //Disable timer interrupt - synta.cmd.currentIVal[DC] = synta.cmd.IVal[DC]; + cmd.currentIVal[DC] = cmd.IVal[DC]; currentMotorSpeed(DC) = startSpeed; stopSpeed[DC] = stoppingSpeed; interruptCount(DC) = 1; - if (encodeDirection[DC]^synta.cmd.dir[DC]) { + if (encodeDirection[DC]^cmd.dir[DC]) { *digitalPinToPortReg(dirPin[DC]) |= _BV(digitalPinToBit(dirPin[DC])); } else { *digitalPinToPortReg(dirPin[DC]) &= ~_BV(digitalPinToBit(dirPin[DC])); } - if(synta.cmd.stopped[DC]) { //if stopped, configure timers - //digitalWrite(dirPin[DC],encodeDirection[DC]^synta.cmd.dir[DC]); //set the direction + if(cmd.stopped[DC]) { //if stopped, configure timers stepIncrementRepeat[DC] = 0; distributionSegment(DC) = 0; int* decelerationSteps = (int*)&decelerationStepsLow(DC); //low and high are in sequential registers so we can treat them as an int in the sram. - *decelerationSteps = -gotoDeceleration; + *decelerationSteps = gotoDeceleration; timerCountRegister(DC) = 0; interruptOVFCount(DC) = timerOVF[DC][0]; - timerEnable(DC,highSpeed[DC]); - synta.cmd.setStopped(DC, 0); + timerEnable(DC); + cmd_setStopped(DC, 0); } interruptControlRegister(DC) |= interruptControlBitMask(DC); //enable timer interrupt -#ifdef DEBUG - Serial1.println(F("StartSpeed:")); - Serial1.println(startSpeed); - Serial1.println(); -#endif } //As there is plenty of FLASH left, then to improve speed, I have created two motorStop functions (one for RA and one for DEC) @@ -704,24 +845,24 @@ void motorStopRA(byte emergency){ if (emergency) { //trigger instant shutdown of the motor in an emergency. timerDisable(RA); - synta.cmd.setGotoEn(RA,0); //Not in goto mode. - synta.cmd.setStopped(RA,1); //mark as stopped + cmd_setGotoEn(RA,0); //Not in goto mode. + cmd_setStopped(RA,1); //mark as stopped readyToGo[RA] = 0; gotoRunning[RA] = 0; - } else if (!synta.cmd.stopped[RA]){ //Only stop if not already stopped - for some reason EQMOD stops both axis when slewing, even if one isn't currently moving? + } else if (!cmd.stopped[RA]){ //Only stop if not already stopped - for some reason EQMOD stops both axis when slewing, even if one isn't currently moving? //trigger ISR based decelleration //readyToGo[RA] = 0; - synta.cmd.setGotoEn(RA,0); //No longer in goto mode. + cmd_setGotoEn(RA,0); //No longer in goto mode. gotoRunning[RA] = 0; interruptControlRegister(RA) &= ~interruptControlBitMask(RA); //Disable timer interrupt - if(synta.cmd.currentIVal[RA] < minSpeed[RA]){ + if(cmd.currentIVal[RA] < minSpeed[RA]){ if(stopSpeed[RA] > minSpeed[RA]){ stopSpeed[RA] = minSpeed[RA]; } }/* else { - stopSpeed[RA] = synta.cmd.currentIVal[RA]; + stopSpeed[RA] = cmd.currentIVal[RA]; }*/ - synta.cmd.currentIVal[RA] = stopSpeed[RA] + 1;//synta.cmd.stepIncrement[motor]; + cmd.currentIVal[RA] = stopSpeed[RA] + 1;//cmd.stepIncrement[motor]; interruptControlRegister(RA) |= interruptControlBitMask(RA); //enable timer interrupt } } @@ -730,24 +871,24 @@ void motorStopDC(byte emergency){ if (emergency) { //trigger instant shutdown of the motor in an emergency. timerDisable(DC); - synta.cmd.setGotoEn(DC,0); //Not in goto mode. - synta.cmd.setStopped(DC,1); //mark as stopped + cmd_setGotoEn(DC,0); //Not in goto mode. + cmd_setStopped(DC,1); //mark as stopped readyToGo[DC] = 0; gotoRunning[DC] = 0; - } else if (!synta.cmd.stopped[DC]){ //Only stop if not already stopped - for some reason EQMOD stops both axis when slewing, even if one isn't currently moving? + } else if (!cmd.stopped[DC]){ //Only stop if not already stopped - for some reason EQMOD stops both axis when slewing, even if one isn't currently moving? //trigger ISR based decelleration //readyToGo[motor] = 0; - synta.cmd.setGotoEn(DC,0); //No longer in goto mode. + cmd_setGotoEn(DC,0); //No longer in goto mode. gotoRunning[DC] = 0; interruptControlRegister(DC) &= ~interruptControlBitMask(DC); //Disable timer interrupt - if(synta.cmd.currentIVal[DC] < minSpeed[DC]){ + if(cmd.currentIVal[DC] < minSpeed[DC]){ if(stopSpeed[DC] > minSpeed[DC]){ stopSpeed[DC] = minSpeed[DC]; } }/* else { - stopSpeed[DC] = synta.cmd.currentIVal[DC]; + stopSpeed[DC] = cmd.currentIVal[DC]; }*/ - synta.cmd.currentIVal[DC] = stopSpeed[DC] + 1;//synta.cmd.stepIncrement[motor]; + cmd.currentIVal[DC] = stopSpeed[DC] + 1;//cmd.stepIncrement[motor]; interruptControlRegister(DC) |= interruptControlBitMask(DC); //enable timer interrupt } } @@ -771,11 +912,11 @@ void configureTimer(){ ISR(PCINT0_vect) { //ST4 Pin Change Interrupt Handler. byte stopped; - if(!synta.cmd.gotoEn[RA]){ + if(!cmd.gotoEn[RA]){ //Only allow when not it goto mode. - stopped = synta.cmd.stopped[RA]; - unsigned int newSpeed = synta.cmd.siderealIVal[RA]; - if (synta.cmd.dir[RA] && !stopped) { + stopped = cmd.stopped[RA]; + unsigned int newSpeed = cmd.siderealIVal[RA]; + if (cmd.dir[RA] && !stopped) { goto ignoreRAST4; //if travelling in the wrong direction, then ignore. } byte multiplier; @@ -814,9 +955,9 @@ setRASpeed: : "0" (newSpeed), "r" (working) : "r1", "r0" ); - synta.cmd.currentIVal[RA] = newSpeed; + cmd.currentIVal[RA] = newSpeed; if (stopped) { - synta.cmd.dir[RA] = 0; //set direction + cmd.dir[RA] = 0; //set direction register byte one asm("r22"); asm volatile( "ldi %0,0x01 \n\t" @@ -824,21 +965,21 @@ setRASpeed: : "0" (one) : ); - synta.cmd.stepDir[RA] = one; //set step direction - synta.cmd.GVal[RA] = one; //slew mode + cmd.stepDir[RA] = one; //set step direction + cmd.GVal[RA] = one; //slew mode //calculateRate(RA); motorStart(RA,one); } else { - if (stopSpeed[RA] < synta.cmd.currentIVal[RA]) { - stopSpeed[RA] = synta.cmd.currentIVal[RA]; //ensure that RA doesn't stop. + if (stopSpeed[RA] < cmd.currentIVal[RA]) { + stopSpeed[RA] = cmd.currentIVal[RA]; //ensure that RA doesn't stop. } } } else { ignoreRAST4: - synta.cmd.currentIVal[RA] = newSpeed; + cmd.currentIVal[RA] = newSpeed; } } - if(!synta.cmd.gotoEn[DC]){ + if(!cmd.gotoEn[DC]){ //Only allow when not it goto mode. byte dir; byte stepDir; @@ -852,14 +993,14 @@ ignoreRAST4: dir = 0; stepDir = 1; setDECSpeed: - synta.cmd.stepDir[DC] = stepDir; //set step direction - synta.cmd.dir[DC] = dir; //set direction - synta.cmd.currentIVal[DC] = (synta.cmd.siderealIVal[DC] << 2); //move at 0.25x sidereal rate - synta.cmd.GVal[DC] = 1; //slew mode + cmd.stepDir[DC] = stepDir; //set step direction + cmd.dir[DC] = dir; //set direction + cmd.currentIVal[DC] = (cmd.siderealIVal[DC] << 2); //move at 0.25x sidereal rate + cmd.GVal[DC] = 1; //slew mode //calculateRate(DC); motorStart(DC,1); } else { - synta.cmd.currentIVal[DC] = stopSpeed[DC] + 1;//make our target >stopSpeed so that ISRs bring us to a halt. + cmd.currentIVal[DC] = stopSpeed[DC] + 1;//make our target >stopSpeed so that ISRs bring us to a halt. } } } @@ -889,7 +1030,7 @@ ISR(TIMER3_CAPT_vect, ISR_NAKED) { "eor r1,r1 \n\t" ); byte timeSegment = distributionSegment(DC); - byte index = (distributionWidth[DC] << 1) & timeSegment; + byte index = ((DecimalDistnWidth-1) << 1) & timeSegment; interruptOVFCount(DC) = *(int*)((byte*)timerOVF[DC] + index); //move to next pwm period distributionSegment(DC) = timeSegment + 1; @@ -904,46 +1045,44 @@ ISR(TIMER3_CAPT_vect, ISR_NAKED) { "push r26 \n\t" ); stepPort(DC) = port & stepLow(DC); - unsigned long jVal = synta.cmd.jVal[DC]; - jVal = jVal + synta.cmd.stepDir[DC]; - synta.cmd.jVal[DC] = jVal; + unsigned long jVal = cmd.jVal[DC]; + jVal = jVal + cmd.stepDir[DC]; + cmd.jVal[DC] = jVal; if(gotoRunning[DC]){ if (gotoPosn[DC] == jVal){ //reached the decelleration marker. Note that this line loads gotoPosn[] into r24:r27 //will decellerate the rest of the way. So first move gotoPosn[] to end point. - if (decelerationStepsHigh(DC) & _BV(7)) { + if (gotoCompleteRegister & gotoCompleteBitMask(DC)) { /* unsigned long gotoPos = gotoPosn[DC]; - if (synta.cmd.stepDir[DC] < 0){ - gotoPosn[DC] = gotoPos + decelerationSteps(DC); - } else { + if (cmd.stepDir[DC] < 0){ gotoPosn[DC] = gotoPos - decelerationSteps(DC); + } else { + gotoPosn[DC] = gotoPos + decelerationSteps(DC); } */ //--- This is a heavily optimised version of the code commented out just above ------------ //During compare of jVal and gotoPosn[], gotoPosn[] was loaded into r24 to r27 - register char stepDir asm("r20") = synta.cmd.stepDir[DC]; + //register char stepDir asm("r21") = cmd.stepDir[DC]; register unsigned long newGotoPosn asm("r18"); asm volatile( - "in %A0, %2 \n\t" - "in %B0, %3 \n\t" - "cp %1, __zero_reg__ \n\t" - "brlt .+6 \n\t" - "neg %A0 \n\t" - "com %B0 \n\t" //while this is not strictly accurate (works except when num=512), it is fine for this. - "eor %C0, %C0 \n\t" - "mov %D0, %C0 \n\t" - "add %A0, r24 \n\t" //add previously loaded gotoPosn[] registers to new gotoPosn[] registers. + "in %A0, %1 \n\t" //read in the number of decelleration steps + "in %B0, %2 \n\t" //which is either negative or positive + "ldi %C0, 0xFF \n\t" //assume it is and sign extend + "sbrs %B0, 7 \n\t" //if negative, then skip + "eor %C0, %C0 \n\t" //else clear the sign extension + "mov %D0, %C0 \n\t" //complete any sign extension as necessary + "add %A0, r24 \n\t" //and then add on to get the final stopping position "adc %B0, r25 \n\t" "adc %C0, r26 \n\t" "adc %D0, r27 \n\t" : "=a" (newGotoPosn) //goto selects r18:r21. This adds sts commands for all 4 bytes - : "r" (stepDir),"I" (_SFR_IO_ADDR(decelerationStepsLow(DC))),"I" (_SFR_IO_ADDR(decelerationStepsHigh(DC))) //stepDir is in r19 to match second byte of goto. + : /*"r" (stepDir),*/"I" (_SFR_IO_ADDR(decelerationStepsLow(DC))),"I" (_SFR_IO_ADDR(decelerationStepsHigh(DC))) //stepDir is in r19 to match second byte of goto. : ); gotoPosn[DC] = newGotoPosn; //----------------------------------------------------------------------------------------- - decelerationStepsHigh(DC) = 0; //say we are stopping - synta.cmd.currentIVal[DC] = stopSpeed[DC]; //decellerate to min speed. + gotoCompleteRegister &= ~gotoCompleteBitMask(DC); //say we are stopping + cmd.currentIVal[DC] = stopSpeed[DC]; //decellerate to min speed. } else { goto stopMotorISR3; } @@ -952,10 +1091,10 @@ ISR(TIMER3_CAPT_vect, ISR_NAKED) { if (currentMotorSpeed(DC) > stopSpeed[DC]) { stopMotorISR3: if(gotoRunning[DC]){ //if we are currently running a goto then - synta.cmd.gotoEn[DC] = 0; //Goto mode complete + cmd.gotoEn[DC] = 0; //Goto mode complete gotoRunning[DC] = 0; //Goto no longer running } //otherwise don't as it cancels a 'goto ready' state - synta.cmd.stopped[DC] = 1; //mark as stopped + cmd.stopped[DC] = 1; //mark as stopped timerDisable(DC); } asm volatile ( @@ -964,12 +1103,12 @@ stopMotorISR3: ); } else { stepPort(DC) = port | stepHigh(DC); - register unsigned int iVal asm("r20") = synta.cmd.currentIVal[DC]; + register unsigned int iVal asm("r20") = cmd.currentIVal[DC]; if (iVal != startVal){ port = stepIncrementRepeat[DC]; - register byte repeat asm("r19") = synta.cmd.stepRepeat[DC]; + register byte repeat asm("r19") = cmd.stepRepeat[DC]; if (repeat == port){ - register byte increment asm("r0");// = synta.cmd.stepIncrement[DC]; + register byte increment asm("r0");// = cmd.stepIncrement[DC]; /* stepIncrement[DC] = (startVal >> 5) + 1; */ @@ -1076,7 +1215,7 @@ ISR(TIMER1_CAPT_vect, ISR_NAKED) { "eor r1,r1 \n\t" ); byte timeSegment = distributionSegment(RA); - byte index = (distributionWidth[RA] << 1) & timeSegment; + byte index = ((DecimalDistnWidth-1) << 1) & timeSegment; interruptOVFCount(RA) = *(int*)((byte*)timerOVF[RA] + index); //move to next pwm period distributionSegment(RA) = timeSegment + 1; @@ -1091,31 +1230,30 @@ ISR(TIMER1_CAPT_vect, ISR_NAKED) { "push r26 \n\t" ); stepPort(RA) = port & stepLow(RA); - unsigned long jVal = synta.cmd.jVal[RA]; - jVal = jVal + synta.cmd.stepDir[RA]; - synta.cmd.jVal[RA] = jVal; + unsigned long jVal = cmd.jVal[RA]; + jVal = jVal + cmd.stepDir[RA]; + cmd.jVal[RA] = jVal; if(gotoRunning[RA]){ if (jVal == gotoPosn[RA]){ //reached the decelleration marker //will decellerate the rest of the way. So first move gotoPosn[] to end point. - if (decelerationStepsHigh(RA) & _BV(7)) { + if (gotoCompleteRegister & gotoCompleteBitMask(RA)) { /* unsigned long gotoPos = gotoPosn[RA]; - if (synta.cmd.stepDir[RA] < 0){ + if (cmd.stepDir[RA] < 0){ gotoPosn[RA] = gotoPos + decelerationSteps(RA); } else { gotoPosn[RA] = gotoPos - decelerationSteps(RA); } */ //--- This is a heavily optimised version of the code commented out just above ------------ - register char stepDir asm("r20") = synta.cmd.stepDir[RA]; + //register char stepDir asm("r21") = cmd.stepDir[RA]; register unsigned long newGotoPosn asm("r18"); asm volatile( - "in %A0, %2 \n\t" - "in %B0, %3 \n\t" - "cp %1, __zero_reg__ \n\t" - "brlt .+6 \n\t" - "neg %A0 \n\t" - "com %B0 \n\t" //while this is not strictly accurate (works except when num=512), it is fine for this. + "in %A0, %1 \n\t" + "in %B0, %2 \n\t" + "ldi %C0, 0xFF \n\t" + //"cp %1, __zero_reg__ \n\t" + "sbrs %B0, 7 \n\t" //if negative, then skip "eor %C0, %C0 \n\t" "mov %D0, %C0 \n\t" "add %A0, r24 \n\t" @@ -1123,12 +1261,12 @@ ISR(TIMER1_CAPT_vect, ISR_NAKED) { "adc %C0, r26 \n\t" "adc %D0, r27 \n\t" : "=a" (newGotoPosn) //goto selects r18:r21. This adds sts commands for all 4 bytes - : "r" (stepDir),"I" (_SFR_IO_ADDR(decelerationStepsLow(RA))), "I" (_SFR_IO_ADDR(decelerationStepsHigh(RA))) //temp is in r19 to match second byte of goto. + : /*"r" (stepDir),*/"I" (_SFR_IO_ADDR(decelerationStepsLow(RA))), "I" (_SFR_IO_ADDR(decelerationStepsHigh(RA))) //temp is in r19 to match second byte of goto. : ); gotoPosn[RA] = newGotoPosn; - decelerationStepsHigh(RA) = 0; //say we are stopping - synta.cmd.currentIVal[RA] = stopSpeed[RA]; //decellerate to min speed. This is possible in at most 80 steps. + gotoCompleteRegister &= ~gotoCompleteBitMask(RA); //say we are stopping + cmd.currentIVal[RA] = stopSpeed[RA]; //decellerate to min speed. This is possible in at most 80 steps. } else { goto stopMotorISR1; } @@ -1137,10 +1275,10 @@ ISR(TIMER1_CAPT_vect, ISR_NAKED) { if (currentMotorSpeed(RA) > stopSpeed[RA]) { stopMotorISR1: if(gotoRunning[RA]){ //if we are currently running a goto then - synta.cmd.gotoEn[RA] = 0; //Goto mode complete + cmd.gotoEn[RA] = 0; //Goto mode complete gotoRunning[RA] = 0; //Goto complete. } //otherwise don't as it cancels a 'goto ready' state - synta.cmd.stopped[RA] = 1; //mark as stopped + cmd.stopped[RA] = 1; //mark as stopped timerDisable(RA); } asm volatile ( @@ -1149,12 +1287,12 @@ stopMotorISR1: ); } else { stepPort(RA) = port | stepHigh(RA); - register unsigned int iVal asm("r20") = synta.cmd.currentIVal[RA]; + register unsigned int iVal asm("r20") = cmd.currentIVal[RA]; if (iVal != startVal){ port = stepIncrementRepeat[RA]; - register byte repeat asm("r19") = synta.cmd.stepRepeat[RA]; + register byte repeat asm("r19") = cmd.stepRepeat[RA]; if (repeat == port){ - register byte increment asm("r0");// = synta.cmd.stepIncrement[RA]; + register byte increment asm("r0");// = cmd.stepIncrement[RA]; /* stepIncrement[RA] = (startVal >> 5) + 1; */ diff --git a/AstroEQ-Firmware/AstroEQ.h b/AstroEQ-Firmware/AstroEQ.h new file mode 100644 index 0000000000000000000000000000000000000000..e9e8b22a713d23c044f26ca6a5481b394bc18395 --- /dev/null +++ b/AstroEQ-Firmware/AstroEQ.h @@ -0,0 +1,97 @@ +/* + 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 + + Current Verison: 7.2 +*/ + +//Only works with ATmega162, and Arduino Mega boards (1280 and 2560) +#if defined(__AVR_ATmega162__) || defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) + +#ifndef __ASTROEQ_H__ +#define __ASTROEQ_H__ + +#ifdef __cplusplus +extern "C"{ +#endif + +#include "PinMappings.h" //Read Pin Mappings +#include "EEPROMAddresses.h" //Config file addresses +#include "UnionHelpers.h" + +#include <string.h> +#include <stdlib.h> +#include <math.h> + +#include <avr/pgmspace.h> +#include <avr/io.h> +#include <avr/interrupt.h> + +#include <inttypes.h> +#ifndef sbi + #define sbi(r,b) r |= _BV(b) +#endif +#ifndef cbi + #define cbi(r,b) r &= ~_BV(b) +#endif + +#define HIGH 1 +#define LOW 0 + +#ifdef abs +#undef abs +#endif + +#define abs(x) ((x)>0?(x):-(x)) + +#ifndef max +#define max(a,b) ((a > b) ? a : b) +#endif + +typedef uint8_t byte; + +#define RA 0 //Right Ascension is AstroEQ axis 0 (Synta axis '1') +#define DC 1 //Declination is AstroEQ axis 1 (Synta axis '2') + +bool checkEEPROM(); +void buildEEPROM(); +void storeEEPROM(); +void systemInitialiser(); +unsigned int calculateDecelerationLength (byte axis); +int main(void); +void decodeCommand(char command, char* packetIn); +void calculateRate(byte motor); +void motorEnable(byte axis); +void motorDisable(byte axis); +void slewMode(byte axis); +void gotoMode(byte axis); +extern inline void timerEnable(byte motor); +extern inline void timerDisable(byte motor); +void motorStart(byte motor, signed int gotoDeceleration); +void motorStartRA(signed int gotoDeceleration); +void motorStartDC(signed int gotoDeceleration); +void motorStop(byte motor, byte emergency); +void motorStopRA(byte emergency); +void motorStopDC(byte emergency); +void configureTimer(); +void buildModeMapping(byte microsteps, bool driverVersion); + + +#ifdef __cplusplus +} // extern "C" +#endif + + +#endif + + +#else +#error Unsupported Part! Please use an Arduino Mega, or ATMega162 +#endif diff --git a/AstroEQ-Firmware/AstroEQ.ino b/AstroEQ-Firmware/AstroEQ.ino new file mode 100644 index 0000000000000000000000000000000000000000..69b3a58b0cd7aeab80e7e5b7d3556ed0dd9b5219 --- /dev/null +++ b/AstroEQ-Firmware/AstroEQ.ino @@ -0,0 +1 @@ +//Refer to AstroEQ.cpp - The .ino is empty as the Arduino core is neither needed nor wanted. diff --git a/AstroEQ-Firmware/Open me first/Driver (Atmega162 Version)/AstroEQ USB-Serial.hex b/AstroEQ-Firmware/Driver (Atmega162 Version)/AstroEQ USB-Serial.hex similarity index 100% rename from AstroEQ-Firmware/Open me first/Driver (Atmega162 Version)/AstroEQ USB-Serial.hex rename to AstroEQ-Firmware/Driver (Atmega162 Version)/AstroEQ USB-Serial.hex diff --git a/AstroEQ-Firmware/Open me first/Driver (Atmega162 Version)/mchpcdc.cat b/AstroEQ-Firmware/Driver (Atmega162 Version)/mchpcdc.cat similarity index 100% rename from AstroEQ-Firmware/Open me first/Driver (Atmega162 Version)/mchpcdc.cat rename to AstroEQ-Firmware/Driver (Atmega162 Version)/mchpcdc.cat diff --git a/AstroEQ-Firmware/Open me first/Driver (Atmega162 Version)/mchpcdc.inf b/AstroEQ-Firmware/Driver (Atmega162 Version)/mchpcdc.inf similarity index 100% rename from AstroEQ-Firmware/Open me first/Driver (Atmega162 Version)/mchpcdc.inf rename to AstroEQ-Firmware/Driver (Atmega162 Version)/mchpcdc.inf diff --git a/AstroEQ-Firmware/EEPROMAddresses.h b/AstroEQ-Firmware/EEPROMAddresses.h index 07252b4faf7e117b92c6375142a41cd4351c4d7c..3897614813a26e3b294239caa22d201cbbad7e24 100644 --- a/AstroEQ-Firmware/EEPROMAddresses.h +++ b/AstroEQ-Firmware/EEPROMAddresses.h @@ -1,12 +1,12 @@ #define EEPROMStart_Address ( 0 ) #define AstroEQID_Address (EEPROMStart_Address + 0 ) -#define Microstep_Address (EEPROMStart_Address + 8) //whether to use microstepping. +#define Microstep_Address (EEPROMStart_Address + 8 ) //whether to use microstepping. #define RAReverse_Address (EEPROMStart_Address + 9 ) #define DECReverse_Address (EEPROMStart_Address + 10) #define Driver_Address (EEPROMStart_Address + 11) -#define RAGoto_Address (EEPROMStart_Address + 12) //and 13 -#define DECGoto_Address (EEPROMStart_Address + 13) //and 13 +#define RAGoto_Address (EEPROMStart_Address + 12) +#define DECGoto_Address (EEPROMStart_Address + 13) #define aVal1_Address (EEPROMStart_Address + 14) //steps/axis #define aVal2_Address (EEPROMStart_Address + 18) //steps/axis #define bVal1_Address (EEPROMStart_Address + 22) //sidereal rate diff --git a/AstroEQ-Firmware/EEPROMReader.cpp b/AstroEQ-Firmware/EEPROMReader.cpp index 9e5fb8315181c01505317e59b8742123a30a5341..8fef4f0baecc3f203d910957073facd9d8ad7654 100644 --- a/AstroEQ-Firmware/EEPROMReader.cpp +++ b/AstroEQ-Firmware/EEPROMReader.cpp @@ -1,58 +1,55 @@ #include <avr/eeprom.h> -#include "Arduino.h" #include "EEPROMReader.h" -uint8_t EEPROMReader::readByte(byte address) +byte EEPROM_readByte(byte address) { - return eeprom_read_byte((unsigned char *) address); + return eeprom_read_byte((byte*) address); } -uint16_t EEPROMReader::readInt(byte address) +unsigned int EEPROM_readInt(byte address) { TwoBytes fetcher; - fetcher.array[0] = readByte(address); - fetcher.array[1] = readByte(address+1); + fetcher.array[0] = EEPROM_readByte(address); + fetcher.array[1] = EEPROM_readByte(address+1); return fetcher.integer; } -uint32_t EEPROMReader::readLong(byte address) +unsigned long EEPROM_readLong(byte address) { FourBytes fetcher; - fetcher.array[0] = readInt(address); - fetcher.array[1] = readInt(address+2); + fetcher.array[0] = EEPROM_readInt(address); + fetcher.array[1] = EEPROM_readInt(address+2); return fetcher.integer; } -void EEPROMReader::readString(char* string, byte len, byte address) +void EEPROM_readString(char* string, byte len, byte address) { for(byte i = 0; i < len; i++) { - string[i] = readByte(address++); + string[i] = EEPROM_readByte(address++); } } -void EEPROMReader::writeByte(uint8_t val, byte address) +void EEPROM_writeByte(byte val, byte address) { - return eeprom_write_byte((unsigned char *) address, val); + return eeprom_update_byte((byte*) address, val); } -void EEPROMReader::writeInt(uint16_t val, byte address) +void EEPROM_writeInt(unsigned int val, byte address) { TwoBytes storer = {val}; - writeByte(storer.array[0], address); - writeByte(storer.array[1], address+1); + EEPROM_writeByte(storer.array[0], address); + EEPROM_writeByte(storer.array[1], address+1); } -void EEPROMReader::writeLong(uint32_t val, byte address) +void EEPROM_writeLong(unsigned long val, byte address) { FourBytes storer = {val}; - writeInt(storer.array[0], address); - writeInt(storer.array[1], address+2); + EEPROM_writeInt(storer.array[0], address); + EEPROM_writeInt(storer.array[1], address+2); } -void EEPROMReader::writeString(const char* string, byte len, byte address) +void EEPROM_writeString(const char* string, byte len, byte address) { for(byte i = 0; i < len; i++) { - writeByte(string[i], address+i); + EEPROM_writeByte(string[i], address+i); } } -EEPROMReader EEPROM; - diff --git a/AstroEQ-Firmware/EEPROMReader.h b/AstroEQ-Firmware/EEPROMReader.h index 9dbaaa7202324d3ddfc67141f0b946b77b43ba81..d7a7c1b39cd2ad4c738980c5c9f4874b24ce4080 100644 --- a/AstroEQ-Firmware/EEPROMReader.h +++ b/AstroEQ-Firmware/EEPROMReader.h @@ -1,22 +1,15 @@ -#ifndef EEPROM_h -#define EEPROM_h +#ifndef __EEPROM_H__ +#define __EEPROM_H__ -#include "Arduino.h" -#include "UnionHelpers.h" +#include "AstroEQ.h" -class EEPROMReader -{ - public: - uint8_t readByte(byte); - uint16_t readInt(byte); - uint32_t readLong(byte); - void readString(char* string, byte len, byte address); - void writeByte(uint8_t,byte); - void writeInt(uint16_t,byte); - void writeLong(uint32_t,byte); - void writeString(const char* string, byte len, byte address); -}; +byte EEPROM_readByte(byte); +unsigned int EEPROM_readInt(byte); +unsigned long EEPROM_readLong(byte); +void EEPROM_readString(char* string, byte len, byte address); +void EEPROM_writeByte(byte,byte); +void EEPROM_writeInt(unsigned int,byte); +void EEPROM_writeLong(unsigned long,byte); +void EEPROM_writeString(const char* string, byte len, byte address); -extern EEPROMReader EEPROM; - -#endif +#endif //__EEPROM_H__ diff --git a/AstroEQ-Firmware/Open me first/HardwareSerial.cpp b/AstroEQ-Firmware/Open me first/HardwareSerial.cpp deleted file mode 100644 index 2bde9208bb8ffa49ea369b884777130222f45a88..0000000000000000000000000000000000000000 --- a/AstroEQ-Firmware/Open me first/HardwareSerial.cpp +++ /dev/null @@ -1,665 +0,0 @@ -/* - HardwareSerial.cpp - Hardware serial library for Wiring - Copyright (c) 2006 Nicholas Zambetti. All right reserved. - - 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - - Modified 23 November 2006 by David A. Mellis - Modified 28 September 2010 by Mark Sproul -*/ - -#include <stdlib.h> -#include <stdio.h> -#include <string.h> -#include <inttypes.h> -#include "Arduino.h" -#include "wiring_private.h" - -// this next line disables the entire HardwareSerial.cpp, -// this is so I can support Attiny series and any other chip without a uart -#if defined(UBRRH) || defined(UBRR0H) || defined(UBRR1H) || defined(UBRR2H) || defined(UBRR3H) - -#include "HardwareSerial.h" - -// Define constants and variables for buffering incoming serial data. We're -// using a ring buffer (I think), in which head is the index of the location -// to which to write the next incoming character and tail is the index of the -// location from which to read. MAX SIZE IS 128 for this implementation!! -#if (RAMEND < 1000) - #define SERIAL_BUFFER_SIZE 16 -#else - #define SERIAL_BUFFER_SIZE 96 -#endif - -template<class T> inline T modulo(T head) { //Not a true '%' function, but it is all that is required by this library! - if(head >= SERIAL_BUFFER_SIZE){ - head -= SERIAL_BUFFER_SIZE; - } - return head; -} - -struct ring_buffer -{ - unsigned char buffer[SERIAL_BUFFER_SIZE]; - volatile unsigned char head; - volatile unsigned char tail; -}; - -#if defined(USBCON) - ring_buffer rx_buffer = { { 0 }, 0, 0}; - ring_buffer tx_buffer = { { 0 }, 0, 0}; -#endif -#if defined(UBRRH) || defined(UBRR0H) - ring_buffer rx_buffer = { { 0 }, 0, 0 }; - ring_buffer tx_buffer = { { 0 }, 0, 0 }; -#endif -#if defined(UBRR1H) - ring_buffer rx_buffer1 = { { 0 }, 0, 0 }; - ring_buffer tx_buffer1 = { { 0 }, 0, 0 }; -#endif -#if defined(UBRR2H) - ring_buffer rx_buffer2 = { { 0 }, 0, 0 }; - ring_buffer tx_buffer2 = { { 0 }, 0, 0 }; -#endif -#if defined(UBRR3H) - ring_buffer rx_buffer3 = { { 0 }, 0, 0 }; - ring_buffer tx_buffer3 = { { 0 }, 0, 0 }; -#endif - -inline void store_char(unsigned char c, ring_buffer *buffer) -{ - register unsigned char i asm("r25"); - register unsigned char tail asm("r24"); - asm volatile ( - "push %0 \n\t" - "push %1 \n\t" - "push r30 \n\t" - "push r31 \n\t" - ::"r" (i), "r" (tail): - ); - i = modulo((unsigned char)(buffer->head+1));// % SERIAL_BUFFER_SIZE; - // if we should be storing the received character into the location - // just before the tail (meaning that the head would advance to the - // current location of the tail), we're about to overflow the buffer - // and so we don't write the character or advance the head. - tail = buffer->tail; - if (i != tail) { - buffer->buffer[buffer->head] = c; - buffer->head = i; - } - asm volatile ( - "pop r31 \n\t" - "pop r30 \n\t" - "pop %1 \n\t" - "pop %0 \n\t" - :"=r" (i), "=r" (tail):: - ); -} - -#if !defined(USART0_RX_vect) && defined(USART1_RX_vect) -// do nothing - on the 32u4 the first USART is USART1 -#else -#if !defined(USART_RX_vect) && !defined(SIG_USART0_RECV) && \ - !defined(SIG_UART0_RECV) && !defined(USART0_RX_vect) && \ - !defined(SIG_UART_RECV) - #error "Don't know what the Data Received vector is called for the first UART" -#else - void serialEvent() __attribute__((weak)); - void serialEvent() {} - #define serialEvent_implemented -#if defined(USART_RX_vect) - ISR(USART_RX_vect,ISR_NAKED) -#elif defined(SIG_USART0_RECV) - ISR(SIG_USART0_RECV,ISR_NAKED) -#elif defined(SIG_UART0_RECV) - ISR(SIG_UART0_RECV,ISR_NAKED) -#elif defined(USART0_RX_vect) - ISR(USART0_RX_vect,ISR_NAKED) -#elif defined(SIG_UART_RECV) - ISR(SIG_UART_RECV,ISR_NAKED) -#endif - { - register unsigned char c asm("r18"); - asm volatile ( - "push %0 \n\t" - :: "a" (c): - ); - c = SREG; - asm volatile ( - "push %0 \n\t" - :: "a" (c): - ); - #if defined(UDR0) - c = UDR0; - #elif defined(UDR) - c = UDR; - #else - #error UDR not defined - #endif - store_char(c, &rx_buffer); - asm volatile ( - "pop %0 \n\t" - : "=a" (c):: - ); - SREG = c; - asm volatile ( - "pop %0 \n\t" - "reti \n\t" - : "=a" (c):: - ); - } -#endif -#endif - -#if defined(USART1_RX_vect) - void serialEvent1() __attribute__((weak)); - void serialEvent1() {} - #define serialEvent1_implemented - ISR(USART1_RX_vect,ISR_NAKED) - { - register unsigned char c asm("r18"); - asm volatile ( - "push %0 \n\t" - :: "a" (c): - ); - c = SREG; - asm volatile ( - "push %0 \n\t" - :: "a" (c): - ); - c = UDR1; - store_char(c, &rx_buffer1); - asm volatile ( - "pop %0 \n\t" - : "=a" (c):: - ); - SREG = c; - asm volatile ( - "pop %0 \n\t" - "reti \n\t" - : "=a" (c):: - ); - } -#elif defined(SIG_USART1_RECV) - #error SIG_USART1_RECV -#endif - -#if defined(USART2_RX_vect) && defined(UDR2) - void serialEvent2() __attribute__((weak)); - void serialEvent2() {} - #define serialEvent2_implemented - ISR(USART2_RX_vect,ISR_NAKED) - { - register unsigned char c asm("r18"); - asm volatile ( - "push %0 \n\t" - :: "a" (c): - ); - c = SREG; - asm volatile ( - "push %0 \n\t" - :: "a" (c): - ); - c = UDR2; - store_char(c, &rx_buffer2); - asm volatile ( - "pop %0 \n\t" - : "=a" (c):: - ); - SREG = c; - asm volatile ( - "pop %0 \n\t" - "reti \n\t" - : "=a" (c):: - ); - } -#elif defined(SIG_USART2_RECV) - #error SIG_USART2_RECV -#endif - -#if defined(USART3_RX_vect) && defined(UDR3) - void serialEvent3() __attribute__((weak)); - void serialEvent3() {} - #define serialEvent3_implemented - ISR(USART3_RX_vect,ISR_NAKED) - { - register unsigned char c asm("r18"); - asm volatile ( - "push %0 \n\t" - :: "a" (c): - ); - c = SREG; - asm volatile ( - "push %0 \n\t" - :: "a" (c): - ); - c = UDR3; - store_char(c, &rx_buffer3); - asm volatile ( - "pop %0 \n\t" - : "=a" (c):: - ); - SREG = c; - asm volatile ( - "pop %0 \n\t" - "reti \n\t" - : "=a" (c):: - ); - } -#elif defined(SIG_USART3_RECV) - #error SIG_USART3_RECV -#endif - -void serialEventRun(void) -{ -#ifdef serialEvent_implemented - if (Serial.available()) serialEvent(); -#endif -#ifdef serialEvent1_implemented - if (Serial1.available()) serialEvent1(); -#endif -#ifdef serialEvent2_implemented - if (Serial2.available()) serialEvent2(); -#endif -#ifdef serialEvent3_implemented - if (Serial3.available()) serialEvent3(); -#endif -} - - -#if !defined(USART0_UDRE_vect) && defined(USART1_UDRE_vect) -// do nothing - on the 32u4 the first USART is USART1 -#else -#if !defined(UART0_UDRE_vect) && !defined(UART_UDRE_vect) && !defined(USART0_UDRE_vect) && !defined(USART_UDRE_vect) - #error "Don't know what the Data Register Empty vector is called for the first UART" -#else -#if defined(UART0_UDRE_vect) -ISR(UART0_UDRE_vect, ISR_NAKED) -#elif defined(UART_UDRE_vect) -ISR(UART_UDRE_vect, ISR_NAKED) -#elif defined(USART0_UDRE_vect) -ISR(USART0_UDRE_vect, ISR_NAKED) -#elif defined(USART_UDRE_vect) -ISR(USART_UDRE_vect, ISR_NAKED) -#endif -{ - register unsigned char tail asm("r25"); - register unsigned char head asm("r24"); - register unsigned char ch asm("r18"); - asm volatile ( - "push %0 \n\t" - :: "r" (tail): - ); - tail = SREG; - asm volatile ( - "push %0 \n\t" - "push %1 \n\t" - "push %2 \n\t" - "push r30 \n\t" - "push r31 \n\t" - :: "r" (tail), "r" (head), "r" (ch): - ); - tail = tx_buffer.tail; - head = tx_buffer.head; - if (head == tail) { - // Buffer empty, so disable interrupts -#if defined(UCSR0B) - cbi(UCSR0B, UDRIE0); -#else - cbi(UCSRB, UDRIE); -#endif - } - else { - // There is more data in the output buffer. Send the next byte - ch = tx_buffer.buffer[tail]; - tx_buffer.tail = modulo(++tail); - //tx_buffer.tail = (tx_buffer.tail + 1) % SERIAL_BUFFER_SIZE; - - #if defined(UDR0) - UDR0 = ch; - #elif defined(UDR) - UDR = ch; - #else - #error UDR not defined - #endif - } - asm volatile ( - "pop r31 \n\t" - "pop r30 \n\t" - "pop %2 \n\t" - "pop %1 \n\t" - "pop %0 \n\t" - :"=r" (tail), "=r" (head), "=r" (ch):: - ); - SREG = tail; - asm volatile ( - "pop %0 \n\t" - "reti \n\t" - :"=r" (tail):: - ); -} -#endif -#endif - -#ifdef USART1_UDRE_vect -ISR(USART1_UDRE_vect, ISR_NAKED) -{ - register unsigned char tail asm("r25"); - register unsigned char head asm("r24"); - register unsigned char ch asm("r18"); - asm volatile ( - "push %0 \n\t" - :: "r" (tail): - ); - tail = SREG; - asm volatile ( - "push %0 \n\t" - "push %1 \n\t" - "push %2 \n\t" - "push r30 \n\t" - "push r31 \n\t" - :: "r" (tail), "r" (head), "r" (ch): - ); - tail = tx_buffer1.tail; - head = tx_buffer1.head; - if (head == tail) { - // Buffer empty, so disable interrupts - cbi(UCSR1B, UDRIE1); - } - else { - // There is more data in the output buffer. Send the next byte - head = tx_buffer1.buffer[tail]; - tx_buffer1.tail = modulo(++tail); - //tx_buffer1.tail = (tx_buffer1.tail + 1) % SERIAL_BUFFER_SIZE; - - UDR1 = head; - } - asm volatile ( - "pop r31 \n\t" - "pop r30 \n\t" - "pop %2 \n\t" - "pop %1 \n\t" - "pop %0 \n\t" - :"=r" (tail), "=r" (head), "=r" (ch):: - ); - SREG = tail; - asm volatile ( - "pop %0 \n\t" - "reti \n\t" - :"=r" (tail):: - ); -} -#endif - -#ifdef USART2_UDRE_vect -ISR(USART2_UDRE_vect, ISR_NAKED) -{ - register unsigned char tail asm("r25"); - register unsigned char head asm("r24"); - register unsigned char ch asm("r18"); - asm volatile ( - "push %0 \n\t" - :: "r" (tail): - ); - tail = SREG; - asm volatile ( - "push %0 \n\t" - "push %1 \n\t" - "push %2 \n\t" - "push r30 \n\t" - "push r31 \n\t" - :: "r" (tail), "r" (head), "r" (ch): - ); - tail = tx_buffer2.tail; - head = tx_buffer2.head; - if (head == tail) { - // Buffer empty, so disable interrupts - cbi(UCSR2B, UDRIE2); - } - else { - // There is more data in the output buffer. Send the next byte - head = tx_buffer2.buffer[tail]; - tx_buffer2.tail = modulo(++tail); - //tx_buffer2.tail = (tx_buffer2.tail + 1) % SERIAL_BUFFER_SIZE; - - UDR2 = head; - } - asm volatile ( - "pop r31 \n\t" - "pop r30 \n\t" - "pop %2 \n\t" - "pop %1 \n\t" - "pop %0 \n\t" - :"=r" (tail), "=r" (head), "=r" (ch):: - ); - SREG = tail; - asm volatile ( - "pop %0 \n\t" - "reti \n\t" - :"=r" (tail):: - ); -} -#endif - -#ifdef USART3_UDRE_vect -ISR(USART3_UDRE_vect, ISR_NAKED) -{ - register unsigned char tail asm("r25"); - register unsigned char head asm("r24"); - register unsigned char ch asm("r18"); - asm volatile ( - "push %0 \n\t" - :: "r" (tail): - ); - tail = SREG; - asm volatile ( - "push %0 \n\t" - "push %1 \n\t" - "push %2 \n\t" - "push r30 \n\t" - "push r31 \n\t" - :: "r" (tail), "r" (head), "r" (ch): - ); - tail = tx_buffer3.tail; - head = tx_buffer3.head; - if (head == tail) { - // Buffer empty, so disable interrupts - cbi(UCSR3B, UDRIE3); - } - else { - // There is more data in the output buffer. Send the next byte - head = tx_buffer3.buffer[tail]; - tx_buffer3.tail = modulo(++tail); - //tx_buffer3.tail = (tx_buffer3.tail + 1) % SERIAL_BUFFER_SIZE; - - UDR3 = head; - } - asm volatile ( - "pop r31 \n\t" - "pop r30 \n\t" - "pop %2 \n\t" - "pop %1 \n\t" - "pop %0 \n\t" - :"=r" (tail), "=r" (head), "=r" (ch):: - ); - SREG = tail; - asm volatile ( - "pop %0 \n\t" - "reti \n\t" - :"=r" (tail):: - ); -} -#endif - - -// Constructors //////////////////////////////////////////////////////////////// - -HardwareSerial::HardwareSerial(ring_buffer *rx_buffer, ring_buffer *tx_buffer, - volatile uint8_t *ubrrh, volatile uint8_t *ubrrl, - volatile uint8_t *ucsra, volatile uint8_t *ucsrb, - volatile uint8_t *udr, - uint8_t rxen, uint8_t txen, uint8_t rxcie, uint8_t udrie, uint8_t u2x) -{ - _rx_buffer = rx_buffer; - _tx_buffer = tx_buffer; - _ubrrh = ubrrh; - _ubrrl = ubrrl; - _ucsra = ucsra; - _ucsrb = ucsrb; - _udr = udr; - _rxen = rxen; - _txen = txen; - _rxcie = rxcie; - _udrie = udrie; - _u2x = u2x; -} - -// Public Methods ////////////////////////////////////////////////////////////// - -void HardwareSerial::begin(unsigned long baud) -{ - uint16_t baud_setting; - bool use_u2x = true; - -#if (F_CPU == 16000000UL) || (F_CPU == 24000000UL) - // hardcoded exception for compatibility with the bootloader shipped - // with the Duemilanove and previous boards and the firmware on the 8U2 - // on the Uno and Mega 2560. - if (baud == 57600) { - use_u2x = false; - } -#endif - -try_again: - - if (use_u2x) { - *_ucsra = 1 << _u2x; - baud_setting = (F_CPU / 4 / baud - 1) / 2; - } else { - *_ucsra = 0; - baud_setting = (F_CPU / 8 / baud - 1) / 2; - } - - if ((baud_setting > 4095) && use_u2x) - { - use_u2x = false; - goto try_again; - } - - // assign the baud_setting, a.k.a. ubbr (USART Baud Rate Register) - *_ubrrh = baud_setting >> 8; - *_ubrrl = baud_setting; - - sbi(*_ucsrb, _rxen); - sbi(*_ucsrb, _txen); - sbi(*_ucsrb, _rxcie); - cbi(*_ucsrb, _udrie); -} - -void HardwareSerial::end() -{ - // wait for transmission of outgoing data - while (_tx_buffer->head != _tx_buffer->tail) - ; - - cbi(*_ucsrb, _rxen); - cbi(*_ucsrb, _txen); - cbi(*_ucsrb, _rxcie); - cbi(*_ucsrb, _udrie); - - // clear any received data - _rx_buffer->head = _rx_buffer->tail; -} - -int HardwareSerial::available(void) -{ - unsigned int difference = SERIAL_BUFFER_SIZE + _rx_buffer->head - _rx_buffer->tail; - return modulo(difference); - //return (unsigned int)(SERIAL_BUFFER_SIZE + _rx_buffer->head - _rx_buffer->tail) % SERIAL_BUFFER_SIZE; -} - -int HardwareSerial::peek(void) -{ - if (_rx_buffer->head == _rx_buffer->tail) { - return -1; - } else { - return _rx_buffer->buffer[_rx_buffer->tail]; - } -} - -int HardwareSerial::read(void) -{ - // if the head isn't ahead of the tail, we don't have any characters - if (_rx_buffer->head == _rx_buffer->tail) { - return -1; - } else { - unsigned char c = _rx_buffer->buffer[_rx_buffer->tail]; - _rx_buffer->tail = modulo(++_rx_buffer->tail);//(unsigned int)(_rx_buffer->tail + 1) % SERIAL_BUFFER_SIZE; - return c; - } -} - -void HardwareSerial::flush() -{ - while (_tx_buffer->head != _tx_buffer->tail) - ; -} - -size_t HardwareSerial::write(uint8_t c) -{ - unsigned char i = modulo((unsigned char)(_tx_buffer->head+1));//(unsigned char)((_tx_buffer->head + 1) % SERIAL_BUFFER_SIZE); - - // If the output buffer is full, there's nothing for it other than to - // wait for the interrupt handler to empty it a bit - // ???: return 0 here instead? - while (i == _tx_buffer->tail) - ; - - _tx_buffer->buffer[_tx_buffer->head] = c; - _tx_buffer->head = i; - - sbi(*_ucsrb, _udrie); - - return 1; -} - -HardwareSerial::operator bool() { - return true; -} - -// Preinstantiate Objects ////////////////////////////////////////////////////// - -#if defined(UBRRH) && defined(UBRRL) - HardwareSerial Serial(&rx_buffer, &tx_buffer, &UBRRH, &UBRRL, &UCSRA, &UCSRB, &UDR, RXEN, TXEN, RXCIE, UDRIE, U2X); -#elif defined(UBRR0H) && defined(UBRR0L) - HardwareSerial Serial(&rx_buffer, &tx_buffer, &UBRR0H, &UBRR0L, &UCSR0A, &UCSR0B, &UDR0, RXEN0, TXEN0, RXCIE0, UDRIE0, U2X0); -#elif defined(USBCON) - // do nothing - Serial object and buffers are initialized in CDC code -#else - #error no serial port defined (port 0) -#endif - -#if defined(UBRR1H) - HardwareSerial Serial1(&rx_buffer1, &tx_buffer1, &UBRR1H, &UBRR1L, &UCSR1A, &UCSR1B, &UDR1, RXEN1, TXEN1, RXCIE1, UDRIE1, U2X1); -#endif -#if defined(UBRR2H) - HardwareSerial Serial2(&rx_buffer2, &tx_buffer2, &UBRR2H, &UBRR2L, &UCSR2A, &UCSR2B, &UDR2, RXEN2, TXEN2, RXCIE2, UDRIE2, U2X2); -#endif -#if defined(UBRR3H) - HardwareSerial Serial3(&rx_buffer3, &tx_buffer3, &UBRR3H, &UBRR3L, &UCSR3A, &UCSR3B, &UDR3, RXEN3, TXEN3, RXCIE3, UDRIE3, U2X3); -#endif - -#endif // whole file - diff --git a/AstroEQ-Firmware/Open me first/HardwareSerial.h b/AstroEQ-Firmware/Open me first/HardwareSerial.h deleted file mode 100644 index bf4924c6d4abf4b54f5197592f5dfcc9cfd721c6..0000000000000000000000000000000000000000 --- a/AstroEQ-Firmware/Open me first/HardwareSerial.h +++ /dev/null @@ -1,81 +0,0 @@ -/* - HardwareSerial.h - Hardware serial library for Wiring - Copyright (c) 2006 Nicholas Zambetti. All right reserved. - - 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - - Modified 28 September 2010 by Mark Sproul -*/ - -#ifndef HardwareSerial_h -#define HardwareSerial_h - -#include <inttypes.h> - -#include "Stream.h" - -struct ring_buffer; - -class HardwareSerial : public Stream -{ - private: - ring_buffer *_rx_buffer; - ring_buffer *_tx_buffer; - volatile uint8_t *_ubrrh; - volatile uint8_t *_ubrrl; - volatile uint8_t *_ucsra; - volatile uint8_t *_ucsrb; - volatile uint8_t *_udr; - uint8_t _rxen; - uint8_t _txen; - uint8_t _rxcie; - uint8_t _udrie; - uint8_t _u2x; - public: - HardwareSerial(ring_buffer *rx_buffer, ring_buffer *tx_buffer, - volatile uint8_t *ubrrh, volatile uint8_t *ubrrl, - volatile uint8_t *ucsra, volatile uint8_t *ucsrb, - volatile uint8_t *udr, - uint8_t rxen, uint8_t txen, uint8_t rxcie, uint8_t udrie, uint8_t u2x); - void begin(unsigned long); - void end(); - virtual int available(void); - virtual int peek(void); - virtual int read(void); - virtual void flush(void); - virtual size_t write(uint8_t); - using Print::write; // pull in write(str) and write(buf, size) from Print - operator bool(); -}; - -#if defined(UBRRH) || defined(UBRR0H) - extern HardwareSerial Serial; -#elif defined(USBCON) - #include "USBAPI.h" -// extern HardwareSerial Serial_; -#endif -#if defined(UBRR1H) - extern HardwareSerial Serial1; -#endif -#if defined(UBRR2H) - extern HardwareSerial Serial2; -#endif -#if defined(UBRR3H) - extern HardwareSerial Serial3; -#endif - -extern void serialEventRun(void) __attribute__((weak)); - -#endif diff --git a/AstroEQ-Firmware/Open me first/README.txt b/AstroEQ-Firmware/Open me first/README.txt deleted file mode 100644 index c91e87c6d318eb10edfc52432da4253e1aaf0941..0000000000000000000000000000000000000000 --- a/AstroEQ-Firmware/Open me first/README.txt +++ /dev/null @@ -1,18 +0,0 @@ -Replace the following two files: - -HardwareSerial.h -HardwareSerial.cpp - -In the directory: - -<arduino install>\hardware\arduino\cores\arduino\ - --------------------------------------- - -Replace the following file: - -iom162.h - -In the directory: - -<arduino install>\hardware\tools\avr\avr\include\avr\ \ No newline at end of file diff --git a/AstroEQ-Firmware/Open me first/iom162.h b/AstroEQ-Firmware/Open me first/iom162.h deleted file mode 100644 index 0a95150c8228c6f9871b0318dc68c8c624c22f96..0000000000000000000000000000000000000000 --- a/AstroEQ-Firmware/Open me first/iom162.h +++ /dev/null @@ -1,951 +0,0 @@ -/* Copyright (c) 2002, Nils Kristian Strom <nilsst@omegav.ntnu.no> - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the - distribution. - - * Neither the name of the copyright holders nor the names of - contributors may be used to endorse or promote products derived - from this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - POSSIBILITY OF SUCH DAMAGE. */ - -/* $Id: iom162.h,v 1.13.2.5 2008/10/17 23:27:47 arcanum Exp $ */ - -/* iom162.h - definitions for ATmega162 */ - -#ifndef _AVR_IOM162_H_ -#define _AVR_IOM162_H_ 1 - -/* This file should only be included from <avr/io.h>, never directly. */ - -#ifndef _AVR_IO_H_ -# error "Include <avr/io.h> instead of this file." -#endif - -#ifndef _AVR_IOXXX_H_ -# define _AVR_IOXXX_H_ "iom162.h" -#else -# error "Attempt to include more than one <avr/ioXXX.h> file." -#endif - -/* Memory mapped I/O registers */ - -/* Timer/Counter3 Control Register A */ -#define TCCR3A _SFR_MEM8(0x8B) - -/* Timer/Counter3 Control Register B */ -#define TCCR3B _SFR_MEM8(0x8A) - -/* Timer/Counter3 - Counter Register */ -#define TCNT3H _SFR_MEM8(0x89) -#define TCNT3L _SFR_MEM8(0x88) -#define TCNT3 _SFR_MEM16(0x88) - -/* Timer/Counter3 - Output Compare Register A */ -#define OCR3AH _SFR_MEM8(0x87) -#define OCR3AL _SFR_MEM8(0x86) -#define OCR3A _SFR_MEM16(0x86) - -/* Timer/Counter3 - Output Compare Register B */ -#define OCR3BH _SFR_MEM8(0x85) -#define OCR3BL _SFR_MEM8(0x84) -#define OCR3B _SFR_MEM16(0x84) - -/* Timer/Counter3 - Input Capture Register */ -#define ICR3H _SFR_MEM8(0x81) -#define ICR3L _SFR_MEM8(0x80) -#define ICR3 _SFR_MEM16(0x80) - -/* Extended Timer/Counter Interrupt Mask */ -#define ETIMSK _SFR_MEM8(0x7D) - -/* Extended Timer/Counter Interrupt Flag Register */ -#define ETIFR _SFR_MEM8(0x7C) - -/* Pin Change Mask Register 1 */ -#define PCMSK1 _SFR_MEM8(0x6C) - -/* Pin Change Mask Register 0 */ -#define PCMSK0 _SFR_MEM8(0x6B) - -/* Clock PRescale */ -#define CLKPR _SFR_MEM8(0x61) - - -/* Standard I/O registers */ - -/* 0x3F SREG */ -/* 0x3D..0x3E SP */ -#define UBRR1H _SFR_IO8(0x3C) /* USART 1 Baud Rate Register High Byte, Shared with UCSR1C */ -#define UCSR1C _SFR_IO8(0x3C) /* USART 1 Control and Status Register, Shared with UBRR1H */ -#define GICR _SFR_IO8(0x3B) /* General Interrupt Control Register */ -#define GIFR _SFR_IO8(0x3A) /* General Interrupt Flag Register */ -#define TIMSK _SFR_IO8(0x39) /* Timer Interrupt Mask */ -#define TIFR _SFR_IO8(0x38) /* Timer Interrupt Flag Register */ -#define SPMCR _SFR_IO8(0x37) /* Store Program Memory Control Register */ -#define EMCUCR _SFR_IO8(0x36) /* Extended MCU Control Register */ -#define MCUCR _SFR_IO8(0x35) /* MCU Control Register */ -#define MCUCSR _SFR_IO8(0x34) /* MCU Control and Status Register */ -#define TCCR0 _SFR_IO8(0x33) /* Timer/Counter 0 Control Register */ -#define TCNT0 _SFR_IO8(0x32) /* TImer/Counter 0 */ -#define OCR0 _SFR_IO8(0x31) /* Output Compare Register 0 */ -#define SFIOR _SFR_IO8(0x30) /* Special Function I/O Register */ -#define TCCR1A _SFR_IO8(0x2F) /* Timer/Counter 1 Control Register A */ -#define TCCR1B _SFR_IO8(0x2E) /* Timer/Counter 1 Control Register A */ -#define TCNT1H _SFR_IO8(0x2D) /* Timer/Counter 1 High Byte */ -#define TCNT1L _SFR_IO8(0x2C) /* Timer/Counter 1 Low Byte */ -#define TCNT1 _SFR_IO16(0x2C) /* Timer/Counter 1 */ -#define OCR1AH _SFR_IO8(0x2B) /* Timer/Counter 1 Output Compare Register A High Byte */ -#define OCR1AL _SFR_IO8(0x2A) /* Timer/Counter 1 Output Compare Register A Low Byte */ -#define OCR1A _SFR_IO16(0x2A) /* Timer/Counter 1 Output Compare Register A */ -#define OCR1BH _SFR_IO8(0x29) /* Timer/Counter 1 Output Compare Register B High Byte */ -#define OCR1BL _SFR_IO8(0x28) /* Timer/Counter 1 Output Compare Register B Low Byte */ -#define OCR1B _SFR_IO16(0x28) /* Timer/Counter 1 Output Compare Register B */ -#define TCCR2 _SFR_IO8(0x27) /* Timer/Counter 2 Control Register */ -#define ASSR _SFR_IO8(0x26) /* Asynchronous Status Register */ -#define ICR1H _SFR_IO8(0x25) /* Input Capture Register 1 High Byte */ -#define ICR1L _SFR_IO8(0x24) /* Input Capture Register 1 Low Byte */ -#define ICR1 _SFR_IO16(0x24) /* Input Capture Register 1 */ -#define TCNT2 _SFR_IO8(0x23) /* Timer/Counter 2 */ -#define OCR2 _SFR_IO8(0x22) /* Timer/Counter 2 Output Compare Register */ -#define WDTCR _SFR_IO8(0x21) /* Watchdow Timer Control Register */ -#define UBRR0H _SFR_IO8(0x20) /* USART 0 Baud-Rate Register High Byte, Shared with UCSR0C */ -#define UCSR0C _SFR_IO8(0x20) /* USART 0 Control and Status Register C, Shared with UBRR0H */ -#define EEARH _SFR_IO8(0x1F) /* EEPROM Address Register High Byte */ -#define EEARL _SFR_IO8(0x1E) /* EEPROM Address Register Low Byte */ -#define EEAR _SFR_IO16(0x1E) /* EEPROM Address Register */ -#define EEDR _SFR_IO8(0x1D) /* EEPROM Data Register */ -#define EECR _SFR_IO8(0x1C) /* EEPROM Control Register */ -#define PORTA _SFR_IO8(0x1B) /* Port A */ -#define DDRA _SFR_IO8(0x1A) /* Port A Data Direction Register */ -#define PINA _SFR_IO8(0x19) /* Port A Pin Register */ -#define PORTB _SFR_IO8(0x18) /* Port B */ -#define DDRB _SFR_IO8(0x17) /* Port B Data Direction Register */ -#define PINB _SFR_IO8(0x16) /* Port B Pin Register */ -#define PORTC _SFR_IO8(0x15) /* Port C */ -#define DDRC _SFR_IO8(0x14) /* Port C Data Direction Register */ -#define PINC _SFR_IO8(0x13) /* Port C Pin Register */ -#define PORTD _SFR_IO8(0x12) /* Port D */ -#define DDRD _SFR_IO8(0x11) /* Port D Data Direction Register */ -#define PIND _SFR_IO8(0x10) /* Port D Pin Register */ -#define SPDR _SFR_IO8(0x0F) /* SPI Data Register */ -#define SPSR _SFR_IO8(0x0E) /* SPI Status Register */ -#define SPCR _SFR_IO8(0x0D) /* SPI Control Register */ -#define UDR0 _SFR_IO8(0x0C) /* USART 0 Data Register */ -#define UCSR0A _SFR_IO8(0x0B) /* USART 0 Control and Status Register A */ -#define UCSR0B _SFR_IO8(0x0A) /* USART 0 Control and Status Register B */ -#define UBRR0L _SFR_IO8(0x09) /* USART 0 Baud-Rate Register Low Byte */ -#define ACSR _SFR_IO8(0x08) /* Analog Comparator Status Register */ -#define PORTE _SFR_IO8(0x07) /* Port E */ -#define DDRE _SFR_IO8(0x06) /* Port E Data Direction Register */ -#define PINE _SFR_IO8(0x05) /* Port E Pin Register */ -#define OSCCAL _SFR_IO8(0x04) /* Oscillator Calibration, Shared with OCDR */ -#define OCDR _SFR_IO8(0x04) /* On-Chip Debug Register, Shared with OSCCAL */ -#define UDR1 _SFR_IO8(0x03) /* USART 1 Data Register */ -#define UCSR1A _SFR_IO8(0x02) /* USART 1 Control and Status Register A */ -#define UCSR1B _SFR_IO8(0x01) /* USART 1 Control and Status Register B */ -#define UBRR1L _SFR_IO8(0x00) /* USART 0 Baud Rate Register High Byte */ - - -/* Interrupt vectors (byte addresses) */ - -/* External Interrupt Request 0 */ -#define INT0_vect _VECTOR(1) -#define SIG_INTERRUPT0 _VECTOR(1) - -/* External Interrupt Request 1 */ -#define INT1_vect _VECTOR(2) -#define SIG_INTERRUPT1 _VECTOR(2) - -/* External Interrupt Request 2 */ -#define INT2_vect _VECTOR(3) -#define SIG_INTERRUPT2 _VECTOR(3) - -/* Pin Change Interrupt Request 0 */ -#define PCINT0_vect _VECTOR(4) -#define SIG_PIN_CHANGE0 _VECTOR(4) - -/* Pin Change Interrupt Request 1 */ -#define PCINT1_vect _VECTOR(5) -#define SIG_PIN_CHANGE1 _VECTOR(5) - -/* Timer/Counter3 Capture Event */ -#define TIMER3_CAPT_vect _VECTOR(6) -#define SIG_INPUT_CAPTURE3 _VECTOR(6) - -/* Timer/Counter3 Compare Match A */ -#define TIMER3_COMPA_vect _VECTOR(7) -#define SIG_OUTPUT_COMPARE3A _VECTOR(7) - -/* Timer/Counter3 Compare Match B */ -#define TIMER3_COMPB_vect _VECTOR(8) -#define SIG_OUTPUT_COMPARE3B _VECTOR(8) - -/* Timer/Counter3 Overflow */ -#define TIMER3_OVF_vect _VECTOR(9) -#define SIG_OVERFLOW3 _VECTOR(9) - -/* Timer/Counter2 Compare Match */ -#define TIMER2_COMP_vect _VECTOR(10) -#define SIG_OUTPUT_COMPARE2 _VECTOR(10) - -/* Timer/Counter2 Overflow */ -#define TIMER2_OVF_vect _VECTOR(11) -#define SIG_OVERFLOW2 _VECTOR(11) - -/* Timer/Counter1 Capture Event */ -#define TIMER1_CAPT_vect _VECTOR(12) -#define SIG_INPUT_CAPTURE1 _VECTOR(12) - -/* Timer/Counter1 Compare Match A */ -#define TIMER1_COMPA_vect _VECTOR(13) -#define SIG_OUTPUT_COMPARE1A _VECTOR(13) - -/* Timer/Counter Compare Match B */ -#define TIMER1_COMPB_vect _VECTOR(14) -#define SIG_OUTPUT_COMPARE1B _VECTOR(14) - -/* Timer/Counter1 Overflow */ -#define TIMER1_OVF_vect _VECTOR(15) -#define SIG_OVERFLOW1 _VECTOR(15) - -/* Timer/Counter0 Compare Match */ -#define TIMER0_COMP_vect _VECTOR(16) -#define SIG_OUTPUT_COMPARE0 _VECTOR(16) - -/* Timer/Counter0 Overflow */ -#define TIMER0_OVF_vect _VECTOR(17) -#define SIG_OVERFLOW0 _VECTOR(17) - -/* SPI Serial Transfer Complete */ -#define SPI_STC_vect _VECTOR(18) -#define SIG_SPI _VECTOR(18) - -/* USART0, Rx Complete */ -#define USART0_RX_vect _VECTOR(19) -#define SIG_USART0_RECV _VECTOR(19) - -/* USART1, Rx Complete */ -#define USART1_RX_vect _VECTOR(20) -#define SIG_USART1_RECV _VECTOR(20) - -/* USART0 Data register Empty */ -#define USART0_UDRE_vect _VECTOR(21) -#define SIG_USART0_DATA _VECTOR(21) - -/* USART1, Data register Empty */ -#define USART1_UDRE_vect _VECTOR(22) -#define SIG_USART1_DATA _VECTOR(22) - -/* USART0, Tx Complete */ -#define USART0_TX_vect _VECTOR(23) -#define SIG_USART0_TRANS _VECTOR(23) - -/* USART1, Tx Complete */ -#define USART1_TX_vect _VECTOR(24) -#define SIG_USART1_TRANS _VECTOR(24) - -/* EEPROM Ready */ -#define EE_RDY_vect _VECTOR(25) -#define SIG_EEPROM_READY _VECTOR(25) - -/* Analog Comparator */ -#define ANA_COMP_vect _VECTOR(26) -#define SIG_COMPARATOR _VECTOR(26) - -/* Store Program Memory Read */ -#define SPM_RDY_vect _VECTOR(27) -#define SIG_SPM_READY _VECTOR(27) - -#define _VECTORS_SIZE 112 /* = (num vec+1) * 4 */ - - - - - -/* TCCR3B bit definitions, memory mapped I/O */ - -#define ICNC3 7 -#define ICES3 6 -#define WGM33 4 -#define WGM32 3 -#define CS32 2 -#define CS31 1 -#define CS30 0 - - - -/* TCCR3A bit definitions, memory mapped I/O */ - -#define COM3A1 7 -#define COM3A0 6 -#define COM3B1 5 -#define COM3B0 4 -#define FOC3A 3 -#define FOC3B 2 -#define WGM31 1 -#define WGM30 0 - - - -/* ETIMSK bit definitions, memory mapped I/O */ - -#define TICIE3 5 -#define OCIE3A 4 -#define OCIE3B 3 -#define TOIE3 2 - - - -/* ETIFR bit definitions, memory mapped I/O */ - -#define ICF3 5 -#define OCF3A 4 -#define OCF3B 3 -#define TOV3 2 - - - -/* PCMSK1 bit definitions, memory mapped I/O */ -#define PCINT15 7 -#define PCINT14 6 -#define PCINT13 5 -#define PCINT12 4 -#define PCINT11 3 -#define PCINT10 2 -#define PCINT9 1 -#define PCINT8 0 - - - -/* PCMSK0 bit definitions, memory mapped I/O */ - -#define PCINT7 7 -#define PCINT6 6 -#define PCINT5 5 -#define PCINT4 4 -#define PCINT3 3 -#define PCINT2 2 -#define PCINT1 1 -#define PCINT0 0 - - - -/* CLKPR bit definitions, memory mapped I/O */ - -#define CLKPCE 7 -#define CLKPS3 3 -#define CLKPS2 2 -#define CLKPS1 1 -#define CLKPS0 0 - - - -/* SPH bit definitions */ - -#define SP15 15 -#define SP14 14 -#define SP13 13 -#define SP12 12 -#define SP11 11 -#define SP10 10 -#define SP9 9 -#define SP8 8 - - - -/* SPL bit definitions */ - -#define SP7 7 -#define SP6 6 -#define SP5 5 -#define SP4 4 -#define SP3 3 -#define SP2 2 -#define SP1 1 -#define SP0 0 - - - -/* UBRR1H bit definitions */ - -#define URSEL1 7 -#define UBRR111 3 -#define UBRR110 2 -#define UBRR19 1 -#define UBRR18 0 - - - -/* UCSR1C bit definitions */ - -#define URSEL1 7 -#define UMSEL1 6 -#define UPM11 5 -#define UPM10 4 -#define USBS1 3 -#define UCSZ11 2 -#define UCSZ10 1 -#define UCPOL1 0 - - - -/* GICR bit definitions */ - -#define INT1 7 -#define INT0 6 -#define INT2 5 -#define PCIE1 4 -#define PCIE0 3 -#define IVSEL 1 -#define IVCE 0 - - - -/* GIFR bit definitions */ - -#define INTF1 7 -#define INTF0 6 -#define INTF2 5 -#define PCIF1 4 -#define PCIF0 3 - - - -/* TIMSK bit definitions */ - -#define TOIE1 7 -#define OCIE1A 6 -#define OCIE1B 5 -#define OCIE2 4 -#define TICIE1 3 -#define TOIE2 2 -#define TOIE0 1 -#define OCIE0 0 - - - -/* TIFR bit definitions */ - -#define TOV1 7 -#define OCF1A 6 -#define OCF1B 5 -#define OCF2 4 -#define ICF1 3 -#define TOV2 2 -#define TOV0 1 -#define OCF0 0 - - - -/* SPMCR bit definitions */ - -#define SPMIE 7 -#define RWWSB 6 -#define RWWSRE 4 -#define BLBSET 3 -#define PGWRT 2 -#define PGERS 1 -#define SPMEN 0 - - - -/* EMCUCR bit definitions */ - -#define SM0 7 -#define SRL2 6 -#define SRL1 5 -#define SRL0 4 -#define SRW01 3 -#define SRW00 2 -#define SRW11 1 -#define ISC2 0 - - - -/* MCUCR bit definitions */ - -#define SRE 7 -#define SRW10 6 -#define SE 5 -#define SM1 4 -#define ISC11 3 -#define ISC10 2 -#define ISC01 1 -#define ISC00 0 - - - -/* MCUCSR bit definitions */ - -#define JTD 7 -#define SM2 5 -#define JTRF 4 -#define WDRF 3 -#define BORF 2 -#define EXTRF 1 -#define PORF 0 - - - -/* TCCR0 bit definitions */ - -#define FOC0 7 -#define WGM00 6 -#define COM01 5 -#define COM00 4 -#define WGM01 3 -#define CS02 2 -#define CS01 1 -#define CS00 0 - - - -/* SFIOR bit definitions */ - -#define TSM 7 -#define XMBK 6 -#define XMM2 5 -#define XMM1 4 -#define XMM0 3 -#define PUD 2 -#define PSR2 1 -#define PSR310 0 - - - -/* TCCR1A bit definitions */ - -#define COM1A1 7 -#define COM1A0 6 -#define COM1B1 5 -#define COM1B0 4 -#define FOC1A 3 -#define FOC1B 2 -#define WGM11 1 -#define WGM10 0 - - - - -/* TCCR1B bit definitions */ - -#define ICNC1 7 /* Input Capture Noise Canceler */ -#define ICES1 6 /* Input Capture Edge Select */ -#define WGM13 4 /* Waveform Generation Mode 3 */ -#define WGM12 3 /* Waveform Generation Mode 2 */ -#define CS12 2 /* Clock Select 2 */ -#define CS11 1 /* Clock Select 1 */ -#define CS10 0 /* Clock Select 0 */ - - - -/* TCCR2 bit definitions */ - -#define FOC2 7 -#define WGM20 6 -#define COM21 5 -#define COM20 4 -#define WGM21 3 -#define CS22 2 -#define CS21 1 -#define CS20 0 - - - -/* ASSR bit definitions */ - -#define AS2 3 -#define TCON2UB 2 -#define OCR2UB 1 -#define TCR2UB 0 - - - -/* WDTCR bit definitions */ - -#define WDCE 4 -#define WDE 3 -#define WDP2 2 -#define WDP1 1 -#define WDP0 0 - - - -/* UBRR0H bif definitions */ - -#define URSEL0 7 -#define UBRR011 3 -#define UBRR010 2 -#define UBRR09 1 -#define UBRR08 0 - - - -/* UCSR0C bit definitions */ - -#define URSEL0 7 -#define UMSEL0 6 -#define UPM01 5 -#define UPM00 4 -#define USBS0 3 -#define UCSZ01 2 -#define UCSZ00 1 -#define UCPOL0 0 - - - -/* EEARH bit definitions */ - -#define EEAR8 0 - - - -/* EECR bit definitions */ - -#define EERIE 3 -#define EEMWE 2 -#define EEWE 1 -#define EERE 0 - - - -/* PORTA bit definitions */ - -#define PA7 7 -#define PA6 6 -#define PA5 5 -#define PA4 4 -#define PA3 3 -#define PA2 2 -#define PA1 1 -#define PA0 0 - - - -/* DDRA bit definitions */ - -#define DDA7 7 -#define DDA6 6 -#define DDA5 5 -#define DDA4 4 -#define DDA3 3 -#define DDA2 2 -#define DDA1 1 -#define DDA0 0 - - - -/* PINA bit definitions */ - -#define PINA7 7 -#define PINA6 6 -#define PINA5 5 -#define PINA4 4 -#define PINA3 3 -#define PINA2 2 -#define PINA1 1 -#define PINA0 0 - - -/* PORTB bit definitions */ - -#define PB7 7 -#define PB6 6 -#define PB5 5 -#define PB4 4 -#define PB3 3 -#define PB2 2 -#define PB1 1 -#define PB0 0 - - - -/* DDRB bit definitions */ - -#define DDB7 7 -#define DDB6 6 -#define DDB5 5 -#define DDB4 4 -#define DDB3 3 -#define DDB2 2 -#define DDB1 1 -#define DDB0 0 - - - -/* PINB bit definitions */ - -#define PINB7 7 -#define PINB6 6 -#define PINB5 5 -#define PINB4 4 -#define PINB3 3 -#define PINB2 2 -#define PINB1 1 -#define PINB0 0 - - - -/* PORTC bit definitions */ - -#define PC7 7 -#define PC6 6 -#define PC5 5 -#define PC4 4 -#define PC3 3 -#define PC2 2 -#define PC1 1 -#define PC0 0 - - - -/* DDRC bit definitions */ - -#define DDC7 7 -#define DDC6 6 -#define DDC5 5 -#define DDC4 4 -#define DDC3 3 -#define DDC2 2 -#define DDC1 1 -#define DDC0 0 - - - -/* PINC bit definitions */ - -#define PINC7 7 -#define PINC6 6 -#define PINC5 5 -#define PINC4 4 -#define PINC3 3 -#define PINC2 2 -#define PINC1 1 -#define PINC0 0 - - - -/* PORTD bit definitions */ - -#define PD7 7 -#define PD6 6 -#define PD5 5 -#define PD4 4 -#define PD3 3 -#define PD2 2 -#define PD1 1 -#define PD0 0 - - - -/* DDRD bit definitions */ - -#define DDD7 7 -#define DDD6 6 -#define DDD5 5 -#define DDD4 4 -#define DDD3 3 -#define DDD2 2 -#define DDD1 1 -#define DDD0 0 - - - -/* PIND bit definitions */ - -#define PIND7 7 -#define PIND6 6 -#define PIND5 5 -#define PIND4 4 -#define PIND3 3 -#define PIND2 2 -#define PIND1 1 -#define PIND0 0 - - - -/* SPSR bit definitions */ - -#define SPIF 7 -#define WCOL 6 -#define SPI2X 0 - - - -/* SPCR bit definitions */ - -#define SPIE 7 -#define SPE 6 -#define DORD 5 -#define MSTR 4 -#define CPOL 3 -#define CPHA 2 -#define SPR1 1 -#define SPR0 0 - - - -/* UCSR0A bit definitions */ - -#define RXC0 7 -#define TXC0 6 -#define UDRE0 5 -#define FE0 4 -#define DOR0 3 -#define UPE0 2 -#define U2X0 1 -#define MPCM0 0 - - - -/* UCSR0B bit definitions */ - -#define RXCIE0 7 -#define TXCIE0 6 -#define UDRIE0 5 -#define RXEN0 4 -#define TXEN0 3 -#define UCSZ02 2 -#define RXB80 1 -#define TXB80 0 - - - -/* ACSR bit definitions */ - -#define ACD 7 -#define ACBG 6 -#define ACO 5 -#define ACI 4 -#define ACIE 3 -#define ACIC 2 -#define ACIS1 1 -#define ACIS0 0 - - - -/* PORTE bit definitions */ - -#define PE2 2 -#define PE1 1 -#define PE0 0 - - - -/* DDRE bit definitions */ - -#define DDE2 2 -#define DDE1 1 -#define DDE0 0 - - - -/* PINE bit definitions */ - -#define PINE2 2 -#define PINE1 1 -#define PINE0 0 - - - -/* UCSR1A bit definitions */ - -#define RXC1 7 -#define TXC1 6 -#define UDRE1 5 -#define FE1 4 -#define DOR1 3 -#define UPE1 2 -#define U2X1 1 -#define MPCM1 0 - - - -/* UCSR1B bit definitions */ - -#define RXCIE1 7 -#define TXCIE1 6 -#define UDRIE1 5 -#define RXEN1 4 -#define TXEN1 3 -#define UCSZ12 2 -#define RXB81 1 -#define TXB81 0 - - -/* Constants */ -#define SPM_PAGESIZE 128 -#define RAMEND 0x4FF -#define XRAMEND 0xFFFF -#define E2END 0x1FF -#define E2PAGESIZE 4 -#define FLASHEND 0x3FFF - - -/* Fuses */ - -#define FUSE_MEMORY_SIZE 3 - -/* Low Fuse Byte */ -#define FUSE_CKSEL0 (unsigned char)~_BV(0) -#define FUSE_CKSEL1 (unsigned char)~_BV(1) -#define FUSE_CKSEL2 (unsigned char)~_BV(2) -#define FUSE_CKSEL3 (unsigned char)~_BV(3) -#define FUSE_SUT0 (unsigned char)~_BV(4) -#define FUSE_SUT1 (unsigned char)~_BV(5) -#define FUSE_CKOUT (unsigned char)~_BV(6) -#define FUSE_CKDIV8 (unsigned char)~_BV(7) -#define LFUSE_DEFAULT (FUSE_CKSEL0 & FUSE_CKSEL2 & FUSE_CKSEL3 & FUSE_SUT0 & FUSE_CKDIV8) - -/* High Fuse Byte */ -#define FUSE_BOOTRST (unsigned char)~_BV(0) -#define FUSE_BOOTSZ0 (unsigned char)~_BV(1) -#define FUSE_BOOTSZ1 (unsigned char)~_BV(2) -#define FUSE_EESAVE (unsigned char)~_BV(3) -#define FUSE_WDTON (unsigned char)~_BV(4) -#define FUSE_SPIEN (unsigned char)~_BV(5) -#define FUSE_JTAGEN (unsigned char)~_BV(6) -#define FUSE_OCDEN (unsigned char)~_BV(7) -#define HFUSE_DEFAULT (FUSE_BOOTSZ0 & FUSE_BOOTSZ1 & FUSE_SPIEN & FUSE_JTAGEN) - -/* Extended Fuse Byte */ -#define FUSE_BODLEVEL0 (unsigned char)~_BV(1) -#define FUSE_BODLEVEL1 (unsigned char)~_BV(2) -#define FUSE_BODLEVEL2 (unsigned char)~_BV(3) -#define FUSE_M161C (unsigned char)~_BV(4) -#define EFUSE_DEFAULT (0xFF) - - -/* Lock Bits */ -#define __LOCK_BITS_EXIST -#define __BOOT_LOCK_BITS_0_EXIST -#define __BOOT_LOCK_BITS_1_EXIST - - -/* Signature */ -#define SIGNATURE_0 0x1E -#define SIGNATURE_1 0x94 -#define SIGNATURE_2 0x04 - - -#endif /* _AVR_IOM162_H_ */ diff --git a/AstroEQ-Firmware/PinMappings.h b/AstroEQ-Firmware/PinMappings.h index 63cd85dae176d4b41cfb1500d830766f1f73cc27..c42005763c53ba568bd2c62fcd4ac9506045600e 100644 --- a/AstroEQ-Firmware/PinMappings.h +++ b/AstroEQ-Firmware/PinMappings.h @@ -1,9 +1,6 @@ #if defined(__AVR_ATmega162__) -//This is for HARDWARE versions prior to 4.0. This includes all versions using Arduino Mega board. -//#define LEGACY_MODE 1 - //----- User Configurable Pin Definitions for ATMega162 Variants ----- //Warning: D20 to D27 inclusive are NOT allowed #define statusPin_Define 13 @@ -25,19 +22,12 @@ #define ST4SubPin_0_Define 31 #define ST4SubPin_1_Define 32 -#ifdef LEGACY_MODE -#define modePins0_0_Define 16 -#define modePins2_0_Define 17 -#define modePins0_1_Define 19 -#define modePins2_1_Define 18 -#else #define modePins0_0_Define 6 #define modePins1_0_Define 17 #define modePins2_0_Define 16 #define modePins0_1_Define 10 #define modePins1_1_Define 18 #define modePins2_1_Define 19 -#endif #elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) @@ -46,8 +36,8 @@ //Warning: D30 to D37 inclusive are NOT allowed #define statusPin_Define 13 -#define resetPin_0_Define A1 -#define resetPin_1_Define A0 +#define resetPin_0_Define 55 +#define resetPin_1_Define 54 #define dirPin_0_Define 3 #define dirPin_1_Define 7 @@ -63,9 +53,11 @@ #define ST4SubPin_0_Define 53 #define ST4SubPin_1_Define 52 -#define modePins0_0_Define 16 +#define modePins0_0_Define 15 +#define modePins1_0_Define 16 #define modePins2_0_Define 17 -#define modePins0_1_Define 19 +#define modePins0_1_Define 20 +#define modePins1_1_Define 19 #define modePins2_1_Define 18 @@ -93,8 +85,11 @@ #if defined(__AVR_ATmega162__) +//Pick some registers we are not going use for GPIOR #define GPIOR0 TCNT2 #define GPIOR1 OCR2 +#define GPIOR2 SPCR + #ifndef TIMSK3 #define TIMSK3 ETIMSK #endif @@ -107,6 +102,9 @@ #ifndef ICIE1 #define ICIE1 TICIE1 #endif +#ifndef OCR0A +#define OCR0A OCR0 +#endif #define digitalPinToPortReg(P) \ ((((P) >= 14 && (P) <= 17) || ((P) >= 31 && (P) <= 34)) ? &PORTA : \ @@ -114,6 +112,12 @@ ((((P) >= 20 && (P) <= 27)) ? &PORTC : \ ((((P) <= 7)) ? &PORTD : &PORTE )))) +#define digitalPinToDirectionReg(P) \ +((((P) >= 14 && (P) <= 17) || ((P) >= 31 && (P) <= 34)) ? &DDRA : \ +((((P) >= 8 && (P) <= 13) || ((P) >= 18 && (P) <= 19)) ? &DDRB : \ +((((P) >= 20 && (P) <= 27)) ? &DDRC : \ +((((P) <= 7)) ? &DDRD : &DDRE )))) + #define digitalPinToPinReg(P) \ ((((P) >= 14 && (P) <= 17) || ((P) >= 31 && (P) <= 34)) ? &PINA : \ ((((P) >= 8 && (P) <= 13) || ((P) >= 18 && (P) <= 19)) ? &PINB : \ @@ -151,6 +155,18 @@ (((P) == 14 || (P) == 15) ? &PORTJ : \ (((P) >= 62 && (P) <= 69) ? &PORTK : &PORTL)))))))))) +#define digitalPinToDirectionReg(P) \ +(((P) >= 22 && (P) <= 29) ? &DDRA : \ +((((P) >= 10 && (P) <= 13) || ((P) >= 50 && (P) <= 53)) ? &DDRB : \ +(((P) >= 30 && (P) <= 37) ? &DDRC : \ +((((P) >= 18 && (P) <= 21) || (P) == 38) ? &DDRD : \ +((((P) >= 0 && (P) <= 3) || (P) == 5) ? &DDRE : \ +(((P) >= 54 && (P) <= 61) ? &DDRF : \ +((((P) >= 39 && (P) <= 41) || (P) == 4) ? &DDRG : \ +((((P) >= 6 && (P) <= 9) || (P) == 16 || (P) == 17) ? &DDRH : \ +(((P) == 14 || (P) == 15) ? &DDRJ : \ +(((P) >= 62 && (P) <= 69) ? &DDRK : &DDRL)))))))))) + #define digitalPinToPinReg(P) \ (((P) >= 22 && (P) <= 29) ? &PINA : \ ((((P) >= 10 && (P) <= 13) || ((P) >= 50 && (P) <= 53)) ? &PINB : \ diff --git a/AstroEQ-Firmware/SerialLink.cpp b/AstroEQ-Firmware/SerialLink.cpp new file mode 100644 index 0000000000000000000000000000000000000000..354c24d7f992d8e95165684ab9946983d80d9681 --- /dev/null +++ b/AstroEQ-Firmware/SerialLink.cpp @@ -0,0 +1,171 @@ + +#include "SerialLink.h" +#include <avr/io.h> +#include <avr/interrupt.h> + +#ifndef USART0_TX_vect +#defin USART0_TX_vect USART0_TXC_vect +#endif +#ifndef USART0_RX_vect +#defin USART0_RX_vect USART0_RXC_vect +#endif + +typedef struct { + unsigned char buffer[64]; + volatile unsigned char head; + volatile unsigned char tail; +} RingBuffer; + +RingBuffer txBuf = {{0},0,0}; +RingBuffer rxBuf = {{0},0,0}; + +void Serial_initialise(const unsigned long baud){ + Byter baud_setting; + + UCSR0A = _BV(U2X0); + baud_setting.integer = (F_CPU / 4 / baud - 1) / 2; + + if (baud_setting.high & 0xF0) + { + UCSR0A = 0; + baud_setting.integer = (F_CPU / 8 / baud - 1) / 2; + } + + // assign the baud_setting, a.k.a. ubbr (USART Baud Rate Register) + UBRR0H = baud_setting.high & 0x0F; + UBRR0L = baud_setting.low; + + sbi(UCSR0B, RXEN0); + sbi(UCSR0B, TXEN0); + sbi(UCSR0B, RXCIE0); + cbi(UCSR0B, UDRIE0); +} + +byte Serial_available(void){ + return ((rxBuf.head - rxBuf.tail) & 0x3F); //number of bytes available +} + +char Serial_read(void){ + byte tail = rxBuf.tail; + if (rxBuf.head == tail) { + return -1; + } else { + char c = rxBuf.buffer[tail]; + rxBuf.tail = ((tail + 1) & 0x3F); + return c; + } +} + +void Serial_write(char ch){ + unsigned char head = ((txBuf.head + 1) & 0x3F); + while (head == txBuf.tail); //wait for buffer to empty + txBuf.buffer[txBuf.head] = ch; + txBuf.head = head; + + sbi(UCSR0B, UDRIE0); +} + +void Serial_writeStr(char* str){ + while(*str){ + Serial_write(*str++); + } +} + +void Serial_writeArr(char* arr, byte len){ + while(len--){ + Serial_write(*arr++); + } +} + + +ISR(USART0_RX_vect,ISR_NAKED) +{ + register unsigned char c asm("r18"); + register unsigned char head asm("r25"); + register unsigned char tail asm("r24"); + asm volatile ( + "push %0 \n\t" + :: "a" (c): + ); + c = SREG; + asm volatile ( + "push %0 \n\t" + "push %1 \n\t" + "push %2 \n\t" + "push r30 \n\t" + "push r31 \n\t" + :: "a" (c), "r" (head), "r" (tail): + ); + + //Read in from the serial data register + c = UDR0; + //get the current head + head = rxBuf.head; + head++; + head &= 0x3F; + tail = rxBuf.tail; + + if (head != tail) { + rxBuf.buffer[rxBuf.head] = c; + rxBuf.head = head; + } + + asm volatile ( + "pop r31 \n\t" + "pop r30 \n\t" + "pop %2 \n\t" + "pop %1 \n\t" + "pop %0 \n\t" + : "=a" (c), "=r" (head), "=r" (tail):: + ); + SREG = c; + asm volatile ( + "pop %0 \n\t" + "reti \n\t" + : "=a" (c):: + ); +} + +ISR(USART0_UDRE_vect, ISR_NAKED) +{ + register unsigned char tail asm("r25"); + register unsigned char temp asm("r24"); + asm volatile ( + "push %0 \n\t" + :: "r" (temp): + ); + temp = SREG; + asm volatile ( + "push %0 \n\t" + "push %1 \n\t" + "push r30 \n\t" + "push r31 \n\t" + :: "r" (temp), "r" (tail): + ); + tail = txBuf.tail; + temp = txBuf.head; + if (temp == tail) { + // Buffer empty, so disable interrupts + cbi(UCSR0B, UDRIE0); + } else { + // There is more data in the output buffer. Send the next byte + temp = txBuf.buffer[tail]; + tail++; + tail &= 0x3F; + txBuf.tail = tail; + UDR0 = temp; + } + asm volatile ( + "pop r31 \n\t" + "pop r30 \n\t" + "pop %1 \n\t" + "pop %0 \n\t" + :"=r" (temp), "=r" (tail):: + ); + SREG = temp; + asm volatile ( + "pop %0 \n\t" + "reti \n\t" + :"=r" (temp):: + ); +} diff --git a/AstroEQ-Firmware/SerialLink.h b/AstroEQ-Firmware/SerialLink.h new file mode 100644 index 0000000000000000000000000000000000000000..1d46c30f4cfcee8158700a8310834fe2908153d2 --- /dev/null +++ b/AstroEQ-Firmware/SerialLink.h @@ -0,0 +1,14 @@ +#ifndef __SERIAL_LINK_H__ +#define __SERIAL_LINK_H__ + +#include "AstroEQ.h" + +void Serial_initialise(const unsigned long baud); +byte Serial_available(void); +char Serial_read(void); +void Serial_write(char ch); +void Serial_writeStr(char* str); +void Serial_writeArr(char* arr, byte len); + +#endif //__SERIAL_LINK_H__ + diff --git a/AstroEQ-Firmware/UnionHelpers.h b/AstroEQ-Firmware/UnionHelpers.h index 505c60d2ac36694b56070ff5b4b80f88324776c4..a43bde073981669d2fb3a43daefd0ef82ebf7eca 100644 --- a/AstroEQ-Firmware/UnionHelpers.h +++ b/AstroEQ-Firmware/UnionHelpers.h @@ -1,6 +1,9 @@ -#ifndef UnionHelpers_h -#define UnionHelpers_h +#ifndef __UNION_HELPERS_H__ +#define __UNION_HELPERS_H__ + +#include <inttypes.h> +typedef uint8_t byte; typedef union { uint16_t integer; @@ -70,4 +73,4 @@ typedef union{ }; } DoubleNibbler; -#endif +#endif //__UNION_HELPERS_H__ diff --git a/AstroEQ-Firmware/commands.cpp b/AstroEQ-Firmware/commands.cpp index 124aa0bf780ddd9e78e545925b9ade375ec31b05..bcc5444be7dda8a9a43b1184842df14534c3f1f1 100644 --- a/AstroEQ-Firmware/commands.cpp +++ b/AstroEQ-Firmware/commands.cpp @@ -16,66 +16,76 @@ // //---------------------------------------------------------------------------- -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif - #include "commands.h" -void Commands::init(unsigned long _eVal, byte _gVal){ - aVal[0] = EEPROM.readLong(aVal1_Address); //steps/axis - aVal[1] = EEPROM.readLong(aVal2_Address); //steps/axis - bVal[0] = EEPROM.readLong(bVal1_Address); //sidereal rate - bVal[1] = EEPROM.readLong(bVal2_Address); //sidereal rate - sVal[0] = EEPROM.readLong(sVal1_Address); //steps/worm rotation - sVal[1] = EEPROM.readLong(sVal2_Address); //steps/worm rotation - siderealIVal[0] = EEPROM.readInt(IVal1_Address); //steps/worm rotation - siderealIVal[1] = EEPROM.readInt(IVal2_Address); //steps/worm rotation + +Commands cmd = {{0},{0},{0},{0},{0},{0},{0},{0},{0},{0},{0},{0},{0},{0},{0},{0},{0},{0}}; + +void Commands_init(unsigned long _eVal, byte _gVal){ + cmd.aVal[0] = EEPROM_readLong(aVal1_Address); //steps/axis + cmd.aVal[1] = EEPROM_readLong(aVal2_Address); //steps/axis + cmd.bVal[0] = EEPROM_readLong(bVal1_Address); //sidereal rate + cmd.bVal[1] = EEPROM_readLong(bVal2_Address); //sidereal rate + cmd.sVal[0] = EEPROM_readLong(sVal1_Address); //steps/worm rotation + cmd.sVal[1] = EEPROM_readLong(sVal2_Address); //steps/worm rotation + cmd.siderealIVal[0] = EEPROM_readInt(IVal1_Address); //steps/worm rotation + cmd.siderealIVal[1] = EEPROM_readInt(IVal2_Address); //steps/worm rotation for(byte i = 0;i < 2;i++){ - dir[i] = 0; - stopped[i] = 1; - gotoEn[i] = 0; - FVal[i] = 0; - jVal[i] = 0x800000; //Current position, 0x800000 is the centre - IVal[i] = 0; //Recieved Speed - GVal[i] = 0; //Mode recieved from :G command - HVal[i] = 0; //Value recieved from :H command - eVal[i] = _eVal; //version number - gVal[i] = _gVal; //High speed scalar + cmd.dir[i] = 0; + cmd.stopped[i] = 1; + cmd.gotoEn[i] = 0; + cmd.FVal[i] = 0; + cmd.jVal[i] = 0x800000; //Current position, 0x800000 is the centre + cmd.IVal[i] = 0; //Recieved Speed + cmd.GVal[i] = 0; //Mode recieved from :G command + cmd.HVal[i] = 0; //Value recieved from :H command + cmd.eVal[i] = _eVal; //version number + cmd.gVal[i] = _gVal; //High speed scalar - stepRepeat[i] = 0;//siderealIVal[i]/75;//((aVal[i] < 5600000UL) ? ((aVal[i] < 2800000UL) ? 16 : 8) : 4); + cmd.stepRepeat[i] = 0;//siderealIVal[i]/75;//((aVal[i] < 5600000UL) ? ((aVal[i] < 2800000UL) ? 16 : 8) : 4); } } -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}, - {'A', 6, 0}, - {'B', 6, 0}, - {'S', 6, 0} }; +const char cmd_commands[numberOfCommands][3] = { {'j', 0, 6}, //arranged in order of most frequently used to reduce searching time. + {'f', 0, 3}, + {'I', 6, 0}, + {'G', 2, 0}, + {'J', 0, 0}, + {'K', 0, 0}, + {'H', 6, 0}, + {'M', 6, 0}, + {'e', 0, 6}, + {'a', 0, 6}, + {'b', 0, 6}, + {'g', 0, 2}, + {'s', 0, 6}, + {'E', 6, 0}, + {'P', 1, 0}, + {'F', 0, 0}, + {'L', 0, 0}, + //Programmer Commands + {'A', 6, 0}, + {'B', 6, 0}, + {'S', 6, 0}, + {'n', 0, 6}, + {'N', 6, 0}, + {'D', 2, 0}, + {'d', 0, 2}, + {'C', 1, 0}, + {'c', 0, 2}, + {'Z', 2, 0}, + {'z', 0, 2}, + {'O', 1, 0}, + {'T', 0, 0}, + {'R', 0, 0} + }; -char Commands::getLength(char cmd, boolean sendRecieve){ +char Commands_getLength(char cmd, bool sendRecieve){ for(byte i = 0;i < numberOfCommands;i++){ - if(command[i][0] == cmd){ + if(cmd_commands[i][0] == cmd){ if(sendRecieve){ - return command[i][1]; + return cmd_commands[i][1]; } else { - return command[i][2]; + return cmd_commands[i][2]; } } } diff --git a/AstroEQ-Firmware/commands.h b/AstroEQ-Firmware/commands.h index 4a39a5a05b2286e0b776fc0d32cc7a746aec431e..c79a013d9893b3424285bd7622c8c838f5e35336 100644 --- a/AstroEQ-Firmware/commands.h +++ b/AstroEQ-Firmware/commands.h @@ -12,78 +12,13 @@ //to returns it in a more useful format // //---------------------------------------------------------------------------- -#ifndef commands_h -#define commands_h +#ifndef __COMMANDS_H__ +#define __COMMANDS_H__ - #if ARDUINO >= 100 - #include "Arduino.h" - #else - #include "WProgram.h" - #endif - - #include "EEPROMReader.h" - #include "EEPROMAddresses.h" - - #define numberOfCommands 20 - - class Commands{ - public: - - void init(unsigned long _eVal, byte _gVal); - - //Command definitions - static const char command[numberOfCommands][3]; - - //Methods for accessing class variables - inline void setDir(byte target, byte _dir){ //Set Method - _dir &= 1; - dir[target] = _dir; //set direction - } - - inline void updateStepDir(byte target){ - byte _dir = dir[target]; - if(_dir){ - stepDir[target] = -1; //set step direction - } else { - stepDir[target] = 1; //set step direction - } - } - - inline unsigned int fVal(byte target){ //_fVal: 00ds000g000f; d = dir, s = stopped, g = goto, f = energised - return ((dir[target] << 9)|(stopped[target] << 8)|(gotoEn[target] << 4)|(FVal[target] << 0)); - } - - inline void setStopped(byte target, byte _stopped){ //Set Method - stopped[target] = _stopped & 1; - } - - inline void setGotoEn(byte target, byte _gotoEn){ //Set Method - gotoEn[target] = _gotoEn & 1; - } - - inline void setFVal(byte target, byte _FVal){ //Set Method - FVal[target] = _FVal & 1; - } - - inline void setjVal(byte target, unsigned long _jVal){ //Set Method - jVal[target] = _jVal; - } - - inline void setIVal(byte target, unsigned int _IVal){ //Set Method - IVal[target] = _IVal; - } - - inline void setHVal(byte target, unsigned long _HVal){ //Set Method - HVal[target] = _HVal; - } - - inline void setGVal(byte target, byte _GVal){ //Set Method - GVal[target] = _GVal; - } - - - char getLength(char cmd, boolean sendRecieve); + #include "AstroEQ.h" + #include "EEPROMReader.h" //Read config file + typedef struct{ //class variables unsigned long jVal[2]; //_jVal: Current position unsigned int IVal[2]; //_IVal: speed to move if in slew mode @@ -104,5 +39,77 @@ unsigned int siderealIVal[2]; //_IVal: at sidereal rate unsigned int currentIVal[2]; //_IVal: this will be upldated to match the requested IVal once the motors are stopped. - }; -#endif + } Commands; + + #define numberOfCommands 31 + + void Commands_init(unsigned long _eVal, byte _gVal); + char Commands_getLength(char cmd, bool sendRecieve); + + //Command definitions + extern const char command[numberOfCommands][3]; + extern Commands cmd; + + //Methods for accessing command variables + inline void cmd_setDir(byte target, byte _dir){ //Set Method + _dir &= 1; + cmd.dir[target] = _dir; //set direction + } + + inline void cmd_updateStepDir(byte target, byte stepSize){ + byte _dir = cmd.dir[target]; + if(_dir){ + cmd.stepDir[target] = -stepSize; //set step direction + } else { + cmd.stepDir[target] = stepSize; //set step direction + } + } + + inline unsigned int cmd_fVal(byte target){ //_fVal: 00ds000g000f; d = dir, s = stopped, g = goto, f = energised + return ((cmd.dir[target] << 9)|(cmd.stopped[target] << 8)|(cmd.gotoEn[target] << 4)|(cmd.FVal[target] << 0)); + } + + inline void cmd_setsideIVal(byte target, unsigned int _sideIVal){ //set Method + cmd.siderealIVal[target] = _sideIVal; + } + + inline void cmd_setStopped(byte target, byte _stopped){ //Set Method + cmd.stopped[target] = _stopped & 1; + } + + inline void cmd_setGotoEn(byte target, byte _gotoEn){ //Set Method + cmd.gotoEn[target] = _gotoEn & 1; + } + + inline void cmd_setFVal(byte target, byte _FVal){ //Set Method + cmd.FVal[target] = _FVal & 1; + } + + inline void cmd_setjVal(byte target, unsigned long _jVal){ //Set Method + cmd.jVal[target] = _jVal; + } + + inline void cmd_setIVal(byte target, unsigned int _IVal){ //Set Method + cmd.IVal[target] = _IVal; + } + + inline void cmd_setaVal(byte target, unsigned long _aVal){ //Set Method + cmd.aVal[target] = _aVal; + } + + inline void cmd_setbVal(byte target, unsigned long _bVal){ //Set Method + cmd.bVal[target] = _bVal; + } + + inline void cmd_setsVal(byte target, unsigned long _sVal){ //Set Method + cmd.sVal[target] = _sVal; + } + + inline void cmd_setHVal(byte target, unsigned long _HVal){ //Set Method + cmd.HVal[target] = _HVal; + } + + inline void cmd_setGVal(byte target, byte _GVal){ //Set Method + cmd.GVal[target] = _GVal; + } +#endif //__COMMANDS_H__ diff --git a/AstroEQ-Firmware/synta.cpp b/AstroEQ-Firmware/synta.cpp index e36e9923428480616663f5749df879734da76eda..bb2239c268c73d32be71458b95b971797a4c287d 100644 --- a/AstroEQ-Firmware/synta.cpp +++ b/AstroEQ-Firmware/synta.cpp @@ -1,98 +1,51 @@ #include "synta.h" -#include "UnionHelpers.h" +#include <string.h> -void Synta::initialise(unsigned long eVal){ - validPacket = 0; - _axis = 0; - commandIndex = 0; - clearBuffer(commandString,sizeof(commandString)); - //scalar[0] = EEPROM.readByte(scalar1_Address) - 1; - //scalar[1] = EEPROM.readByte(scalar2_Address) - 1; - cmd.init(eVal, 1); -} -const char Synta::startInChar = ':'; -const char Synta::startOutChar = '='; -const char Synta::errorChar = '!'; -const char Synta::endChar = '\r'; +bool validateCommand(byte len); +bool validPacket; +char commandString[11]; +byte commandIndex; -void Synta::error(char* buf){ - buf[0] = errorChar; - buf[1] = endChar; - buf[2] = 0; -} +byte _axis; +char _command; -void Synta::clearBuffer(char* buf, byte len){ - strncpy(buf,"",len); +void synta_initialise(unsigned long eVal){ + validPacket = 0; + commandIndex = 0; + memset(commandString,0,sizeof(commandString)); + _axis = 0; + + byte gVal = 1; + if(EEPROM_readByte(Microstep_Address)>=8){ + gVal = 8; + } + Commands_init(eVal, gVal); } + +const char startInChar = ':'; +const char startOutChar = '='; +const char errorChar = '!'; +const char endChar = '\r'; -//void Synta::success(char* buf, char data[], byte dataLen){ -// strcpy(buf + 1,data); -// buf[0] = startOutChar; -// buf[dataLen] = endChar; -// buf[dataLen + 1] = 0; -//} - - - - -//const char hexLookup[] = {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'}; inline void nibbleToHex(char* hex/*, const byte offset*/, byte nibble) { -// char hexChar; -// asm volatile( -// "movw Y, %1 \n\t" -// "add r28, %2 \n\t" -// "adc r29, r1 \n\t" -// "ld %0, Y \n\t" -// : "=r" (hexChar) //goto selects r18:r21. This adds sts commands for all 4 bytes -// : "e" (hexLookup),"r" (nibble) //stepDir is in r19 to match second byte of goto. -// : "r28","r29" -// ); -// hex[offset] = hexChar; if (nibble > 9){ nibble += (('A'-'0')-0xA); } *hex = (nibble + '0'); - //char hexChar = hexLookup[nibble]; - //hex[offset] = hexChar; } + inline void private_byteToHex(char* lower, char* upper, Nibbler nibbler){ nibbleToHex(lower, nibbler.low); nibbleToHex(upper, nibbler.high); } -/* -inline void longToHex(char* hex, unsigned long data){ - Inter inter = Inter(data); - private_byteToHex(hex+5,hex+4,inter.highByter.lowNibbler); - private_byteToHex(hex+3,hex+2,inter.lowByter.highNibbler); - private_byteToHex(hex+1,hex+0,inter.lowByter.lowNibbler); - hex[6] = 0; -} - -inline void intToHex(char* hex, unsigned int data){ - DoubleNibbler nibble = {data}; - hex[3] = 0; - nibbleToHex(hex+2, nibble.low); - nibbleToHex(hex+1, nibble.mid); - nibbleToHex(hex+0, nibble.high); -} -inline void byteToHex(char* hex, byte data){ - Nibbler nibble = {data}; - hex[2] = 0; - private_byteToHex(hex+1,hex+0,nibble); -}*/ - - - - -void Synta::assembleResponse(char* dataPacket, char commandOrError, unsigned long responseData){ - char replyLength = cmd.getLength(commandOrError,0); //get the number of data bytes for response +void synta_assembleResponse(char* dataPacket, char commandOrError, unsigned long responseData){ + char replyLength = Commands_getLength(commandOrError,0); //get the number of data bytes for response - //char tempStr[11]; - if (replyLength == -1) { - replyLength++; + if (replyLength < 0) { + replyLength = 0; dataPacket[0] = errorChar; } else { dataPacket[0] = startOutChar; @@ -113,40 +66,19 @@ void Synta::assembleResponse(char* dataPacket, char commandOrError, unsigned lon } } - /* - dataPacket++; - switch (replyLength){ - case -1: - //error(dataPacket); //In otherwords, invalid command, so send error - //return; - break; - case 0: - //clearBuffer(dataPacket+1,sizeof(tempStr)); //empty temporary string - break; - case 2: - byteToHex(dataPacket,responseData); - break; - case 3: - intToHex(dataPacket,responseData); - break; - case 6: - longToHex(dataPacket,responseData); - break; - }*/ dataPacket[(byte)replyLength + 1] = endChar; dataPacket[(byte)replyLength + 2] = 0; - //success(dataPacket,tempStr,replyLength + 1); //compile response return; } -boolean Synta::validateCommand(byte len){ +bool synta_validateCommand(byte len, char* decoded){ _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 + char requiredLength = Commands_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; @@ -154,23 +86,26 @@ boolean Synta::validateCommand(byte len){ byte i; for(i = 0;i < len;i++){ - commandString[i] = commandString[i + 2]; + decoded[i] = commandString[i + 2]; } - commandString[i] = 0; //Null + decoded[i] = 0; //Null return 1; } -char Synta::recieveCommand(char* dataPacket, char character){ +char synta_recieveCommand(char* dataPacket, char character){ if(validPacket){ if (character == startInChar){ - goto error; //new command without old finishing! (dataPacket contains error message) + dataPacket[0] = errorChar; + dataPacket[1] = endChar; + dataPacket[2] = 0; + validPacket = 0; //new command without old finishing! (dataPacket contains error message) + return -2; } commandString[commandIndex++] = character; //Add character to current string build if(character == endChar){ - if(validateCommand(commandIndex)){ - strcpy(dataPacket,commandString); //Return decoded packet + if(synta_validateCommand(commandIndex, dataPacket)){ validPacket = 0; return 1; //Successful decode (dataPacket contains decoded packet) } else { @@ -183,11 +118,13 @@ char Synta::recieveCommand(char* dataPacket, char character){ //Begin new command commandIndex = 0; validPacket = 1; - clearBuffer(commandString,sizeof(commandString)); + commandString[0] = '\0'; } return 0; //Decode not finished (dataPacket unchanged) error: - error(dataPacket); + dataPacket[0] = errorChar; + dataPacket[1] = endChar; + dataPacket[2] = 0; validPacket = 0; return -1; } @@ -205,7 +142,11 @@ inline byte hexToByte(char* hex){ Nibbler high = {hexToNibbler(hex[0])<<4}; return ((high.high<<4)|low.low); } -unsigned long Synta::hexToLong(char* hex){ + +byte synta_hexToByte(char* hex){ + return hexToByte(hex); +} +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 @@ -218,11 +159,11 @@ unsigned long Synta::hexToLong(char* hex){ return inter.integer; //and convert it to an integer } -char Synta::command(){ +char synta_command(){ return _command; } -byte Synta::axis(byte axis){ +byte synta_axis(byte axis){ if(axis < 2){ _axis = axis; } diff --git a/AstroEQ-Firmware/synta.h b/AstroEQ-Firmware/synta.h index 993c0af5c0fb8f65db4fec6d9602cec7b98cdb57..4678e2d4d562af04bcccbe306ae025e30633fa4d 100644 --- a/AstroEQ-Firmware/synta.h +++ b/AstroEQ-Firmware/synta.h @@ -1,61 +1,27 @@ #ifndef synta_h #define synta_h - #if ARDUINO >= 100 - #include "Arduino.h" - #else - #include "WProgram.h" - #endif - + #include "AstroEQ.h" #include "commands.h" - class Synta{ - public: - - static Synta& getInstance(unsigned long version) - { - static Synta singleton = Synta(version); - return singleton; - } - - Commands cmd; - void assembleResponse(char* dataPacket, char commandOrError, unsigned long responseData); - char recieveCommand(char* dataPacket, char character); - byte axis(byte axis = 2); //make target readonly to outside world. - char command(); //make current command readonly to outside world. - - unsigned long hexToLong(char* hex); - //void longToHex(char* hex, unsigned long data); - //void intToHex(char* hex, unsigned int data); - //void byteToHex(char* hex, byte data); - - //byte scalar[2]; - - private: - Synta(unsigned long version) { - initialise(version); - }; - //Synta(Synta const&); - void operator=(Synta const&); - - void initialise(unsigned long eVal); - - - void clearBuffer(char* buf, byte len); -// void success(char* buf, char data[], byte dataLen); - void error(char* buf); - boolean validateCommand(byte len); - - boolean validPacket; - char commandString[11]; - byte commandIndex; - - byte _axis; - char _command; - - static const char startInChar; - static const char startOutChar; - static const char errorChar; - static const char endChar; - }; + void synta_initialise(unsigned long version); + void synta_assembleResponse(char* dataPacket, char commandOrError, unsigned long responseData); + char synta_recieveCommand(char* dataPacket, char character); + byte synta_axis(byte axis = 2); //make target readonly to outside world. + char synta_command(); //make current command readonly to outside world. + unsigned long synta_hexToLong(char* hex); + byte synta_hexToByte(char* hex); + + //Methods for accessing command variables + extern inline void cmd_setDir(byte target, byte _dir); + extern inline void cmd_updateStepDir(byte target, byte stepSize); + extern inline unsigned int cmd_fVal(byte target); + extern inline void cmd_setStopped(byte target, byte _stopped); + extern inline void cmd_setGotoEn(byte target, byte _gotoEn); + extern inline void cmd_setFVal(byte target, byte _FVal); + extern inline void cmd_setjVal(byte target, unsigned long _jVal); + extern inline void cmd_setIVal(byte target, unsigned int _IVal); + extern inline void cmd_setHVal(byte target, unsigned long _HVal); + extern inline void cmd_setGVal(byte target, byte _GVal); + #endif diff --git a/Downloads/AstroEQ-ConfigUtility-LINUX.zip b/Downloads/AstroEQ-ConfigUtility-LINUX.zip new file mode 100644 index 0000000000000000000000000000000000000000..4ec563189630670e7903636b07c467a08e9b5e2a Binary files /dev/null and b/Downloads/AstroEQ-ConfigUtility-LINUX.zip differ diff --git a/Downloads/AstroEQ6-ConfigUtility.zip b/Downloads/AstroEQ-ConfigUtility.zip similarity index 50% rename from Downloads/AstroEQ6-ConfigUtility.zip rename to Downloads/AstroEQ-ConfigUtility.zip index 9d3c9fe8e4847472334e864e99f78acdf4e56412..9d453cb563c9b40bf0b14613765b174fd609d20c 100644 Binary files a/Downloads/AstroEQ6-ConfigUtility.zip and b/Downloads/AstroEQ-ConfigUtility.zip differ diff --git a/Downloads/AstroEQ-Firmware.zip b/Downloads/AstroEQ-Firmware.zip new file mode 100644 index 0000000000000000000000000000000000000000..a25e96d14744af51e31d8fd60c400fb342a3a7c3 Binary files /dev/null and b/Downloads/AstroEQ-Firmware.zip differ diff --git a/Downloads/AstroEQ6-ConfigUtility-LINUX.zip b/Downloads/AstroEQ6-ConfigUtility-LINUX.zip deleted file mode 100644 index dc18983d66b13d6c2db6e201ba939cb9438936ad..0000000000000000000000000000000000000000 Binary files a/Downloads/AstroEQ6-ConfigUtility-LINUX.zip and /dev/null differ diff --git a/Downloads/AstroEQ6-Firmware.zip b/Downloads/AstroEQ6-Firmware.zip deleted file mode 100644 index c7bc703eb98864ecf1f3e72b16ddbc2789f79811..0000000000000000000000000000000000000000 Binary files a/Downloads/AstroEQ6-Firmware.zip and /dev/null differ diff --git a/README b/README index 92b177c7d952ee9fb84f0dc6fb954223741833b5..06e3fab4f58cc16496d0c1b86ae6283e0b897240 100644 --- a/README +++ b/README @@ -1,15 +1,13 @@ Last Updated: 16/02/2014 -Version 7 includes a change to the microstepping mode being used. AstroEQ now uses 1/4 and 1/32th stepping modes for the DRV8825 chip. If you have legacy hardware, please read the "Upgrading from 6.x to 7.x firmware" file. +Version 7 includes a change to the microstepping mode being used. AstroEQ now has a user selectable stepping modes allowing used of all modes supported by the DRV8825 and A4988 chips. If you have legacy hardware, please read the "Upgrading from 6.x to 7.x firmware" file. The Arduino Mega variant of the design has been adjusted as described in the upgrade file to bring it up to date and as such, it is no longer considered legacy hardware. A small number of AstroEQ controllers are available to purchase. These can be bought from me on my website (http://www.astroeq.co.uk). -AstroEQ6 has been rebuilt from the ground up to be the best AstroEQ firmware to date. +AstroEQ has been rebuilt from the ground up to be the best AstroEQ firmware to date. 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 almost entirely through hole components, and can be made for much cheaper. - -Please note that the new software still support boards built with the old hardware design (<4.0), so if you have already built one, you can still take advantage of the new software. +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. ------------------------------------------------------------------------------------- @@ -24,7 +22,7 @@ The EQMOD Project can be found at: http://eq-mod.sourceforge.net/ Works with EQ3, EQ5, HEQ5, and EQ6 mounts. Along With custom mounts. - Current Software Verison: 7.0 - Current Hardware Version: 4.3 + Current Software Verison: 7.2 + Current Hardware Version: 4.5 --------------------------------------------------------------------------------------- diff --git a/Upgrading from 6.x to 7.x firmware.txt b/Upgrading from 6.x to 7.x firmware.txt index f42d9139a306688a976186aac6e8df7a2978240f..fc53c25b4de15a27558de39e1ac9c0991a7cb1f7 100644 --- a/Upgrading from 6.x to 7.x firmware.txt +++ b/Upgrading from 6.x to 7.x firmware.txt @@ -1,29 +1,19 @@ -Upgrading to 7.x from 6.x: +Upgrading from 6.x from 7.1+: -If you have a non-legacy controller, i.e. one which does not have '(legacy)' written next to it in the configuration utility, then refer to section 'A'. -If you have a legacy controller, refer to section 'B' +There has been another important change in version 7.1 to the microstepping mode selection. It is now possible to select the exact mode you wish to use from a list. +This change has also lead to the unification of the Arduino Mega based versions, they are no longer considered legacy hardware. In order for this change to work, two new pins have been assigned to control the missing mode select pins to allow full control of which microstepping mode is to be used. The pin connections are as follows: +RA: +Mode 0 - Pin 15 +Mode 1 - Pin 16 +Mode 2 - Pin 17 -Section 'A': +Dec: +Mode 0 - Pin 20 +Mode 1 - Pin 19 +Mode 2 - Pin 18 -As of version 7, AstroEQ now uses 1/4 and 1/32th stepping for the DRV8824/5 driver boards. The change does not affect the A498x driver boards as they do not support 1/32th stepping mode. - -To account for these changes, please download and run the new configuration utility. Enter your step angle and gear ratios as normal and click 'Update'. That is all. - - - -Section 'B': - -As of version 7, AstroEQ now uses 1/4 and 1/32th stepping for the DRV8824/5 driver boards. The change does not affect the A498x driver boards as they do not support 1/32th stepping mode. - -For legacy controllers, only two pins are used to select the step mode. Because of this, one of the mode pins for each driver board is wired to a supply rail. - -If you have a A498x board, you do not need to make any hardware changes. Simply download and run the new config utility, enter your gear ratios/step angles and proceed as normal. - -If you have a DRV8824/5 board, you need to make some changes. Essentially you need to swap the pins on the driver boards labelled 'M0' and 'M1'. Once the changes are made, download and run the new config utility, enter your gear ratios/step angles and proceed as normal. - - - -While I know this is an inconvenience it is a necessary evil to improve the performance of AstroEQ. +If you are using an Arduino Mega, please make the changes required. If you are using an Atmega162 variety (as with all purchased controllers), no changes are required. +This is a bit of a pain for those using Arduinos, but rest assured, it is the last hardware change and has been done to bring the legacy design up to date. diff --git a/repo/dists/stable/main/binary-amd64/Packages.gz b/repo/dists/stable/main/binary-amd64/Packages.gz deleted file mode 100644 index a5bae0ba4ba08499ffa52b369d801503e69f9557..0000000000000000000000000000000000000000 Binary files a/repo/dists/stable/main/binary-amd64/Packages.gz and /dev/null differ diff --git a/repo/dists/stable/main/binary-armhf/Packages.gz b/repo/dists/stable/main/binary-armhf/Packages.gz deleted file mode 100644 index 3b55ae336c008d130c96b8743738e3cac3e9b50f..0000000000000000000000000000000000000000 Binary files a/repo/dists/stable/main/binary-armhf/Packages.gz and /dev/null differ diff --git a/repo/dists/stable/main/binary-i386/Packages.gz b/repo/dists/stable/main/binary-i386/Packages.gz deleted file mode 100644 index 2d09dc5229a5e69694a9c62f2f063c53e7ac08f1..0000000000000000000000000000000000000000 Binary files a/repo/dists/stable/main/binary-i386/Packages.gz and /dev/null differ diff --git a/repo/dists/stable/main/binary/Packages.gz b/repo/dists/stable/main/binary/Packages.gz new file mode 100644 index 0000000000000000000000000000000000000000..6024538ba57ac3ecb7bd29abe3f992b48928e83e Binary files /dev/null and b/repo/dists/stable/main/binary/Packages.gz differ diff --git a/repo/pool/main/amd64/astroequploader/astroequploader-1.05-amd64.deb b/repo/pool/main/amd64/astroequploader/astroequploader-1.05-amd64.deb deleted file mode 100644 index c08ca6ba4bcd83e5c81d14aae187638571a7b46b..0000000000000000000000000000000000000000 Binary files a/repo/pool/main/amd64/astroequploader/astroequploader-1.05-amd64.deb and /dev/null differ diff --git a/repo/pool/main/armhf/astroequploader/astroequploader-1.05-armhf.deb b/repo/pool/main/armhf/astroequploader/astroequploader-1.05-armhf.deb deleted file mode 100644 index 579cd716d4671a39262d1f36d5c20148008906f2..0000000000000000000000000000000000000000 Binary files a/repo/pool/main/armhf/astroequploader/astroequploader-1.05-armhf.deb and /dev/null differ diff --git a/repo/pool/main/astroequploader/astroequploader-1.07.deb b/repo/pool/main/astroequploader/astroequploader-1.07.deb new file mode 100644 index 0000000000000000000000000000000000000000..ee63b14837b961a8824d22ec722b888410a0f5cc Binary files /dev/null and b/repo/pool/main/astroequploader/astroequploader-1.07.deb differ diff --git a/repo/pool/main/i386/astroequploader/astroequploader-1.05-i386.deb b/repo/pool/main/i386/astroequploader/astroequploader-1.05-i386.deb deleted file mode 100644 index 691163f43e31349b5ae13362bbb662edd289834c..0000000000000000000000000000000000000000 Binary files a/repo/pool/main/i386/astroequploader/astroequploader-1.05-i386.deb and /dev/null differ