Arduino-TWI
Two-Wire Interface (TWI) library for Arduino
TWI.h
Go to the documentation of this file.
1 
19 #ifndef SOFTWARE_TWI_H
20 #define SOFTWARE_TWI_H
21 
22 #include "TWI.h"
23 #include "GPIO.h"
24 
30 namespace Software {
31 template<BOARD::pin_t SDA_PIN, BOARD::pin_t SCL_PIN>
32 class TWI : public ::TWI {
33 public:
39  TWI()
40  {
41  m_sda.open_drain();
42  m_scl.open_drain();
43  }
44 
51  virtual bool acquire()
52  {
53  while (m_busy) yield();
54  m_busy = true;
55  m_start = true;
56  return (start_condition());
57  }
58 
65  virtual bool release()
66  {
67  m_start = false;
68  m_busy = false;
69  return (stop_condition());
70  }
71 
80  virtual int read(uint8_t addr, void* buf, size_t count)
81  {
82  // Check if repeated start condition should be generated
83  if (!m_start && !repeated_start_condition()) return (-1);
84  m_start = false;
85 
86  // Address device with read request and check that it acknowledges
87  bool nack;
88  if (!write_byte(addr | 1, nack) || nack) return (-1);
89 
90  // Read bytes and acknowledge until required size
91  uint8_t* bp = (uint8_t*) buf;
92  size_t size = count;
93  while (size--) {
94  bool ack = (size != 0);
95  uint8_t data;
96  if (!read_byte(data, ack)) return (-1);
97  *bp++ = data;
98  }
99  return (count);
100  }
101 
109  virtual int write(uint8_t addr, iovec_t* vp)
110  {
111  // Check if repeated start condition should be generated
112  if (!m_start && !repeated_start_condition()) return (-1);
113  m_start = false;
114 
115  // Address device with write request and check that it acknowledges
116  bool nack;
117  if (!write_byte(addr | 0, nack) || nack) return (-1);
118  if (vp == NULL) return (0);
119 
120  // Write given io vector buffers to device
121  int count = 0;
122  for(; vp->buf != NULL; vp++) {
123  const uint8_t* bp = (const uint8_t*) vp->buf;
124  size_t size = vp->size;
125  count += size;
126  while (size--) {
127  uint8_t data = *bp++;
128  if (!write_byte(data, nack) || nack) return (-1);
129  }
130  }
131  return (count);
132  }
133 
134 protected:
136  static const int T1 = 4;
137 
139  static const int T2 = 5;
140 
142  static const int CLOCK_STRETCHING_RETRY_MAX = 25;
143 
145  GPIO<SDA_PIN> m_sda;
146 
148  GPIO<SCL_PIN> m_scl;
149 
151  bool m_start;
152 
159  {
160  for (int retry = 0; retry < CLOCK_STRETCHING_RETRY_MAX; retry++) {
161  if (m_scl) return (true);
162  delayMicroseconds(T1);
163  }
164  return (false);
165  }
166 
173  {
174  m_sda.input();
175  if (m_sda == 0) return (false);
176  m_sda.output();
177  delayMicroseconds(T1);
178  m_scl.output();
179  return (true);
180  }
181 
188  {
189  delayMicroseconds(T1);
190  m_sda.input();
191  if (m_sda == 0) return (false);
192  m_scl.input();
193  delayMicroseconds(T2);
194  m_sda.output();
195  delayMicroseconds(T1);
196  m_scl.output();
197  return (true);
198  }
199 
206  {
207  delayMicroseconds(T1);
208  m_sda.output();
209  m_scl.input();
210  delayMicroseconds(T1);
211  if (!clock_stretching()) return (false);
212  m_sda.input();
213  return (m_sda == 0);
214  }
215 
222  bool write_bit(bool value)
223  {
224  if (value) m_sda.input(); else m_sda.output();
225  delayMicroseconds(T2);
226  m_scl.input();
227  delayMicroseconds(T1);
228  if (!clock_stretching()) return (false);
229  m_scl.output();
230  return (true);
231  }
232 
239  bool read_bit(bool& value)
240  {
241  m_sda.input();
242  delayMicroseconds(T2);
243  m_scl.input();
244  delayMicroseconds(T1);
245  if (!clock_stretching()) return (false);
246  value = m_sda;
247  m_scl.output();
248  return (true);
249  }
250 
258  bool write_byte(uint8_t byte, bool& nack)
259  {
260  for (int i = 0; i < 8; i++) {
261  if (!write_bit(byte & 0x80)) return (false);
262  byte <<= 1;
263  }
264  return (read_bit(nack));
265  }
266 
275  bool read_byte(uint8_t& byte, bool ack)
276  {
277  bool value;
278  byte = 0;
279  for (int i = 0; i < 8; i++) {
280  if (!read_bit(value)) return (false);
281  byte = (byte << 1) | value;
282  }
283  return (write_bit(!ack));
284  }
285 };
286 };
287 #endif
GPIO< SCL_PIN > m_scl
Definition: TWI.h:148
bool clock_stretching()
Definition: TWI.h:158
static const int T2
Definition: TWI.h:139
virtual bool release()
Definition: TWI.h:65
virtual int read(uint8_t addr, void *buf, size_t count)
Definition: TWI.h:80
bool repeated_start_condition()
Definition: TWI.h:187
static const int CLOCK_STRETCHING_RETRY_MAX
Definition: TWI.h:142
virtual int write(uint8_t addr, iovec_t *vp)
Definition: TWI.h:109
volatile bool m_busy
Definition: TWI.h:171
GPIO< SDA_PIN > m_sda
Definition: TWI.h:145
Definition: TWI.h:30
bool start_condition()
Definition: TWI.h:172
static const int T1
Definition: TWI.h:136
bool write_byte(uint8_t byte, bool &nack)
Definition: TWI.h:258
virtual bool acquire()
Definition: TWI.h:51
bool read_bit(bool &value)
Definition: TWI.h:239
bool stop_condition()
Definition: TWI.h:205
bool read_byte(uint8_t &byte, bool ack)
Definition: TWI.h:275
bool m_start
Definition: TWI.h:151
bool write_bit(bool value)
Definition: TWI.h:222