Tripple Controller for the TLE5206 H Bridge motor controller

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers SimpleTLE5206.cpp Source File

SimpleTLE5206.cpp

00001 /*
00002     Copyright (c) 2011 Andy Kirkham
00003  
00004     Permission is hereby granted, free of charge, to any person obtaining a copy
00005     of this software and associated documentation files (the "Software"), to deal
00006     in the Software without restriction, including without limitation the rights
00007     to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
00008     copies of the Software, and to permit persons to whom the Software is
00009     furnished to do so, subject to the following conditions:
00010  
00011     The above copyright notice and this permission notice shall be included in
00012     all copies or substantial portions of the Software.
00013  
00014     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
00015     IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
00016     FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
00017     AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
00018     LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
00019     OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
00020     THE SOFTWARE.
00021 */
00022 
00023 
00024 #include "mbed.h"
00025 #include "SimpleTLE5206.h"
00026 
00027 namespace AjK {
00028 
00029 SimpleTLE5206::SimpleTLE5206(SimpleTLE5206Output *in1, SimpleTLE5206Output *in2)
00030 {
00031     _in1 = in1;
00032     _in2 = in2;
00033     init(0);
00034 }
00035 
00036 SimpleTLE5206::SimpleTLE5206(SimpleTLE5206Output *in1, SimpleTLE5206Output *in2, int duty_cycle_hz)
00037 {
00038     _in1 = in1;
00039     _in2 = in2;
00040     if (duty_cycle_hz == 0) error("Division by zero!\n");
00041     init((uint32_t)(12000000UL / duty_cycle_hz * 2));
00042 }
00043 
00044 void
00045 SimpleTLE5206::init(uint32_t duty)
00046 {
00047     _in1->as_pwm();
00048     _in2->as_pwm();
00049     if (duty != 0) setDuty(duty);
00050     setSpeed(0.0);
00051 }
00052 
00053 void
00054 SimpleTLE5206::setDuty(uint32_t duty)
00055 {
00056 
00057     _duty = duty;
00058     
00059     // Skip the setup if the duty has already been set
00060     // by a previous instance of controller.
00061     if (LPC_PWM1->MR0 == duty) {
00062         return;
00063     }
00064     
00065     // Ensure powered up (default is 1)  
00066     LPC_SC->PCONP |= (1UL << 6);  
00067         
00068     // CCLK/4 = 24MHz
00069     LPC_SC->PCLKSEL0 &= ~(3UL << 12);
00070     
00071     // Reset.
00072     LPC_PWM1->TCR   = 2; 
00073     
00074     LPC_PWM1->PR    = 0;
00075     LPC_PWM1->MR0   = _duty;
00076     LPC_PWM1->MR1   = 0;
00077     LPC_PWM1->MR2   = 0;
00078     LPC_PWM1->MR3   = 0;
00079     LPC_PWM1->MR4   = 0;
00080     LPC_PWM1->MR5   = 0;
00081     LPC_PWM1->MR6   = 0;
00082         
00083     LPC_PWM1->MCR   = 2; // MR0 resets TC.        
00084     LPC_PWM1->TCR   = 9; // Enable.        
00085 }
00086 
00087 void
00088 SimpleTLE5206::setSpeed(double speed)
00089 {
00090     uint32_t value1, value2;
00091 
00092     // Ensure we cap the speed to +/-1.0
00093     if (speed > +1.0) speed = +1.0;
00094     if (speed < -1.0) speed = -1.0;
00095 
00096     value1 = _duty + 1; // Output always on.
00097     value2 = _duty + 1; // Output always on.
00098         
00099     if (speed != 0.0) {
00100         if (speed > 0.0) {
00101             value2 = (uint32_t)(speed * _duty);       // Scale for requested speed.
00102             if (value2 >= _duty) value2 = _duty - 1;  // Don't allow the value to overrun the duty.
00103             value2 = _duty - value2;                  // Invert logic sense.
00104         }
00105         
00106         if (speed < 0.0) {
00107             speed *= -1; // invert sign.              
00108             value1 = (uint32_t)(speed * _duty);       // Scale for requested speed.
00109             if (value1 >= _duty) value1 = _duty - 1;  // Don't allow the value to overrun the duty.
00110             value1 = _duty - value1;                  // Invert logic sense.
00111         }
00112     }
00113     
00114     switch(_in1->getPin()) {
00115         case p21:            setMRx(Pwm6, value1); break;
00116         case p22:            setMRx(Pwm5, value1); break;
00117         case p23: case LED4: setMRx(Pwm4, value1); break;
00118         case p24: case LED3: setMRx(Pwm3, value1); break;
00119         case p25: case LED2: setMRx(Pwm2, value1); break;
00120         case p26: case LED1: setMRx(Pwm1, value1); break;                          
00121     }
00122         
00123     switch(_in2->getPin()) {
00124         case p21:            setMRx(Pwm6, value2); break;
00125         case p22:            setMRx(Pwm5, value2); break;
00126         case p23: case LED4: setMRx(Pwm4, value2); break;
00127         case p24: case LED3: setMRx(Pwm3, value2); break;
00128         case p25: case LED2: setMRx(Pwm2, value2); break;
00129         case p26: case LED1: setMRx(Pwm1, value2); break;                          
00130     }
00131 }
00132 
00133 void 
00134 SimpleTLE5206::setMRx(PwmCh ch, uint32_t value) 
00135 {
00136     switch(ch) {
00137         case Pwm1: LPC_PWM1->MR1 = value; break;
00138         case Pwm2: LPC_PWM1->MR2 = value; break;
00139         case Pwm3: LPC_PWM1->MR3 = value; break;
00140         case Pwm4: LPC_PWM1->MR4 = value; break;
00141         case Pwm5: LPC_PWM1->MR5 = value; break;
00142         case Pwm6: LPC_PWM1->MR6 = value; break;        
00143     }
00144     LPC_PWM1->LER |= (1UL << ch);
00145 }
00146 
00147 }; // namespace AjK ends.