Tripple Controller for the TLE5206 H Bridge motor controller

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers SimpleTLE5206Output.h Source File

SimpleTLE5206Output.h

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 #ifndef AJK_SIMPLETLE5206OUTPUT_H
00024 #define AJK_SIMPLETLE5206OUTPUT_H
00025 
00026 #ifndef __ARMCC_VERSION
00027 #include "SimpleTLE5206Mbed.h"
00028 #define error(...)
00029 #else
00030 #include "mbed.h"
00031 #endif
00032 
00033 
00034 namespace AjK {
00035 
00036 /** SimpleTLE5206Output - Adds pin output objects.
00037  *
00038  * The Mbed library supplies the DigitalIn and DigitalOut objects to allow you
00039  * to specify ins and outs.
00040  *
00041  * SimpleTLE5206Output allows library objects to implement pins without the requirement
00042  * to link against the Mbed library. This increase portability when using
00043  * alternate compilers (such as the Code Red GCC C++ compiler for LPCXpresso).
00044  *
00045  * Additionally, this class allows the pin to be configured as a GPIO output or swapped
00046  * to PWM output mode.
00047  *
00048  * Note, this class can only be used for pins p21 through p26 as these are used for PWM pins.
00049  * Trying to set this to any other pin will result in a fatal error() call.
00050  *
00051  * @ingroup SimpleTLE5206Output
00052  */
00053 class SimpleTLE5206Output {
00054 public:
00055     enum Direction {
00056           Out = 0
00057         , In
00058     };
00059     
00060     enum PinType {
00061           IsGPIO = 0
00062         , IsPWM
00063     };
00064 
00065 protected:
00066     PinName pin;
00067     uint32_t mask;
00068     uint32_t fiodir;
00069     uint32_t fiomask;
00070     uint32_t fiopin;
00071     uint32_t fioset;
00072     uint32_t fioclr;
00073 
00074     PinType pin_type;
00075     
00076     inline void setpin(PinName p)  { pin     = p; }
00077     inline void setmask(PinName p) { mask    = (uint32_t)(1UL << ((uint32_t)p & 0x1F)); }
00078     inline void setDir(PinName p)  { fiodir  = (uint32_t)(p & ~0x1F) + 0x00; }
00079     inline void setMask(PinName p) { fiomask = (uint32_t)(p & ~0x1F) + 0x10; }
00080     inline void setPin(PinName p)  { fiopin  = (uint32_t)(p & ~0x1F) + 0x14; }
00081     inline void setSet(PinName p)  { fioset  = (uint32_t)(p & ~0x1F) + 0x18; }
00082     inline void setClr(PinName p)  { fioclr  = (uint32_t)(p & ~0x1F) + 0x1C; }
00083 
00084     inline void pinUp() { *((volatile uint32_t *)fioset) = mask; }
00085     inline void pinDn() { *((volatile uint32_t *)fioclr) = mask; }
00086     inline uint32_t pinIs() { return *((volatile uint32_t *)(fiopin)) & mask; }
00087 
00088 public:
00089 
00090     /** Constructor
00091      * @ingroup SimpleTLE5206Output
00092      */
00093     SimpleTLE5206Output(PinName p, Direction d = Out, PinMode m = PullDown) { 
00094     
00095         if (p == p21 || p == p22 || p == p23 || p == p24 || p == p25 || p == p26 || p == LED1 || p == LED2 || p == LED3 || p == LED4) {
00096             init(p, d, m); 
00097         }
00098         else {
00099             error("Invalid pin supplied.\n");
00100         }
00101     };
00102 
00103     /** write
00104      *
00105      * Writes a value to the pin.
00106      *
00107      * @see http://cornflakes.wikidot.com/lib17:core:lib17-dio
00108      * @ingroup SimpleTLE5206Output
00109      * @param i Zero makes the pin 0v, non-zero makes the pin 1.
00110      */
00111     void write(int i)     { if (i!=0) { pinUp(); } else { pinDn(); } }
00112 
00113     /** read
00114      *
00115      * Reads the value on the pin.
00116      *
00117      * @see http://cornflakes.wikidot.com/lib17:core:lib17-dio
00118      * @ingroup SimpleTLE5206Output
00119      * @return int 0v returns zero, otherwise returns 1.
00120      */
00121     int  read(void)       { return pinIs() ? 1 : 0; };
00122 
00123     /** output
00124      *
00125      * Setup the pin to be an output.
00126      *
00127      * @see http://cornflakes.wikidot.com/lib17:core:lib17-dio
00128      * @ingroup SimpleTLE5206Output
00129      * @ingroup API
00130      * @return int 0v returns zero, otherwise returns 1.
00131      */
00132     void output(void)    { *((volatile uint32_t *)fiodir) |=  mask; }
00133 
00134     /** input
00135      *
00136      * Setup the pin to be an input.
00137      *
00138      * @see http://cornflakes.wikidot.com/lib17:core:lib17-dio
00139      * @ingroup SimpleTLE5206Output
00140      * @return int 0v returns zero, otherwise returns 1.
00141      */
00142     void input(void)    { *((volatile uint32_t *)fiodir) &= ~mask; }
00143 
00144     /** getPin
00145      *
00146      * Get the PinName this object is operating on.
00147      *
00148      * @see http://cornflakes.wikidot.com/lib17:core:lib17-dio
00149      * @ingroup SimpleTLE5206Output
00150      * @return int 0v returns zero, otherwise returns 1.
00151      */
00152     PinName getPin(void) { return pin; }
00153 
00154     /** getDirection
00155      *
00156      * Get the operational direction this pin is setup for.
00157      *
00158      * @see http://cornflakes.wikidot.com/lib17:core:lib17-dio
00159      * @ingroup SimpleTLE5206Output
00160      * @return int 0v returns zero, otherwise returns 1.
00161      */
00162     int getDirection(void) { return *((volatile uint32_t *)fiomask) & mask ? 1 : 0; }
00163 
00164     /**  operator int()
00165      *
00166      * Reads the value on the pin.
00167      *
00168      * @see read
00169      * @see http://cornflakes.wikidot.com/lib17:core:lib17-dio
00170      * @ingroup SimpleTLE5206Output
00171      * @return int 0v returns zero, otherwise returns 1.
00172      */
00173     operator int() { return read(); }
00174 
00175     /** operator=
00176      *
00177      * Writes a value to the pin.
00178      *
00179      * @see write
00180      * @see http://cornflakes.wikidot.com/lib17:core:lib17-dio
00181      * @ingroup SimpleTLE5206Output
00182      */
00183     SimpleTLE5206Output& operator= (int value)  { write(value); return *this; }
00184 
00185     /** operator=
00186      *
00187      * Writes a value to the pin.
00188      *
00189      * @see write
00190      * @see http://cornflakes.wikidot.com/lib17:core:lib17-dio
00191      * @ingroup SimpleTLE5206Output
00192      */
00193     SimpleTLE5206Output& operator= (SimpleTLE5206Output& rhs) { write(rhs.read()); return *this; }
00194 
00195     /** getMask
00196      *
00197      * Get the mask value for this pin.
00198      *
00199      * @see http://cornflakes.wikidot.com/lib17:core:lib17-dio
00200      * @ingroup SimpleTLE5206Output
00201      * @return uint32_t The mask value used by this pin.
00202      */
00203     uint32_t getMask(void)    { return mask;    }
00204 
00205     /** getFiodir
00206      *
00207      * Get the FIODIR register for the port the pin is on.
00208      *
00209      * @see http://cornflakes.wikidot.com/lib17:core:lib17-dio
00210      * @ingroup SimpleTLE5206Output
00211      * @return uint32_t The register value.
00212      */
00213     uint32_t getFiodir(void)  { return fiodir;  }
00214 
00215     /** getFiomask
00216      *
00217      * Get the FIOMASK register for the port the pin is on.
00218      *
00219      * @see http://cornflakes.wikidot.com/lib17:core:lib17-dio
00220      * @ingroup SimpleTLE5206Output
00221      * @return uint32_t The register value.
00222      */
00223     uint32_t getFiomask(void) { return fiomask; }
00224 
00225     /** getFiopin
00226      *
00227      * Get the FIOPIN register for the port the pin is on.
00228      *
00229      * @see http://cornflakes.wikidot.com/lib17:core:lib17-dio
00230      * @ingroup SimpleTLE5206Output
00231      * @return uint32_t The register value.
00232      */
00233     uint32_t getFiopin(void)  { return fiopin;  }
00234 
00235     /** getFioset
00236      *
00237      * Get the FIOSET register for the port the pin is on.
00238      *
00239      * @see http://cornflakes.wikidot.com/lib17:core:lib17-dio
00240      * @ingroup SimpleTLE5206Output
00241      * @return uint32_t The register value.
00242      */
00243     uint32_t getFioset(void)  { return fioset;  }
00244 
00245     /** getFioclr
00246      *
00247      * Get the FIOCLR register for the port the pin is on.
00248      *
00249      * @see http://cornflakes.wikidot.com/lib17:core:lib17-dio
00250      * @ingroup SimpleTLE5206Output
00251      * @return uint32_t The register value.
00252      */
00253     uint32_t getFioclr(void)  { return fioclr;  }
00254 
00255 
00256 protected:
00257     void init(PinName p, Direction d, PinMode m)
00258     {
00259         // We rely on the fact that by default the LPC1768
00260         // sets all pins to be GPIO. The user will change
00261         // that if they need to. So we don't bother trying
00262         // to setup PINSELx
00263 
00264         // psel(); // Not used, see above.
00265 
00266         setpin(p);
00267         setmask(p);
00268         setDir(p);
00269         setMask(p);
00270         setPin(p);
00271         setSet(p);
00272         setClr(p);
00273 
00274         if (d == Out) output();
00275         else mode( m );
00276         
00277         pin_type = IsGPIO; // GPIO.
00278     }
00279 
00280 public:
00281     void as_gpio(void)
00282     {
00283         pin_type = IsGPIO;
00284         
00285                 switch(pin) {
00286         case P2_0:    
00287             LPC_PINCON->PINSEL4 &= ~(3UL << 0); // Mbed p26 P2.0 clr bits
00288             return;
00289         case P1_18: // Mbed LED1
00290             LPC_PINCON->PINSEL3 &= ~(3UL << 4); // Mbed LED2 P1.18 clr bits
00291             return;
00292         }
00293         
00294         switch(pin) {
00295         case P2_1:
00296             LPC_PINCON->PINSEL4 &= ~(3UL << 2); // Mbed p25 P2.1 clr bits
00297             return;
00298         case P1_20: // Mbed LED2
00299             LPC_PINCON->PINSEL3 &= ~(3UL << 8); // Mbed LED2 P1.20 clr bits
00300             return;
00301         }
00302 
00303         switch(pin) {
00304         case P2_2:
00305             LPC_PINCON->PINSEL4 &= ~(3UL << 4); // Mbed p24 P2.2 clr bits
00306             return;
00307         case P1_21: // Mbed LED3
00308             LPC_PINCON->PINSEL3 &= ~(3UL << 10); // Mbed LED3 P1.21 clr bits
00309             return;
00310         }   
00311     
00312         switch(pin) {
00313         case P2_3:
00314             LPC_PINCON->PINSEL4 &= ~(3UL << 6); // Mbed p23 P2.3 clr bits
00315             return;
00316         case P1_23: // Mbed LED4
00317             LPC_PINCON->PINSEL3 &= ~(3UL << 14); // Mbed LED4 P1.23 clr bits
00318             return;
00319         }
00320     
00321         switch(pin) {
00322         case P2_4: // Mbed p22
00323             LPC_PINCON->PINSEL4 &= ~(3UL << 8); // Mbed p22 P2.4 clr bits
00324             return;
00325         case P1_24:            
00326             LPC_PINCON->PINSEL3 &= ~(3UL << 16); // P1.24 clr bits
00327             return;
00328         }
00329     
00330         switch(pin) {
00331         case P2_5: // Mbed p21
00332             LPC_PINCON->PINSEL4 &= ~(3UL << 10); // Mbed p21 P2.5 clr bits
00333             return;
00334         case P1_26:
00335             LPC_PINCON->PINSEL3 &= ~(3UL << 20); // P1.26 clr bits
00336             return;
00337         }
00338     }
00339 
00340     void as_pwm(void)
00341     {
00342         pin_type = IsPWM;    
00343         
00344         switch(pin) {
00345         case P2_0:    
00346             LPC_PINCON->PINSEL4 &= ~(3UL << 0); // Mbed p26 P2.0 clr bits
00347             LPC_PINCON->PINSEL4 |=  (1UL << 0); // Mbed p26 P2.0 set bits
00348             LPC_PWM1->PCR |= (1UL << 9);
00349             return;
00350         case P1_18: // Mbed LED1
00351             LPC_PINCON->PINSEL3 &= ~(3UL << 4); // Mbed LED2 P1.18 clr bits
00352             LPC_PINCON->PINSEL3 |=  (2UL << 4); // Mbed LED2 P1.18 set bits
00353             LPC_PWM1->PCR |= (1UL << 9);
00354             return;
00355         }
00356         
00357         switch(pin) {
00358         case P2_1:
00359             LPC_PINCON->PINSEL4 &= ~(3UL << 2); // Mbed p25 P2.1 clr bits
00360             LPC_PINCON->PINSEL4 |=  (1UL << 2); // Mbed p25 P2.1 set bits
00361             LPC_PWM1->PCR |= (1UL << 10);
00362             return;
00363         case P1_20: // Mbed LED2
00364             LPC_PINCON->PINSEL3 &= ~(3UL << 8); // Mbed LED2 P1.20 clr bits
00365             LPC_PINCON->PINSEL3 |=  (2UL << 8); // Mbed LED2 P1.20 set bits
00366             LPC_PWM1->PCR |= (1UL << 10);
00367             return;
00368         }
00369 
00370         switch(pin) {
00371         case P2_2:
00372             LPC_PINCON->PINSEL4 &= ~(3UL << 4); // Mbed p24 P2.2 clr bits
00373             LPC_PINCON->PINSEL4 |=  (1UL << 4); // Mbed p24 P2.2 set bits
00374             LPC_PWM1->PCR |= (1UL << 11);
00375             return;
00376         case P1_21: // Mbed LED3
00377             LPC_PINCON->PINSEL3 &= ~(3UL << 10); // Mbed LED3 P1.21 clr bits
00378             LPC_PINCON->PINSEL3 |=  (2UL << 10); // Mbed LED3 P1.21 set bits
00379             LPC_PWM1->PCR |= (1UL << 11);
00380             return;
00381         }   
00382     
00383         switch(pin) {
00384         case P2_3:
00385             LPC_PINCON->PINSEL4 &= ~(3UL << 6); // Mbed p23 P2.3 clr bits
00386             LPC_PINCON->PINSEL4 |=  (1UL << 6); // Mbed p23 P2.3 set bits
00387             LPC_PWM1->PCR |= (1UL << 12);
00388             return;
00389         case P1_23: // Mbed LED4
00390             LPC_PINCON->PINSEL3 &= ~(3UL << 14); // Mbed LED4 P1.23 clr bits
00391             LPC_PINCON->PINSEL3 |=  (2UL << 14); // Mbed LED4 P1.23 set bits
00392             LPC_PWM1->PCR |= (1UL << 12);
00393             return;
00394         }
00395     
00396         switch(pin) {
00397         case P2_4: // Mbed p22
00398             LPC_PINCON->PINSEL4 &= ~(3UL << 8); // Mbed p22 P2.4 clr bits
00399             LPC_PINCON->PINSEL4 |=  (1UL << 8); // Mbed p22 P2.4 set bits
00400             LPC_PWM1->PCR |= (1UL << 13);
00401             return;
00402         case P1_24:            
00403             LPC_PINCON->PINSEL3 &= ~(3UL << 16); // P1.24 clr bits
00404             LPC_PINCON->PINSEL3 |=  (2UL << 16); // P1.24 set bits
00405             LPC_PWM1->PCR |= (1UL << 13);
00406             return;
00407         }
00408     
00409         switch(pin) {
00410         case P2_5: // Mbed p21
00411             LPC_PINCON->PINSEL4 &= ~(3UL << 10); // Mbed p21 P2.5 clr bits
00412             LPC_PINCON->PINSEL4 |=  (1UL << 10); // Mbed p21 P2.5 set bits
00413             LPC_PWM1->PCR |= (1UL << 14);
00414             return;
00415         case P1_26:
00416             LPC_PINCON->PINSEL3 &= ~(3UL << 20); // P1.26 clr bits
00417             LPC_PINCON->PINSEL3 |=  (2UL << 20); // P1.26 set bits
00418             LPC_PWM1->PCR |= (1UL << 14);
00419             return;
00420         }
00421 
00422 /*    
00423         uint32_t ppsel, pumask;
00424 
00425         if (pin >= P2_0 && pin <= P2_5) {
00426             ppsel = (uint32_t)(&LPC_PINCON->PINSEL4);
00427             pumask = ~(3UL << ((pin & 0x1F)>>1));
00428             *((volatile uint32_t *)ppsel) &= pumask;
00429             pumask = (1UL << ((pin & 0x1F)>>1));
00430             *((volatile uint32_t *)ppsel) |= pumask;
00431         }
00432         else if (pin >= LED1 && pin <= LED4) {
00433             ppsel = (uint32_t)(&LPC_PINCON->PINSEL3);                
00434             pumask = ~(3UL << ((pin & 0x1F)>>1));
00435             *((volatile uint32_t *)ppsel) &= pumask;
00436             pumask = (2UL << ((pin & 0x1F)>>1));
00437             *((volatile uint32_t *)ppsel) |= pumask;
00438         }
00439         else return;    
00440 */        
00441         
00442     }
00443 
00444     PinType get_pin_type(void) { return pin_type; }
00445     
00446     void mode(PinMode m)
00447     {
00448         uint32_t ppmod, pumask;
00449 
00450         if (m == OpenDrain) {
00451             openDrain(1);
00452         }
00453         else {            
00454             if (pin >= P2_0 && pin <= P2_5) {
00455                 ppmod = (uint32_t)(&LPC_PINCON->PINMODE4);
00456                 pumask = ((m & 0x3) << ( ((pin & 0x1F)-0)*2) );
00457             }
00458             else return;
00459 
00460             *((volatile uint32_t *)ppmod) |= pumask;
00461         }
00462     }
00463 
00464 public:
00465     void openDrain(int i = 1)
00466     {
00467         if (pin >= P2_0 && pin <= P2_5)      { if (i) LPC_PINCON->PINMODE_OD2 |= mask; else LPC_PINCON->PINMODE_OD2 &= ~mask; }        
00468     }
00469 
00470 };
00471 
00472 }; /* namespace AjK ends. */
00473 
00474 using namespace AjK;
00475 
00476 #endif /* AJK_SIMPLETLE5206OUTPUT_H */