Provides an API software interface to TIMER2 to control upto four stepper motors.
src/SimpleSteppers.cpp@0:7393c52297ee, 2011-05-02 (annotated)
- Committer:
- AjK
- Date:
- Mon May 02 10:02:18 2011 +0000
- Revision:
- 0:7393c52297ee
- Child:
- 4:7b7940df7865
Who changed what in which revision?
User | Revision | Line number | New 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. |