Tripple Controller for the TLE5206 H Bridge motor controller

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?

UserRevisionLine numberNew 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.