Provides an API software interface to TIMER2 to control upto four stepper motors.

Dependents:   Steppermotor

Committer:
AjK
Date:
Fri May 20 09:13:31 2011 +0000
Revision:
4:7b7940df7865
Parent:
0:7393c52297ee
1.1 See ChangeLog.h

Who changed what in which revision?

UserRevisionLine numberNew contents of line
AjK 0:7393c52297ee 1 /*
AjK 0:7393c52297ee 2 Copyright (c) 2010 Andy Kirkham
AjK 0:7393c52297ee 3
AjK 0:7393c52297ee 4 Permission is hereby granted, free of charge, to any person obtaining a copy
AjK 0:7393c52297ee 5 of this software and associated documentation files (the "Software"), to deal
AjK 0:7393c52297ee 6 in the Software without restriction, including without limitation the rights
AjK 0:7393c52297ee 7 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
AjK 0:7393c52297ee 8 copies of the Software, and to permit persons to whom the Software is
AjK 0:7393c52297ee 9 furnished to do so, subject to the following conditions:
AjK 0:7393c52297ee 10
AjK 0:7393c52297ee 11 The above copyright notice and this permission notice shall be included in
AjK 0:7393c52297ee 12 all copies or substantial portions of the Software.
AjK 0:7393c52297ee 13
AjK 0:7393c52297ee 14 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
AjK 0:7393c52297ee 15 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
AjK 0:7393c52297ee 16 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AjK 0:7393c52297ee 17 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
AjK 0:7393c52297ee 18 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
AjK 0:7393c52297ee 19 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
AjK 0:7393c52297ee 20 THE SOFTWARE.
AjK 0:7393c52297ee 21 */
AjK 0:7393c52297ee 22
AjK 0:7393c52297ee 23 #include <math.h>
AjK 0:7393c52297ee 24 #include "SimpleSteppers.h"
AjK 0:7393c52297ee 25 #include "IOmacros.h"
AjK 0:7393c52297ee 26
AjK 0:7393c52297ee 27 #define _PMR *((uint32_t *)_pMR)
AjK 0:7393c52297ee 28
AjK 0:7393c52297ee 29 namespace AjK {
AjK 0:7393c52297ee 30
AjK 0:7393c52297ee 31 extern SimpleStepperController __simpleStepperController;
AjK 0:7393c52297ee 32
AjK 0:7393c52297ee 33 void TIMER2_IRQHandler(void);
AjK 0:7393c52297ee 34
AjK 0:7393c52297ee 35 SimpleStepper::SimpleStepper(PinName pulse, SimpleStepperOutput *direction)
AjK 0:7393c52297ee 36 {
AjK 0:7393c52297ee 37 _simpleStepperController = &__simpleStepperController;
AjK 0:7393c52297ee 38 _pulse = pulse;
AjK 0:7393c52297ee 39 _direction = direction;
AjK 0:7393c52297ee 40 init();
AjK 0:7393c52297ee 41 }
AjK 0:7393c52297ee 42
AjK 0:7393c52297ee 43 SimpleStepper::SimpleStepper(SimpleStepperController *con, PinName pulse, SimpleStepperOutput *direction)
AjK 0:7393c52297ee 44 {
AjK 0:7393c52297ee 45 _simpleStepperController = con;
AjK 0:7393c52297ee 46 _pulse = pulse;
AjK 0:7393c52297ee 47 _direction = direction;
AjK 0:7393c52297ee 48 init();
AjK 0:7393c52297ee 49 }
AjK 0:7393c52297ee 50
AjK 0:7393c52297ee 51 void
AjK 0:7393c52297ee 52 SimpleStepper::init(void)
AjK 0:7393c52297ee 53 {
AjK 0:7393c52297ee 54 _pulseCounter = 0;
AjK 0:7393c52297ee 55 _pulseWrapPos = 0;
AjK 0:7393c52297ee 56 _pulseWrapNeg = 0;
AjK 0:7393c52297ee 57
AjK 0:7393c52297ee 58 _maintainPositionData = true;
AjK 0:7393c52297ee 59
AjK 4:7b7940df7865 60 _steps_per_second = 0;
AjK 4:7b7940df7865 61
AjK 0:7393c52297ee 62 setPulseSense(1);
AjK 0:7393c52297ee 63 setDirectionSense(1);
AjK 0:7393c52297ee 64
AjK 0:7393c52297ee 65 switch (_pulse) {
AjK 0:7393c52297ee 66 case P0_6: // Mbed p8
AjK 0:7393c52297ee 67 _pulseMAT = MAT2_0;
AjK 0:7393c52297ee 68 _operShift = 4;
AjK 0:7393c52297ee 69 _pMR = 0x40090018; // T2MR0
AjK 0:7393c52297ee 70 _match_shift = 0;
AjK 0:7393c52297ee 71 _EMmask = 1;
AjK 0:7393c52297ee 72 _EMCshift = 4;
AjK 0:7393c52297ee 73 _simpleStepperController->_stepper[0] = this;
AjK 0:7393c52297ee 74 if (_pulseSense) LPC_TIM2->EMR &= ~_EMmask; else LPC_TIM2->EMR |= _EMmask;
AjK 0:7393c52297ee 75 LPC_PINCON->PINSEL0 |= (3UL << 12);
AjK 0:7393c52297ee 76 break;
AjK 0:7393c52297ee 77 case P0_7: // Mbed p7
AjK 0:7393c52297ee 78 _pulseMAT = MAT2_1;
AjK 0:7393c52297ee 79 _operShift = 6;
AjK 0:7393c52297ee 80 _pMR = 0x4009001C; // T2MR1
AjK 0:7393c52297ee 81 _match_shift = 3;
AjK 0:7393c52297ee 82 _EMmask = 2;
AjK 0:7393c52297ee 83 _EMCshift = 6;
AjK 0:7393c52297ee 84 _simpleStepperController->_stepper[1] = this;
AjK 0:7393c52297ee 85 if (_pulseSense) LPC_TIM2->EMR &= ~_EMmask; else LPC_TIM2->EMR |= _EMmask;
AjK 0:7393c52297ee 86 LPC_PINCON->PINSEL0 |= (3UL << 14);
AjK 0:7393c52297ee 87 break;
AjK 0:7393c52297ee 88 case P0_8: // Mbed p6
AjK 0:7393c52297ee 89 _pulseMAT = MAT2_2;
AjK 0:7393c52297ee 90 _operShift = 8;
AjK 0:7393c52297ee 91 _pMR = 0x40090020; // T2MR2
AjK 0:7393c52297ee 92 _match_shift = 6;
AjK 0:7393c52297ee 93 _EMmask = 4;
AjK 0:7393c52297ee 94 _EMCshift = 8;
AjK 0:7393c52297ee 95 _simpleStepperController->_stepper[2] = this;
AjK 0:7393c52297ee 96 if (_pulseSense) LPC_TIM2->EMR &= ~_EMmask; else LPC_TIM2->EMR |= _EMmask;
AjK 0:7393c52297ee 97 LPC_PINCON->PINSEL0 |= (3UL << 16);
AjK 0:7393c52297ee 98 break;
AjK 0:7393c52297ee 99 case P0_9: // Mbed p5
AjK 0:7393c52297ee 100 _pulseMAT = MAT2_3;
AjK 0:7393c52297ee 101 _operShift = 10;
AjK 0:7393c52297ee 102 _pMR = 0x40090024; // T2MR3
AjK 0:7393c52297ee 103 _match_shift = 9;
AjK 0:7393c52297ee 104 _EMmask = 8;
AjK 0:7393c52297ee 105 _EMCshift = 10;
AjK 0:7393c52297ee 106 _simpleStepperController->_stepper[3] = this;
AjK 0:7393c52297ee 107 if (_pulseSense) LPC_TIM2->EMR &= ~_EMmask; else LPC_TIM2->EMR |= _EMmask;
AjK 0:7393c52297ee 108 LPC_PINCON->PINSEL0 |= (3UL << 18);
AjK 0:7393c52297ee 109 break;
AjK 0:7393c52297ee 110 default:
AjK 0:7393c52297ee 111 while(1); /* ToDo, proper error reporting. */
AjK 0:7393c52297ee 112 }
AjK 0:7393c52297ee 113
AjK 0:7393c52297ee 114
AjK 0:7393c52297ee 115 // The default pulse length. 5 * (1/SIMPLESTEPPER_F) = 100us.
AjK 0:7393c52297ee 116 _pulseLen = 5;
AjK 0:7393c52297ee 117
AjK 0:7393c52297ee 118 // Initial state machine conditions.
AjK 0:7393c52297ee 119 _pulseState = PulseIdle;
AjK 0:7393c52297ee 120 _stepperState = Stopped;
AjK 0:7393c52297ee 121 }
AjK 0:7393c52297ee 122
AjK 0:7393c52297ee 123 void
AjK 0:7393c52297ee 124 SimpleStepper::setInterval(int interval, uint32_t raw)
AjK 0:7393c52297ee 125 {
AjK 0:7393c52297ee 126
AjK 0:7393c52297ee 127 if (interval == 0) { setSpeed((int)0); }
AjK 0:7393c52297ee 128 else {
AjK 0:7393c52297ee 129 int n = interval;
AjK 0:7393c52297ee 130 if (n < 0) n *= -1;
AjK 0:7393c52297ee 131 if (_direction) {
AjK 0:7393c52297ee 132 if (_directionSense) {
AjK 0:7393c52297ee 133 if (interval >= 0.0) _direction->write(1);
AjK 0:7393c52297ee 134 if (interval < 0.0) _direction->write(0);
AjK 0:7393c52297ee 135 }
AjK 0:7393c52297ee 136 else {
AjK 0:7393c52297ee 137 if (interval >= 0.0) _direction->write(0);
AjK 0:7393c52297ee 138 if (interval < 0.0) _direction->write(1);
AjK 0:7393c52297ee 139 }
AjK 0:7393c52297ee 140 }
AjK 0:7393c52297ee 141 _commandSpeed = n - _pulseLen;
AjK 0:7393c52297ee 142 _pulseState = PulseAssert;
AjK 0:7393c52297ee 143 _stepperState = ConstantSpeed;
AjK 0:7393c52297ee 144 if (raw) {
AjK 0:7393c52297ee 145 _PMR = raw + _commandSpeed;
AjK 0:7393c52297ee 146 }
AjK 0:7393c52297ee 147 else {
AjK 0:7393c52297ee 148 _PMR = LPC_TIM2->TC + _commandSpeed;
AjK 0:7393c52297ee 149 }
AjK 0:7393c52297ee 150 if (_pulseSense) LPC_TIM2->EMR &= ~_EMmask; else LPC_TIM2->EMR |= _EMmask;
AjK 0:7393c52297ee 151 LPC_TIM2->MCR &= ~(7UL << _match_shift);
AjK 0:7393c52297ee 152 LPC_TIM2->MCR |= (1UL << _match_shift);
AjK 0:7393c52297ee 153 }
AjK 0:7393c52297ee 154 }
AjK 0:7393c52297ee 155
AjK 0:7393c52297ee 156 void
AjK 0:7393c52297ee 157 SimpleStepper::setSpeed(double steps_per_second, uint32_t raw)
AjK 0:7393c52297ee 158 {
AjK 0:7393c52297ee 159 int i = 0;
AjK 0:7393c52297ee 160
AjK 0:7393c52297ee 161 if (steps_per_second == 0.0) { setSpeed(i); }
AjK 0:7393c52297ee 162 else {
AjK 0:7393c52297ee 163 double fractpart, intpart;
AjK 0:7393c52297ee 164 fractpart = modf (steps_per_second , &intpart);
AjK 0:7393c52297ee 165 if (fractpart >= 0.50) intpart++;
AjK 0:7393c52297ee 166 double n = intpart;
AjK 0:7393c52297ee 167 if (n < 0.0) n *= -1.0;
AjK 0:7393c52297ee 168 if (_direction) {
AjK 0:7393c52297ee 169 if (_directionSense) {
AjK 0:7393c52297ee 170 if (steps_per_second >= 0.0) _direction->write(1);
AjK 0:7393c52297ee 171 if (steps_per_second < 0.0) _direction->write(0);
AjK 0:7393c52297ee 172 }
AjK 0:7393c52297ee 173 else {
AjK 0:7393c52297ee 174 if (steps_per_second >= 0.0) _direction->write(0);
AjK 0:7393c52297ee 175 if (steps_per_second < 0.0) _direction->write(1);
AjK 0:7393c52297ee 176 }
AjK 0:7393c52297ee 177 }
AjK 0:7393c52297ee 178 _commandSpeed = (int)(((double)SIMPLESTEPPER_F / n)) - _pulseLen;
AjK 0:7393c52297ee 179 _pulseState = PulseAssert;
AjK 0:7393c52297ee 180 _stepperState = ConstantSpeed;
AjK 0:7393c52297ee 181 if (raw) {
AjK 0:7393c52297ee 182 _PMR = raw + _commandSpeed;
AjK 0:7393c52297ee 183 }
AjK 0:7393c52297ee 184 else {
AjK 0:7393c52297ee 185 _PMR = LPC_TIM2->TC + _commandSpeed;
AjK 0:7393c52297ee 186 }
AjK 0:7393c52297ee 187 if (_pulseSense) LPC_TIM2->EMR &= ~_EMmask; else LPC_TIM2->EMR |= _EMmask;
AjK 0:7393c52297ee 188 LPC_TIM2->MCR &= ~(7UL << _match_shift);
AjK 0:7393c52297ee 189 LPC_TIM2->MCR |= (1UL << _match_shift);
AjK 0:7393c52297ee 190 }
AjK 0:7393c52297ee 191 }
AjK 0:7393c52297ee 192
AjK 0:7393c52297ee 193 void
AjK 0:7393c52297ee 194 SimpleStepper::setSpeed(int steps_per_second, uint32_t raw)
AjK 0:7393c52297ee 195 {
AjK 0:7393c52297ee 196 if (steps_per_second == 0) {
AjK 0:7393c52297ee 197 LPC_TIM2->EMR |= (NothingOnMatch << _EMCshift);
AjK 0:7393c52297ee 198 LPC_TIM2->MCR &= ~(7UL << _match_shift);
AjK 4:7b7940df7865 199 if (_pulseSense) LPC_TIM2->EMR |= _EMmask; else LPC_TIM2->EMR &= ~_EMmask;
AjK 0:7393c52297ee 200 _stepperState = Stopped;
AjK 0:7393c52297ee 201 _pulseState = PulseIdle;
AjK 0:7393c52297ee 202 _commandSpeed = 0;
AjK 4:7b7940df7865 203 _steps_per_second = 0;
AjK 0:7393c52297ee 204 }
AjK 0:7393c52297ee 205 else {
AjK 4:7b7940df7865 206 _steps_per_second = steps_per_second;
AjK 0:7393c52297ee 207 int n = steps_per_second;
AjK 0:7393c52297ee 208 if (n < 0) n *= -1;
AjK 0:7393c52297ee 209 if (_direction) {
AjK 0:7393c52297ee 210 if (_directionSense) {
AjK 0:7393c52297ee 211 if (steps_per_second >= 0) _direction->write(1);
AjK 0:7393c52297ee 212 if (steps_per_second < 0) _direction->write(0);
AjK 0:7393c52297ee 213 }
AjK 0:7393c52297ee 214 else {
AjK 0:7393c52297ee 215 if (steps_per_second >= 0) _direction->write(0);
AjK 0:7393c52297ee 216 if (steps_per_second < 0) _direction->write(1);
AjK 0:7393c52297ee 217 }
AjK 0:7393c52297ee 218 }
AjK 0:7393c52297ee 219 _commandSpeed = (SIMPLESTEPPER_F / n) - _pulseLen;
AjK 0:7393c52297ee 220 _pulseState = PulseAssert;
AjK 0:7393c52297ee 221 _stepperState = ConstantSpeed;
AjK 0:7393c52297ee 222 if (raw) {
AjK 0:7393c52297ee 223 _PMR = raw + _commandSpeed;
AjK 0:7393c52297ee 224 }
AjK 0:7393c52297ee 225 else {
AjK 0:7393c52297ee 226 _PMR = LPC_TIM2->TC + _commandSpeed;
AjK 0:7393c52297ee 227 }
AjK 0:7393c52297ee 228 if (_pulseSense) LPC_TIM2->EMR &= ~_EMmask; else LPC_TIM2->EMR |= _EMmask;
AjK 0:7393c52297ee 229 LPC_TIM2->MCR &= ~(7UL << _match_shift);
AjK 0:7393c52297ee 230 LPC_TIM2->MCR |= (1UL << _match_shift);
AjK 0:7393c52297ee 231 }
AjK 0:7393c52297ee 232 }
AjK 0:7393c52297ee 233
AjK 0:7393c52297ee 234 void
AjK 0:7393c52297ee 235 SimpleStepper::next_step(void)
AjK 0:7393c52297ee 236 {
AjK 0:7393c52297ee 237 _PMR += _commandSpeed;
AjK 0:7393c52297ee 238
AjK 0:7393c52297ee 239 switch(_pulseSense) {
AjK 0:7393c52297ee 240 case 1:
AjK 0:7393c52297ee 241 LPC_TIM2->EMR &= ~(3UL << _EMCshift);
AjK 0:7393c52297ee 242 LPC_TIM2->EMR |= (SetOnMatch << _EMCshift);
AjK 0:7393c52297ee 243 break;
AjK 0:7393c52297ee 244 case 0:
AjK 0:7393c52297ee 245 LPC_TIM2->EMR &= ~(3UL << _EMCshift);
AjK 0:7393c52297ee 246 LPC_TIM2->EMR |= (ClrOnMatch << _EMCshift);
AjK 0:7393c52297ee 247 break;
AjK 0:7393c52297ee 248 }
AjK 0:7393c52297ee 249
AjK 0:7393c52297ee 250 // Next IRQ will automatically assert the pulse.
AjK 0:7393c52297ee 251 _pulseState = PulseAssert;
AjK 0:7393c52297ee 252 }
AjK 0:7393c52297ee 253
AjK 0:7393c52297ee 254 void
AjK 0:7393c52297ee 255 SimpleStepper::isr(uint32_t ir)
AjK 0:7393c52297ee 256 {
AjK 0:7393c52297ee 257 // Test to see if this interrupt is for us.
AjK 0:7393c52297ee 258 if (ir & _EMmask) {
AjK 0:7393c52297ee 259
AjK 0:7393c52297ee 260 if (_stepperState == Stopped) {
AjK 0:7393c52297ee 261 if (_pulseSense) LPC_TIM2->EMR &= ~_EMmask; else LPC_TIM2->EMR |= _EMmask;
AjK 0:7393c52297ee 262 return;
AjK 0:7393c52297ee 263 }
AjK 0:7393c52297ee 264
AjK 0:7393c52297ee 265 switch(_pulseState) {
AjK 0:7393c52297ee 266 case PulseIdle:
AjK 0:7393c52297ee 267 if (_pulseSense) LPC_TIM2->EMR &= ~_EMmask; else LPC_TIM2->EMR |= _EMmask;
AjK 0:7393c52297ee 268 _currentMatch = _PMR; // Store the current match value for profile().
AjK 0:7393c52297ee 269 next_step();
AjK 0:7393c52297ee 270 break;
AjK 0:7393c52297ee 271
AjK 0:7393c52297ee 272 case PulseAssert: // Pulse has just been asserted on MAT2_x.
AjK 0:7393c52297ee 273 _PMR += _pulseLen; // We now program for the deassert IRQ to occur at the required time.
AjK 0:7393c52297ee 274 LPC_TIM2->EMR &= ~(ToggleOnMatch << _EMCshift); // At next IRQ we want to switch the pulse off...
AjK 0:7393c52297ee 275 LPC_TIM2->EMR |= (ToggleOnMatch << _EMCshift); // ... we do this by toggling it.
AjK 0:7393c52297ee 276 _pulseState = PulseDeassert; // Set state for next interrupt.
AjK 0:7393c52297ee 277
AjK 0:7393c52297ee 278 if (_maintainPositionData) {
AjK 0:7393c52297ee 279 if (_directionSense) {
AjK 0:7393c52297ee 280 if (_commandSpeed > 0) {
AjK 0:7393c52297ee 281 _pulseCounter++;
AjK 0:7393c52297ee 282 if (_pulseWrapPos && _pulseCounter >= _pulseWrapPos) {
AjK 0:7393c52297ee 283 _pulseCounter = _pulseWrapNeg + 1;
AjK 0:7393c52297ee 284 }
AjK 0:7393c52297ee 285 }
AjK 0:7393c52297ee 286 if (_commandSpeed < 0) {
AjK 0:7393c52297ee 287 _pulseCounter--;
AjK 0:7393c52297ee 288 if (_pulseWrapNeg && _pulseCounter <= _pulseWrapNeg) {
AjK 0:7393c52297ee 289 _pulseCounter = _pulseWrapPos - 1;
AjK 0:7393c52297ee 290 }
AjK 0:7393c52297ee 291 }
AjK 0:7393c52297ee 292 }
AjK 0:7393c52297ee 293 else {
AjK 0:7393c52297ee 294 if (_commandSpeed > 0) {
AjK 0:7393c52297ee 295 _pulseCounter--;
AjK 0:7393c52297ee 296 if (_pulseWrapNeg && _pulseCounter <= _pulseWrapNeg) {
AjK 0:7393c52297ee 297 _pulseCounter = _pulseWrapPos - 1;
AjK 0:7393c52297ee 298 }
AjK 0:7393c52297ee 299 }
AjK 0:7393c52297ee 300 if (_commandSpeed < 0) {
AjK 0:7393c52297ee 301 _pulseCounter++;
AjK 0:7393c52297ee 302 if (_pulseWrapPos && _pulseCounter >= _pulseWrapPos) {
AjK 0:7393c52297ee 303 _pulseCounter = _pulseWrapNeg + 1;
AjK 0:7393c52297ee 304 }
AjK 0:7393c52297ee 305 }
AjK 0:7393c52297ee 306 }
AjK 0:7393c52297ee 307 }
AjK 0:7393c52297ee 308 break;
AjK 0:7393c52297ee 309
AjK 0:7393c52297ee 310 case PulseDeassert: // Pulse has just been deasserted on MAT2_x.
AjK 0:7393c52297ee 311 LPC_TIM2->EMR &= ~(NothingOnMatch << _EMCshift); // No further action...
AjK 0:7393c52297ee 312 LPC_TIM2->EMR |= (NothingOnMatch << _EMCshift); // ... just in case.
AjK 0:7393c52297ee 313 _pulseState = PulseIdle; // Set state for next interrupt (profile() may change this).
AjK 0:7393c52297ee 314 _currentMatch = _PMR; // Store the current match value for profile().
AjK 0:7393c52297ee 315 next_step();
AjK 0:7393c52297ee 316 break;
AjK 0:7393c52297ee 317 }
AjK 0:7393c52297ee 318 }
AjK 0:7393c52297ee 319 }
AjK 0:7393c52297ee 320
AjK 0:7393c52297ee 321 // **************************************************
AjK 0:7393c52297ee 322 // * Controller class SimpleStepperController code. *
AjK 0:7393c52297ee 323 // **************************************************
AjK 0:7393c52297ee 324
AjK 0:7393c52297ee 325 SimpleStepperController::SimpleStepperController()
AjK 0:7393c52297ee 326 {
AjK 0:7393c52297ee 327 for (int i = 0; i < 4; i++) _stepper[i] = 0;
AjK 0:7393c52297ee 328
AjK 0:7393c52297ee 329 uint32_t pr = (uint32_t)(SystemCoreClock / 8 / SIMPLESTEPPER_F);
AjK 0:7393c52297ee 330
AjK 0:7393c52297ee 331 LPC_SC->PCONP |= (1UL << 22); // TIM2 On
AjK 0:7393c52297ee 332 LPC_SC->PCLKSEL1 |= (3UL << 12); // CCLK/8 = 12MHz
AjK 0:7393c52297ee 333 LPC_TIM2->PR = pr - 1; // TC clocks at SIMPLESTEPPER_F hz.
AjK 0:7393c52297ee 334 LPC_TIM2->MR0 = 0;
AjK 0:7393c52297ee 335 LPC_TIM2->MR1 = 0;
AjK 0:7393c52297ee 336 LPC_TIM2->MR2 = 0;
AjK 0:7393c52297ee 337 LPC_TIM2->MR3 = 0;
AjK 0:7393c52297ee 338 LPC_TIM2->MCR = 0;
AjK 0:7393c52297ee 339
AjK 0:7393c52297ee 340 // Enable interrupts
AjK 0:7393c52297ee 341 NVIC_EnableIRQ(TIMER2_IRQn);
AjK 0:7393c52297ee 342
AjK 0:7393c52297ee 343 // Start timer operations.
AjK 0:7393c52297ee 344 LPC_TIM2->TCR = 2; // reset
AjK 0:7393c52297ee 345 LPC_TIM2->TCR = 1; // enable
AjK 0:7393c52297ee 346 }
AjK 0:7393c52297ee 347
AjK 0:7393c52297ee 348 SimpleStepperController::~SimpleStepperController()
AjK 0:7393c52297ee 349 {
AjK 0:7393c52297ee 350 NVIC_DisableIRQ(TIMER2_IRQn);
AjK 0:7393c52297ee 351 LPC_SC->PCONP &= ~(1UL << 22); // TIM2 Off.
AjK 0:7393c52297ee 352 }
AjK 0:7393c52297ee 353
AjK 0:7393c52297ee 354 void
AjK 0:7393c52297ee 355 SimpleStepperController::isr(void)
AjK 0:7393c52297ee 356 {
AjK 0:7393c52297ee 357 uint32_t ir = LPC_TIM2->IR & 0xF;
AjK 0:7393c52297ee 358 if (_stepper[0] && ir & 1) _stepper[0]->isr(ir);
AjK 0:7393c52297ee 359 if (_stepper[1] && ir & 2) _stepper[1]->isr(ir);
AjK 0:7393c52297ee 360 if (_stepper[2] && ir & 4) _stepper[2]->isr(ir);
AjK 0:7393c52297ee 361 if (_stepper[3] && ir & 8) _stepper[3]->isr(ir);
AjK 0:7393c52297ee 362 }
AjK 0:7393c52297ee 363
AjK 0:7393c52297ee 364 }; // namespace AjK ends.