Arduino-TWI
Two-Wire Interface (TWI) library for Arduino
TWI.h
Go to the documentation of this file.
1 
19 #ifndef HARDWARE_SAM_TWI_H
20 #define HARDWARE_SAM_TWI_H
21 
22 #include "TWI.h"
23 #include "include/twi.h"
24 #include "variant.h"
25 
29 namespace Hardware {
30 class TWI : public ::TWI {
31 public:
36  TWI(uint32_t freq = DEFAULT_FREQ) :
38  {
39  // Initiate hardware registers
40  pmc_enable_periph_clk(WIRE_INTERFACE_ID);
41  PIO_Configure(g_APinDescription[PIN_WIRE_SDA].pPort,
42  g_APinDescription[PIN_WIRE_SDA].ulPinType,
43  g_APinDescription[PIN_WIRE_SDA].ulPin,
44  g_APinDescription[PIN_WIRE_SDA].ulPinConfiguration);
45  PIO_Configure(g_APinDescription[PIN_WIRE_SCL].pPort,
46  g_APinDescription[PIN_WIRE_SCL].ulPinType,
47  g_APinDescription[PIN_WIRE_SCL].ulPin,
48  g_APinDescription[PIN_WIRE_SCL].ulPinConfiguration);
49  m_twi = WIRE_INTERFACE;
50  TWI_ConfigureMaster(m_twi, freq, VARIANT_MCK);
51  }
52 
59  virtual bool acquire()
60  {
61  // Wait for bus manager to become idle
62  lock();
64  return (true);
65  }
66 
73  virtual bool release()
74  {
75  bool res = true;
76 
77  // Check for terminating write sequence with stop condition
78  if (m_state == WRITE_STATE) res = stop_condition();
79 
80  // Mark bus manager as idle
81  unlock();
83  return (res);
84  }
85 
94  virtual int read(uint8_t addr, void* buf, size_t count)
95  {
96  // Ignore zero length read
97  if (count == 0) return (0);
98  uint32_t retry;
99 
100  // Check if stop condition is needed before read
101  if (m_state == WRITE_STATE && !stop_condition()) return (-1);
102 
103  // Adjust address
104  addr >>= 1;
105 
106  // Read requested bytes from device
107  uint8_t* bp = (uint8_t*) buf;
108  int res = 0;
109  m_twi->TWI_MMR = (addr << 16) | TWI_MMR_MREAD;
110  m_twi->TWI_CR = TWI_CR_START;
111  while (count--) {
112  if (count == 0) m_twi->TWI_CR |= TWI_CR_STOP;
113  retry = RETRY_MAX;
114  while (((m_twi->TWI_SR & TWI_SR_RXRDY) == 0) && (--retry));
115  if (retry == 0) return (-1);
116  *bp++ = m_twi->TWI_RHR;
117  res += 1;
118  }
119  retry = RETRY_MAX;
120  while (((m_twi->TWI_SR & TWI_SR_TXCOMP) == 0) && (--retry));
121  if (retry == 0) return (-1);
122 
123  // Return number of bytes read
124  return (res);
125  }
126 
134  virtual int write(uint8_t addr, iovec_t* vp)
135  {
136  uint32_t retry;
137 
138  // Adjust address
139  addr >>= 1;
140 
141  // Check for scan of given device
142  if (vp == NULL) {
143  m_twi->TWI_MMR = (addr << 16);
144  m_twi->TWI_THR = 0;
145  if (!stop_condition()) return (-1);
146  return (0);
147  }
148 
149  // Check for preceeding write state
150  if (m_state != WRITE_STATE) m_twi->TWI_MMR = (addr << 16);
152  int res = 0;
153 
154  // Write buffer sequence to the device
155  for(; vp->buf != NULL; vp++) {
156  const uint8_t* bp = (const uint8_t*) vp->buf;
157  size_t size = vp->size;
158  while (size--) {
159  m_twi->TWI_THR = *bp++;
160  res += 1;
161  retry = RETRY_MAX;
162  while ((m_twi->TWI_SR & TWI_SR_TXRDY) == 0)
163  if (--retry == 0) return (-1);
164  }
165  }
166  // Do not terminate with a stop condition. Additional
167  // read/write may follow
168 
169  return (res);
170  }
171 
172 protected:
174  static const uint32_t RETRY_MAX = 100000;
175 
177  Twi* m_twi;
178 
180  enum state_t {
184  };
186 
188  {
189  uint32_t sr;
190  uint32_t retry = RETRY_MAX;
191  m_twi->TWI_CR = TWI_CR_STOP;
192  m_state = BUSY_STATE;
193  do {
194  sr = m_twi->TWI_SR;
195  if (sr & TWI_SR_NACK) return (false);
196  if (--retry == 0) return (false);
197  } while ((sr & TWI_SR_TXCOMP) == 0);
198  return (true);
199  }
200 };
201 };
202 
203 #endif
Definition: TWI.h:28
void lock()
Definition: TWI.h:176
Definition: TWI.h:27
TWI(uint32_t freq=DEFAULT_FREQ)
Definition: TWI.h:36
virtual int write(uint8_t addr, iovec_t *vp)
Definition: TWI.h:134
virtual bool acquire()
Definition: TWI.h:59
virtual bool release()
Definition: TWI.h:73
bool stop_condition()
Definition: TWI.h:187
static const uint32_t DEFAULT_FREQ
Definition: TWI.h:108
virtual int read(uint8_t addr, void *buf, size_t count)
Definition: TWI.h:94
static const uint32_t RETRY_MAX
Definition: TWI.h:174
Twi * m_twi
Definition: TWI.h:177
state_t m_state
Definition: TWI.h:185
void unlock()
Definition: TWI.h:185