Skip to content

Commit

Permalink
GpioIterator iterates over GpioPinRef objects in port. #133
Browse files Browse the repository at this point in the history
  • Loading branch information
andysworkshop committed Oct 31, 2015
1 parent d5c5753 commit 550d627
Show file tree
Hide file tree
Showing 11 changed files with 446 additions and 4 deletions.
11 changes: 10 additions & 1 deletion lib/include/config/gpio.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,10 @@
* external interface includes this as a dependency so there's little chance that you'll need to include it directly.
*/

// dependencies

#include "util/BitHacks.h"

// generic peripheral includes

#include "gpio/GpioPortBase.h"
Expand All @@ -23,6 +27,8 @@

#include "gpio/f1/GpioPinMap.h"
#include "gpio/f1/Gpio.h"
#include "gpio/GpioPinRef.h"
#include "gpio/GpioIterator.h"
#include "gpio/f1/GpioPort.h"
#include "gpio/f1/features/DigitalOutputFeature.h"
#include "gpio/f1/features/DigitalInputFeature.h"
Expand All @@ -35,6 +41,8 @@

#include "gpio/f4/GpioPinMap.h"
#include "gpio/f4/Gpio.h"
#include "gpio/GpioPinRef.h"
#include "gpio/GpioIterator.h"
#include "gpio/f4/GpioPort.h"
#include "gpio/f4/features/DigitalOutputFeature.h"
#include "gpio/f4/features/DigitalInputFeature.h"
Expand All @@ -47,6 +55,8 @@

#include "gpio/f0/GpioPinMap.h"
#include "gpio/f0/Gpio.h"
#include "gpio/GpioPinRef.h"
#include "gpio/GpioIterator.h"
#include "gpio/f0/GpioPort.h"
#include "gpio/f0/features/DigitalOutputFeature.h"
#include "gpio/f0/features/DigitalInputFeature.h"
Expand All @@ -59,4 +69,3 @@
// generic utility includes

#include "gpio/GpioPinInitialiser.h"
#include "gpio/GpioPinRef.h"
126 changes: 126 additions & 0 deletions lib/include/gpio/GpioIterator.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
/*
* This file is a part of the open source stm32plus library.
* Copyright (c) 2011,2012,2013,2014 Andy Brown <www.andybrown.me.uk>
* Please see website for licensing terms.
*/


#pragma once


namespace stm32plus {


/*
* STL compatible forward iterator that can be used to iterate over GpioPinRef
* instances in a port
*/

struct GpioIterator {

Gpio **_pinHandlers;
GPIO_TypeDef *_peripheralAddress;
uint8_t _index;
GpioPinRef _current;


/**
* Default constructor
*/

GpioIterator() {}


/**
* Construct with initial parameters
* @param pinHandlers The base of the sparse array of Gpio pointers
* @param peripheralAddress The GPIO peripheral address
* @param index The initial index for this iterator
*/

GpioIterator(Gpio **pinHandlers,GPIO_TypeDef *peripheralAddress,uint8_t index) {
_pinHandlers=pinHandlers;
_peripheralAddress=peripheralAddress;
_index=index;
}


/**
* Copy constructor
* @param it The iterator to copy from
*/

GpioIterator(const GpioIterator& it) {
_pinHandlers=it._pinHandlers;
_peripheralAddress=it._peripheralAddress;
_index=it._index;
}


/**
* Dereference operator
* @return reference to Gpio object at position
*/

GpioPinRef& operator*() {
Gpio& r(*_pinHandlers[_index]);
r.setSelectedPin(_index);
_current=r;
return _current;
}


/**
* Pointer operator
* @return
*/

GpioPinRef *operator->() {
return &(operator*());
}

GpioIterator& operator++() {
increment();
return *this;
}

GpioIterator& operator++(int) {
GpioIterator& tmp=*this;
increment();
return tmp;
}

GpioIterator& operator--() {
decrement();
return *this;
}

GpioIterator& operator--(int) {
GpioIterator& tmp=*this;
increment();
return tmp;
}


bool operator==(const GpioIterator& rhs) const {
return _peripheralAddress==rhs._peripheralAddress && _index==rhs._index;
}

bool operator!=(const GpioIterator& rhs) const {
return _peripheralAddress!=rhs._peripheralAddress || _index!=rhs._index;
}


void increment() {
do {
_index++;
} while(_pinHandlers[_index]==nullptr && _index!=16);
}

void decrement() {
do {
_index--;
} while(_pinHandlers[_index]==nullptr);
}
};
}
84 changes: 82 additions & 2 deletions lib/include/gpio/GpioPinRef.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,15 @@ namespace stm32plus {

GPIO_TypeDef *getPeripheralAddress() const;
uint16_t getPin() const;
uint8_t getPinIndex() const;

GpioPinRef& operator=(const GpioPinRef& src);
GpioPinRef& operator=(const Gpio& src);

bool operator==(const GpioPinRef& src) const;
bool operator!=(const GpioPinRef& src) const;

Gpio::GpioModeType getMode() const;
};


Expand Down Expand Up @@ -65,6 +74,7 @@ namespace stm32plus {

/**
* Return the port
* @return The GPIO_TypeDef port address
*/

inline GPIO_TypeDef* GpioPinRef::getPeripheralAddress() const {
Expand All @@ -73,7 +83,8 @@ namespace stm32plus {


/**
* Return the pin
* Return the pin. This is the pin bit mask (1,2,4,8,16...)
* @return The pin bit mask.
*/

inline uint16_t GpioPinRef::getPin() const {
Expand All @@ -82,7 +93,7 @@ namespace stm32plus {


/**
* Set the pin
* Set the pin to HIGH
*/

inline void GpioPinRef::set() const {
Expand Down Expand Up @@ -116,4 +127,73 @@ namespace stm32plus {
inline bool GpioPinRef::read() const {
return GPIO_ReadInputDataBit(_peripheralAddress,_pin);
}


/**
* Assignment operator from GpioPinRef
* @param src the object to copy from
* @return self
*/

inline GpioPinRef& GpioPinRef::operator=(const GpioPinRef& src) {
_peripheralAddress=src.getPeripheralAddress();
_pin=src.getPin();
return *this;
}



/**
* Assignment operator from Gpio
* @param src the object to copy from
* @return self
*/

inline GpioPinRef& GpioPinRef::operator=(const Gpio& src) {
_peripheralAddress=src.getPeripheralAddress();
_pin=src.getSelectedPin();
return *this;
}


/**
* Equality comparison operator
* @param src the object to compare to
* @return true if equal
*/

inline bool GpioPinRef::operator==(const GpioPinRef& src) const {
return _peripheralAddress==src._peripheralAddress && _pin==src._pin;
}


/**
* Inequality comparison operator
* @param src the object to compare to
* @return true if not equal
*/

inline bool GpioPinRef::operator!=(const GpioPinRef& src) const {
return _peripheralAddress!=src._peripheralAddress || _pin!=src._pin;
}


/**
* Get the pin index (0..15)
* @return the pin index in the port
*/

inline uint8_t GpioPinRef::getPinIndex() const {
return bithacks::firstSetBit(_pin);
}


/**
* Get the pin mode type (input,output,analog,alternate function)
* @return the mode type
*/

inline Gpio::GpioModeType GpioPinRef::getMode() const {
return Gpio::getMode(_peripheralAddress,_pin);
}
}
7 changes: 7 additions & 0 deletions lib/include/gpio/GpioPortBase.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ namespace stm32plus {
public:
Gpio *_pinHandlers[16];
GPIO_TypeDef *_peripheralAddress;
uint8_t _low;

public:
GpioPortBase(GPIO_TypeDef *peripheralAddress);
Expand All @@ -38,6 +39,8 @@ namespace stm32plus {

inline GpioPortBase::GpioPortBase(GPIO_TypeDef *peripheralAddress)
: _peripheralAddress(peripheralAddress) {
memset(_pinHandlers,'\0',sizeof(_pinHandlers));
_low=15;
}


Expand All @@ -48,7 +51,11 @@ namespace stm32plus {
*/

inline void GpioPortBase::setPinHandler(uint8_t index,Gpio *pinHandler) {

_pinHandlers[index]=pinHandler;

if(index<_low)
_low=index;
}


Expand Down
44 changes: 44 additions & 0 deletions lib/include/gpio/f0/Gpio.h
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,9 @@ namespace stm32plus {
uint16_t getSelectedPin() const;

GPIO_TypeDef *getPeripheralAddress() const;

static GpioModeType getMode(GPIO_TypeDef *peripheralAddress,uint16_t pin);
GpioModeType getMode() const;
};


Expand Down Expand Up @@ -353,4 +356,45 @@ namespace stm32plus {
}
}
}


/**
* Get the pin mode type (input,output,analog,alternate function)
* @param peripheralAddress the peripheral register address
* @param pin the pin bitmask
* @return The mode type
*/

inline Gpio::GpioModeType Gpio::getMode(GPIO_TypeDef *peripheralAddress,uint16_t pin) {

uint8_t pinIndex;

pinIndex=bithacks::firstSetBit(pin);

switch((peripheralAddress->MODER >> (pinIndex*2)) & 0x3) {

case 0:
return Gpio::INPUT;

case 1:
return Gpio::OUTPUT;

case 2:
return Gpio::ALTERNATE_FUNCTION;

case 3:
default:
return Gpio::ANALOG;
}
}


/**
* Get the pin mode type (input,output,analog,alternate function)
* @return the mode type
*/

inline Gpio::GpioModeType Gpio::getMode() const {
return getMode(_peripheralAddress,_selectedPin);
}
}
Loading

0 comments on commit 550d627

Please sign in to comment.