Added iterators to all io ports

This commit is contained in:
John Wellbelove 2017-04-17 22:03:21 +01:00
parent 0338612f48
commit f4c7f1aa01
2 changed files with 532 additions and 28 deletions

View File

@ -36,6 +36,7 @@ SOFTWARE.
///\ingroup utilities
#include <stdint.h>
#include <iterator>
#include "nullptr.h"
#include "parameter_type.h"
@ -55,7 +56,7 @@ namespace etl
public:
class iterator
class iterator : public std::iterator<std::bidirectional_iterator_tag, T>
{
typedef io_port_rw<T, ADDRESS> iop_t;
@ -67,14 +68,14 @@ namespace etl
}
iterator(const iterator& other)
: p_iop(other)
: p_iop(other.p_iop)
{
}
iterator& operator =(const iterator& other)
{
p_iop = other.p_iop;
return *this;
return *this;
}
iop_t& operator *()
@ -160,6 +161,58 @@ namespace etl
public:
class iterator : public std::iterator<std::bidirectional_iterator_tag, T>
{
typedef io_port_ro<T, ADDRESS> iop_t;
public:
iterator(iop_t& iop)
: p_iop(&iop)
{
}
iterator(const iterator& other)
: p_iop(other.p_iop)
{
}
iterator& operator =(const iterator& other)
{
p_iop = other.p_iop;
return *this;
}
const iop_t& operator *() const
{
return *p_iop;
}
iterator& operator ++()
{
return *this;
}
iterator operator ++(int)
{
return *this;
}
iterator& operator --()
{
return *this;
}
iterator operator --(int)
{
return *this;
}
private:
iop_t* p_iop;
};
/// Read.
operator T() volatile const
{
@ -177,6 +230,12 @@ namespace etl
{
return reinterpret_cast<pointer_t>(ADDRESS);
}
/// Get the iterator.
iterator get_iterator()
{
return iterator(*this);
}
};
//***************************************************************************
@ -195,6 +254,58 @@ namespace etl
public:
class iterator : public std::iterator<std::bidirectional_iterator_tag, T>
{
typedef io_port_wo<T, ADDRESS> iop_t;
public:
iterator(iop_t& iop)
: p_iop(&iop)
{
}
iterator(const iterator& other)
: p_iop(other.p_iop)
{
}
iterator& operator =(const iterator& other)
{
p_iop = other.p_iop;
return *this;
}
iop_t& operator *()
{
return *p_iop;
}
iterator& operator ++()
{
return *this;
}
iterator operator ++(int)
{
return *this;
}
iterator& operator --()
{
return *this;
}
iterator operator --(int)
{
return *this;
}
private:
iop_t* p_iop;
};
/// Write.
void operator =(parameter_t value)
{
@ -206,6 +317,12 @@ namespace etl
{
return reinterpret_cast<pointer_t>(ADDRESS);
}
/// Get the iterator.
iterator get_iterator()
{
return iterator(*this);
}
};
//***************************************************************************
@ -221,6 +338,63 @@ namespace etl
public:
class iterator : public std::iterator<std::bidirectional_iterator_tag, T>
{
typedef io_port_wos<T, ADDRESS> iop_t;
public:
iterator(iop_t& iop)
: p_iop(&iop)
{
}
iterator(const iterator& other)
: p_iop(other.p_iop)
{
}
iterator& operator =(const iterator& other)
{
p_iop = other.p_iop;
return *this;
}
iop_t& operator *()
{
return *p_iop;
}
const iop_t& operator *() const
{
return *p_iop;
}
iterator& operator ++()
{
return *this;
}
iterator operator ++(int)
{
return *this;
}
iterator& operator --()
{
return *this;
}
iterator operator --(int)
{
return *this;
}
private:
iop_t* p_iop;
};
/// Read.
operator T() const
{
@ -247,6 +421,12 @@ namespace etl
return reinterpret_cast<pointer_t>(ADDRESS);
}
/// Get the iterator.
iterator get_iterator()
{
return iterator(*this);
}
private:
T shadow_value;
@ -266,6 +446,64 @@ namespace etl
public:
class iterator : public std::iterator<std::bidirectional_iterator_tag, T>
{
typedef io_port_rw<T, 0> iop_t;
public:
iterator(iop_t& iop)
: p_iop(&iop)
{
}
iterator(const iterator& other)
: p_iop(other.p_iop)
{
}
iterator& operator =(const iterator& other)
{
p_iop = other.p_iop;
return *this;
}
iop_t& operator *()
{
return *p_iop;
}
const iop_t& operator *() const
{
return *p_iop;
}
iterator& operator ++()
{
return *this;
}
iterator operator ++(int)
{
return *this;
}
iterator& operator --()
{
return *this;
}
iterator operator --(int)
{
return *this;
}
private:
iop_t* p_iop;
};
// Default constructor.
io_port_rw()
: address(nullptr)
@ -290,6 +528,12 @@ namespace etl
return address;
}
/// Get the iterator.
iterator get_iterator()
{
return iterator(*this);
}
/// Read.
operator T() volatile const
{
@ -327,6 +571,58 @@ namespace etl
public:
class iterator : public std::iterator<std::bidirectional_iterator_tag, T>
{
typedef io_port_ro<T, 0> iop_t;
public:
iterator(iop_t& iop)
: p_iop(&iop)
{
}
iterator(const iterator& other)
: p_iop(other.p_iop)
{
}
iterator& operator =(const iterator& other)
{
p_iop = other.p_iop;
return *this;
}
const iop_t& operator *() const
{
return *p_iop;
}
iterator& operator ++()
{
return *this;
}
iterator operator ++(int)
{
return *this;
}
iterator& operator --()
{
return *this;
}
iterator operator --(int)
{
return *this;
}
private:
iop_t* p_iop;
};
// Default constructor.
io_port_ro()
: address(nullptr)
@ -350,6 +646,12 @@ namespace etl
return address;
}
/// Get the iterator.
iterator get_iterator()
{
return iterator(*this);
}
/// Read.
operator T() volatile const
{
@ -385,6 +687,58 @@ namespace etl
public:
class iterator : public std::iterator<std::bidirectional_iterator_tag, T>
{
typedef io_port_wo<T, 0> iop_t;
public:
iterator(iop_t& iop)
: p_iop(&iop)
{
}
iterator(const iterator& other)
: p_iop(other.p_iop)
{
}
iterator& operator =(const iterator& other)
{
p_iop = other.p_iop;
return *this;
}
iop_t& operator *()
{
return *p_iop;
}
iterator& operator ++()
{
return *this;
}
iterator operator ++(int)
{
return *this;
}
iterator& operator --()
{
return *this;
}
iterator operator --(int)
{
return *this;
}
private:
iop_t* p_iop;
};
typedef typename etl::parameter_type<T>::type parameter_t;
// Default constructor.
@ -411,6 +765,12 @@ namespace etl
return address;
}
/// Get the iterator.
iterator get_iterator()
{
return iterator(*this);
}
/// Write.
void operator =(parameter_t value)
{
@ -439,6 +799,63 @@ namespace etl
public:
class iterator : public std::iterator<std::bidirectional_iterator_tag, T>
{
typedef io_port_wos<T, 0> iop_t;
public:
iterator(iop_t& iop)
: p_iop(&iop)
{
}
iterator(const iterator& other)
: p_iop(other.p_iop)
{
}
iterator& operator =(const iterator& other)
{
p_iop = other.p_iop;
return *this;
}
iop_t& operator *()
{
return *p_iop;
}
const iop_t& operator *() const
{
return *p_iop;
}
iterator& operator ++()
{
return *this;
}
iterator operator ++(int)
{
return *this;
}
iterator& operator --()
{
return *this;
}
iterator operator --(int)
{
return *this;
}
private:
iop_t* p_iop;
};
// Default constructor.
io_port_wos()
: address(nullptr)
@ -463,6 +880,12 @@ namespace etl
return address;
}
/// Get the iterator.
iterator get_iterator()
{
return iterator(*this);
}
/// Read.
operator T() const
{

View File

@ -31,6 +31,7 @@ SOFTWARE.
#include "../src/io_port.h"
#include <stdint.h>
#include <array>
#if defined(ETL_COMPILER_GCC)
#pragma GCC diagnostic push
@ -39,37 +40,45 @@ SOFTWARE.
#pragma warning(disable:4101) // Unused variable.
#endif
template <uintptr_t ADDRESS>
struct serial_port
namespace
{
etl::io_port_ro<uint8_t, ADDRESS> rxdata;
etl::io_port_wo<uint8_t, ADDRESS + 1> txdata;
etl::io_port_rw<uint16_t, ADDRESS + 2> control;
etl::io_port_ro<uint16_t, ADDRESS + 4> status;
etl::io_port_wos<uint8_t, ADDRESS + 6> control2;
};
struct dynamic_serial_port
{
dynamic_serial_port(uint8_t* base)
: rxdata(base),
txdata(base + 1),
control(base + 2),
status(base + 4),
control2(base + 6)
template <uintptr_t ADDRESS>
struct serial_port
{
}
etl::io_port_ro<uint8_t, ADDRESS> rxdata;
etl::io_port_wo<uint8_t, ADDRESS + 1> txdata;
etl::io_port_rw<uint16_t, ADDRESS + 2> control;
etl::io_port_ro<uint16_t, ADDRESS + 4> status;
etl::io_port_wos<uint8_t, ADDRESS + 6> control2;
};
etl::io_port_ro<uint8_t> rxdata;
etl::io_port_wo<uint8_t> txdata;
etl::io_port_rw<uint16_t> control;
etl::io_port_ro<uint16_t> status;
etl::io_port_wos<uint8_t> control2;
};
struct dynamic_serial_port
{
dynamic_serial_port(uint8_t* base)
: rxdata(base),
txdata(base + 1),
control(base + 2),
status(base + 4),
control2(base + 6)
{
}
etl::io_port_ro<uint8_t> rxdata;
etl::io_port_wo<uint8_t> txdata;
etl::io_port_rw<uint16_t> control;
etl::io_port_ro<uint16_t> status;
etl::io_port_wos<uint8_t> control2;
};
etl::io_port_rw<uint8_t> iop_rw;
etl::io_port_ro<uint8_t> iop_ro;
etl::io_port_wo<uint8_t> iop_wo;
etl::io_port_wos<uint8_t> iop_wos;
}
namespace
{
SUITE(test_alignment)
SUITE(test_io_ports)
{
//*************************************************************************
TEST(test_io_port)
@ -116,6 +125,78 @@ namespace
uint8_t* address = port.control2.get_address();
CHECK_EQUAL(reinterpret_cast<uint8_t* const>(0x1000), address);
}
//*************************************************************************
TEST(test_dynamic_io_port_iterators)
{
uint8_t memory_rw = 0x12;
uint8_t memory_ro = 0x34;
uint8_t memory_wo = 0x56;
uint8_t memory_wos = 0x78;
iop_rw.set_address(uintptr_t(&memory_rw));
iop_ro.set_address(uintptr_t(&memory_ro));
iop_wo.set_address(uintptr_t(&memory_wo));
iop_wos.set_address(uintptr_t(&memory_wos));
std::array<uint8_t, 10> compare;
std::array<uint8_t, 10> result;
// Read from RW IOP.
etl::io_port_rw<uint8_t>::iterator itr_rw = iop_rw.get_iterator();
std::copy_n(itr_rw, result.size(), result.begin());
compare.fill(0x12);
for (size_t i = 0; i < compare.size(); ++i)
{
CHECK_EQUAL(compare[i], result[i]);
}
// Write to RW IOP.
compare.fill(0x34);
std::copy_n(compare.begin(), compare.size(), itr_rw);
CHECK_EQUAL(compare[0], iop_rw);
// Read from RO IOP.
etl::io_port_ro<uint8_t>::iterator itr_ro = iop_ro.get_iterator();
std::copy_n(itr_ro, result.size(), result.begin());
compare.fill(0x34);
for (size_t i = 0; i < compare.size(); ++i)
{
CHECK_EQUAL(compare[i], result[i]);
}
// Write to WO IOP.
etl::io_port_wo<uint8_t>::iterator itr_wo = iop_wo.get_iterator();
compare.fill(0x56);
std::copy_n(compare.begin(), compare.size(), itr_wo);
CHECK_EQUAL(compare[0], memory_wo);
// Read from WOS IOP.
etl::io_port_wos<uint8_t>::iterator itr_wos = iop_wos.get_iterator();
*itr_wos = 0x78;
std::copy_n(itr_wos, result.size(), result.begin());
compare.fill(0x78);
for (size_t i = 0; i < compare.size(); ++i)
{
CHECK_EQUAL(compare[i], result[i]);
}
// Write to WOS IOP.
compare.fill(0x90);
std::copy_n(compare.begin(), compare.size(), itr_wos);
CHECK_EQUAL(compare[0], iop_wos);
}
};
}