uTL
micro Template library
i2c.h
Go to the documentation of this file.
1 
21 #ifndef _utl_com_i2c_h__
22 #define _utl_com_i2c_h__
23 
24 #include <utl/core/impl.h>
25 #include <utl/core/crtp.h>
26 #include <utl/meta/meta.h>
27 
28 namespace utl {
29 
34 
42  template <typename impl_t>
43  class i2c_i {
44  _CRTP_IMPL(impl_t);
45 
46  public:
47  using type = i2c_i<impl_t>;
48  enum class Sequence {
50  BYTE =0,
51  ACK,
52  BYTEnACK
53  };
54 
58  protected:
60  i2c_i () = default;
61  ~i2c_i () = default;
62  i2c_i (const type&) = delete;
63  type& operator= (const type&) = delete;
65 
72  private:
74  uint32_t _clock () const { return impl()._clock (); }
75  void _clock (uint32_t c) { impl()._clock (c); }
76  void _start() { impl()._start (); }
77  void _stop() { impl()._stop (); }
78  byte_t _rx_data (bool ack, Sequence seq) { return impl()._rx_data (ack, seq); }
79  bool _tx_data (byte_t byte, Sequence seq) { return impl()._tx_data (byte, seq); }
81 
85  public:
87  uint32_t clock () const { return _clock (); }
88  void clock (uint32_t f) { _clock (f); }
89 
94  public:
96  void start() { _start (); }
97  void stop () { _stop (); }
98 
112  return _rx_data (ack, seq);
113  }
114 
128  return _tx_data (byte, seq);
129  }
131 
132  };
133 
139  template<>
140  class i2c_i <virtual_tag> {
141  public:
143 
145  enum class Sequence {
146  BYTE=0,
147  ACK,
148  BYTEnACK
149  };
150 
154  protected:
156  i2c_i () = default;
157  i2c_i (const type&) = delete;
158  type& operator= (const type&) = delete;
159  public:
160  virtual ~i2c_i () = default;
161 
166  private:
168  virtual uint32_t _clock () const = 0;
169  virtual void _clock (uint32_t) = 0;
170  virtual void _start() = 0;
171  virtual void _stop() = 0;
172  virtual byte_t _rx_data (bool ack, Sequence seq) = 0;
173  virtual bool _tx_data (byte_t byte, Sequence seq) = 0;
174 
178  public:
180  uint32_t clock () const { return _clock(); }
181  void clock (uint32_t c) { _clock(c); }
182 
187  public:
189  void start () { _start(); }
190  void stop () { _stop(); }
204  return _rx_data (ack, seq);
205  }
219  return _tx_data (byte, seq);
220  }
222 
223  };
224 
225 #if defined _utl_have_concepts
226 
229  template <typename T>
230  concept bool I2c_i = requires (T t, const T ct, typename T::Sequence s) {
231  // Object type
232  requires not_<std::is_copy_constructible<T>::value>::value;
233  requires not_<std::is_copy_assignable<T>::value>::value;
234  // Methods
235  {ct.clock()} -> uint32_t;
236  {t.clock(0)} -> void;
237  {t.start()} -> void;
238  {t.stop()} -> void;
239  {t.rx_data (1, s)} -> byte_t;
240  {t.tx_data (0, s)} -> bool;
241  };
242 #else
243  namespace i2c_i_details {
244  using std::declval;
245 
246  template <class _Tp> using try_cclk_t = decltype (declval<const _Tp>().clock());
247  template <class _Tp> using try_clk_t = decltype (declval<_Tp>().clock(declval<uint32_t>()));
248  template <class _Tp> using try_start_t = decltype (declval<_Tp>().start());
249  template <class _Tp> using try_stop_t = decltype (declval<_Tp>().stop());
250  template <class _Tp> using try_rx_data_t
251  = decltype (declval<_Tp>().rx_data (declval<bool>(), declval<typename _Tp::Sequence>()));
252  template <class _Tp> using try_tx_data_t
253  = decltype (declval<_Tp>().tx_data (declval<byte_t>(), declval<typename _Tp::Sequence>()));
254 
256  template <typename _Tp, typename =void>
257  struct is_i2c_ : meta::false_ { };
258 
260  template <typename _Tp>
261  struct is_i2c_ <_Tp,
262  meta::void_t <
263  typename _Tp::Sequence,
264 // meta::use_if_same_t <uint32_t,try_cclk_t <_Tp>>,
265 // meta::use_if_same_t <void, try_clk_t <_Tp>>,
266 // meta::use_if_same_t <void, try_start_t <_Tp>>,
267 // meta::use_if_same_t <void, try_stop_t <_Tp>>,
268 // meta::use_if_same_t <byte_t, try_rx_data_t <_Tp>>,
269 // meta::use_if_same_t <bool, try_tx_data_t <_Tp>>
270  void
271  >
272  > : meta::true_ { };
273  }
279 // template <typename _Tp>
280 // constexpr bool I2c_i = i2c_i_details::is_i2c_<_Tp>::value;
281 #endif
282 
284 
285 } // namespace utl
286 
287 #endif // _utl_com_i2c_h__
Include all meta library.
void void_t
void_t type alias
Definition: detection.h:55
Primary template to catch any non I2C interface types.
Definition: i2c.h:257
void clock(uint32_t f)
set clock frequency of the bus
Definition: i2c.h:88
Abstract base class for i2c bus.
Definition: i2c.h:43
decltype(declval< _Tp >().stop()) try_stop_t
Definition: i2c.h:249
A virtual base class specialization.
Definition: i2c.h:140
bool_< true > true_
The type used as a compile-time boolean with true value.
Definition: integral.h:68
decltype(declval< _Tp >().tx_data(declval< byte_t >(), declval< typename _Tp::Sequence >())) try_tx_data_t
Definition: i2c.h:253
decltype(declval< const _Tp >().clock()) try_cclk_t
Definition: i2c.h:246
decltype(declval< _Tp >().rx_data(declval< bool >(), declval< typename _Tp::Sequence >())) try_rx_data_t
Definition: i2c.h:251
i2c_i()=default
Allow constructor from derived only.
void _stop()
Send stop functionality.
Definition: i2c.h:77
~i2c_i()=default
Allow destructor from derived only.
decltype(declval< _Tp >().clock(declval< uint32_t >())) try_clk_t
Definition: i2c.h:247
bool_< false > false_
The type used as a compile-time boolean with false value.
Definition: integral.h:69
void _clock(uint32_t c)
set clock frequency of the bus [Hz]
Definition: i2c.h:75
STL&#39;s core language concepts.
Definition: _1wire.h:30
uint32_t clock() const
Definition: i2c.h:180
void stop()
Send stop functionality.
Definition: i2c.h:97
void start()
Send start functionality.
Definition: i2c.h:96
Sequence
I2C transmit/receive sequence.
Definition: i2c.h:49
i2c_i< impl_t > type
Definition: i2c.h:47
Only send/receive ack [1 clock].
bool _tx_data(byte_t byte, Sequence seq)
Definition: i2c.h:79
byte_t rx_data(bool ack, Sequence seq=Sequence::BYTEnACK)
Receive a byte from the i2c bus.
Definition: i2c.h:203
type & operator=(const type &)=delete
uint32_t clock() const
Definition: i2c.h:87
void clock(uint32_t c)
set clock frequency of the bus [Hz]
Definition: i2c.h:181
byte_t rx_data(bool ack, Sequence seq=Sequence::BYTEnACK)
Receive a byte from the i2c bus.
Definition: i2c.h:111
_CRTP_IMPL(impl_t)
bool tx_data(byte_t byte, Sequence seq=Sequence::BYTEnACK)
Transmit a byte to the i2c bus.
Definition: i2c.h:127
uint8_t byte_t
8 bits wide
Definition: types.h:31
virtual support tag type
Definition: crtp.h:40
bool tx_data(byte_t byte, Sequence seq=Sequence::BYTEnACK)
Transmit a byte to the i2c bus.
Definition: i2c.h:218
Read/Write byte and ack [9 clocks].
uint32_t _clock() const
clock frequency of the bus [Hz]
Definition: i2c.h:74
Only read/write byte [8 clocks].
void _start()
Send start functionality.
Definition: i2c.h:76
Sequence
I2C transmit/receive sequence.
Definition: i2c.h:145
byte_t _rx_data(bool ack, Sequence seq)
Definition: i2c.h:78
decltype(declval< _Tp >().start()) try_start_t
Definition: i2c.h:248
Implementation detail main forward header.