Provides an API software interface to TIMER2 to control upto four stepper motors.
src/SimpleSteppers.cpp@4:7b7940df7865, 2011-05-20 (annotated)
- 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?
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 | 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. |