Tripple Controller for the TLE5206 H Bridge motor controller

Revision:
0:e2433ca2ce59
Child:
2:c5fbe0cb8a97
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/SimpleTLE5206.cpp	Tue Jul 05 07:43:28 2011 +0000
@@ -0,0 +1,139 @@
+/*
+    Copyright (c) 2011 Andy Kirkham
+ 
+    Permission is hereby granted, free of charge, to any person obtaining a copy
+    of this software and associated documentation files (the "Software"), to deal
+    in the Software without restriction, including without limitation the rights
+    to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+    copies of the Software, and to permit persons to whom the Software is
+    furnished to do so, subject to the following conditions:
+ 
+    The above copyright notice and this permission notice shall be included in
+    all copies or substantial portions of the Software.
+ 
+    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+    IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+    FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+    AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+    LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+    OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+    THE SOFTWARE.
+*/
+
+
+#include "mbed.h"
+#include "SimpleTLE5206.h"
+
+namespace AjK {
+
+SimpleTLE5206::SimpleTLE5206(SimpleTLE5206Output *in1, SimpleTLE5206Output *in2)
+{
+    // Start initially as GPIO and both on (no drive, no speed).
+    _in1 = in1;
+    _in2 = in2;
+    init();
+}
+
+void
+SimpleTLE5206::init()
+{
+    setDuty(240000UL);
+    setSpeed(0.0);
+}
+
+void
+SimpleTLE5206::setDuty(uint32_t duty)
+{
+    // Ensure powered up (default is 1)  
+    LPC_SC->PCONP |= (1UL << 6);  
+        
+    // CCLK/4 = 24MHz
+    LPC_SC->PCLKSEL0 &= ~(3UL << 12);
+    
+    // Reset.
+    LPC_PWM1->TCR   = 2; 
+    
+    _duty = duty;
+    
+    LPC_PWM1->PR    = 0;
+    LPC_PWM1->MR0   = _duty;
+    LPC_PWM1->MR1   = 0;
+    LPC_PWM1->MR2   = 0;
+    LPC_PWM1->MR3   = 0;
+    LPC_PWM1->MR4   = 0;
+    LPC_PWM1->MR5   = 0;
+    LPC_PWM1->MR6   = 0;
+        
+    LPC_PWM1->MCR   = 2; // MR0 resets TC.
+        
+    LPC_PWM1->TCR   = 9; // Enable.        
+}
+
+void
+SimpleTLE5206::setSpeed(double speed)
+{
+    uint32_t value;
+
+    // Ensure we cap the speed to +/-1.0
+    if (speed > +1.0) speed = +1.0;
+    if (speed < -1.0) speed = -1.0;
+        
+    if (speed == 0) {
+        _in1->as_gpio();
+        _in2->as_gpio();
+        _in1->write(1);    
+        _in2->write(1);    
+    }
+    else {
+        if (speed > 0.0) {
+            // Check the outputs are configured for the direction requested. 
+            if (_in1->get_pin_type() != SimpleTLE5206Output::IsGPIO) _in1->as_gpio();                
+            if (_in2->get_pin_type() != SimpleTLE5206Output::IsPWM)  _in2->as_pwm();                
+        }
+        
+        if (speed < 0.0) {
+            // Check the outputs are configured for the direction requested. 
+            if (_in1->get_pin_type() != SimpleTLE5206Output::IsPWM)  _in1->as_pwm();                
+            if (_in2->get_pin_type() != SimpleTLE5206Output::IsGPIO) _in2->as_gpio();  
+            speed *= -1; // invert sign.              
+        }
+    
+        value = (uint32_t)(speed * _duty);      // Scale for requested speed.
+        if (value >= _duty) value = _duty - 1;  // Don't allow the value to overrun the duty.
+        value = _duty - value;                  // Invert logic sense.
+        
+        switch(_in1->getPin()) {
+            case p21:            setMRx(Pwm6, value); break;
+            case p22:            setMRx(Pwm5, value); break;
+            case p23: case LED4: setMRx(Pwm4, value); break;
+            case p24: case LED3: setMRx(Pwm3, value); break;
+            case p25: case LED2: setMRx(Pwm2, value); break;
+            case p26: case LED1: setMRx(Pwm1, value); break;                          
+        }
+        
+        switch(_in2->getPin()) {
+            case p21:            setMRx(Pwm6, value); break;
+            case p22:            setMRx(Pwm5, value); break;
+            case p23: case LED4: setMRx(Pwm4, value); break;
+            case p24: case LED3: setMRx(Pwm3, value); break;
+            case p25: case LED2: setMRx(Pwm2, value); break;
+            case p26: case LED1: setMRx(Pwm1, value); break;                          
+        }
+    }
+}
+
+void 
+SimpleTLE5206::setMRx(PwmCh ch, uint32_t value) 
+{
+    switch(ch) {
+        case Pwm1: LPC_PWM1->MR1 = value; break;
+        case Pwm2: LPC_PWM1->MR2 = value; break;
+        case Pwm3: LPC_PWM1->MR3 = value; break;
+        case Pwm4: LPC_PWM1->MR4 = value; break;
+        case Pwm5: LPC_PWM1->MR5 = value; break;
+        case Pwm6: LPC_PWM1->MR6 = value; break;        
+    }
+    LPC_PWM1->LER |= (1UL << ch);
+}
+
+}; // namespace AjK ends.