Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/adafruit/Adafruit-Motor-Shield-library.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBrian Schmalz <brian@schmalzhaus.com>2012-09-22 20:50:31 +0400
committerBrian Schmalz <brian@schmalzhaus.com>2012-09-22 20:50:31 +0400
commit33e4a2748d00be8a16b6c67890ed9e7ae29b4f0a (patch)
tree7f6184e496710dcfbdade05cc7d2b5a2b5452072
parentc7189c22ea7a027dfcecd0fb89bae5189f5a9d69 (diff)
Added support for cipKIT/MPIDE (PIC32 architecture) boards. Please see AFMotor.h for usage notes and workarounds for 2 minor issues.
Tested with all examples (and AccelStepper) and all work properly with the exception of the Motor Party example. (See AFMotor.h for reason why not.) Tested all 4 DC motor ouptuts (with PWM) and 2 stepper outputs (with microstepping) and all work properly.
-rw-r--r--AFMotor.cpp114
-rw-r--r--AFMotor.h95
-rw-r--r--README.txt1
3 files changed, 175 insertions, 35 deletions
diff --git a/AFMotor.cpp b/AFMotor.cpp
index 220e066..c1f6482 100644
--- a/AFMotor.cpp
+++ b/AFMotor.cpp
@@ -25,6 +25,7 @@ uint8_t microstepcurve[] = {0, 25, 50, 74, 98, 120, 141, 162, 180, 197, 212, 225
#endif
AFMotorController::AFMotorController(void) {
+ TimerInitalized = false;
}
void AFMotorController::enable(void) {
@@ -78,7 +79,6 @@ void AFMotorController::latch_tx(void) {
static AFMotorController MC;
-
/******************************************
MOTORS
******************************************/
@@ -98,11 +98,46 @@ inline void initPWM1(uint8_t freq) {
TCCR1B = (freq & 0x7) | _BV(WGM12);
OCR1A = 0;
#elif defined(__PIC32MX__)
-/// TODO: Fill this in for PIC32
+ #if defined(PIC32_USE_PIN9_FOR_M1_PWM)
+ // Make sure that pin 11 is an input, since we have tied together 9 and 11
+ pinMode(9, OUTPUT);
+ pinMode(11, INPUT);
+ if (!MC.TimerInitalized)
+ { // Set up Timer2 for 80MHz counting fro 0 to 256
+ T2CON = 0x8000 | ((freq & 0x07) << 4); // ON=1, FRZ=0, SIDL=0, TGATE=0, TCKPS=<freq>, T32=0, TCS=0; // ON=1, FRZ=0, SIDL=0, TGATE=0, TCKPS=0, T32=0, TCS=0
+ TMR2 = 0x0000;
+ PR2 = 0x0100;
+ MC.TimerInitalized = true;
+ }
+ // Setup OC4 (pin 9) in PWM mode, with Timer2 as timebase
+ OC4CON = 0x8006; // OC32 = 0, OCTSEL=0, OCM=6
+ OC4RS = 0x0000;
+ OC4R = 0x0000;
+ #elif defined(PIC32_USE_PIN10_FOR_M1_PWM)
+ // Make sure that pin 11 is an input, since we have tied together 9 and 11
+ pinMode(10, OUTPUT);
+ pinMode(11, INPUT);
+ if (!MC.TimerInitalized)
+ { // Set up Timer2 for 80MHz counting fro 0 to 256
+ T2CON = 0x8000 | ((freq & 0x07) << 4); // ON=1, FRZ=0, SIDL=0, TGATE=0, TCKPS=<freq>, T32=0, TCS=0; // ON=1, FRZ=0, SIDL=0, TGATE=0, TCKPS=0, T32=0, TCS=0
+ TMR2 = 0x0000;
+ PR2 = 0x0100;
+ MC.TimerInitalized = true;
+ }
+ // Setup OC5 (pin 10) in PWM mode, with Timer2 as timebase
+ OC5CON = 0x8006; // OC32 = 0, OCTSEL=0, OCM=6
+ OC5RS = 0x0000;
+ OC5R = 0x0000;
+ #else
+ // If we are not using PWM for pin 11, then just do digital
+ digitalWrite(11, LOW);
+ #endif
#else
#error "This chip is not supported!"
#endif
- pinMode(11, OUTPUT);
+ #if !defined(PIC32_USE_PIN9_FOR_M1_PWM) && !defined(PIC32_USE_PIN10_FOR_M1_PWM)
+ pinMode(11, OUTPUT);
+ #endif
}
inline void setPWM1(uint8_t s) {
@@ -117,7 +152,23 @@ inline void setPWM1(uint8_t s) {
// on arduino mega, pin 11 is now PB5 (OC1A)
OCR1A = s;
#elif defined(__PIC32MX__)
-/// TODO: Fill this in for PIC32
+ #if defined(PIC32_USE_PIN9_FOR_M1_PWM)
+ // Set the OC4 (pin 9) PMW duty cycle from 0 to 255
+ OC4RS = s;
+ #elif defined(PIC32_USE_PIN10_FOR_M1_PWM)
+ // Set the OC5 (pin 10) PMW duty cycle from 0 to 255
+ OC5RS = s;
+ #else
+ // If we are not doing PWM output for M1, then just use on/off
+ if (s > 127)
+ {
+ digitalWrite(11, HIGH);
+ }
+ else
+ {
+ digitalWrite(11, LOW);
+ }
+ #endif
#else
#error "This chip is not supported!"
#endif
@@ -139,7 +190,17 @@ inline void initPWM2(uint8_t freq) {
TCCR3B = (freq & 0x7) | _BV(WGM12);
OCR3C = 0;
#elif defined(__PIC32MX__)
-/// TODO: Fill this in for PIC32
+ if (!MC.TimerInitalized)
+ { // Set up Timer2 for 80MHz counting fro 0 to 256
+ T2CON = 0x8000 | ((freq & 0x07) << 4); // ON=1, FRZ=0, SIDL=0, TGATE=0, TCKPS=<freq>, T32=0, TCS=0; // ON=1, FRZ=0, SIDL=0, TGATE=0, TCKPS=0, T32=0, TCS=0
+ TMR2 = 0x0000;
+ PR2 = 0x0100;
+ MC.TimerInitalized = true;
+ }
+ // Setup OC1 (pin3) in PWM mode, with Timer2 as timebase
+ OC1CON = 0x8006; // OC32 = 0, OCTSEL=0, OCM=6
+ OC1RS = 0x0000;
+ OC1R = 0x0000;
#else
#error "This chip is not supported!"
#endif
@@ -159,7 +220,8 @@ inline void setPWM2(uint8_t s) {
// on arduino mega, pin 11 is now PB5 (OC1A)
OCR3C = s;
#elif defined(__PIC32MX__)
-/// TODO: Fill this in for PIC32
+ // Set the OC1 (pin3) PMW duty cycle from 0 to 255
+ OC1RS = s;
#else
#error "This chip is not supported!"
#endif
@@ -182,7 +244,17 @@ inline void initPWM3(uint8_t freq) {
//TCCR4B = 1 | _BV(WGM12);
OCR4A = 0;
#elif defined(__PIC32MX__)
-/// TODO: Fill this in for PIC32
+ if (!MC.TimerInitalized)
+ { // Set up Timer2 for 80MHz counting fro 0 to 256
+ T2CON = 0x8000 | ((freq & 0x07) << 4); // ON=1, FRZ=0, SIDL=0, TGATE=0, TCKPS=<freq>, T32=0, TCS=0; // ON=1, FRZ=0, SIDL=0, TGATE=0, TCKPS=0, T32=0, TCS=0
+ TMR2 = 0x0000;
+ PR2 = 0x0100;
+ MC.TimerInitalized = true;
+ }
+ // Setup OC3 (pin 6) in PWM mode, with Timer2 as timebase
+ OC3CON = 0x8006; // OC32 = 0, OCTSEL=0, OCM=6
+ OC3RS = 0x0000;
+ OC3R = 0x0000;
#else
#error "This chip is not supported!"
#endif
@@ -201,7 +273,8 @@ inline void setPWM3(uint8_t s) {
// on arduino mega, pin 6 is now PH3 (OC4A)
OCR4A = s;
#elif defined(__PIC32MX__)
-/// TODO: Fill this in for PIC32
+ // Set the OC3 (pin 6) PMW duty cycle from 0 to 255
+ OC3RS = s;
#else
#error "This chip is not supported!"
#endif
@@ -226,7 +299,17 @@ inline void initPWM4(uint8_t freq) {
//TCCR4B = 1 | _BV(WGM12);
OCR3A = 0;
#elif defined(__PIC32MX__)
-/// TODO: Fill this in for PIC32
+ if (!MC.TimerInitalized)
+ { // Set up Timer2 for 80MHz counting fro 0 to 256
+ T2CON = 0x8000 | ((freq & 0x07) << 4); // ON=1, FRZ=0, SIDL=0, TGATE=0, TCKPS=<freq>, T32=0, TCS=0; // ON=1, FRZ=0, SIDL=0, TGATE=0, TCKPS=0, T32=0, TCS=0
+ TMR2 = 0x0000;
+ PR2 = 0x0100;
+ MC.TimerInitalized = true;
+ }
+ // Setup OC2 (pin 5) in PWM mode, with Timer2 as timebase
+ OC2CON = 0x8006; // OC32 = 0, OCTSEL=0, OCM=6
+ OC2RS = 0x0000;
+ OC2R = 0x0000;
#else
#error "This chip is not supported!"
#endif
@@ -245,7 +328,8 @@ inline void setPWM4(uint8_t s) {
// on arduino mega, pin 6 is now PH3 (OC4A)
OCR3A = s;
#elif defined(__PIC32MX__)
-/// TODO: Fill this in for PIC32
+ // Set the OC2 (pin 5) PMW duty cycle from 0 to 255
+ OC2RS = s;
#else
#error "This chip is not supported!"
#endif
@@ -308,7 +392,7 @@ void AF_DCMotor::run(uint8_t cmd) {
MC.latch_tx();
break;
case RELEASE:
- latch_state &= ~_BV(a);
+ latch_state &= ~_BV(a); // A and B both low
latch_state &= ~_BV(b);
MC.latch_tx();
break;
@@ -351,8 +435,8 @@ AF_Stepper::AF_Stepper(uint16_t steps, uint8_t num) {
digitalWrite(3, HIGH);
// use PWM for microstepping support
- initPWM1(MOTOR12_64KHZ);
- initPWM2(MOTOR12_64KHZ);
+ initPWM1(STEPPER1_PWM_RATE);
+ initPWM2(STEPPER1_PWM_RATE);
setPWM1(255);
setPWM2(255);
@@ -369,8 +453,8 @@ AF_Stepper::AF_Stepper(uint16_t steps, uint8_t num) {
// use PWM for microstepping support
// use PWM for microstepping support
- initPWM3(1);
- initPWM4(1);
+ initPWM3(STEPPER2_PWM_RATE);
+ initPWM4(STEPPER2_PWM_RATE);
setPWM3(255);
setPWM4(255);
}
diff --git a/AFMotor.h b/AFMotor.h
index 6f3d99b..0362211 100644
--- a/AFMotor.h
+++ b/AFMotor.h
@@ -2,8 +2,33 @@
// copyright Adafruit Industries LLC, 2009
// this code is public domain, enjoy!
+/*
+ * Usage Notes:
+ * For PIC32, all features work properly with the following two exceptions:
+ *
+ * 1) Because the PIC32 only has 5 PWM outputs, and the AFMotor shield needs 6
+ * to completely operate (for for motor outputs and two for RC servos), the
+ * M1 motor output will not have PWM ability when used with a PIC32 board.
+ * However, there is a very simple workaround. If you need to drive a stepper
+ * or DC motor with PWM on motor output M1, you can use the PWM output on pin
+ * 9 or pin 10 (normally use for RC servo outputs on Arduino, not needed for
+ * RC servo outputs on PIC32) to drive the PWM input for M1 by simply putting
+ * a jumber from pin 9 to pin 11 or pin 10 to pin 11. Then uncomment one of the
+ * two #defines below to activate the PWM on either pin 9 or pin 10. You will
+ * then have a fully functional microstepping for 2 stepper motors, or four
+ * DC motor outputs with PWM.
+ *
+ * 2) There is a conflict between RC Servo outputs on pins 9 and pins 10 and
+ * the operation of DC motors and stepper motors as of 9/2012. This issue
+ * will get fixed in future MPIDE releases, but at the present time it means
+ * that the Motor Party example will NOT work properly. Any time you attach
+ * an RC servo to pins 9 or pins 10, ALL PWM outputs on the whole board will
+ * stop working. Thus no steppers or DC motors.
+ *
+ */
// <BPS> 09/15/2012 Modified for use with chipKIT boards
+
#ifndef _AFMotor_h_
#define _AFMotor_h_
@@ -13,31 +38,60 @@
//#define MOTORDEBUG 1
- #define MICROSTEPS 16 // 8 or 16
+ #define MICROSTEPS 16 // 8 or 16
- #define MOTOR12_64KHZ _BV(CS20) // no prescale
- #define MOTOR12_8KHZ _BV(CS21) // divide by 8
- #define MOTOR12_2KHZ _BV(CS21) | _BV(CS20) // divide by 32
- #define MOTOR12_1KHZ _BV(CS22) // divide by 64
+ #define MOTOR12_64KHZ _BV(CS20) // no prescale
+ #define MOTOR12_8KHZ _BV(CS21) // divide by 8
+ #define MOTOR12_2KHZ _BV(CS21) | _BV(CS20) // divide by 32
+ #define MOTOR12_1KHZ _BV(CS22) // divide by 64
- #define MOTOR34_64KHZ _BV(CS00) // no prescale
- #define MOTOR34_8KHZ _BV(CS01) // divide by 8
+ #define MOTOR34_64KHZ _BV(CS00) // no prescale
+ #define MOTOR34_8KHZ _BV(CS01) // divide by 8
#define MOTOR34_1KHZ _BV(CS01) | _BV(CS00) // divide by 64
+ #define DC_MOTOR_PWM_RATE MOTOR34_8KHZ // PWM rate for DC motors
+ #define STEPPER1_PWM_RATE MOTOR12_64KHZ // PWM rate for stepper 1
+ #define STEPPER2_PWM_RATE MOTOR34_64KHZ // PWM rate for stepper 2
+
#elif defined(__PIC32MX__)
- /// TODO: Update this for PIC32 microstepping
//#define MOTORDEBUG 1
-
- #define MICROSTEPS 16 // 8 or 16
-
- #define MOTOR12_64KHZ 1 // no prescale
- #define MOTOR12_8KHZ 2 // divide by 8
- #define MOTOR12_2KHZ 3 // divide by 32
- #define MOTOR12_1KHZ 4// divide by 64
-
- #define MOTOR34_64KHZ 5 // no prescale
- #define MOTOR34_8KHZ 6 // divide by 8
- #define MOTOR34_1KHZ 7 // divide by 64
+
+ // Uncomment the one of following lines if you have put a jumper from
+ // either pin 9 to pin 11 or pin 10 to pin 11 on your Motor Shield.
+ // Either will enable PWM for M1
+ //#define PIC32_USE_PIN9_FOR_M1_PWM
+ //#define PIC32_USE_PIN10_FOR_M1_PWM
+
+ #define MICROSTEPS 16 // 8 or 16
+
+ // For PIC32 Timers, define prescale settings by PWM frequency
+ #define MOTOR12_312KHZ 0 // 1:1, actual frequency 312KHz
+ #define MOTOR12_156KHZ 1 // 1:2, actual frequency 156KHz
+ #define MOTOR12_64KHZ 2 // 1:4, actual frequency 78KHz
+ #define MOTOR12_39KHZ 3 // 1:8, acutal frequency 39KHz
+ #define MOTOR12_19KHZ 4 // 1:16, actual frequency 19KHz
+ #define MOTOR12_8KHZ 5 // 1:32, actual frequency 9.7KHz
+ #define MOTOR12_4_8KHZ 6 // 1:64, actual frequency 4.8KHz
+ #define MOTOR12_2KHZ 7 // 1:256, actual frequency 1.2KHz
+ #define MOTOR12_1KHZ 7 // 1:256, actual frequency 1.2KHz
+
+ #define MOTOR34_312KHZ 0 // 1:1, actual frequency 312KHz
+ #define MOTOR34_156KHZ 1 // 1:2, actual frequency 156KHz
+ #define MOTOR34_64KHZ 2 // 1:4, actual frequency 78KHz
+ #define MOTOR34_39KHZ 3 // 1:8, acutal frequency 39KHz
+ #define MOTOR34_19KHZ 4 // 1:16, actual frequency 19KHz
+ #define MOTOR34_8KHZ 5 // 1:32, actual frequency 9.7KHz
+ #define MOTOR34_4_8KHZ 6 // 1:64, actual frequency 4.8KHz
+ #define MOTOR34_2KHZ 7 // 1:256, actual frequency 1.2KHz
+ #define MOTOR34_1KHZ 7 // 1:256, actual frequency 1.2KHz
+
+ // PWM rate for DC motors.
+ #define DC_MOTOR_PWM_RATE MOTOR34_39KHZ
+ // Note: for PIC32, both of these must be set to the same value
+ // since there's only one timebase for all 4 PWM outputs
+ #define STEPPER1_PWM_RATE MOTOR12_39KHZ
+ #define STEPPER2_PWM_RATE MOTOR34_39KHZ
+
#endif
// Bit positions in the 74HCT595 shift register output
@@ -93,12 +147,13 @@ class AFMotorController
void enable(void);
friend class AF_DCMotor;
void latch_tx(void);
+ uint8_t TimerInitalized;
};
class AF_DCMotor
{
public:
- AF_DCMotor(uint8_t motornum, uint8_t freq = MOTOR34_8KHZ);
+ AF_DCMotor(uint8_t motornum, uint8_t freq = DC_MOTOR_PWM_RATE);
void run(uint8_t);
void setSpeed(uint8_t);
diff --git a/README.txt b/README.txt
index dfc5765..00cc0e9 100644
--- a/README.txt
+++ b/README.txt
@@ -1,4 +1,5 @@
This is the August 12, 2009 Adafruit Motor shield firmware with basic Microstepping support. Works with all Arduinos and the Mega
+Updated in September 2012 for use on PIC32 architecture (chipKIT/MPIDE)
For more information on the shield, please visit http://www.ladyada.net/make/mshield/