Provides an API software interface to TIMER2 to control upto four stepper motors.
Diff: inc/SimpleStepperOutput.h
- Revision:
- 0:7393c52297ee
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/inc/SimpleStepperOutput.h Mon May 02 10:02:18 2011 +0000 @@ -0,0 +1,339 @@ +/**************************************************************************** + * 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 */