Replacement for regular GPIO (DigitalIn, DigitalOut, DigitalInOut) classes which has superior speed.
Fork of FastIO by
Revision 0:d394ebd01052, committed 2014-07-01
- Comitter:
- Sissors
- Date:
- Tue Jul 01 17:04:08 2014 +0000
- Child:
- 1:85a4a54f15e3
- Commit message:
- v1.0
Changed in this revision
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/FastIO.h Tue Jul 01 17:04:08 2014 +0000 @@ -0,0 +1,152 @@ +#ifndef __FAST_IO_H +#define __FAST_IO_H + +#include "FastIO_LPC1768.h" +#include "FastIO_LPC11UXX.h" +#include "FastIO_KLXX.h" + +#ifndef INIT_PIN +#error Target is not supported +#endif + +#include "mbed.h" + +/** + * Faster alternative compared to regular DigitalInOut + * + * Except the constructor it is compatible with regular DigitalInOut. + * Code is based on Igor Skochinsky's code (http://mbed.org/users/igorsk/code/FastIO/) + */ +template <PinName pin> class FastInOut +{ +public: + /** + * Construct new FastInOut object + * + * @code + * FastInOut<LED1> led1; + * @endcode + * + * No initialization is done regarding input/output mode, + * FastIn/FastOut can be used if that is required + * + * @param pin pin the FastOut object should be used for + */ + FastInOut() { + INIT_PIN; + } + + void write(int value) { + if ( value ) + WRITE_PIN_SET; + else + WRITE_PIN_CLR; + } + int read() { + return READ_PIN; + } + + void mode(PinMode pull) { + SET_MODE(pull); + } + + void output() { + SET_DIR_OUTPUT; + } + + void input() { + SET_DIR_INPUT; + } + + FastInOut& operator= (int value) { + write(value); + return *this; + }; + FastInOut& operator= (FastInOut& rhs) { + return write(rhs.read()); + }; + operator int() { + return read(); + }; + + private: + fastio_vars container; +}; + +/** + * Faster alternative compared to regular DigitalOut + * + * Except the constructor it is compatible with regular DigitalOut. Aditionally all + * functions from DigitalInOut are also available (only initialization is different) + * Code is based on Igor Skochinsky's code (http://mbed.org/users/igorsk/code/FastIO/) + */ +template <PinName pin, int initial = 0> class FastOut : public FastInOut<pin> +{ +public: + /** + * Construct new FastOut object + * + * @code + * FastOut<LED1> led1; + * @endcode + * + * @param pin pin the FastOut object should be used for + * @param initial (optional) initial state of the pin after construction: default is 0 (low) + */ + FastOut() { + FastInOut<pin>::FastInOut(); + write(initial); + SET_DIR_OUTPUT; + } + + FastOut& operator= (int value) { + this->write(value); + return *this; + }; + FastOut& operator= (FastOut& rhs) { + return this->write(rhs.read()); + }; + operator int() { + return this->read(); + }; +}; + +/** + * Faster alternative compared to regular DigitalIn + * + * Except the constructor it is compatible with regular DigitalIn. Aditionally all + * functions from DigitalInOut are also available (only initialization is different) + * Code is based on Igor Skochinsky's code (http://mbed.org/users/igorsk/code/FastIO/) + */ +template <PinName pin, PinMode mode = PullDefault> class FastIn : public FastInOut<pin> +{ +public: + /** + * Construct new FastIn object + * + * @code + * FastIn<LED1> led1; + * @endcode + * + * @param pin pin the FastIn object should be used for + * @param mode (optional) initial mode of the pin after construction: default is PullDefault + */ + FastIn() { + FastInOut::FastInOut(); + SET_MODE(mode); + SET_DIR_INPUT; + } + + FastIn& operator= (int value) { + this->write(value); + return *this; + }; + FastIn& operator= (FastIn& rhs) { + return this->write(rhs.read()); + }; + operator int() { + return this->read(); + }; +}; + +#endif \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/FastIO_KLXX.h Tue Jul 01 17:04:08 2014 +0000 @@ -0,0 +1,25 @@ +#ifdef TARGET_KLXX + +#include "mbed.h" +#include "pinmap.h" + +typedef struct { + uint32_t mask; +} fastio_vars; + +#define PORT_BASE ((FGPIO_Type *)(FPTA_BASE + ((unsigned int)pin >> PORT_SHIFT) * 0x40)) +#define PINMASK (1 << ((pin & 0x7F) >> 2)) +#define PCR ((__IO uint32_t*)(PORTA_BASE + pin)) + +#define INIT_PIN container.mask = PINMASK; pin_function(pin, 1) + +#define SET_DIR_INPUT (PORT_BASE->PDDR &= ~PINMASK) +#define SET_DIR_OUTPUT (PORT_BASE->PDDR |= PINMASK) +#define SET_MODE(pull) (*PCR = (*PCR & ~0x3) | pull) + +#define WRITE_PIN_SET (PORT_BASE->PSOR |= PINMASK) +#define WRITE_PIN_CLR (PORT_BASE->PCOR |= PINMASK) + +#define READ_PIN ((PORT_BASE->PDIR & container.mask) ? 1 : 0) + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/FastIO_LPC11UXX.h Tue Jul 01 17:04:08 2014 +0000 @@ -0,0 +1,37 @@ +#ifdef TARGET_LPC11UXX + +#include "mbed.h" +#include "pinmap.h" + +typedef struct { + uint32_t mask; +} fastio_vars; + +#define PORT ((unsigned int)pin >> PORT_SHIFT) +#define PINMASK (1 << ((int)pin & 0x1F)) +static inline void initpin(PinName pin); + +#define INIT_PIN container.mask = PINMASK; initpin(pin) + +#define SET_DIR_INPUT (LPC_GPIO->DIR[PORT] &= ~PINMASK) +#define SET_DIR_OUTPUT (LPC_GPIO->DIR[PORT] |= PINMASK) +#define SET_MODE(pull) (pin_mode(pin, pull)) + +#define WRITE_PIN_SET (LPC_GPIO->SET[PORT] = PINMASK) +#define WRITE_PIN_CLR (LPC_GPIO->CLR[PORT] = PINMASK) + +#define READ_PIN ((LPC_GPIO->PIN[PORT] & container.mask) ? 1 : 0) + +static inline void initpin(PinName pin) { + int f = ((pin == P0_0) || + (pin == P0_10) || + (pin == P0_11) || + (pin == P0_12) || + (pin == P0_13) || + (pin == P0_14) || + (pin == P0_15)) ? (1) : (0); + + pin_function(pin, f); +} + +#endif \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/FastIO_LPC1768.h Tue Jul 01 17:04:08 2014 +0000 @@ -0,0 +1,27 @@ +#ifdef TARGET_LPC1768 + +#include "mbed.h" +#include "pinmap.h" + +typedef struct { + uint32_t mask; +} fastio_vars; + +#define LPC_GPIO ((LPC_GPIO_TypeDef*)(pin & ~0x1F)) +#define PINMASK (1UL << (((pin) - P0_0)%32)) + +#define PINSELREG (*(volatile uint32_t*)(LPC_PINCON_BASE + 4*(((pin) - P0_0)/16))) +#define PINSELMASK (0x03 << (((pin - P0_0)%16)*2) ) + +#define INIT_PIN container.mask = PINMASK; (PINSELREG &= ~PINSELMASK) + +#define SET_DIR_INPUT (LPC_GPIO->FIODIR &= ~PINMASK) +#define SET_DIR_OUTPUT (LPC_GPIO->FIODIR |= PINMASK) +#define SET_MODE(pull) (pin_mode(pin, pull)) + +#define WRITE_PIN_SET (LPC_GPIO->FIOSET = PINMASK) +#define WRITE_PIN_CLR (LPC_GPIO->FIOCLR = PINMASK) + +#define READ_PIN ((LPC_GPIO->FIOPIN & container.mask) ? 1 : 0) + +#endif \ No newline at end of file