diff --git a/README.md b/README.md index a296e4a..0d3c3be 100644 --- a/README.md +++ b/README.md @@ -1,10 +1,8 @@ -SparkFun AutoDriver Arduino Library +Ponoor L6470 Library ========== -[![AutoDriver](https://dlnmh9ip6v2uc.cloudfront.net/images/products/1/1/6/1/1/11611-01_medium.jpg) -*AutoDriver (BOB-13752)*](https://www.sparkfun.com/products/13752) +Arduino library support for STMicroelectronics [L6470](https://www.st.com/en/motor-drivers/l6470.html) chip. -The AutoDriver is a bipolar stepper driver based on the ST Micro L6470 chip. -It allows a processor to control a single 3A bipolar stepper motor across an 8-45V supply range. +This library is a modification of the L6470-based SparkFun [AutoDriver library](https://github.com/sparkfun/SparkFun_AutoDriver_Arduino_Library). Repository Contents ------------------- @@ -13,22 +11,16 @@ Repository Contents * **keywords.txt** - List of words to be highlighted by the Arduino IDE * **library.properties** - Used by the Arduino package manager -Documentation +Differences from the original library ------------------- -* **[Installing an Arduino Library Guide](https://learn.sparkfun.com/tutorials/installing-an-arduino-library)** - Basic information on how to install an Arduino library. -* **[Product Repository](https://github.com/sparkfun/L6470-AutoDriver)** - Main repository (including hardware files) for the AutoDriver board. -* **[Hookup Guide](https://learn.sparkfun.com/tutorials/getting-started-with-the-autodriver---v13)** - Basic hookup guide for the AutoDriver board. - -Version History -------------------- - -* [v 1.0.0](https://github.com/sparkfun/SparkFun_AutoDriver_Arduino_Library/tree/V_1.0.0) - Initial release -* [v 1.3.0](https://github.com/sparkfun/SparkFun_AutoDriver_Arduino_Library/tree/V_1.3.0) - Library release for V 1.3 +- Added `getSpeed()` function +- Disable interrupts during `getStatus` and `xferParam` to avoid return value collapse for ATSAMD +- Changed some constants name(`CMD_GET_STATUS`, `REG_STATUS`) to avoid conflicts with other libraries. License Information ------------------- This product is open source! -The code is beerware; if you see me (or any other SparkFun employee) at the local, and you've found our code helpful, please buy us a round! +The code is beerware; if you see any SparkFun employee at the local, and you've found their code helpful, please buy them a round! Please use, reuse, and modify these files as you see fit. Please maintain attribution to SparkFun Electronics and release anything derivative under the same license. Distributed as-is; no warranty is given. diff --git a/library.properties b/library.properties index 428545f..b495178 100644 --- a/library.properties +++ b/library.properties @@ -1,9 +1,10 @@ name=Ponoor L6470 Library -version=0.1.0 +version=1.0.0 author=Ponoor Experiments Inc maintainer=Kanta Horio -sentence=L6470 library, modified version of Sparkfun AutoDriver Library -paragraph=L6470 library, modified version of Sparkfun AutoDriver Library -category=Other -url=https://github.com/kanta/Ponoor_L6470_Library +sentence=STM L6470 stepper driver chip library. +paragraph=This library is modified from SparkFun AutoDriver library for SAMD support and some other functionalities and compatibilities. +category=Device Control +url=https://github.com/ponoor/Ponoor_L6470_Library architectures=* +includes=Ponoor_L6470Library.h diff --git a/src/Ponoor_L6470Commands.cpp b/src/Ponoor_L6470Commands.cpp index 67bd4aa..55ed8a4 100644 --- a/src/Ponoor_L6470Commands.cpp +++ b/src/Ponoor_L6470Commands.cpp @@ -55,8 +55,11 @@ long AutoDriver::getMark() // appropriate integer values for this function. void AutoDriver::run(byte dir, float stepsPerSec) { - SPIXfer(CMD_RUN | dir); unsigned long integerSpeed = spdCalc(stepsPerSec); + runRaw(dir, integerSpeed); +} +void AutoDriver::runRaw(byte dir, unsigned long integerSpeed) { + SPIXfer(CMD_RUN | dir); if (integerSpeed > 0xFFFFF) integerSpeed = 0xFFFFF; // Now we need to push this value out to the dSPIN. The 32-bit value is @@ -137,9 +140,12 @@ void AutoDriver::goToDir(byte dir, long pos) // either RESET to 0 or COPY-ed into the MARK register. void AutoDriver::goUntil(byte action, byte dir, float stepsPerSec) { + unsigned long integerSpeed = spdCalc(stepsPerSec); + goUntilRaw(action, dir, integerSpeed); +} +void AutoDriver::goUntilRaw(byte action, byte dir, unsigned long integerSpeed) { action = (action > 0) << 3; SPIXfer(CMD_GO_UNTIL | action | dir); - unsigned long integerSpeed = spdCalc(stepsPerSec); if (integerSpeed > 0x3FFFFF) integerSpeed = 0x3FFFFF; // See run() for an explanation of what's going on here. byte* bytePointer = (byte*)&integerSpeed; @@ -148,7 +154,6 @@ void AutoDriver::goUntil(byte action, byte dir, float stepsPerSec) SPIXfer(bytePointer[i]); } } - // Similar in nature to GoUntil, ReleaseSW produces motion at the // higher of two speeds: the value in MIN_SPEED or 5 steps/s. // The motor continues to run at this speed until a rising edge @@ -234,9 +239,15 @@ void AutoDriver::hardHiZ() int AutoDriver::getStatus() { int temp = 0; +#if defined(ARDUINO_ARCH_SAMD) + __disable_irq(); +#endif byte* bytePointer = (byte*)&temp; SPIXfer(CMD_GET_STATUS); bytePointer[1] = SPIXfer(0); bytePointer[0] = SPIXfer(0); +#if defined(ARDUINO_ARCH_SAMD) + __enable_irq(); +#endif return temp; } diff --git a/src/Ponoor_L6470Config.cpp b/src/Ponoor_L6470Config.cpp index 7db2839..02a5c7c 100644 --- a/src/Ponoor_L6470Config.cpp +++ b/src/Ponoor_L6470Config.cpp @@ -48,8 +48,12 @@ void AutoDriver::setMaxSpeed(float stepsPerSecond) // the dSPIN can understand. Fortunately, we have a function to do that. unsigned long integerSpeed = maxSpdCalc(stepsPerSecond); - // Now, we can set that paramter. - setParam(MAX_SPEED, integerSpeed); + setMaxSpeedRaw(integerSpeed); +} +void AutoDriver::setMaxSpeedRaw(unsigned long integerSpeed) +{ + // Now, we can set that paramter. + setParam(MAX_SPEED, integerSpeed); } // Get current speed @@ -62,6 +66,10 @@ float AutoDriver::getMaxSpeed() { return maxSpdParse(getParam(MAX_SPEED)); } +unsigned long AutoDriver::getMaxSpeedRaw() +{ + return getParam(MAX_SPEED); +} // Set the minimum speed allowable in the system. This is the speed a motion // starts with; it will then ramp up to the designated speed or the max @@ -71,7 +79,10 @@ void AutoDriver::setMinSpeed(float stepsPerSecond) // We need to convert the floating point stepsPerSecond into a value that // the dSPIN can understand. Fortunately, we have a function to do that. unsigned long integerSpeed = minSpdCalc(stepsPerSecond); - + setMinSpeedRaw(integerSpeed); +} +void AutoDriver::setMinSpeedRaw(unsigned long integerSpeed) +{ // MIN_SPEED also contains the LSPD_OPT flag, so we need to protect that. unsigned long temp = getParam(MIN_SPEED) & 0x00001000; @@ -83,12 +94,21 @@ float AutoDriver::getMinSpeed() { return minSpdParse(getParam(MIN_SPEED)); } +unsigned long AutoDriver::getMinSpeedRaw() +{ + return getParam(MIN_SPEED); +} + // Above this threshold, the dSPIN will cease microstepping and go to full-step // mode. void AutoDriver::setFullSpeed(float stepsPerSecond) { unsigned long integerSpeed = FSCalc(stepsPerSecond); + setFullSpeedRaw(integerSpeed); +} +void AutoDriver::setFullSpeedRaw(unsigned long integerSpeed) +{ setParam(FS_SPD, integerSpeed); } @@ -96,32 +116,51 @@ float AutoDriver::getFullSpeed() { return FSParse(getParam(FS_SPD)); } - +unsigned long AutoDriver::getFullSpeedRaw() +{ + return getParam(FS_SPD); +} // Set the acceleration rate, in steps per second per second. This value is // converted to a dSPIN friendly value. Any value larger than 29802 will // disable acceleration, putting the chip in "infinite" acceleration mode. void AutoDriver::setAcc(float stepsPerSecondPerSecond) { unsigned long integerAcc = accCalc(stepsPerSecondPerSecond); - setParam(ACC, integerAcc); + setAccRaw(integerAcc); +} +void AutoDriver::setAccRaw(unsigned long integerAcc) +{ + setParam(ACC, integerAcc); } float AutoDriver::getAcc() { return accParse(getParam(ACC)); } +unsigned long AutoDriver::getAccRaw() +{ + return getParam(ACC); +} // Same rules as setAcc(). void AutoDriver::setDec(float stepsPerSecondPerSecond) { unsigned long integerDec = decCalc(stepsPerSecondPerSecond); - setParam(DECEL, integerDec); + setDecRaw(integerDec); +} +void AutoDriver::setDecRaw(unsigned long integerDec) +{ + setParam(DECEL, integerDec); } float AutoDriver::getDec() { return accParse(getParam(DECEL)); } +unsigned long AutoDriver::getDecRaw() +{ + return getParam(DECEL); +} void AutoDriver::setOCThreshold(byte threshold) { diff --git a/src/Ponoor_L6470Constants.h b/src/Ponoor_L6470Constants.h index fd5955b..fd1f8d5 100644 --- a/src/Ponoor_L6470Constants.h +++ b/src/Ponoor_L6470Constants.h @@ -184,7 +184,7 @@ #define STEP_MODE 0x16 #define ALARM_EN 0x17 #define CONFIG 0x18 -#define STATUS 0x19 +#define REG_STATUS 0x19 //dSPIN commands #define CMD_NOP 0x00 diff --git a/src/Ponoor_L6470Library.cpp b/src/Ponoor_L6470Library.cpp index 36d4e59..fc273e3 100644 --- a/src/Ponoor_L6470Library.cpp +++ b/src/Ponoor_L6470Library.cpp @@ -33,7 +33,7 @@ int AutoDriver::busyCheck(void) { if (_busyPin == -1) { - if (getParam(STATUS) & 0x0002) return 0; + if (getParam(REG_STATUS) & 0x0002) return 0; else return 1; } else diff --git a/src/Ponoor_L6470Library.h b/src/Ponoor_L6470Library.h index 60b008e..5758fd6 100644 --- a/src/Ponoor_L6470Library.h +++ b/src/Ponoor_L6470Library.h @@ -38,6 +38,11 @@ class AutoDriver void setFullSpeed(float stepsPerSecond); void setAcc(float stepsPerSecondPerSecond); void setDec(float stepsPerSecondPerSecond); + void setMaxSpeedRaw(unsigned long integerSpeed); + void setMinSpeedRaw(unsigned long integerSpeed); + void setFullSpeedRaw(unsigned long integerSpeed); + void setAccRaw(unsigned long integerSpeed); + void setDecRaw(unsigned long integerSpeed); void setOCThreshold(byte threshold); void setPWMFreq(int divisor, int multiplier); void setSlewRate(int slewRate); @@ -59,6 +64,11 @@ class AutoDriver float getFullSpeed(); float getAcc(); float getDec(); + unsigned long getMaxSpeedRaw(); + unsigned long getMinSpeedRaw(); + unsigned long getFullSpeedRaw(); + unsigned long getAccRaw(); + unsigned long getDecRaw(); byte getOCThreshold(); int getPWMFreqDivisor(); int getPWMFreqMultiplier(); @@ -76,11 +86,13 @@ class AutoDriver long getPos(); long getMark(); void run(byte dir, float stepsPerSec); + void runRaw(byte dir, unsigned long integerSpeed); void stepClock(byte dir); void move(byte dir, unsigned long numSteps); void goTo(long pos); void goToDir(byte dir, long pos); void goUntil(byte action, byte dir, float stepsPerSec); + void goUntilRaw(byte action, byte dir, unsigned long integerSpeed); void releaseSw(byte action, byte dir); void goHome(); void goMark(); diff --git a/src/Ponoor_L6470Support.cpp b/src/Ponoor_L6470Support.cpp index 5f7d059..e362819 100644 --- a/src/Ponoor_L6470Support.cpp +++ b/src/Ponoor_L6470Support.cpp @@ -276,7 +276,7 @@ long AutoDriver::paramHandler(byte param, unsigned long value) // comprehensive set of constants for masking and testing this register is provided, but // users should refer to the datasheet to ensure that they fully understand each one of // the bits in the register. - case STATUS: // STATUS is a read-only register + case REG_STATUS: // STATUS is a read-only register retVal = xferParam(0, 16);; break; default: @@ -297,14 +297,18 @@ long AutoDriver::xferParam(unsigned long value, byte bitLen) byte temp; unsigned long retVal = 0; - +#if defined(ARDUINO_ARCH_SAMD) + __disable_irq(); +#endif for (int i = 0; i < byteLen; i++) { retVal = retVal << 8; temp = SPIXfer((byte)(value>>((byteLen-i-1)*8))); retVal |= temp; } - +#if defined(ARDUINO_ARCH_SAMD) + __enable_irq(); +#endif unsigned long mask = 0xffffffff >> (32-bitLen); return retVal & mask; }