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

Dependents:   Steppermotor

Committer:
AjK
Date:
Mon May 02 10:02:18 2011 +0000
Revision:
0:7393c52297ee
Child:
4:7b7940df7865

        

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 0:7393c52297ee 60 setPulseSense(1);
AjK 0:7393c52297ee 61 setDirectionSense(1);
AjK 0:7393c52297ee 62
AjK 0:7393c52297ee 63 switch (_pulse) {
AjK 0:7393c52297ee 64 case P0_6: // Mbed p8
AjK 0:7393c52297ee 65 _pulseMAT = MAT2_0;
AjK 0:7393c52297ee 66 _operShift = 4;
AjK 0:7393c52297ee 67 _pMR = 0x40090018; // T2MR0
AjK 0:7393c52297ee 68 _match_shift = 0;
AjK 0:7393c52297ee 69 _EMmask = 1;
AjK 0:7393c52297ee 70 _EMCshift = 4;
AjK 0:7393c52297ee 71 _simpleStepperController->_stepper[0] = this;
AjK 0:7393c52297ee 72 if (_pulseSense) LPC_TIM2->EMR &= ~_EMmask; else LPC_TIM2->EMR |= _EMmask;
AjK 0:7393c52297ee 73 LPC_PINCON->PINSEL0 |= (3UL << 12);
AjK 0:7393c52297ee 74 break;
AjK 0:7393c52297ee 75 case P0_7: // Mbed p7
AjK 0:7393c52297ee 76 _pulseMAT = MAT2_1;
AjK 0:7393c52297ee 77 _operShift = 6;
AjK 0:7393c52297ee 78 _pMR = 0x4009001C; // T2MR1
AjK 0:7393c52297ee 79 _match_shift = 3;
AjK 0:7393c52297ee 80 _EMmask = 2;
AjK 0:7393c52297ee 81 _EMCshift = 6;
AjK 0:7393c52297ee 82 _simpleStepperController->_stepper[1] = this;
AjK 0:7393c52297ee 83 if (_pulseSense) LPC_TIM2->EMR &= ~_EMmask; else LPC_TIM2->EMR |= _EMmask;
AjK 0:7393c52297ee 84 LPC_PINCON->PINSEL0 |= (3UL << 14);
AjK 0:7393c52297ee 85 break;
AjK 0:7393c52297ee 86 case P0_8: // Mbed p6
AjK 0:7393c52297ee 87 _pulseMAT = MAT2_2;
AjK 0:7393c52297ee 88 _operShift = 8;
AjK 0:7393c52297ee 89 _pMR = 0x40090020; // T2MR2
AjK 0:7393c52297ee 90 _match_shift = 6;
AjK 0:7393c52297ee 91 _EMmask = 4;
AjK 0:7393c52297ee 92 _EMCshift = 8;
AjK 0:7393c52297ee 93 _simpleStepperController->_stepper[2] = this;
AjK 0:7393c52297ee 94 if (_pulseSense) LPC_TIM2->EMR &= ~_EMmask; else LPC_TIM2->EMR |= _EMmask;
AjK 0:7393c52297ee 95 LPC_PINCON->PINSEL0 |= (3UL << 16);
AjK 0:7393c52297ee 96 break;
AjK 0:7393c52297ee 97 case P0_9: // Mbed p5
AjK 0:7393c52297ee 98 _pulseMAT = MAT2_3;
AjK 0:7393c52297ee 99 _operShift = 10;
AjK 0:7393c52297ee 100 _pMR = 0x40090024; // T2MR3
AjK 0:7393c52297ee 101 _match_shift = 9;
AjK 0:7393c52297ee 102 _EMmask = 8;
AjK 0:7393c52297ee 103 _EMCshift = 10;
AjK 0:7393c52297ee 104 _simpleStepperController->_stepper[3] = this;
AjK 0:7393c52297ee 105 if (_pulseSense) LPC_TIM2->EMR &= ~_EMmask; else LPC_TIM2->EMR |= _EMmask;
AjK 0:7393c52297ee 106 LPC_PINCON->PINSEL0 |= (3UL << 18);
AjK 0:7393c52297ee 107 break;
AjK 0:7393c52297ee 108 default:
AjK 0:7393c52297ee 109 while(1); /* ToDo, proper error reporting. */
AjK 0:7393c52297ee 110 }
AjK 0:7393c52297ee 111
AjK 0:7393c52297ee 112
AjK 0:7393c52297ee 113 // The default pulse length. 5 * (1/SIMPLESTEPPER_F) = 100us.
AjK 0:7393c52297ee 114 _pulseLen = 5;
AjK 0:7393c52297ee 115
AjK 0:7393c52297ee 116 // Initial state machine conditions.
AjK 0:7393c52297ee 117 _pulseState = PulseIdle;
AjK 0:7393c52297ee 118 _stepperState = Stopped;
AjK 0:7393c52297ee 119 }
AjK 0:7393c52297ee 120
AjK 0:7393c52297ee 121 void
AjK 0:7393c52297ee 122 SimpleStepper::setInterval(int interval, uint32_t raw)
AjK 0:7393c52297ee 123 {
AjK 0:7393c52297ee 124
AjK 0:7393c52297ee 125 if (interval == 0) { setSpeed((int)0); }
AjK 0:7393c52297ee 126 else {
AjK 0:7393c52297ee 127 int n = interval;
AjK 0:7393c52297ee 128 if (n < 0) n *= -1;
AjK 0:7393c52297ee 129 if (_direction) {
AjK 0:7393c52297ee 130 if (_directionSense) {
AjK 0:7393c52297ee 131 if (interval >= 0.0) _direction->write(1);
AjK 0:7393c52297ee 132 if (interval < 0.0) _direction->write(0);
AjK 0:7393c52297ee 133 }
AjK 0:7393c52297ee 134 else {
AjK 0:7393c52297ee 135 if (interval >= 0.0) _direction->write(0);
AjK 0:7393c52297ee 136 if (interval < 0.0) _direction->write(1);
AjK 0:7393c52297ee 137 }
AjK 0:7393c52297ee 138 }
AjK 0:7393c52297ee 139 _commandSpeed = n - _pulseLen;
AjK 0:7393c52297ee 140 _pulseState = PulseAssert;
AjK 0:7393c52297ee 141 _stepperState = ConstantSpeed;
AjK 0:7393c52297ee 142 if (raw) {
AjK 0:7393c52297ee 143 _PMR = raw + _commandSpeed;
AjK 0:7393c52297ee 144 }
AjK 0:7393c52297ee 145 else {
AjK 0:7393c52297ee 146 _PMR = LPC_TIM2->TC + _commandSpeed;
AjK 0:7393c52297ee 147 }
AjK 0:7393c52297ee 148 if (_pulseSense) LPC_TIM2->EMR &= ~_EMmask; else LPC_TIM2->EMR |= _EMmask;
AjK 0:7393c52297ee 149 LPC_TIM2->MCR &= ~(7UL << _match_shift);
AjK 0:7393c52297ee 150 LPC_TIM2->MCR |= (1UL << _match_shift);
AjK 0:7393c52297ee 151 }
AjK 0:7393c52297ee 152 }
AjK 0:7393c52297ee 153
AjK 0:7393c52297ee 154 void
AjK 0:7393c52297ee 155 SimpleStepper::setSpeed(double steps_per_second, uint32_t raw)
AjK 0:7393c52297ee 156 {
AjK 0:7393c52297ee 157 int i = 0;
AjK 0:7393c52297ee 158
AjK 0:7393c52297ee 159 if (steps_per_second == 0.0) { setSpeed(i); }
AjK 0:7393c52297ee 160 else {
AjK 0:7393c52297ee 161 double fractpart, intpart;
AjK 0:7393c52297ee 162 fractpart = modf (steps_per_second , &intpart);
AjK 0:7393c52297ee 163 if (fractpart >= 0.50) intpart++;
AjK 0:7393c52297ee 164 double n = intpart;
AjK 0:7393c52297ee 165 if (n < 0.0) n *= -1.0;
AjK 0:7393c52297ee 166 if (_direction) {
AjK 0:7393c52297ee 167 if (_directionSense) {
AjK 0:7393c52297ee 168 if (steps_per_second >= 0.0) _direction->write(1);
AjK 0:7393c52297ee 169 if (steps_per_second < 0.0) _direction->write(0);
AjK 0:7393c52297ee 170 }
AjK 0:7393c52297ee 171 else {
AjK 0:7393c52297ee 172 if (steps_per_second >= 0.0) _direction->write(0);
AjK 0:7393c52297ee 173 if (steps_per_second < 0.0) _direction->write(1);
AjK 0:7393c52297ee 174 }
AjK 0:7393c52297ee 175 }
AjK 0:7393c52297ee 176 _commandSpeed = (int)(((double)SIMPLESTEPPER_F / n)) - _pulseLen;
AjK 0:7393c52297ee 177 _pulseState = PulseAssert;
AjK 0:7393c52297ee 178 _stepperState = ConstantSpeed;
AjK 0:7393c52297ee 179 if (raw) {
AjK 0:7393c52297ee 180 _PMR = raw + _commandSpeed;
AjK 0:7393c52297ee 181 }
AjK 0:7393c52297ee 182 else {
AjK 0:7393c52297ee 183 _PMR = LPC_TIM2->TC + _commandSpeed;
AjK 0:7393c52297ee 184 }
AjK 0:7393c52297ee 185 if (_pulseSense) LPC_TIM2->EMR &= ~_EMmask; else LPC_TIM2->EMR |= _EMmask;
AjK 0:7393c52297ee 186 LPC_TIM2->MCR &= ~(7UL << _match_shift);
AjK 0:7393c52297ee 187 LPC_TIM2->MCR |= (1UL << _match_shift);
AjK 0:7393c52297ee 188 }
AjK 0:7393c52297ee 189 }
AjK 0:7393c52297ee 190
AjK 0:7393c52297ee 191 void
AjK 0:7393c52297ee 192 SimpleStepper::setSpeed(int steps_per_second, uint32_t raw)
AjK 0:7393c52297ee 193 {
AjK 0:7393c52297ee 194 if (steps_per_second == 0) {
AjK 0:7393c52297ee 195 LPC_TIM2->EMR |= (NothingOnMatch << _EMCshift);
AjK 0:7393c52297ee 196 LPC_TIM2->MCR &= ~(7UL << _match_shift);
AjK 0:7393c52297ee 197 if (_pulseSense) LPC_TIM2->EMR &= ~_EMmask; else LPC_TIM2->EMR |= _EMmask;
AjK 0:7393c52297ee 198 _stepperState = Stopped;
AjK 0:7393c52297ee 199 _pulseState = PulseIdle;
AjK 0:7393c52297ee 200 _commandSpeed = 0;
AjK 0:7393c52297ee 201 }
AjK 0:7393c52297ee 202 else {
AjK 0:7393c52297ee 203 int n = steps_per_second;
AjK 0:7393c52297ee 204 if (n < 0) n *= -1;
AjK 0:7393c52297ee 205 if (_direction) {
AjK 0:7393c52297ee 206 if (_directionSense) {
AjK 0:7393c52297ee 207 if (steps_per_second >= 0) _direction->write(1);
AjK 0:7393c52297ee 208 if (steps_per_second < 0) _direction->write(0);
AjK 0:7393c52297ee 209 }
AjK 0:7393c52297ee 210 else {
AjK 0:7393c52297ee 211 if (steps_per_second >= 0) _direction->write(0);
AjK 0:7393c52297ee 212 if (steps_per_second < 0) _direction->write(1);
AjK 0:7393c52297ee 213 }
AjK 0:7393c52297ee 214 }
AjK 0:7393c52297ee 215 _commandSpeed = (SIMPLESTEPPER_F / n) - _pulseLen;
AjK 0:7393c52297ee 216 _pulseState = PulseAssert;
AjK 0:7393c52297ee 217 _stepperState = ConstantSpeed;
AjK 0:7393c52297ee 218 if (raw) {
AjK 0:7393c52297ee 219 _PMR = raw + _commandSpeed;
AjK 0:7393c52297ee 220 }
AjK 0:7393c52297ee 221 else {
AjK 0:7393c52297ee 222 _PMR = LPC_TIM2->TC + _commandSpeed;
AjK 0:7393c52297ee 223 }
AjK 0:7393c52297ee 224 if (_pulseSense) LPC_TIM2->EMR &= ~_EMmask; else LPC_TIM2->EMR |= _EMmask;
AjK 0:7393c52297ee 225 LPC_TIM2->MCR &= ~(7UL << _match_shift);
AjK 0:7393c52297ee 226 LPC_TIM2->MCR |= (1UL << _match_shift);
AjK 0:7393c52297ee 227 }
AjK 0:7393c52297ee 228 }
AjK 0:7393c52297ee 229
AjK 0:7393c52297ee 230 void
AjK 0:7393c52297ee 231 SimpleStepper::next_step(void)
AjK 0:7393c52297ee 232 {
AjK 0:7393c52297ee 233 _PMR += _commandSpeed;
AjK 0:7393c52297ee 234
AjK 0:7393c52297ee 235 switch(_pulseSense) {
AjK 0:7393c52297ee 236 case 1:
AjK 0:7393c52297ee 237 LPC_TIM2->EMR &= ~(3UL << _EMCshift);
AjK 0:7393c52297ee 238 LPC_TIM2->EMR |= (SetOnMatch << _EMCshift);
AjK 0:7393c52297ee 239 break;
AjK 0:7393c52297ee 240 case 0:
AjK 0:7393c52297ee 241 LPC_TIM2->EMR &= ~(3UL << _EMCshift);
AjK 0:7393c52297ee 242 LPC_TIM2->EMR |= (ClrOnMatch << _EMCshift);
AjK 0:7393c52297ee 243 break;
AjK 0:7393c52297ee 244 }
AjK 0:7393c52297ee 245
AjK 0:7393c52297ee 246 // Next IRQ will automatically assert the pulse.
AjK 0:7393c52297ee 247 _pulseState = PulseAssert;
AjK 0:7393c52297ee 248 }
AjK 0:7393c52297ee 249
AjK 0:7393c52297ee 250 void
AjK 0:7393c52297ee 251 SimpleStepper::isr(uint32_t ir)
AjK 0:7393c52297ee 252 {
AjK 0:7393c52297ee 253 // Test to see if this interrupt is for us.
AjK 0:7393c52297ee 254 if (ir & _EMmask) {
AjK 0:7393c52297ee 255
AjK 0:7393c52297ee 256 if (_stepperState == Stopped) {
AjK 0:7393c52297ee 257 if (_pulseSense) LPC_TIM2->EMR &= ~_EMmask; else LPC_TIM2->EMR |= _EMmask;
AjK 0:7393c52297ee 258 return;
AjK 0:7393c52297ee 259 }
AjK 0:7393c52297ee 260
AjK 0:7393c52297ee 261 switch(_pulseState) {
AjK 0:7393c52297ee 262 case PulseIdle:
AjK 0:7393c52297ee 263 if (_pulseSense) LPC_TIM2->EMR &= ~_EMmask; else LPC_TIM2->EMR |= _EMmask;
AjK 0:7393c52297ee 264 _currentMatch = _PMR; // Store the current match value for profile().
AjK 0:7393c52297ee 265 next_step();
AjK 0:7393c52297ee 266 break;
AjK 0:7393c52297ee 267
AjK 0:7393c52297ee 268 case PulseAssert: // Pulse has just been asserted on MAT2_x.
AjK 0:7393c52297ee 269 _PMR += _pulseLen; // We now program for the deassert IRQ to occur at the required time.
AjK 0:7393c52297ee 270 LPC_TIM2->EMR &= ~(ToggleOnMatch << _EMCshift); // At next IRQ we want to switch the pulse off...
AjK 0:7393c52297ee 271 LPC_TIM2->EMR |= (ToggleOnMatch << _EMCshift); // ... we do this by toggling it.
AjK 0:7393c52297ee 272 _pulseState = PulseDeassert; // Set state for next interrupt.
AjK 0:7393c52297ee 273
AjK 0:7393c52297ee 274 if (_maintainPositionData) {
AjK 0:7393c52297ee 275 if (_directionSense) {
AjK 0:7393c52297ee 276 if (_commandSpeed > 0) {
AjK 0:7393c52297ee 277 _pulseCounter++;
AjK 0:7393c52297ee 278 if (_pulseWrapPos && _pulseCounter >= _pulseWrapPos) {
AjK 0:7393c52297ee 279 _pulseCounter = _pulseWrapNeg + 1;
AjK 0:7393c52297ee 280 }
AjK 0:7393c52297ee 281 }
AjK 0:7393c52297ee 282 if (_commandSpeed < 0) {
AjK 0:7393c52297ee 283 _pulseCounter--;
AjK 0:7393c52297ee 284 if (_pulseWrapNeg && _pulseCounter <= _pulseWrapNeg) {
AjK 0:7393c52297ee 285 _pulseCounter = _pulseWrapPos - 1;
AjK 0:7393c52297ee 286 }
AjK 0:7393c52297ee 287 }
AjK 0:7393c52297ee 288 }
AjK 0:7393c52297ee 289 else {
AjK 0:7393c52297ee 290 if (_commandSpeed > 0) {
AjK 0:7393c52297ee 291 _pulseCounter--;
AjK 0:7393c52297ee 292 if (_pulseWrapNeg && _pulseCounter <= _pulseWrapNeg) {
AjK 0:7393c52297ee 293 _pulseCounter = _pulseWrapPos - 1;
AjK 0:7393c52297ee 294 }
AjK 0:7393c52297ee 295 }
AjK 0:7393c52297ee 296 if (_commandSpeed < 0) {
AjK 0:7393c52297ee 297 _pulseCounter++;
AjK 0:7393c52297ee 298 if (_pulseWrapPos && _pulseCounter >= _pulseWrapPos) {
AjK 0:7393c52297ee 299 _pulseCounter = _pulseWrapNeg + 1;
AjK 0:7393c52297ee 300 }
AjK 0:7393c52297ee 301 }
AjK 0:7393c52297ee 302 }
AjK 0:7393c52297ee 303 }
AjK 0:7393c52297ee 304 break;
AjK 0:7393c52297ee 305
AjK 0:7393c52297ee 306 case PulseDeassert: // Pulse has just been deasserted on MAT2_x.
AjK 0:7393c52297ee 307 LPC_TIM2->EMR &= ~(NothingOnMatch << _EMCshift); // No further action...
AjK 0:7393c52297ee 308 LPC_TIM2->EMR |= (NothingOnMatch << _EMCshift); // ... just in case.
AjK 0:7393c52297ee 309 _pulseState = PulseIdle; // Set state for next interrupt (profile() may change this).
AjK 0:7393c52297ee 310 _currentMatch = _PMR; // Store the current match value for profile().
AjK 0:7393c52297ee 311 next_step();
AjK 0:7393c52297ee 312 break;
AjK 0:7393c52297ee 313 }
AjK 0:7393c52297ee 314 }
AjK 0:7393c52297ee 315 }
AjK 0:7393c52297ee 316
AjK 0:7393c52297ee 317 // **************************************************
AjK 0:7393c52297ee 318 // * Controller class SimpleStepperController code. *
AjK 0:7393c52297ee 319 // **************************************************
AjK 0:7393c52297ee 320
AjK 0:7393c52297ee 321 SimpleStepperController::SimpleStepperController()
AjK 0:7393c52297ee 322 {
AjK 0:7393c52297ee 323 for (int i = 0; i < 4; i++) _stepper[i] = 0;
AjK 0:7393c52297ee 324
AjK 0:7393c52297ee 325 uint32_t pr = (uint32_t)(SystemCoreClock / 8 / SIMPLESTEPPER_F);
AjK 0:7393c52297ee 326
AjK 0:7393c52297ee 327 LPC_SC->PCONP |= (1UL << 22); // TIM2 On
AjK 0:7393c52297ee 328 LPC_SC->PCLKSEL1 |= (3UL << 12); // CCLK/8 = 12MHz
AjK 0:7393c52297ee 329 LPC_TIM2->PR = pr - 1; // TC clocks at SIMPLESTEPPER_F hz.
AjK 0:7393c52297ee 330 LPC_TIM2->MR0 = 0;
AjK 0:7393c52297ee 331 LPC_TIM2->MR1 = 0;
AjK 0:7393c52297ee 332 LPC_TIM2->MR2 = 0;
AjK 0:7393c52297ee 333 LPC_TIM2->MR3 = 0;
AjK 0:7393c52297ee 334 LPC_TIM2->MCR = 0;
AjK 0:7393c52297ee 335
AjK 0:7393c52297ee 336 // Enable interrupts
AjK 0:7393c52297ee 337 NVIC_EnableIRQ(TIMER2_IRQn);
AjK 0:7393c52297ee 338
AjK 0:7393c52297ee 339 // Start timer operations.
AjK 0:7393c52297ee 340 LPC_TIM2->TCR = 2; // reset
AjK 0:7393c52297ee 341 LPC_TIM2->TCR = 1; // enable
AjK 0:7393c52297ee 342 }
AjK 0:7393c52297ee 343
AjK 0:7393c52297ee 344 SimpleStepperController::~SimpleStepperController()
AjK 0:7393c52297ee 345 {
AjK 0:7393c52297ee 346 NVIC_DisableIRQ(TIMER2_IRQn);
AjK 0:7393c52297ee 347 LPC_SC->PCONP &= ~(1UL << 22); // TIM2 Off.
AjK 0:7393c52297ee 348 }
AjK 0:7393c52297ee 349
AjK 0:7393c52297ee 350 void
AjK 0:7393c52297ee 351 SimpleStepperController::isr(void)
AjK 0:7393c52297ee 352 {
AjK 0:7393c52297ee 353 uint32_t ir = LPC_TIM2->IR & 0xF;
AjK 0:7393c52297ee 354 if (_stepper[0] && ir & 1) _stepper[0]->isr(ir);
AjK 0:7393c52297ee 355 if (_stepper[1] && ir & 2) _stepper[1]->isr(ir);
AjK 0:7393c52297ee 356 if (_stepper[2] && ir & 4) _stepper[2]->isr(ir);
AjK 0:7393c52297ee 357 if (_stepper[3] && ir & 8) _stepper[3]->isr(ir);
AjK 0:7393c52297ee 358 }
AjK 0:7393c52297ee 359
AjK 0:7393c52297ee 360 }; // namespace AjK ends.