Provides an API software interface to TIMER2 to control upto four stepper motors.
Revision 0:7393c52297ee, committed 2011-05-02
- Comitter:
- AjK
- Date:
- Mon May 02 10:02:18 2011 +0000
- Child:
- 1:1030a91cbf4c
- Commit message:
Changed in this revision
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/inc/IOmacros.h Mon May 02 10:02:18 2011 +0000 @@ -0,0 +1,426 @@ +/**************************************************************************** + * 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. + * + ***************************************************************************/ + +#ifndef AJK_LIB17_IOMACROS_H +#define AJK_LIB17_IOMACROS_H + +#ifndef __LPC17xx_H__ +#include "LPC17xx.h" +#endif + +#define PIN_PULLUP 0UL +#define PIN_REPEAT 1UL +#define PIN_NONE 2UL +#define PIN_PULLDOWN 3UL + +/* p5 is P0.9 */ +#define p5_SEL_MASK ~(3UL << 18) +#define p5_SET_MASK (1UL << 9) +#define p5_CLR_MASK ~(p5_SET_MASK) +#define p5_AS_OUTPUT LPC_PINCON->PINSEL0&=p5_SEL_MASK;LPC_GPIO0->FIODIR|=p5_SET_MASK +#define p5_AS_INPUT LPC_GPIO0->FIOMASK &= p5_CLR_MASK; +#define p5_SET LPC_GPIO0->FIOSET = p5_SET_MASK +#define p5_CLR LPC_GPIO0->FIOCLR = p5_SET_MASK +#define p5_IS_SET (bool)(LPC_GPIO0->FIOPIN & p5_SET_MASK) +#define p5_IS_CLR !(p5_IS_SET) +#define p5_MODE(x) LPC_PINCON->PINMODE0&=p5_SEL_MASK;LPC_PINCON->PINMODE0|=((x&0x3)<<18) + +/* p6 is P0.8 */ +#define p6_SEL_MASK ~(3UL << 16) +#define p6_SET_MASK (1UL << 8) +#define p6_CLR_MASK ~(p6_SET_MASK) +#define p6_AS_OUTPUT LPC_PINCON->PINSEL0&=p6_SEL_MASK;LPC_GPIO0->FIODIR|=p6_SET_MASK +#define p6_AS_INPUT LPC_GPIO0->FIOMASK &= p6_CLR_MASK; +#define p6_SET LPC_GPIO0->FIOSET = p6_SET_MASK +#define p6_CLR LPC_GPIO0->FIOCLR = p6_SET_MASK +#define p6_IS_SET (bool)(LPC_GPIO0->FIOPIN & p6_SET_MASK) +#define p6_IS_CLR !(p6_IS_SET) +#define p6_MODE(x) LPC_PINCON->PINMODE0&=p6_SEL_MASK;LPC_PINCON->PINMODE0|=((x&0x3)<<16) + +/* p7 is P0.7 */ +#define p7_SEL_MASK ~(3UL << 14) +#define p7_SET_MASK (1UL << 7) +#define p7_CLR_MASK ~(p7_SET_MASK) +#define p7_AS_OUTPUT LPC_PINCON->PINSEL0&=p7_SEL_MASK;LPC_GPIO0->FIODIR|=p7_SET_MASK +#define p7_AS_INPUT LPC_GPIO0->FIOMASK &= p7_CLR_MASK; +#define p7_SET LPC_GPIO0->FIOSET = p7_SET_MASK +#define p7_CLR LPC_GPIO0->FIOCLR = p7_SET_MASK +#define p7_IS_SET (bool)(LPC_GPIO0->FIOPIN & p7_SET_MASK) +#define p7_IS_CLR !(p7_IS_SET) +#define p7_MODE(x) LPC_PINCON->PINMODE0&=p7_SEL_MASK;LPC_PINCON->PINMODE0|=((x&0x3)<<14) + +/* p8 is P0.6 */ +#define p8_SEL_MASK ~(3UL << 12) +#define p8_SET_MASK (1UL << 6) +#define p8_AS_OUTPUT LPC_PINCON->PINSEL0&=p8_SEL_MASK;LPC_GPIO0->FIODIR|=p8_SET_MASK +#define p8_AS_INPUT LPC_GPIO0->FIOMASK &= p8_CLR_MASK; +#define p8_SET LPC_GPIO0->FIOSET = p8_SET_MASK +#define p8_CLR LPC_GPIO0->FIOCLR = p8_SET_MASK +#define p8_IS_SET (bool)(LPC_GPIO0->FIOPIN & p8_SET_MASK) +#define p8_IS_CLR !(p8_IS_SET) +#define p8_MODE(x) LPC_PINCON->PINMODE0&=p8_SEL_MASK;LPC_PINCON->PINMODE0|=((x&0x3)<<12) + +/* p9 is P0.0 */ +#define p9_SEL_MASK ~(3UL << 0) +#define p9_SET_MASK (1UL << 0) +#define p9_CLR_MASK ~(p9_SET_MASK) +#define p9_AS_OUTPUT LPC_PINCON->PINSEL0&=p9_SEL_MASK;LPC_GPIO0->FIODIR|=p9_SET_MASK +#define p9_AS_INPUT LPC_GPIO0->FIOMASK &= p9_CLR_MASK; +#define p9_SET LPC_GPIO0->FIOSET = p9_SET_MASK +#define p9_CLR LPC_GPIO0->FIOCLR = p9_SET_MASK +#define p9_IS_SET (bool)(LPC_GPIO0->FIOPIN & p9_SET_MASK) +#define p9_IS_CLR !(p9_IS_SET) +#define p9_MODE(x) LPC_PINCON->PINMODE0&=p9_SEL_MASK;LPC_PINCON->PINMODE0|=((x&0x3)<<0) + +/* p10 is P0.1 */ +#define p10_SEL_MASK ~(3UL << 2) +#define p10_SET_MASK (1UL << 1) +#define p10_CLR_MASK ~(p10_SET_MASK) +#define p10_AS_OUTPUT LPC_PINCON->PINSEL0&=p10_SEL_MASK;LPC_GPIO0->FIODIR|=p10_SET_MASK +#define p10_AS_INPUT LPC_GPIO0->FIOMASK &= p10_CLR_MASK; +#define p10_SET LPC_GPIO0->FIOSET = p10_SET_MASK +#define p10_CLR LPC_GPIO0->FIOCLR = p10_SET_MASK +#define p10_IS_SET (bool)(LPC_GPIO0->FIOPIN & p10_SET_MASK) +#define p10_IS_CLR !(p10_IS_SET) +#define p10_MODE(x) LPC_PINCON->PINMODE0&=p10_SEL_MASK;LPC_PINCON->PINMODE0|=((x&0x3)<<2) + +/* p11 is P0.18 */ +#define p11_SEL_MASK ~(3UL << 4) +#define p11_SET_MASK (1UL << 18) +#define p11_CLR_MASK ~(p11_SET_MASK) +#define p11_AS_OUTPUT LPC_PINCON->PINSEL1&=p11_SEL_MASK;LPC_GPIO0->FIODIR|=p11_SET_MASK +#define p11_AS_INPUT LPC_GPIO0->FIOMASK &= p11_CLR_MASK; +#define p11_SET LPC_GPIO0->FIOSET = p11_SET_MASK +#define p11_CLR LPC_GPIO0->FIOCLR = p11_SET_MASK +#define p11_IS_SET (bool)(LPC_GPIO0->FIOPIN & p11_SET_MASK) +#define p11_IS_CLR !(p11_IS_SET) +#define p11_MODE(x) LPC_PINCON->PINMODE1&=p11_SEL_MASK;LPC_PINCON->PINMODE1|=((x&0x3)<<4) + +/* p12 is P0.17 */ +#define p12_SEL_MASK ~(3UL << 2) +#define p12_SET_MASK (1UL << 17) +#define p12_CLR_MASK ~(p12_SET_MASK) +#define p12_AS_OUTPUT LPC_PINCON->PINSEL1&=p12_SEL_MASK;LPC_GPIO0->FIODIR|=p12_SET_MASK +#define p12_AS_INPUT LPC_GPIO0->FIOMASK &= p12_CLR_MASK; +#define p12_SET LPC_GPIO0->FIOSET = p12_SET_MASK +#define p12_CLR LPC_GPIO0->FIOCLR = p12_SET_MASK +#define p12_IS_SET (bool)(LPC_GPIO0->FIOPIN & p12_SET_MASK) +#define p12_IS_CLR !(p12_IS_SET) +#define p12_MODE(x) LPC_PINCON->PINMODE1&=p12_SEL_MASK;LPC_PINCON->PINMODE1|=((x&0x3)<<2) + +/* p13 is P0.15 */ +#define p13_SEL_MASK ~(3UL << 30) +#define p13_SET_MASK (1UL << 15) +#define p13_CLR_MASK ~(p13_SET_MASK) +#define p13_AS_OUTPUT LPC_PINCON->PINSEL0&=p13_SEL_MASK;LPC_GPIO0->FIODIR|=p13_SET_MASK +#define p13_AS_INPUT LPC_GPIO0->FIOMASK &= p13_CLR_MASK; +#define p13_SET LPC_GPIO0->FIOSET = p13_SET_MASK +#define p13_CLR LPC_GPIO0->FIOCLR = p13_SET_MASK +#define p13_IS_SET (bool)(LPC_GPIO0->FIOPIN & p13_SET_MASK) +#define p13_IS_CLR !(p13_IS_SET) +#define p13_MODE(x) LPC_PINCON->PINMODE0&=p13_SEL_MASK;LPC_PINCON->PINMODE0|=((x&0x3)<<30) + +/* p14 is P0.16 */ +#define p14_SEL_MASK ~(3UL << 0) +#define p14_SET_MASK (1UL << 16) +#define p14_CLR_MASK ~(p14_SET_MASK) +#define p14_AS_OUTPUT LPC_PINCON->PINSEL1&=p14_SEL_MASK;LPC_GPIO0->FIODIR|=p14_SET_MASK +#define p14_AS_INPUT LPC_GPIO0->FIOMASK &= p14_CLR_MASK; +#define p14_SET LPC_GPIO0->FIOSET = p14_SET_MASK +#define p14_CLR LPC_GPIO0->FIOCLR = p14_SET_MASK +#define p14_IS_SET (bool)(LPC_GPIO0->FIOPIN & p14_SET_MASK) +#define p14_IS_CLR !(p14_IS_SET) +#define p14_MODE(x) LPC_PINCON->PINMODE1&=p14_SEL_MASK;LPC_PINCON->PINMODE1|=((x&0x3)<<0) + +/* p15 is P0.23 */ +#define p15_SEL_MASK ~(3UL << 14) +#define p15_SET_MASK (1UL << 23) +#define p15_CLR_MASK ~(p15_SET_MASK) +#define p15_AS_OUTPUT LPC_PINCON->PINSEL1&=p15_SEL_MASK;LPC_GPIO0->FIODIR|=p15_SET_MASK +#define p15_AS_INPUT LPC_GPIO0->FIOMASK &= p15_CLR_MASK; +#define p15_SET LPC_GPIO0->FIOSET = p15_SET_MASK +#define p15_CLR LPC_GPIO0->FIOCLR = p15_SET_MASK +#define p15_IS_SET (bool)(LPC_GPIO0->FIOPIN & p15_SET_MASK) +#define p15_IS_CLR !(p15_IS_SET) +#define p15_MODE(x) LPC_PINCON->PINMODE1&=p15_SEL_MASK;LPC_PINCON->PINMODE1|=((x&0x3)<<14) + +/* p16 is P0.24 */ +#define p16_SEL_MASK ~(3UL << 16) +#define p16_SET_MASK (1UL << 24) +#define p16_CLR_MASK ~(p16_SET_MASK) +#define p16_AS_OUTPUT LPC_PINCON->PINSEL1&=p16_SEL_MASK;LPC_GPIO0->FIODIR|=p16_SET_MASK +#define p16_AS_INPUT LPC_GPIO0->FIOMASK &= p16_CLR_MASK; +#define p16_SET LPC_GPIO0->FIOSET = p16_SET_MASK +#define p16_CLR LPC_GPIO0->FIOCLR = p16_SET_MASK +#define p16_IS_SET (bool)(LPC_GPIO0->FIOPIN & p16_SET_MASK) +#define p16_IS_CLR !(p16_IS_SET) +#define p16_MODE(x) LPC_PINCON->PINMODE1&=p16_SEL_MASK;LPC_PINCON->PINMODE1|=((x&0x3)<<16) + +/* p17 is P0.25 */ +#define p17_SEL_MASK ~(3UL << 18) +#define p17_SET_MASK (1UL << 25) +#define p17_CLR_MASK ~(p17_SET_MASK) +#define p17_AS_OUTPUT LPC_PINCON->PINSEL1&=p17_SEL_MASK;LPC_GPIO0->FIODIR|=p17_SET_MASK +#define p17_AS_INPUT LPC_GPIO0->FIOMASK &= p17_CLR_MASK; +#define p17_SET LPC_GPIO0->FIOSET = p17_SET_MASK +#define p17_CLR LPC_GPIO0->FIOCLR = p17_SET_MASK +#define p17_IS_SET (bool)(LPC_GPIO0->FIOPIN & p17_SET_MASK) +#define p17_IS_CLR !(p17_IS_SET) +#define p17_MODE(x) LPC_PINCON->PINMODE1&=p17_SEL_MASK;LPC_PINCON->PINMODE1|=((x&0x3)<<18) + +/* p18 is P0.26 */ +#define p18_SEL_MASK ~(3UL << 20) +#define p18_SET_MASK (1UL << 26) +#define p18_CLR_MASK ~(p18_SET_MASK) +#define p18_AS_OUTPUT LPC_PINCON->PINSEL1&=p18_SEL_MASK;LPC_GPIO0->FIODIR|=p18_SET_MASK +#define p18_AS_INPUT LPC_GPIO0->FIOMASK &= p18_CLR_MASK; +#define p18_SET LPC_GPIO0->FIOSET = p18_SET_MASK +#define p18_CLR LPC_GPIO0->FIOCLR = p18_SET_MASK +#define p18_IS_SET (bool)(LPC_GPIO0->FIOPIN & p18_SET_MASK) +#define p18_IS_CLR !(p18_IS_SET) +#define p18_MODE(x) LPC_PINCON->PINMODE1&=p18_SEL_MASK;LPC_PINCON->PINMODE1|=((x&0x3)<<20) + +/* p19 is P1.30 */ +#define p19_SEL_MASK ~(3UL << 28) +#define p19_SET_MASK (1UL << 30) +#define p19_AS_OUTPUT LPC_PINCON->PINSEL3&=p19_SEL_MASK;LPC_GPIO1->FIODIR|=p19_SET_MASK +#define p19_AS_INPUT LPC_GPIO1->FIOMASK &= p19_CLR_MASK; +#define p19_SET LPC_GPIO1->FIOSET = p19_SET_MASK +#define p19_CLR LPC_GPIO1->FIOCLR = p19_SET_MASK +#define p19_IS_SET (bool)(LPC_GPIO1->FIOPIN & p19_SET_MASK) +#define p19_IS_CLR !(p19_IS_SET) +#define p19_MODE(x) LPC_PINCON->PINMODE3&=p19_SEL_MASK;LPC_PINCON->PINMODE3|=((x&0x3)<<28) + +/* p20 is P1.31 */ +#define p20_SEL_MASK ~(3UL << 30) +#define p20_SET_MASK (1UL << 31) +#define p20_CLR_MASK ~(p20_SET_MASK) +#define p20_AS_OUTPUT LPC_PINCON->PINSEL3&=p20_SEL_MASK;LPC_GPIO1->FIODIR|=p20_SET_MASK +#define p20_AS_INPUT LPC_GPIO1->FIOMASK &= p20_CLR_MASK; +#define p20_SET LPC_GPIO1->FIOSET = p20_SET_MASK +#define p20_CLR LPC_GPIO1->FIOCLR = p20_SET_MASK +#define p20_IS_SET (bool)(LPC_GPIO1->FIOPIN & p20_SET_MASK) +#define p20_IS_CLR !(p20_IS_SET) +#define p20_MODE(x) LPC_PINCON->PINMODE3&=p20_SEL_MASK;LPC_PINCON->PINMODE3|=((x&0x3)<<30) +#define p20_TOGGLE p20_IS_SET?p20_CLR:p20_SET + +/* p21 is P2.5 */ +#define p21_SEL_MASK ~(3UL << 10) +#define p21_SET_MASK (1UL << 5) +#define p21_CLR_MASK ~(p21_SET_MASK) +#define p21_AS_OUTPUT LPC_PINCON->PINSEL4&=p21_SEL_MASK;LPC_GPIO2->FIODIR|=p21_SET_MASK +#define p21_AS_INPUT LPC_GPIO2->FIOMASK &= p21_CLR_MASK; +#define p21_SET LPC_GPIO2->FIOSET = p21_SET_MASK +#define p21_CLR LPC_GPIO2->FIOCLR = p21_SET_MASK +#define p21_IS_SET (bool)(LPC_GPIO2->FIOPIN & p21_SET_MASK) +#define p21_IS_CLR !(p21_IS_SET) +#define p21_TOGGLE p21_IS_SET?p21_CLR:p21_SET +#define p21_MODE(x) LPC_PINCON->PINMODE4&=p21_SEL_MASK;LPC_PINCON->PINMODE4|=((x&0x3)<<10) + +/* p22 is P2.4 */ +#define p22_SEL_MASK ~(3UL << 8) +#define p22_SET_MASK (1UL << 4) +#define p22_CLR_MASK ~(p22_SET_MASK) +#define p22_AS_OUTPUT LPC_PINCON->PINSEL4&=p22_SEL_MASK;LPC_GPIO2->FIODIR|=p22_SET_MASK +#define p22_AS_INPUT LPC_GPIO2->FIOMASK &= p22_CLR_MASK; +#define p22_SET LPC_GPIO2->FIOSET = p22_SET_MASK +#define p22_CLR LPC_GPIO2->FIOCLR = p22_SET_MASK +#define p22_IS_SET (bool)(LPC_GPIO2->FIOPIN & p22_SET_MASK) +#define p22_IS_CLR !(p22_IS_SET) +#define p22_TOGGLE p22_IS_SET?p22_CLR:p22_SET +#define p22_MODE(x) LPC_PINCON->PINMODE4&=p22_SEL_MASK;LPC_PINCON->PINMODE4|=((x&0x3)<<8) + +/* p23 is P2.3 */ +#define p23_SEL_MASK ~(3UL << 6) +#define p23_SET_MASK (1UL << 3) +#define p23_CLR_MASK ~(p23_SET_MASK) +#define p23_AS_OUTPUT LPC_PINCON->PINSEL4&=p23_SEL_MASK;LPC_GPIO2->FIODIR|=p23_SET_MASK +#define p23_AS_INPUT LPC_GPIO2->FIOMASK &= p23_CLR_MASK; +#define p23_SET LPC_GPIO2->FIOSET = p23_SET_MASK +#define p23_CLR LPC_GPIO2->FIOCLR = p23_SET_MASK +#define p23_IS_SET (bool)(LPC_GPIO2->FIOPIN & p23_SET_MASK) +#define p23_IS_CLR !(p23_IS_SET) +#define p23_TOGGLE p23_IS_SET?p23_CLR:p23_SET +#define p23_MODE(x) LPC_PINCON->PINMODE4&=p23_SEL_MASK;LPC_PINCON->PINMODE4|=((x&0x3)<<6) + +/* p24 is P2.2 */ +#define p24_SEL_MASK ~(3UL << 4) +#define p24_SET_MASK (1UL << 2) +#define p24_CLR_MASK ~(p24_SET_MASK) +#define p24_AS_OUTPUT LPC_PINCON->PINSEL4&=p24_SEL_MASK;LPC_GPIO2->FIODIR|=p24_SET_MASK +#define p24_AS_INPUT LPC_GPIO2->FIOMASK &= p24_CLR_MASK; +#define p24_SET LPC_GPIO2->FIOSET = p24_SET_MASK +#define p24_CLR LPC_GPIO2->FIOCLR = p24_SET_MASK +#define p24_IS_SET (bool)(LPC_GPIO2->FIOPIN & p24_SET_MASK) +#define p24_IS_CLR !(p24_IS_SET) +#define p24_TOGGLE p24_IS_SET?p24_CLR:p24_SET +#define p24_MODE(x) LPC_PINCON->PINMODE4&=p24_SEL_MASK;LPC_PINCON->PINMODE4|=((x&0x3)<<4) + +/* p25 is P2.1 */ +#define p25_SEL_MASK ~(3UL << 2) +#define p25_SET_MASK (1UL << 1) +#define p25_CLR_MASK ~(p25_SET_MASK) +#define p25_AS_OUTPUT LPC_PINCON->PINSEL4&=p25_SEL_MASK;LPC_GPIO2->FIODIR|=p25_SET_MASK +#define p25_AS_INPUT LPC_GPIO2->FIOMASK &= p25_CLR_MASK; +#define p25_SET LPC_GPIO2->FIOSET = p25_SET_MASK +#define p25_CLR LPC_GPIO2->FIOCLR = p25_SET_MASK +#define p25_IS_SET (bool)(LPC_GPIO2->FIOPIN & p25_SET_MASK) +#define p25_IS_CLR !(p25_IS_SET) +#define p25_MODE(x) LPC_PINCON->PINMODE4&=p25_SEL_MASK;LPC_PINCON->PINMODE4|=((x&0x3)<<2) + +/* p26 is P2.0 */ +#define p26_SEL_MASK ~(3UL << 0) +#define p26_SET_MASK (1UL << 0) +#define p26_CLR_MASK ~(p26_SET_MASK) +#define p26_AS_OUTPUT LPC_PINCON->PINSEL4&=p26_SEL_MASK;LPC_GPIO2->FIODIR|=p26_SET_MASK +#define p26_AS_INPUT LPC_GPIO2->FIOMASK &= p26_CLR_MASK; +#define p26_SET LPC_GPIO2->FIOSET = p26_SET_MASK +#define p26_CLR LPC_GPIO2->FIOCLR = p26_SET_MASK +#define p26_IS_SET (bool)(LPC_GPIO2->FIOPIN & p26_SET_MASK) +#define p26_IS_CLR !(p26_IS_SET) +#define p26_MODE(x) LPC_PINCON->PINMODE4&=p26_SEL_MASK;LPC_PINCON->PINMODE4|=((x&0x3)<<0) + +/* p27 is P0.11 */ +#define p27_SEL_MASK ~(3UL << 22) +#define p27_SET_MASK (1UL << 11) +#define p27_CLR_MASK ~(p27_SET_MASK) +#define p27_AS_OUTPUT LPC_PINCON->PINSEL0&=p27_SEL_MASK;LPC_GPIO0->FIODIR|=p27_SET_MASK +#define p27_AS_INPUT LPC_GPIO0->FIOMASK &= p27_CLR_MASK; +#define p27_SET LPC_GPIO0->FIOSET = p27_SET_MASK +#define p27_CLR LPC_GPIO0->FIOCLR = p27_SET_MASK +#define p27_IS_SET (bool)(LPC_GPIO0->FIOPIN & p27_SET_MASK) +#define p27_IS_CLR !(p27_IS_SET) +#define p27_MODE(x) LPC_PINCON->PINMODE0&=p27_SEL_MASK;LPC_PINCON->PINMODE0|=((x&0x3)<<22) + +/* p28 is P0.10 */ +#define p28_SEL_MASK ~(3UL << 20) +#define p28_SET_MASK (1UL << 10) +#define p28_CLR_MASK ~(p28_SET_MASK) +#define p28_AS_OUTPUT LPC_PINCON->PINSEL0&=p28_SEL_MASK;LPC_GPIO0->FIODIR|=p28_SET_MASK +#define p28_AS_INPUT LPC_GPIO0->FIOMASK &= p28_CLR_MASK; +#define p28_SET LPC_GPIO0->FIOSET = p28_SET_MASK +#define p28_CLR LPC_GPIO0->FIOCLR = p28_SET_MASK +#define p28_IS_SET (bool)(LPC_GPIO0->FIOPIN & p28_SET_MASK) +#define p28_IS_CLR !(p28_IS_SET) +#define p28_MODE(x) LPC_PINCON->PINMODE0&=p28_SEL_MASK;LPC_PINCON->PINMODE0|=((x&0x3)<<20) + +/* p29 is P0.5 */ +#define p29_SEL_MASK ~(3UL << 10) +#define p29_SET_MASK (1UL << 5) +#define p29_CLR_MASK ~(p29_SET_MASK) +#define p29_AS_OUTPUT LPC_PINCON->PINSEL0&=p29_SEL_MASK;LPC_GPIO0->FIODIR|=p29_SET_MASK +#define p29_AS_INPUT LPC_GPIO0->FIOMASK &= p29_CLR_MASK; +#define p29_SET LPC_GPIO0->FIOSET = p29_SET_MASK +#define p29_CLR LPC_GPIO0->FIOCLR = p29_SET_MASK +#define p29_IS_SET (bool)(LPC_GPIO0->FIOPIN & p29_SET_MASK) +#define p29_IS_CLR !(p29_IS_SET) +#define p29_TOGGLE p29_IS_SET?p29_CLR:p29_SET +#define p29_MODE(x) LPC_PINCON->PINMODE0&=p29_SEL_MASK;LPC_PINCON->PINMODE0|=((x&0x3)<<10) + +/* p30 is P0.4 */ +#define p30_SEL_MASK ~(3UL << 8) +#define p30_SET_MASK (1UL << 4) +#define p30_CLR_MASK ~(p30_SET_MASK) +#define p30_AS_OUTPUT LPC_PINCON->PINSEL0&=p30_SEL_MASK;LPC_GPIO0->FIODIR|=p30_SET_MASK +#define p30_AS_INPUT LPC_GPIO0->FIOMASK &= p30_CLR_MASK; +#define p30_SET LPC_GPIO0->FIOSET = p30_SET_MASK +#define p30_CLR LPC_GPIO0->FIOCLR = p30_SET_MASK +#define p30_IS_SET (bool)(LPC_GPIO0->FIOPIN & p30_SET_MASK) +#define p30_IS_CLR !(p30_IS_SET) +#define p30_MODE(x) LPC_PINCON->PINMODE0&=p30_SEL_MASK;LPC_PINCON->PINMODE0|=((x&0x3)<<8) + +/* The following definitions are for the four Mbed LEDs. + LED1 = P1.18 + LED2 = P1.20 + LED3 = P1.21 + LED4 = P1.23 */ + +#define P1_18_SEL_MASK ~(3UL << 4) +#define P1_18_SET_MASK (1UL << 18) +#define P1_18_CLR_MASK ~(P1_18_SET_MASK) +#define P1_18_AS_OUTPUT LPC_PINCON->PINSEL3&=P1_18_SEL_MASK;LPC_GPIO1->FIODIR|=P1_18_SET_MASK +#define P1_18_AS_INPUT LPC_GPIO1->FIOMASK &= P1_18_CLR_MASK; +#define P1_18_SET LPC_GPIO1->FIOSET = P1_18_SET_MASK +#define P1_18_CLR LPC_GPIO1->FIOCLR = P1_18_SET_MASK +#define P1_18_IS_SET (bool)(LPC_GPIO1->FIOPIN & P1_18_SET_MASK) +#define P1_18_IS_CLR !(P1_18_IS_SET) +#define LED1_USE P1_18_AS_OUTPUT;P1_18_AS_INPUT +#define LED1_ON P1_18_SET +#define LED1_OFF P1_18_CLR +#define LED1_IS_ON P1_18_IS_SET +#define LED1_TOGGLE P1_18_IS_SET?LED1_OFF:LED1_ON + +#define P1_20_SEL_MASK ~(3UL << 8) +#define P1_20_SET_MASK (1UL << 20) +#define P1_20_CLR_MASK ~(P1_20_SET_MASK) +#define P1_20_AS_OUTPUT LPC_PINCON->PINSEL3&=P1_20_SEL_MASK;LPC_GPIO1->FIODIR|=P1_20_SET_MASK +#define P1_20_AS_INPUT LPC_GPIO1->FIOMASK &= P1_20_CLR_MASK; +#define P1_20_SET LPC_GPIO1->FIOSET = P1_20_SET_MASK +#define P1_20_CLR LPC_GPIO1->FIOCLR = P1_20_SET_MASK +#define P1_20_IS_SET (bool)(LPC_GPIO1->FIOPIN & P1_20_SET_MASK) +#define P1_20_IS_CLR !(P1_20_IS_SET) +#define LED2_USE P1_20_AS_OUTPUT;P1_20_AS_INPUT +#define LED2_ON P1_20_SET +#define LED2_OFF P1_20_CLR +#define LED2_IS_ON P1_20_IS_SET +#define LED2_TOGGLE P1_20_IS_SET?LED2_OFF:LED2_ON + +#define P1_21_SEL_MASK ~(3UL << 10) +#define P1_21_SET_MASK (1UL << 21) +#define P1_21_CLR_MASK ~(P1_21_SET_MASK) +#define P1_21_AS_OUTPUT LPC_PINCON->PINSEL3&=P1_21_SEL_MASK;LPC_GPIO1->FIODIR|=P1_21_SET_MASK +#define P1_21_AS_INPUT LPC_GPIO1->FIOMASK &= P1_21_CLR_MASK; +#define P1_21_SET LPC_GPIO1->FIOSET = P1_21_SET_MASK +#define P1_21_CLR LPC_GPIO1->FIOCLR = P1_21_SET_MASK +#define P1_21_IS_SET (bool)(LPC_GPIO1->FIOPIN & P1_21_SET_MASK) +#define P1_21_IS_CLR !(P1_21_IS_SET) +#define LED3_USE P1_21_AS_OUTPUT;P1_21_AS_INPUT +#define LED3_ON P1_21_SET +#define LED3_OFF P1_21_CLR +#define LED3_IS_ON P1_21_IS_SET +#define LED3_TOGGLE P1_21_IS_SET?LED3_OFF:LED3_ON + +#define P1_23_SEL_MASK ~(3UL << 14) +#define P1_23_SET_MASK (1UL << 23) +#define P1_23_CLR_MASK ~(P1_23_SET_MASK) +#define P1_23_AS_OUTPUT LPC_PINCON->PINSEL3&=P1_23_SEL_MASK;LPC_GPIO1->FIODIR|=P1_23_SET_MASK +#define P1_23_AS_INPUT LPC_GPIO1->FIOMASK &= P1_23_CLR_MASK; +#define P1_23_SET LPC_GPIO1->FIOSET = P1_23_SET_MASK +#define P1_23_CLR LPC_GPIO1->FIOCLR = P1_23_SET_MASK +#define P1_23_IS_SET (bool)(LPC_GPIO1->FIOPIN & P1_23_SET_MASK) +#define P1_23_IS_CLR !(P1_23_IS_SET) +#define LED4_USE P1_23_AS_OUTPUT;P1_23_AS_INPUT +#define LED4_ON P1_23_SET +#define LED4_OFF P1_23_CLR +#define LED4_IS_ON P1_23_IS_SET +#define LED4_TOGGLE P1_23_IS_SET?LED4_OFF:LED4_ON + +#ifndef UB +#define UB(x) LPC_UART0->RBR=x +#endif + +#ifndef UBB +#define UBB(x) { while((LPC_UART0->LSR&(1UL << 5)) == 0); LPC_UART0->RBR=x; } +#endif + +#endif /* AJK_LIB17_IOMACROS_H */ +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/inc/SimpleStepperMbed.h Mon May 02 10:02:18 2011 +0000 @@ -0,0 +1,85 @@ +/* + 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. +*/ + +#ifndef AJK_SIMPLESTEPPERMBED_H +#define AJK_SIMPLESTEPPERMBED_H + +#ifndef MBED_PINNAMES_H +#define MBED_PINNAMES_H + +#ifdef __cplusplus +extern "C" { +#endif + +typedef enum { + P0_0 = LPC_GPIO0_BASE, P0_1, P0_2, P0_3, P0_4, P0_5, P0_6, P0_7 + , P0_8, P0_9, P0_10, P0_11, P0_12, P0_13, P0_14, P0_15 + , P0_16, P0_17, P0_18, P0_19, P0_20, P0_21, P0_22, P0_23 + , P0_24, P0_25, P0_26, P0_27, P0_28, P0_29, P0_30, P0_31 + , P1_0, P1_1, P1_2, P1_3, P1_4, P1_5, P1_6, P1_7 + , P1_8, P1_9, P1_10, P1_11, P1_12, P1_13, P1_14, P1_15 + , P1_16, P1_17, P1_18, P1_19, P1_20, P1_21, P1_22, P1_23 + , P1_24, P1_25, P1_26, P1_27, P1_28, P1_29, P1_30, P1_31 + , P2_0, P2_1, P2_2, P2_3, P2_4, P2_5, P2_6, P2_7 + , P2_8, P2_9, P2_10, P2_11, P2_12, P2_13, P2_14, P2_15 + , P2_16, P2_17, P2_18, P2_19, P2_20, P2_21, P2_22, P2_23 + , P2_24, P2_25, P2_26, P2_27, P2_28, P2_29, P2_30, P2_31 + , P3_0, P3_1, P3_2, P3_3, P3_4, P3_5, P3_6, P3_7 + , P3_8, P3_9, P3_10, P3_11, P3_12, P3_13, P3_14, P3_15 + , P3_16, P3_17, P3_18, P3_19, P3_20, P3_21, P3_22, P3_23 + , P3_24, P3_25, P3_26, P3_27, P3_28, P3_29, P3_30, P3_31 + , P4_0, P4_1, P4_2, P4_3, P4_4, P4_5, P4_6, P4_7 + , P4_8, P4_9, P4_10, P4_11, P4_12, P4_13, P4_14, P4_15 + , P4_16, P4_17, P4_18, P4_19, P4_20, P4_21, P4_22, P4_23 + , P4_24, P4_25, P4_26, P4_27, P4_28, P4_29, P4_30, P4_31 + + // Mbed DIP Pin Names + , p5 = P0_9, p6 = P0_8, p7 = P0_7, p8 = P0_6, p9 = P0_0, p10 = P0_1 + , p11 = P0_18, p12 = P0_17, p13 = P0_15, p14 = P0_16, p15 = P0_23 + , p16 = P0_24, p17 = P0_25, p18 = P0_26, p19 = P1_30, p20 = P1_31 + , p21 = P2_5, p22 = P2_4, p23 = P2_3, p24 = P2_2, p25 = P2_1 + , p26 = P2_0, p27 = P0_11, p28 = P0_10, p29 = P0_5, p30 = P0_4 + + // Other Mbed Pin Names + , LED1 = P1_18, LED2 = P1_20, LED3 = P1_21, LED4 = P1_23 + , USBTX = P0_2, USBRX = P0_3 + + // Not connected + , NC = (int)0xFFFFFFFF + +} PinName; + +typedef enum { + PullUp = 0 + , Repeater = 1 + , PullNone = 2 + , PullDown = 3 + , OpenDrain = 4 +} PinMode; + +#ifdef __cplusplus +} +#endif + +#endif /* MBED_PINNAMES_H */ + +#endif /* AJK_SIMPLESTEPPERMBED_H */
--- /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 */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/inc/SimpleSteppers.h Mon May 02 10:02:18 2011 +0000 @@ -0,0 +1,262 @@ +/* + 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. +*/ + +#ifndef AJK_SIMPLESTEPPERS_H +#define AJK_SIMPLESTEPPERS_H + +#define SIMPLESTEPPER_F 100000 +#include "LPC17xx.h" +#include "core_cm3.h" +#include <stdint.h> + +#ifndef __ARMCC_VERSION +#include "SimpleStepperMbed.h" +#else +#include "mbed.h" +#endif + +#include "SimpleStepperOutput.h" + +namespace AjK { + +// Forward reference the main controller. +class SimpleStepperController; + +/** SimpleStepper + * + * SimpleStepper is a class designed to handle the pulse and direction + * signals for a stepper motor. A simple API is exposed to allow the + * setting of the pulse width and the number of pulses per second. + * + * Note, SimpleStepper uses the SimpleStepperController class to manage + * the TIMER2. SimpleStepperController and SimpleStepper take total + * control of the LPC17xx's TIMER2. Your application or other library that + * your application uses, should use TIMER2. + * + * @include example1.h + */ +class SimpleStepper { + +public: + enum MAT { MAT2_0, MAT2_1, MAT2_2, MAT2_3 }; + enum MATCH_OP { NothingOnMatch, ClrOnMatch, SetOnMatch, ToggleOnMatch }; + enum PULSE_STATE { PulseIdle, PulseAssert, PulseDeassert }; + enum STEPPER_STATE { Stopped, ConstantSpeed }; + +protected: + SimpleStepperController *_simpleStepperController; + SimpleStepperOutput *_direction; + + PinName _pulse; + MAT _pulseMAT; + uint32_t _operShift; + uint32_t _pMR; + uint32_t _match_shift; + uint32_t _EMmask; + uint32_t _EMCshift; + int _pulseLen; + int _pulseSense; + int _directionSense; + int _commandSpeed; + int64_t _pulseCounter; + int64_t _pulseWrapPos; + int64_t _pulseWrapNeg; + uint32_t _currentMatch; + + bool _maintainPositionData; + + PULSE_STATE _pulseState; + + STEPPER_STATE _stepperState; + + void init(void); + + void isr(uint32_t); + + void next_step(void); + +public: + friend class SimpleStepperController; + + /** Constructor + * + * PinName pulse can be p5, p6, p7 or p8 + * SimpleStepperOutput *direction is a pointer to an output. + * + * @param PinName The output for the pulse output. + * @param SimpleStepperOutput *direction The output pin for direction control + */ + SimpleStepper(PinName pulse, SimpleStepperOutput *direction = 0); + + /** Constructor + * + * PinName pulse can be p5, p6, p7 or p8 + * SimpleStepperOutput *direction is a pointer to an output. + * + * @param SimpleStepperController *con A pointer to a base controller. + * @param PinName The output for the pulse output. + * @param SimpleStepperOutput *direction The output pin for direction control + */ + SimpleStepper(SimpleStepperController *con, PinName pulse, SimpleStepperOutput *direction); + + /** setPulseSense + * + * Set's the logic value that pulse asserted assumes. Default is 1. + * + * 1 means pulse goes from 0 to 1 and remains 1 for pulseLen time then goes to 0. + * 0 means pulse goes from 1 to 0 and remains 0 for pulseLen time then goes to 1. + * + * @param int What is the logic sense for the pulse output. + */ + void setPulseSense(int i = 1) { _pulseSense = i; } + + /** setDirectionSense + * + * Set's the logic value that direction forward assumes. Default is 1. + * + * 1 means that the direction output is 1 for forward and 0 for reverse. + * 0 means that the direction output is 0 for forward and 1 for reverse. + * + * Additionally, for position:- + * 1 means forward pulses are counted upwards, reverse means counted downwards. + * 0 means forward pulses are counted downwards, reverse means counted upwards. + * + * @param int What is the logic sense for the direction output. + */ + void setDirectionSense(int i = 1) { _directionSense = i; } + + /** setPulseLen + * + * Used to set the pulse length. Default pulse length is 50us. + * If no arg supplied returns the current pulse length. + * <b>Note,</b> the length is specified as 10us increments. + * The default is 5 which is 50us + * @param int pulse length + * @return int the value of the pulse length. + */ + int setPulseLen(int i = 0) { if (i) _pulseLen = i; return _pulseLen; } + + /** setSpeed + * + * Set the motor speed in pulses per second. Zero stops all motor pulses. + * + * With the default pulseLen of 50us (5 timer "ticks") the maximum speed + * that can be set is 10000 pulses per second (pps) which will produce a square + * wave with 50% duty cycle. Pushing it beyond will give a square wave a duty + * cycle shifts so that the off time between pulses becomes shorter than the on + * pulse length. + * + * The pulseLen can be adjusted using setPulseLen() down even more to eek out + * some extra bandwidth. However, you really should be checking both the datasheet + * for your stepper motor amplifier and stepper motor. Running a stepper motor at + * such high speed may have electrical and mechanical issues. + * + * The arg raw is used when you want to "sync" channels. Suppose for example you + * have the following code to set the speed to two front wheels:- + * @code + * stepper0.setSpeed(100); + * stepper1.setSpeed(100); + * @endcode + * + * The problem here is they will be a few "clock ticks" out from each other as the + * TIMER2 TC increments between the two calls. If you wanted to make two motors sync + * together you can pass in the raw value of TIMER2 TC to make both functions calculate + * the same stepp values and so sync together:- + * @code + * uint32_t i = LPC_TIM2->TC; // Capture TC. + * stepper0.setSpeed(100, i); + * stepper1.setSpeed(100, i); + * @endcode + * + * The above code forces setSpeed() to calculate both axis in sync with respect to + * a common TC value. + * + * @param int steps_per_second Number of pulses per second required. + */ + void setSpeed(int steps_per_second = 0, uint32_t raw = 0); + + /** setSpeed + * + * Set the motor speed in pulses per second. Zero stops all motor pulses. + * @param double steps_per_second Number of pulses per second required. + */ + void setSpeed(double steps_per_second = 0, uint32_t raw = 0); + + /** setInterval + * + * Set the motor speed pulse interval. Zero stops all motor pulses. + * @param int interval + */ + void setInterval(int i = 0, uint32_t raw = 0); + + /** getPosition + * + * Get the current position (the pulse counter). + * + * @return int64_t The current position as maintained by the interrupts. + */ + int64_t getPosition(void) { return _pulseCounter; } + + /** setWrapPos + * + * Set the value that we should wrap the pulse position counter. + * Zero (default) means no wrap occurs. + * + * @param int64_t The value to wrap to NEG at. + */ + void setWrapPos(int64_t i = 0) { _pulseWrapPos = i; } + + /** setWrapNeg + * + * Set the value that we should wrap the pulse position counter. + * Zero (default) means no wrap occurs. + * + * @param int64_t The value to wrap to POS at. + */ + void setWrapNeg(int64_t i = 0) { _pulseWrapNeg = i; } + + /** setMaintainPositionData + * + * Setting this false removes the maintainence of positional data. + * This allows the interrupt service routine to not perform these + * steps (if not required) thus making the ISR run slightly fatser. + * You might want to do this if positional data isn't required. + */ + void setMaintainPositionData(bool b) { _maintainPositionData = b; } + +}; + +class SimpleStepperController { +protected: + SimpleStepper *_stepper[4]; + +public: + friend class SimpleStepper; + + SimpleStepperController(); + ~SimpleStepperController(); + void isr(void); +}; + +}; // namespace AjK ends + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/inc/example1.h Mon May 02 10:02:18 2011 +0000 @@ -0,0 +1,47 @@ + +#include "mbed.h" +#include "SimpleSteppers.h" + +SimpleStepperOutput led1(LED1); + +// SimpleStepperOutput is basically the same as +// Mbed's DigitalOut class. However, it's more +// portable to other platforms without having +// to also port the entire Mbed library. +SimpleStepperOutput sdir0(p17); +SimpleStepperOutput sdir1(p18); +SimpleStepperOutput sdir2(p19); +SimpleStepperOutput sdir3(p20); + +// Create four steppers. +// Stepper0 has the pulse output on p8 and dir on p17 +SimpleStepper stepper0(p8, &sdir0); +// Stepper0 has the pulse output on p7 and dir on p18 +SimpleStepper stepper1(p7, &sdir1); +// Stepper0 has the pulse output on p7 and dir on p19 +SimpleStepper stepper2(p6, &sdir2); +// Stepper0 has the pulse output on p7 and dir on p20 +SimpleStepper stepper3(p5, &sdir3); + +int main() { + pc.baud(115200); + + // We do not need to maintain the stepper position + // for this simple example. This reduces the amount + // of work the ISR has to do. + stepper0.setMaintainPositionData(false); + stepper1.setMaintainPositionData(false); + stepper2.setMaintainPositionData(false); + stepper3.setMaintainPositionData(false); + + // Set all steppers to top speed of 5000 pulses/second. + stepper0.setSpeed(5000); + stepper1.setSpeed(5000); + stepper2.setSpeed(5000); + stepper3.setSpeed(5000); + + while(1) { + led1 = !led1; + wait(0.2); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/SimpleStepperInst.cpp Mon May 02 10:02:18 2011 +0000 @@ -0,0 +1,41 @@ +/* + Copyright (c) 2010 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 "SimpleSteppers.h" +#include "IOmacros.h" + +#ifdef __ARMCC_VERSION +#define __SS_IRQ __irq +#else +#define __SS_IRQ +#endif + +namespace AjK { + +SimpleStepperController __simpleStepperController; + +extern "C" void TIMER2_IRQHandler(void) __SS_IRQ { + __simpleStepperController.isr(); + LPC_TIM2->IR = 0x3F; // Clear all possible TIMER2 interrupts. +} + +}; // namespace AjK ends.
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/SimpleSteppers.cpp Mon May 02 10:02:18 2011 +0000 @@ -0,0 +1,360 @@ +/* + Copyright (c) 2010 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 <math.h> +#include "SimpleSteppers.h" +#include "IOmacros.h" + +#define _PMR *((uint32_t *)_pMR) + +namespace AjK { + +extern SimpleStepperController __simpleStepperController; + +void TIMER2_IRQHandler(void); + +SimpleStepper::SimpleStepper(PinName pulse, SimpleStepperOutput *direction) +{ + _simpleStepperController = &__simpleStepperController; + _pulse = pulse; + _direction = direction; + init(); +} + +SimpleStepper::SimpleStepper(SimpleStepperController *con, PinName pulse, SimpleStepperOutput *direction) +{ + _simpleStepperController = con; + _pulse = pulse; + _direction = direction; + init(); +} + +void +SimpleStepper::init(void) +{ + _pulseCounter = 0; + _pulseWrapPos = 0; + _pulseWrapNeg = 0; + + _maintainPositionData = true; + + setPulseSense(1); + setDirectionSense(1); + + switch (_pulse) { + case P0_6: // Mbed p8 + _pulseMAT = MAT2_0; + _operShift = 4; + _pMR = 0x40090018; // T2MR0 + _match_shift = 0; + _EMmask = 1; + _EMCshift = 4; + _simpleStepperController->_stepper[0] = this; + if (_pulseSense) LPC_TIM2->EMR &= ~_EMmask; else LPC_TIM2->EMR |= _EMmask; + LPC_PINCON->PINSEL0 |= (3UL << 12); + break; + case P0_7: // Mbed p7 + _pulseMAT = MAT2_1; + _operShift = 6; + _pMR = 0x4009001C; // T2MR1 + _match_shift = 3; + _EMmask = 2; + _EMCshift = 6; + _simpleStepperController->_stepper[1] = this; + if (_pulseSense) LPC_TIM2->EMR &= ~_EMmask; else LPC_TIM2->EMR |= _EMmask; + LPC_PINCON->PINSEL0 |= (3UL << 14); + break; + case P0_8: // Mbed p6 + _pulseMAT = MAT2_2; + _operShift = 8; + _pMR = 0x40090020; // T2MR2 + _match_shift = 6; + _EMmask = 4; + _EMCshift = 8; + _simpleStepperController->_stepper[2] = this; + if (_pulseSense) LPC_TIM2->EMR &= ~_EMmask; else LPC_TIM2->EMR |= _EMmask; + LPC_PINCON->PINSEL0 |= (3UL << 16); + break; + case P0_9: // Mbed p5 + _pulseMAT = MAT2_3; + _operShift = 10; + _pMR = 0x40090024; // T2MR3 + _match_shift = 9; + _EMmask = 8; + _EMCshift = 10; + _simpleStepperController->_stepper[3] = this; + if (_pulseSense) LPC_TIM2->EMR &= ~_EMmask; else LPC_TIM2->EMR |= _EMmask; + LPC_PINCON->PINSEL0 |= (3UL << 18); + break; + default: + while(1); /* ToDo, proper error reporting. */ + } + + + // The default pulse length. 5 * (1/SIMPLESTEPPER_F) = 100us. + _pulseLen = 5; + + // Initial state machine conditions. + _pulseState = PulseIdle; + _stepperState = Stopped; +} + +void +SimpleStepper::setInterval(int interval, uint32_t raw) +{ + + if (interval == 0) { setSpeed((int)0); } + else { + int n = interval; + if (n < 0) n *= -1; + if (_direction) { + if (_directionSense) { + if (interval >= 0.0) _direction->write(1); + if (interval < 0.0) _direction->write(0); + } + else { + if (interval >= 0.0) _direction->write(0); + if (interval < 0.0) _direction->write(1); + } + } + _commandSpeed = n - _pulseLen; + _pulseState = PulseAssert; + _stepperState = ConstantSpeed; + if (raw) { + _PMR = raw + _commandSpeed; + } + else { + _PMR = LPC_TIM2->TC + _commandSpeed; + } + if (_pulseSense) LPC_TIM2->EMR &= ~_EMmask; else LPC_TIM2->EMR |= _EMmask; + LPC_TIM2->MCR &= ~(7UL << _match_shift); + LPC_TIM2->MCR |= (1UL << _match_shift); + } +} + +void +SimpleStepper::setSpeed(double steps_per_second, uint32_t raw) +{ + int i = 0; + + if (steps_per_second == 0.0) { setSpeed(i); } + else { + double fractpart, intpart; + fractpart = modf (steps_per_second , &intpart); + if (fractpart >= 0.50) intpart++; + double n = intpart; + if (n < 0.0) n *= -1.0; + if (_direction) { + if (_directionSense) { + if (steps_per_second >= 0.0) _direction->write(1); + if (steps_per_second < 0.0) _direction->write(0); + } + else { + if (steps_per_second >= 0.0) _direction->write(0); + if (steps_per_second < 0.0) _direction->write(1); + } + } + _commandSpeed = (int)(((double)SIMPLESTEPPER_F / n)) - _pulseLen; + _pulseState = PulseAssert; + _stepperState = ConstantSpeed; + if (raw) { + _PMR = raw + _commandSpeed; + } + else { + _PMR = LPC_TIM2->TC + _commandSpeed; + } + if (_pulseSense) LPC_TIM2->EMR &= ~_EMmask; else LPC_TIM2->EMR |= _EMmask; + LPC_TIM2->MCR &= ~(7UL << _match_shift); + LPC_TIM2->MCR |= (1UL << _match_shift); + } +} + +void +SimpleStepper::setSpeed(int steps_per_second, uint32_t raw) +{ + if (steps_per_second == 0) { + LPC_TIM2->EMR |= (NothingOnMatch << _EMCshift); + LPC_TIM2->MCR &= ~(7UL << _match_shift); + if (_pulseSense) LPC_TIM2->EMR &= ~_EMmask; else LPC_TIM2->EMR |= _EMmask; + _stepperState = Stopped; + _pulseState = PulseIdle; + _commandSpeed = 0; + } + else { + int n = steps_per_second; + if (n < 0) n *= -1; + if (_direction) { + if (_directionSense) { + if (steps_per_second >= 0) _direction->write(1); + if (steps_per_second < 0) _direction->write(0); + } + else { + if (steps_per_second >= 0) _direction->write(0); + if (steps_per_second < 0) _direction->write(1); + } + } + _commandSpeed = (SIMPLESTEPPER_F / n) - _pulseLen; + _pulseState = PulseAssert; + _stepperState = ConstantSpeed; + if (raw) { + _PMR = raw + _commandSpeed; + } + else { + _PMR = LPC_TIM2->TC + _commandSpeed; + } + if (_pulseSense) LPC_TIM2->EMR &= ~_EMmask; else LPC_TIM2->EMR |= _EMmask; + LPC_TIM2->MCR &= ~(7UL << _match_shift); + LPC_TIM2->MCR |= (1UL << _match_shift); + } +} + +void +SimpleStepper::next_step(void) +{ + _PMR += _commandSpeed; + + switch(_pulseSense) { + case 1: + LPC_TIM2->EMR &= ~(3UL << _EMCshift); + LPC_TIM2->EMR |= (SetOnMatch << _EMCshift); + break; + case 0: + LPC_TIM2->EMR &= ~(3UL << _EMCshift); + LPC_TIM2->EMR |= (ClrOnMatch << _EMCshift); + break; + } + + // Next IRQ will automatically assert the pulse. + _pulseState = PulseAssert; +} + +void +SimpleStepper::isr(uint32_t ir) +{ + // Test to see if this interrupt is for us. + if (ir & _EMmask) { + + if (_stepperState == Stopped) { + if (_pulseSense) LPC_TIM2->EMR &= ~_EMmask; else LPC_TIM2->EMR |= _EMmask; + return; + } + + switch(_pulseState) { + case PulseIdle: + if (_pulseSense) LPC_TIM2->EMR &= ~_EMmask; else LPC_TIM2->EMR |= _EMmask; + _currentMatch = _PMR; // Store the current match value for profile(). + next_step(); + break; + + case PulseAssert: // Pulse has just been asserted on MAT2_x. + _PMR += _pulseLen; // We now program for the deassert IRQ to occur at the required time. + LPC_TIM2->EMR &= ~(ToggleOnMatch << _EMCshift); // At next IRQ we want to switch the pulse off... + LPC_TIM2->EMR |= (ToggleOnMatch << _EMCshift); // ... we do this by toggling it. + _pulseState = PulseDeassert; // Set state for next interrupt. + + if (_maintainPositionData) { + if (_directionSense) { + if (_commandSpeed > 0) { + _pulseCounter++; + if (_pulseWrapPos && _pulseCounter >= _pulseWrapPos) { + _pulseCounter = _pulseWrapNeg + 1; + } + } + if (_commandSpeed < 0) { + _pulseCounter--; + if (_pulseWrapNeg && _pulseCounter <= _pulseWrapNeg) { + _pulseCounter = _pulseWrapPos - 1; + } + } + } + else { + if (_commandSpeed > 0) { + _pulseCounter--; + if (_pulseWrapNeg && _pulseCounter <= _pulseWrapNeg) { + _pulseCounter = _pulseWrapPos - 1; + } + } + if (_commandSpeed < 0) { + _pulseCounter++; + if (_pulseWrapPos && _pulseCounter >= _pulseWrapPos) { + _pulseCounter = _pulseWrapNeg + 1; + } + } + } + } + break; + + case PulseDeassert: // Pulse has just been deasserted on MAT2_x. + LPC_TIM2->EMR &= ~(NothingOnMatch << _EMCshift); // No further action... + LPC_TIM2->EMR |= (NothingOnMatch << _EMCshift); // ... just in case. + _pulseState = PulseIdle; // Set state for next interrupt (profile() may change this). + _currentMatch = _PMR; // Store the current match value for profile(). + next_step(); + break; + } + } +} + +// ************************************************** +// * Controller class SimpleStepperController code. * +// ************************************************** + +SimpleStepperController::SimpleStepperController() +{ + for (int i = 0; i < 4; i++) _stepper[i] = 0; + + uint32_t pr = (uint32_t)(SystemCoreClock / 8 / SIMPLESTEPPER_F); + + LPC_SC->PCONP |= (1UL << 22); // TIM2 On + LPC_SC->PCLKSEL1 |= (3UL << 12); // CCLK/8 = 12MHz + LPC_TIM2->PR = pr - 1; // TC clocks at SIMPLESTEPPER_F hz. + LPC_TIM2->MR0 = 0; + LPC_TIM2->MR1 = 0; + LPC_TIM2->MR2 = 0; + LPC_TIM2->MR3 = 0; + LPC_TIM2->MCR = 0; + + // Enable interrupts + NVIC_EnableIRQ(TIMER2_IRQn); + + // Start timer operations. + LPC_TIM2->TCR = 2; // reset + LPC_TIM2->TCR = 1; // enable +} + +SimpleStepperController::~SimpleStepperController() +{ + NVIC_DisableIRQ(TIMER2_IRQn); + LPC_SC->PCONP &= ~(1UL << 22); // TIM2 Off. +} + +void +SimpleStepperController::isr(void) +{ + uint32_t ir = LPC_TIM2->IR & 0xF; + if (_stepper[0] && ir & 1) _stepper[0]->isr(ir); + if (_stepper[1] && ir & 2) _stepper[1]->isr(ir); + if (_stepper[2] && ir & 4) _stepper[2]->isr(ir); + if (_stepper[3] && ir & 8) _stepper[3]->isr(ir); +} + +}; // namespace AjK ends.