Mcp320x
Mcp320x.h
Go to the documentation of this file.
1 
8 #pragma once
9 
10 #include <stdint.h>
11 #include <stdbool.h>
12 #include <Arduino.h>
13 #include <SPI.h>
14 
15 namespace MCP320xTypes {
16 
17 namespace MCP3201 {
21  enum Channel {
22  SINGLE_0 = 0x0
23  };
24 };
25 
26 namespace MCP3202 {
41  enum Channel {
42  SINGLE_0 = 0b10,
43  SINGLE_1 = 0b11,
44  DIFF_0PN = 0b00,
45  DIFF_0NP = 0b01,
46  };
47 };
48 
49 namespace MCP3204 {
65  enum Channel {
66  SINGLE_0 = 0b1000,
67  SINGLE_1 = 0b1001,
68  SINGLE_2 = 0b1010,
69  SINGLE_3 = 0b1011,
70  DIFF_0PN = 0b0000,
71  DIFF_0NP = 0b0001,
72  DIFF_1PN = 0b0010,
73  DIFF_1NP = 0b0011
74  };
75 };
76 
77 namespace MCP3208 {
92  enum Channel {
93  SINGLE_0 = 0b1000,
94  SINGLE_1 = 0b1001,
95  SINGLE_2 = 0b1010,
96  SINGLE_3 = 0b1011,
97  SINGLE_4 = 0b1100,
98  SINGLE_5 = 0b1101,
99  SINGLE_6 = 0b1110,
100  SINGLE_7 = 0b1111,
101  DIFF_0PN = 0b0000,
102  DIFF_0NP = 0b0001,
103  DIFF_1PN = 0b0010,
104  DIFF_1NP = 0b0011,
105  DIFF_2PN = 0b0100,
106  DIFF_2NP = 0b0101,
107  DIFF_3PN = 0b0110,
108  DIFF_3NP = 0b0111
109  };
110 };
111 
112 }; // namespace MCP320xTypes
113 
114 template <typename ChannelType>
115 class MCP320x {
116 
117 public:
118 
120  static const uint8_t kResBits = 12;
122  static const uint16_t kRes = (1 << kResBits);
123 
125  using Channel = ChannelType;
126 
134  MCP320x(uint16_t vref, uint8_t csPin, SPIClass *spi);
135 
143  MCP320x(uint16_t vref, uint8_t csPin);
144 
153  void calibrate(Channel ch);
154 
161  uint16_t read(Channel ch) const;
162 
170  template <typename T, size_t N>
171  void read(Channel ch, T (&data)[N]) const
172  {
173  readn(ch, data, N);
174  }
175 
186  template <typename T, size_t N>
187  void read(Channel ch, T (&data)[N], uint32_t splFreq)
188  {
189  readn(ch, data, N, splFreq);
190  }
191 
200  template <typename T, size_t N, typename Predicate>
201  void read_if(Channel ch, T (&data)[N], Predicate p) const
202  {
203  readn_if(ch, data, N, p);
204  }
205 
217  template <typename T, size_t N, typename Predicate>
218  void read_if(Channel ch, T (&data)[N], uint32_t splFreq, Predicate p)
219  {
220  readn_if(ch, data, N, splFreq, p);
221  }
222 
232  template <typename T>
233  void readn(Channel ch, T *data, uint16_t num) const
234  {
235  execute(createCmd(ch), data, num);
236  }
237 
250  template <typename T>
251  void readn(Channel ch, T *data, uint16_t num, uint32_t splFreq)
252  {
253  execute(createCmd(ch), data, num, getSplDelay(ch, splFreq));
254  }
255 
268  template <typename T, typename Predicate>
269  void readn_if(Channel ch, T *data, uint16_t num, Predicate p) const
270  {
271  auto cmd = createCmd(ch);
272  while (!p(execute(cmd))) {}
273  execute(cmd, data, num);
274  }
275 
290  template <typename T, typename Predicate>
291  void readn_if(Channel ch, T *data, uint16_t num, uint32_t splFreq,
292  Predicate p)
293  {
294  auto cmd = createCmd(ch);
295  while (!p(execute(cmd))) {}
296  execute(cmd, data, num, getSplDelay(ch, splFreq));
297  }
298 
306  uint32_t testSplSpeed(Channel ch) const;
307 
315  uint32_t testSplSpeed(Channel ch, uint16_t num) const;
316 
326  uint32_t testSplSpeed(Channel ch, uint16_t num, uint32_t splFreq);
327 
334  uint16_t toAnalog(uint16_t raw) const;
335 
342  uint16_t toDigital(uint16_t val) const;
343 
348  uint16_t getVref() const;
349 
355  uint16_t getAnalogRes() const;
356 
357 private:
358 
363  union SpiData {
364  uint16_t value;
365  struct {
366  uint8_t loByte;
367  uint8_t hiByte;
368  };
369  };
370 
374  template <typename>
375  using Command = SpiData;
376 
382  uint16_t getSplDelay(Channel ch, uint32_t splFreq);
383 
389  static Command<Channel> createCmd(Channel ch);
390 
396  uint16_t execute(Command<Channel> cmd) const;
397 
406  template <typename T>
407  void execute(Command<Channel> cmd, T *data, uint16_t num) const
408  {
409  for (decltype(num) i=0; i < num; i++)
410  data[i] = static_cast<T>(execute(cmd));
411  }
412 
422  template <typename T>
423  void execute(Command<Channel> cmd, T *data, uint16_t num,
424  uint16_t delay) const
425  {
426  for (decltype(num) i=0; i < num; i++) {
427  data[i] = static_cast<T>(execute(cmd));
428  delayMicroseconds(delay);
429  }
430  }
431 
436  uint16_t transfer() const;
437 
443  uint16_t transfer(SpiData cmd) const;
444 
445 private:
446 
447  uint16_t mVref;
448  uint8_t mCsPin;
449  uint32_t mSplSpeed;
450  SPIClass *mSpi;
451 };
452 
void read(Channel ch, T(&data)[N], uint32_t splFreq)
Definition: Mcp320x.h:187
void execute(Command< Channel > cmd, T *data, uint16_t num) const
Definition: Mcp320x.h:407
void read_if(Channel ch, T(&data)[N], uint32_t splFreq, Predicate p)
Definition: Mcp320x.h:218
void readn_if(Channel ch, T *data, uint16_t num, Predicate p) const
Definition: Mcp320x.h:269
uint32_t mSplSpeed
Definition: Mcp320x.h:449
uint16_t mVref
Definition: Mcp320x.h:447
uint8_t hiByte
Definition: Mcp320x.h:367
ChannelType Channel
Definition: Mcp320x.h:125
void execute(Command< Channel > cmd, T *data, uint16_t num, uint16_t delay) const
Definition: Mcp320x.h:423
void read_if(Channel ch, T(&data)[N], Predicate p) const
Definition: Mcp320x.h:201
uint16_t value
Definition: Mcp320x.h:364
void readn(Channel ch, T *data, uint16_t num, uint32_t splFreq)
Definition: Mcp320x.h:251
SPIClass * mSpi
Definition: Mcp320x.h:450
void readn_if(Channel ch, T *data, uint16_t num, uint32_t splFreq, Predicate p)
Definition: Mcp320x.h:291
uint8_t loByte
Definition: Mcp320x.h:366
void read(Channel ch, T(&data)[N]) const
Definition: Mcp320x.h:171
uint8_t mCsPin
Definition: Mcp320x.h:448
void readn(Channel ch, T *data, uint16_t num) const
Definition: Mcp320x.h:233