spi.h
Go to the documentation of this file.
#ifndef _utl_com_spi_h__
#define _utl_com_spi_h__
#include <utl/core/impl.h>
#include <utl/core/crtp.h>
#include <utl/meta/meta.h>
namespace utl {
namespace spi {
enum class bitOrder {
LSB_First =0x01,
MSB_First =0x80
};
enum class cpol {
LOW =0,
HIGH
};
enum class cpha {
LOW =0,
HIGH
};
}
template <typename impl_t>
class spi_i {
_CRTP_IMPL(impl_t);
public:
using type = spi_i<impl_t>;
protected:
spi_i () = default;
~spi_i () = default;
spi_i (const type&) = delete;
type& operator= (const type&) = delete;
private:
uint32_t _clock () const { return impl()._clock (); }
void _clock (uint32_t c) { impl()._clock (c); }
byte_t _tx_data (byte_t b) { return impl()._tx_data (b); }
public:
uint32_t clock () const { return _clock (); }
void clock (uint32_t c) { _clock (c); }
public:
byte_t tx_data (byte_t out) {
return _tx_data (out);
}
size_t tx_data (const byte_t *out, byte_t *in, size_t n);
byte_t rx_data () {
return _tx_data(0xFF);
}
size_t rx_data (byte_t *in, size_t n);
};
template<typename _I>
size_t spi_i<_I>::tx_data (const byte_t *out, byte_t *in, size_t n) {
for (size_t nn {n} ; nn ; --nn)
*in++ = _tx_data (*out++);
return n;
}
template<typename _I>
size_t spi_i<_I>::rx_data (byte_t *in, size_t n) {
for (size_t nn {n} ; nn ; --nn)
*in++ = _tx_data (0xFF);
return n;
}
template <>
class spi_i <virtual_tag> {
public:
using type = spi_i<virtual_tag>;
protected:
spi_i () = default;
spi_i (const type&) = delete;
type& operator= (const type&) = delete;
public:
virtual ~spi_i () = default;
private:
virtual uint32_t _clock () const =0;
virtual void _clock (uint32_t) =0;
virtual byte_t _tx_data (byte_t) =0;
public:
uint32_t clock () const { return _clock (); }
void clock (uint32_t c) { _clock (c); }
public:
byte_t tx_data (byte_t out) {
return _tx_data (out);
}
size_t tx_data (const byte_t *out, byte_t *in, size_t n);
byte_t rx_data () {
return _tx_data (0xFF);
}
size_t rx_data (byte_t *in, size_t n);
};
size_t spi_i<virtual_tag>::tx_data (const byte_t *out, byte_t *in, size_t n) {
for (size_t nn {n} ; nn ; --nn)
*in++ = _tx_data (*out++);
return n;
}
size_t spi_i<virtual_tag>::rx_data (byte_t *in, size_t n) {
for (size_t nn {n} ; nn ; --nn)
*in++ = _tx_data (0xFF);
return n;
}
#if defined _utl_have_concepts
template <typename T>
concept bool Spi_i = requires (T t, const T ct, typename T::Sequence s) {
// Object type
requires not_<std::is_copy_constructible<T>::value>::value;
requires not_<std::is_copy_assignable<T>::value>::value;
// Methods
{ct.clock()} -> uint32_t;
{t.clock(0)} -> void;
{t.tx_data(1)} -> byte_t;
{t.rx_data()} -> byte_t;
};
#else
namespace spi_i_details {
using std::declval;
template <class _Tp> using try_cclock_t= decltype (declval<const _Tp>().clock());
template <class _Tp> using try_clock_t = decltype (declval<_Tp>().clock(declval<uint32_t>()));
template <class _Tp> using try_tx_t = decltype (declval<_Tp>().tx_data(declval<byte_t>()));
template <class _Tp> using try_rx_t = decltype (declval<_Tp>().rx_data());
template <typename _Tp, typename =void>
struct is_spi_ : meta::false_ {};
template <typename _Tp>
struct is_spi_ <
_Tp,
meta::void_t <
meta::use_if_same_t <try_cclock_t<_Tp>, uint32_t>,
meta::use_if_same_t <try_clock_t<_Tp>, void>,
meta::use_if_same_t <try_tx_t<_Tp>, byte_t>,
meta::use_if_same_t <try_rx_t<_Tp>, byte_t>
>
> : meta::true_ {};
}
// template <typename _Tp>
// constexpr bool Spi_i = spi_i_details::is_spi_<_Tp>::value;
#endif
} // namespace utl
#endif /* #ifndef _utl_com_spi_h__ */
meta.h
Include all meta library.
utl::spi::cpol
cpol
Definition: spi.h:47
utl::spi::bitOrder::MSB_First
Less significant first.
utl::meta::void_t
void void_t
void_t type alias
Definition: detection.h:55
utl::spi_i::spi_i
spi_i()=default
Allow constructor from derived only.
utl::spi::bitOrder::LSB_First
Most significant first.
utl::spi_i::clock
uint32_t clock() const
Definition: spi.h:102
utl::meta::true_
bool_< true > true_
The type used as a compile-time boolean with true value.
Definition: integral.h:68
utl::spi_i< virtual_tag >::clock
uint32_t clock() const
Definition: spi.h:208
utl::spi::bitOrder
bitOrder
Definition: spi.h:40
crtp.h
utl::spi_i::~spi_i
~spi_i()=default
Allow destructor from derived only.
utl::spi_i< virtual_tag >::clock
void clock(uint32_t c)
set clock frequency of the bus
Definition: spi.h:209
utl::spi_i::clock
void clock(uint32_t c)
set clock frequency of the bus
Definition: spi.h:103
utl::spi::cpol::LOW
LOW.
utl::spi_i_details::try_rx_t
decltype(declval< _Tp >().rx_data()) try_rx_t
Definition: spi.h:301
utl::spi_i< virtual_tag >
A virtual base class implementation.
Definition: spi.h:177
utl::spi_i::_CRTP_IMPL
_CRTP_IMPL(impl_t)
utl::spi_i::rx_data
byte_t rx_data()
Definition: spi.h:129
utl::meta::false_
bool_< false > false_
The type used as a compile-time boolean with false value.
Definition: integral.h:69
utl::spi_i::tx_data
byte_t tx_data(byte_t out)
Definition: spi.h:114
utl::spi_i< virtual_tag >::rx_data
byte_t rx_data()
Definition: spi.h:235
utl::spi::cpha
cpha
Definition: spi.h:54
utl::spi_i< virtual_tag >::tx_data
byte_t tx_data(byte_t out)
Definition: spi.h:220
utl
STL&#39;s core language concepts.
Definition: _1wire.h:30
utl::spi::cpol::HIGH
HIGH.
utl::spi_i::_tx_data
byte_t _tx_data(byte_t b)
Definition: spi.h:94
utl::spi_i_details::try_tx_t
decltype(declval< _Tp >().tx_data(declval< byte_t >())) try_tx_t
Definition: spi.h:300
utl::spi_i_details::try_clock_t
decltype(declval< _Tp >().clock(declval< uint32_t >())) try_clock_t
Definition: spi.h:299
utl::spi_i
Definition: spi.h:67
utl::spi_i::_clock
uint32_t _clock() const
clock frequency of the bus [Hz]
Definition: spi.h:92
utl::byte_t
uint8_t byte_t
8 bits wide
Definition: types.h:31
utl::virtual_tag
virtual support tag type
Definition: crtp.h:40
utl::spi_i::_clock
void _clock(uint32_t c)
set clock frequency of the bus [Hz]
Definition: spi.h:93
utl::spi_i_details::try_cclock_t
decltype(declval< const _Tp >().clock()) try_cclock_t
Definition: spi.h:298
utl::spi_i::operator=
type & operator=(const type &)=delete
impl.h
Implementation detail main forward header.
utl::spi_i_details::is_spi_
Primary template to catch any non SPI interface types.
Definition: spi.h:305