Tripple Controller for the TLE5206 H Bridge motor controller
Diff: src/SimpleTLE5206.cpp
- 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.