Provides an API software interface to TIMER2 to control upto four stepper motors.

Dependents:   Steppermotor

inc/SimpleStepperOutput.h

Committer:
AjK
Date:
2011-05-20
Revision:
4:7b7940df7865
Parent:
0:7393c52297ee

File content as of revision 4:7b7940df7865:

/****************************************************************************
 * Product: LIB17 Open Source Library
 *
 *                    Steller Technologies Limited
 *                    ----------------------------
 *
 * Copyright (C) 2002-2011 Steller Technologies Limited. All rights reserved.
 *
 * This software may be distributed and modified under the terms of the GNU
 * General Public License version 2 (GPL) as published by the Free Software
 * Foundation and appearing in the file GPL.TXT included in the packaging of
 * this file. Please note that GPL Section 2[b] requires that all works based
 * on this software must also be made publicly available under the terms of
 * the GPL ("Copyleft").
 *
 * Alternatively, this software may be distributed and modified under the
 * terms of Steller Technologies Limited commercial licenses, which expressly
 * supersede the GPL and are specifically designed for licensees interested in
 * retaining the proprietary status of their code.
 *
 * $Id:$
 *
 ***************************************************************************/

/**
 * @defgroup SimpleStepperOutput SimpleStepperOutput functions
 */

#ifndef AJK_SIMPLESTEPPEROUTPUT_H
#define AJK_SIMPLESTEPPEROUTPUT_H

#ifndef __ARMCC_VERSION
#include "SimpleStepperMbed.h"
#else
#include "mbed.h"
#endif


namespace AjK {

/** SimpleStepperOutput - Adds pin output objects.
 *
 * The Mbed library supplies the DigitalIn and DigitalOut objects to allow you
 * to specify ins and outs.
 *
 * SimpleStepperOutput allows library objects to implement pins without the requirement
 * to link against the Mbed library. This increase portability when using
 * alternate compilers (such as the Code Red GCC C++ compiler for LPCXpresso).
 *
 * @ingroup SimpleStepperOutput
 */
class SimpleStepperOutput {
public:
    enum Direction {
          Out = 0
        , In
    };

protected:
    PinName pin;
    uint32_t mask;
    uint32_t fiodir;
    uint32_t fiomask;
    uint32_t fiopin;
    uint32_t fioset;
    uint32_t fioclr;

    inline void setpin(PinName p)  { pin     = p; }
    inline void setmask(PinName p) { mask    = (uint32_t)(1UL << ((uint32_t)p & 0x1F)); }
    inline void setDir(PinName p)  { fiodir  = (uint32_t)(p & ~0x1F) + 0x00; }
    inline void setMask(PinName p) { fiomask = (uint32_t)(p & ~0x1F) + 0x10; }
    inline void setPin(PinName p)  { fiopin  = (uint32_t)(p & ~0x1F) + 0x14; }
    inline void setSet(PinName p)  { fioset  = (uint32_t)(p & ~0x1F) + 0x18; }
    inline void setClr(PinName p)  { fioclr  = (uint32_t)(p & ~0x1F) + 0x1C; }

    inline void pinUp() { *((volatile uint32_t *)fioset) = mask; }
    inline void pinDn() { *((volatile uint32_t *)fioclr) = mask; }
    inline uint32_t pinIs() { return *((volatile uint32_t *)(fiopin)) & mask; }

public:

    /** Constructor
     * @ingroup SimpleStepperOutput
     */
    SimpleStepperOutput(PinName p, Direction d = Out, PinMode m = PullDown) { init(p, d, m); };

    /** write
     *
     * Writes a value to the pin.
     *
     * @see http://cornflakes.wikidot.com/lib17:core:lib17-dio
     * @ingroup SimpleStepperOutput
     * @param i Zero makes the pin 0v, non-zero makes the pin 1.
     */
    void write(int i)     { if (i!=0) { pinUp(); } else { pinDn(); } }

    /** read
     *
     * Reads the value on the pin.
     *
     * @see http://cornflakes.wikidot.com/lib17:core:lib17-dio
     * @ingroup SimpleStepperOutput
     * @return int 0v returns zero, otherwise returns 1.
     */
    int  read(void)       { return pinIs() ? 1 : 0; };

    /** output
     *
     * Setup the pin to be an output.
     *
     * @see http://cornflakes.wikidot.com/lib17:core:lib17-dio
     * @ingroup SimpleStepperOutput
     * @ingroup API
     * @return int 0v returns zero, otherwise returns 1.
     */
    void output(void)    { *((volatile uint32_t *)fiodir) |=  mask; }

    /** input
     *
     * Setup the pin to be an input.
     *
     * @see http://cornflakes.wikidot.com/lib17:core:lib17-dio
     * @ingroup SimpleStepperOutput
     * @return int 0v returns zero, otherwise returns 1.
     */
    void input(void)    { *((volatile uint32_t *)fiodir) &= ~mask; }

    /** getPin
     *
     * Get the PinName this object is operating on.
     *
     * @see http://cornflakes.wikidot.com/lib17:core:lib17-dio
     * @ingroup SimpleStepperOutput
     * @return int 0v returns zero, otherwise returns 1.
     */
    PinName getPin(void) { return pin; }

    /** getDirection
     *
     * Get the operational direction this pin is setup for.
     *
     * @see http://cornflakes.wikidot.com/lib17:core:lib17-dio
     * @ingroup SimpleStepperOutput
     * @return int 0v returns zero, otherwise returns 1.
     */
    int getDirection(void) { return *((volatile uint32_t *)fiomask) & mask ? 1 : 0; }

    /**  operator int()
     *
     * Reads the value on the pin.
     *
     * @see read
     * @see http://cornflakes.wikidot.com/lib17:core:lib17-dio
     * @ingroup SimpleStepperOutput
     * @return int 0v returns zero, otherwise returns 1.
     */
    operator int() { return read(); }

    /** operator=
     *
     * Writes a value to the pin.
     *
     * @see write
     * @see http://cornflakes.wikidot.com/lib17:core:lib17-dio
     * @ingroup SimpleStepperOutput
     */
    SimpleStepperOutput& operator= (int value)  { write(value); return *this; }

    /** operator=
     *
     * Writes a value to the pin.
     *
     * @see write
     * @see http://cornflakes.wikidot.com/lib17:core:lib17-dio
     * @ingroup SimpleStepperOutput
     */
    SimpleStepperOutput& operator= (SimpleStepperOutput& rhs) { write(rhs.read()); return *this; }

    /** getMask
     *
     * Get the mask value for this pin.
     *
     * @see http://cornflakes.wikidot.com/lib17:core:lib17-dio
     * @ingroup SimpleStepperOutput
     * @return uint32_t The mask value used by this pin.
     */
    uint32_t getMask(void)    { return mask;    }

    /** getFiodir
     *
     * Get the FIODIR register for the port the pin is on.
     *
     * @see http://cornflakes.wikidot.com/lib17:core:lib17-dio
     * @ingroup SimpleStepperOutput
     * @return uint32_t The register value.
     */
    uint32_t getFiodir(void)  { return fiodir;  }

    /** getFiomask
     *
     * Get the FIOMASK register for the port the pin is on.
     *
     * @see http://cornflakes.wikidot.com/lib17:core:lib17-dio
     * @ingroup SimpleStepperOutput
     * @return uint32_t The register value.
     */
    uint32_t getFiomask(void) { return fiomask; }

    /** getFiopin
     *
     * Get the FIOPIN register for the port the pin is on.
     *
     * @see http://cornflakes.wikidot.com/lib17:core:lib17-dio
     * @ingroup SimpleStepperOutput
     * @return uint32_t The register value.
     */
    uint32_t getFiopin(void)  { return fiopin;  }

    /** getFioset
     *
     * Get the FIOSET register for the port the pin is on.
     *
     * @see http://cornflakes.wikidot.com/lib17:core:lib17-dio
     * @ingroup SimpleStepperOutput
     * @return uint32_t The register value.
     */
    uint32_t getFioset(void)  { return fioset;  }

    /** getFioclr
     *
     * Get the FIOCLR register for the port the pin is on.
     *
     * @see http://cornflakes.wikidot.com/lib17:core:lib17-dio
     * @ingroup SimpleStepperOutput
     * @return uint32_t The register value.
     */
    uint32_t getFioclr(void)  { return fioclr;  }


protected:
    void init(PinName p, Direction d, PinMode m)
    {
        // We rely on the fact that by default the LPC1768
        // sets all pins to be GPIO. The user will change
        // that if they need to. So we don't bother trying
        // to setup PINSELx

        // psel(); // Not used, see above.

        setpin(p);
        setmask(p);
        setDir(p);
        setMask(p);
        setPin(p);
        setSet(p);
        setClr(p);

        if (d == Out) output();
        else mode( m );
    }

protected:
    void psel(void)
    {
        uint32_t ppsel, pumask;

        if (pin >= P0_0 && pin <= P0_15)         ppsel = (uint32_t)(&LPC_PINCON->PINSEL0);
        else if (pin >= P0_16 && pin <= P0_31)     ppsel = (uint32_t)(&LPC_PINCON->PINSEL1);
        else if (pin >= P1_0 && pin <= P1_15)     ppsel = (uint32_t)(&LPC_PINCON->PINSEL2);
        else if (pin >= P1_16 && pin <= P1_31)     ppsel = (uint32_t)(&LPC_PINCON->PINSEL3);
        else if (pin >= P2_0 && pin <= P2_15)     ppsel = (uint32_t)(&LPC_PINCON->PINSEL4);
        else if (pin >= P3_16 && pin <= P3_31)     ppsel = (uint32_t)(&LPC_PINCON->PINSEL7);
        else if (pin >= P4_16 && pin <= P4_31)     ppsel = (uint32_t)(&LPC_PINCON->PINSEL9);
        else return;

        pumask = ~(3UL << ((pin & 0x1F)>>1));
        *((volatile uint32_t *)ppsel) &= pumask;
    }

public:
    void mode(PinMode m)
    {
        uint32_t ppmod, pumask;

        if (m == OpenDrain) {
            openDrain(1);
        }
        else {
            if (pin >= P0_0 && pin <= P0_15) {
                ppmod = (uint32_t)(&LPC_PINCON->PINMODE0);
                pumask = ((m & 0x3) << ( ((pin & 0x1F)-0)*2) );
            }
            else if (pin >= P0_16 && pin <= P0_31) {
                ppmod = (uint32_t)(&LPC_PINCON->PINMODE1);
                pumask = ((m & 0x3) << ( ((pin & 0x1F)-16)*2) );
            }
            else if (pin >= P1_0 && pin <= P1_15) {
                ppmod = (uint32_t)(&LPC_PINCON->PINMODE2);
                pumask = ((m & 0x3) << ( ((pin & 0x1F)-0)*2) );
            }
            else if (pin >= P1_16 && pin <= P1_31) {
                 ppmod = (uint32_t)(&LPC_PINCON->PINMODE3);
                 pumask = ((m & 0x3) << ( ((pin & 0x1F)-16)*2) );
            }
            else if (pin >= P2_0 && pin <= P2_15) {
                ppmod = (uint32_t)(&LPC_PINCON->PINMODE4);
                pumask = ((m & 0x3) << ( ((pin & 0x1F)-0)*2) );
            }
            else if (pin >= P3_16 && pin <= P3_31) {
                ppmod = (uint32_t)(&LPC_PINCON->PINMODE7);
                pumask = ((m & 0x3) << ( ((pin & 0x1F)-16)*2) );
            }
            else if (pin >= P4_16 && pin <= P4_31) {
                ppmod = (uint32_t)(&LPC_PINCON->PINMODE9);
                pumask = ((m & 0x3) << ( ((pin & 0x1F)-16)*2) );
            }
            else return;

            *((volatile uint32_t *)ppmod) |= pumask;
        }
    }

public:
    void openDrain(int i = 1)
    {
        if (pin >= P0_0 && pin <= P0_31)           { if (i) LPC_PINCON->PINMODE_OD0 |= mask; else LPC_PINCON->PINMODE_OD0 &= ~mask; }
        else if (pin >= P1_0 && pin <= P1_31)      { if (i) LPC_PINCON->PINMODE_OD1 |= mask; else LPC_PINCON->PINMODE_OD1 &= ~mask; }
        else if (pin >= P2_0 && pin <= P2_31)      { if (i) LPC_PINCON->PINMODE_OD2 |= mask; else LPC_PINCON->PINMODE_OD2 &= ~mask; }
        else if (pin >= P3_16 && pin <= P3_31)     { if (i) LPC_PINCON->PINMODE_OD3 |= mask; else LPC_PINCON->PINMODE_OD3 &= ~mask; }
        else if (pin >= P4_16 && pin <= P4_31)     { if (i) LPC_PINCON->PINMODE_OD4 |= mask; else LPC_PINCON->PINMODE_OD4 &= ~mask; }
    }

};

}; /* namespace AjK ends. */

using namespace AjK;

#endif /* AJK_SIMPLESTEPPEROUTPUT_H */