Tripple Controller for the TLE5206 H Bridge motor controller
src/SimpleTLE5206.cpp@5:bfc5c5cc161e, 2011-07-05 (annotated)
- Committer:
- AjK
- Date:
- Tue Jul 05 16:08:38 2011 +0000
- Revision:
- 5:bfc5c5cc161e
- Parent:
- 2:c5fbe0cb8a97
0.7 Beta See ChangeLog.h
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
AjK | 0:e2433ca2ce59 | 1 | /* |
AjK | 0:e2433ca2ce59 | 2 | Copyright (c) 2011 Andy Kirkham |
AjK | 0:e2433ca2ce59 | 3 | |
AjK | 0:e2433ca2ce59 | 4 | Permission is hereby granted, free of charge, to any person obtaining a copy |
AjK | 0:e2433ca2ce59 | 5 | of this software and associated documentation files (the "Software"), to deal |
AjK | 0:e2433ca2ce59 | 6 | in the Software without restriction, including without limitation the rights |
AjK | 0:e2433ca2ce59 | 7 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
AjK | 0:e2433ca2ce59 | 8 | copies of the Software, and to permit persons to whom the Software is |
AjK | 0:e2433ca2ce59 | 9 | furnished to do so, subject to the following conditions: |
AjK | 0:e2433ca2ce59 | 10 | |
AjK | 0:e2433ca2ce59 | 11 | The above copyright notice and this permission notice shall be included in |
AjK | 0:e2433ca2ce59 | 12 | all copies or substantial portions of the Software. |
AjK | 0:e2433ca2ce59 | 13 | |
AjK | 0:e2433ca2ce59 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
AjK | 0:e2433ca2ce59 | 15 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
AjK | 0:e2433ca2ce59 | 16 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
AjK | 0:e2433ca2ce59 | 17 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
AjK | 0:e2433ca2ce59 | 18 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
AjK | 0:e2433ca2ce59 | 19 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN |
AjK | 0:e2433ca2ce59 | 20 | THE SOFTWARE. |
AjK | 0:e2433ca2ce59 | 21 | */ |
AjK | 0:e2433ca2ce59 | 22 | |
AjK | 0:e2433ca2ce59 | 23 | |
AjK | 0:e2433ca2ce59 | 24 | #include "mbed.h" |
AjK | 0:e2433ca2ce59 | 25 | #include "SimpleTLE5206.h" |
AjK | 0:e2433ca2ce59 | 26 | |
AjK | 0:e2433ca2ce59 | 27 | namespace AjK { |
AjK | 0:e2433ca2ce59 | 28 | |
AjK | 0:e2433ca2ce59 | 29 | SimpleTLE5206::SimpleTLE5206(SimpleTLE5206Output *in1, SimpleTLE5206Output *in2) |
AjK | 0:e2433ca2ce59 | 30 | { |
AjK | 0:e2433ca2ce59 | 31 | _in1 = in1; |
AjK | 0:e2433ca2ce59 | 32 | _in2 = in2; |
AjK | 2:c5fbe0cb8a97 | 33 | init(0); |
AjK | 2:c5fbe0cb8a97 | 34 | } |
AjK | 2:c5fbe0cb8a97 | 35 | |
AjK | 2:c5fbe0cb8a97 | 36 | SimpleTLE5206::SimpleTLE5206(SimpleTLE5206Output *in1, SimpleTLE5206Output *in2, int duty_cycle_hz) |
AjK | 2:c5fbe0cb8a97 | 37 | { |
AjK | 2:c5fbe0cb8a97 | 38 | _in1 = in1; |
AjK | 2:c5fbe0cb8a97 | 39 | _in2 = in2; |
AjK | 5:bfc5c5cc161e | 40 | if (duty_cycle_hz == 0) error("Division by zero!\n"); |
AjK | 2:c5fbe0cb8a97 | 41 | init((uint32_t)(12000000UL / duty_cycle_hz * 2)); |
AjK | 0:e2433ca2ce59 | 42 | } |
AjK | 0:e2433ca2ce59 | 43 | |
AjK | 0:e2433ca2ce59 | 44 | void |
AjK | 2:c5fbe0cb8a97 | 45 | SimpleTLE5206::init(uint32_t duty) |
AjK | 0:e2433ca2ce59 | 46 | { |
AjK | 5:bfc5c5cc161e | 47 | _in1->as_pwm(); |
AjK | 5:bfc5c5cc161e | 48 | _in2->as_pwm(); |
AjK | 2:c5fbe0cb8a97 | 49 | if (duty != 0) setDuty(duty); |
AjK | 0:e2433ca2ce59 | 50 | setSpeed(0.0); |
AjK | 0:e2433ca2ce59 | 51 | } |
AjK | 0:e2433ca2ce59 | 52 | |
AjK | 0:e2433ca2ce59 | 53 | void |
AjK | 0:e2433ca2ce59 | 54 | SimpleTLE5206::setDuty(uint32_t duty) |
AjK | 0:e2433ca2ce59 | 55 | { |
AjK | 2:c5fbe0cb8a97 | 56 | |
AjK | 2:c5fbe0cb8a97 | 57 | _duty = duty; |
AjK | 2:c5fbe0cb8a97 | 58 | |
AjK | 5:bfc5c5cc161e | 59 | // Skip the setup if the duty has already been set |
AjK | 2:c5fbe0cb8a97 | 60 | // by a previous instance of controller. |
AjK | 2:c5fbe0cb8a97 | 61 | if (LPC_PWM1->MR0 == duty) { |
AjK | 2:c5fbe0cb8a97 | 62 | return; |
AjK | 2:c5fbe0cb8a97 | 63 | } |
AjK | 2:c5fbe0cb8a97 | 64 | |
AjK | 0:e2433ca2ce59 | 65 | // Ensure powered up (default is 1) |
AjK | 0:e2433ca2ce59 | 66 | LPC_SC->PCONP |= (1UL << 6); |
AjK | 0:e2433ca2ce59 | 67 | |
AjK | 0:e2433ca2ce59 | 68 | // CCLK/4 = 24MHz |
AjK | 0:e2433ca2ce59 | 69 | LPC_SC->PCLKSEL0 &= ~(3UL << 12); |
AjK | 0:e2433ca2ce59 | 70 | |
AjK | 0:e2433ca2ce59 | 71 | // Reset. |
AjK | 0:e2433ca2ce59 | 72 | LPC_PWM1->TCR = 2; |
AjK | 0:e2433ca2ce59 | 73 | |
AjK | 0:e2433ca2ce59 | 74 | LPC_PWM1->PR = 0; |
AjK | 0:e2433ca2ce59 | 75 | LPC_PWM1->MR0 = _duty; |
AjK | 0:e2433ca2ce59 | 76 | LPC_PWM1->MR1 = 0; |
AjK | 0:e2433ca2ce59 | 77 | LPC_PWM1->MR2 = 0; |
AjK | 0:e2433ca2ce59 | 78 | LPC_PWM1->MR3 = 0; |
AjK | 0:e2433ca2ce59 | 79 | LPC_PWM1->MR4 = 0; |
AjK | 0:e2433ca2ce59 | 80 | LPC_PWM1->MR5 = 0; |
AjK | 0:e2433ca2ce59 | 81 | LPC_PWM1->MR6 = 0; |
AjK | 0:e2433ca2ce59 | 82 | |
AjK | 5:bfc5c5cc161e | 83 | LPC_PWM1->MCR = 2; // MR0 resets TC. |
AjK | 0:e2433ca2ce59 | 84 | LPC_PWM1->TCR = 9; // Enable. |
AjK | 0:e2433ca2ce59 | 85 | } |
AjK | 0:e2433ca2ce59 | 86 | |
AjK | 0:e2433ca2ce59 | 87 | void |
AjK | 0:e2433ca2ce59 | 88 | SimpleTLE5206::setSpeed(double speed) |
AjK | 0:e2433ca2ce59 | 89 | { |
AjK | 5:bfc5c5cc161e | 90 | uint32_t value1, value2; |
AjK | 0:e2433ca2ce59 | 91 | |
AjK | 0:e2433ca2ce59 | 92 | // Ensure we cap the speed to +/-1.0 |
AjK | 0:e2433ca2ce59 | 93 | if (speed > +1.0) speed = +1.0; |
AjK | 0:e2433ca2ce59 | 94 | if (speed < -1.0) speed = -1.0; |
AjK | 5:bfc5c5cc161e | 95 | |
AjK | 5:bfc5c5cc161e | 96 | value1 = _duty + 1; // Output always on. |
AjK | 5:bfc5c5cc161e | 97 | value2 = _duty + 1; // Output always on. |
AjK | 0:e2433ca2ce59 | 98 | |
AjK | 5:bfc5c5cc161e | 99 | if (speed != 0.0) { |
AjK | 0:e2433ca2ce59 | 100 | if (speed > 0.0) { |
AjK | 5:bfc5c5cc161e | 101 | value2 = (uint32_t)(speed * _duty); // Scale for requested speed. |
AjK | 5:bfc5c5cc161e | 102 | if (value2 >= _duty) value2 = _duty - 1; // Don't allow the value to overrun the duty. |
AjK | 5:bfc5c5cc161e | 103 | value2 = _duty - value2; // Invert logic sense. |
AjK | 0:e2433ca2ce59 | 104 | } |
AjK | 0:e2433ca2ce59 | 105 | |
AjK | 0:e2433ca2ce59 | 106 | if (speed < 0.0) { |
AjK | 0:e2433ca2ce59 | 107 | speed *= -1; // invert sign. |
AjK | 5:bfc5c5cc161e | 108 | value1 = (uint32_t)(speed * _duty); // Scale for requested speed. |
AjK | 5:bfc5c5cc161e | 109 | if (value1 >= _duty) value1 = _duty - 1; // Don't allow the value to overrun the duty. |
AjK | 5:bfc5c5cc161e | 110 | value1 = _duty - value1; // Invert logic sense. |
AjK | 0:e2433ca2ce59 | 111 | } |
AjK | 5:bfc5c5cc161e | 112 | } |
AjK | 0:e2433ca2ce59 | 113 | |
AjK | 5:bfc5c5cc161e | 114 | switch(_in1->getPin()) { |
AjK | 5:bfc5c5cc161e | 115 | case p21: setMRx(Pwm6, value1); break; |
AjK | 5:bfc5c5cc161e | 116 | case p22: setMRx(Pwm5, value1); break; |
AjK | 5:bfc5c5cc161e | 117 | case p23: case LED4: setMRx(Pwm4, value1); break; |
AjK | 5:bfc5c5cc161e | 118 | case p24: case LED3: setMRx(Pwm3, value1); break; |
AjK | 5:bfc5c5cc161e | 119 | case p25: case LED2: setMRx(Pwm2, value1); break; |
AjK | 5:bfc5c5cc161e | 120 | case p26: case LED1: setMRx(Pwm1, value1); break; |
AjK | 5:bfc5c5cc161e | 121 | } |
AjK | 0:e2433ca2ce59 | 122 | |
AjK | 5:bfc5c5cc161e | 123 | switch(_in2->getPin()) { |
AjK | 5:bfc5c5cc161e | 124 | case p21: setMRx(Pwm6, value2); break; |
AjK | 5:bfc5c5cc161e | 125 | case p22: setMRx(Pwm5, value2); break; |
AjK | 5:bfc5c5cc161e | 126 | case p23: case LED4: setMRx(Pwm4, value2); break; |
AjK | 5:bfc5c5cc161e | 127 | case p24: case LED3: setMRx(Pwm3, value2); break; |
AjK | 5:bfc5c5cc161e | 128 | case p25: case LED2: setMRx(Pwm2, value2); break; |
AjK | 5:bfc5c5cc161e | 129 | case p26: case LED1: setMRx(Pwm1, value2); break; |
AjK | 0:e2433ca2ce59 | 130 | } |
AjK | 0:e2433ca2ce59 | 131 | } |
AjK | 0:e2433ca2ce59 | 132 | |
AjK | 0:e2433ca2ce59 | 133 | void |
AjK | 0:e2433ca2ce59 | 134 | SimpleTLE5206::setMRx(PwmCh ch, uint32_t value) |
AjK | 0:e2433ca2ce59 | 135 | { |
AjK | 0:e2433ca2ce59 | 136 | switch(ch) { |
AjK | 0:e2433ca2ce59 | 137 | case Pwm1: LPC_PWM1->MR1 = value; break; |
AjK | 0:e2433ca2ce59 | 138 | case Pwm2: LPC_PWM1->MR2 = value; break; |
AjK | 0:e2433ca2ce59 | 139 | case Pwm3: LPC_PWM1->MR3 = value; break; |
AjK | 0:e2433ca2ce59 | 140 | case Pwm4: LPC_PWM1->MR4 = value; break; |
AjK | 0:e2433ca2ce59 | 141 | case Pwm5: LPC_PWM1->MR5 = value; break; |
AjK | 0:e2433ca2ce59 | 142 | case Pwm6: LPC_PWM1->MR6 = value; break; |
AjK | 0:e2433ca2ce59 | 143 | } |
AjK | 0:e2433ca2ce59 | 144 | LPC_PWM1->LER |= (1UL << ch); |
AjK | 0:e2433ca2ce59 | 145 | } |
AjK | 0:e2433ca2ce59 | 146 | |
AjK | 0:e2433ca2ce59 | 147 | }; // namespace AjK ends. |