Linduino  1.3.0
Linear Technology Arduino-Compatible Demonstration Board
LT_I2C_Wire.cpp
Go to the documentation of this file.
1 /*!
2 LT_I2C_Wire: I2C Routines based on Wire library to communicate with Arduino based boards.
3 
4 @verbatim
5 
6 
7  Wire.endTransmission() returns 0, 1, 2, 3, or 4. To maintain consistency with our Legacy LT_I2C library,
8  a zero(false) or a non-zero(true) is tested.
9 
10  0 .. success
11  1 .. length to long for buffer
12  2 .. address send, NACK received
13  3 .. data send, NACK received
14  4 .. other twi error (lost bus arbitration, bus error, ..)
15 
16 
17 @endverbatim
18 
19 
20 Copyright 2018(c) Analog Devices, Inc.
21 
22 All rights reserved.
23 
24 Redistribution and use in source and binary forms, with or without
25 modification, are permitted provided that the following conditions are met:
26  - Redistributions of source code must retain the above copyright
27  notice, this list of conditions and the following disclaimer.
28  - Redistributions in binary form must reproduce the above copyright
29  notice, this list of conditions and the following disclaimer in
30  the documentation and/or other materials provided with the
31  distribution.
32  - Neither the name of Analog Devices, Inc. nor the names of its
33  contributors may be used to endorse or promote products derived
34  from this software without specific prior written permission.
35  - The use of this software may or may not infringe the patent rights
36  of one or more patent holders. This license does not release you
37  from the requirement that you obtain separate licenses from these
38  patent holders to use this software.
39  - Use of the software either in source or binary form, must be run
40  on or directly connected to an Analog Devices Inc. component.
41 
42 THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES "AS IS" AND ANY EXPRESS OR
43 IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT,
44 MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
45 IN NO EVENT SHALL ANALOG DEVICES BE LIABLE FOR ANY DIRECT, INDIRECT,
46 INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
47 LIMITED TO, INTELLECTUAL PROPERTY RIGHTS, PROCUREMENT OF SUBSTITUTE GOODS OR
48 SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
49 CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
50 OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
51 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
52 */
53 
54 
55 #include <Arduino.h>
56 #include <stdint.h>
57 #include "Linduino.h"
58 #include "LT_I2C_Wire.h"
59 #include <Wire.h>
60 
61 #if defined(ARDUINO_ARCH_AVR)
62 #include <util/delay.h>
63 #elif defined(ARDUINO_ARCH_SAM)
64 #define Wire Wire1
65 #define _delay_us delayMicroseconds
66 #elif defined(ARDUINO_ARCH_SAMD)
67 #include <delay.h>
68 #define _delay_us delayMicroseconds
69 #endif
70 
71 // Read a byte, store in "value".
72 int8_t i2c_read_byte(uint8_t address, uint8_t *value)
73 {
74  // Wire.requestFrom returns the number of bytes that were requested from the slave.
75  // If the address NAcked, the function returns 0.
76  int8_t ret = 0;
77  Wire.requestFrom((uint8_t)address, (uint8_t)1, (uint8_t)true);
78  while (Wire.available())
79  {
80  *value = Wire.read(); // Read MSB from buffer
81  }
82  delay(100);
83  if(ret == 0)
84  return (1); // Unsuccessful
85  else
86  return(0); // Successful
87 
88 }
89 
90 // Write "value" byte to device at "address"
91 int8_t i2c_write_byte(uint8_t address, uint8_t value)
92 {
93  Wire.beginTransmission(address); // Transmit to device
94  Wire.write(byte(value)); // Sends one byte
95  if (Wire.endTransmission()) // stop transmitting
96  {
97  // endTransmission returns zero on success
98  return(1);
99  }
100  return(0);
101 }
102 
103 // Read a byte of data at register specified by "command", store in "value"
104 int8_t i2c_read_byte_data(uint8_t address, uint8_t command, uint8_t *value)
105 {
106  int8_t ret = 0;
107  Wire.beginTransmission(address);
108  Wire.write(byte(command));
109  if (Wire.endTransmission()) // stop transmitting
110  {
111  // endTransmission returns zero on success
112  return(1);
113  }
114  ret = Wire.requestFrom((uint8_t)address, (uint8_t)1, (uint8_t)true);
115  while (Wire.available())
116  {
117  *value = Wire.read(); // Read MSB from buffer
118  }
119  delay(100);
120  if(ret == 0)
121  return (1); // Unsuccessful
122  else
123  return(0); // Successful
124 }
125 
126 // Write a byte of data to register specified by "command"
127 int8_t i2c_write_byte_data(uint8_t address, uint8_t command, uint8_t value)
128 {
129  Wire.beginTransmission(address); // transmit to device
130  Wire.write(byte(command)); // send instruction byte
131  Wire.write(byte(value)); // send value byte
132  if (Wire.endTransmission()) // stop transmitting
133  {
134  // endTransmission returns zero on success
135  return(1);
136  }
137  return(0);
138 }
139 
140 // Read a 16-bit word of data from register specified by "command"
141 int8_t i2c_read_word_data(uint8_t address, uint8_t command, uint16_t *value)
142 {
143  int8_t ret = 0;
144 
145  union
146  {
147  uint8_t b[2];
148  uint16_t w;
149  } data;
150 
151  Wire.beginTransmission(address);
152  Wire.write(byte(command));
153  if (Wire.endTransmission()) // stop transmitting
154  {
155  // endTransmission returns zero on success
156  return(1);
157  }
158  ret = Wire.requestFrom((uint8_t)address, (uint8_t)2, (uint8_t)true);
159  int i = 1;
160  while (Wire.available())
161  {
162  data.b[i] = Wire.read(); // Read MSB from buffer
163  i--;
164  if (i == 0)
165  break;
166  }
167  delay(100);
168  *value = data.w;
169  if(ret == 0)
170  return (1); // Unsuccessful
171  else
172  return(0); // Successful
173 }
174 
175 // Write a 16-bit word of data to register specified by "command"
176 int8_t i2c_write_word_data(uint8_t address, uint8_t command, uint16_t value)
177 {
178  int8_t ret=0;
179 
180  union
181  {
182  uint8_t b[2];
183  uint16_t w;
184  } data;
185  data.w = value;
186 
187  Wire.beginTransmission(address); // transmit to device
188  Wire.write(byte(command)); // sends instruction byte
189  Wire.write(byte(data.b[1])); // send value byte
190  Wire.write(byte(data.b[0])); // send value byte
191  if (Wire.endTransmission()) // stop transmitting
192  {
193  // endTransmission returns zero on success
194  return(1);
195  }
196  return(0);
197 }
198 
199 // Read a block of data, starting at register specified by "command" and ending at (command + length - 1)
200 int8_t i2c_read_block_data(uint8_t address, uint8_t command, uint8_t length, uint8_t *values)
201 {
202  uint8_t i = (length-1);
203  int8_t ret = 0;
204 
205  Wire.beginTransmission(address);
206  Wire.write(byte(command));
207  if (Wire.endTransmission()) // stop transmitting
208  {
209  // endTransmission returns zero on success
210  return(1);
211  }
212  ret = Wire.requestFrom((uint8_t)address, (uint8_t)length, (uint8_t)true);
213 
214  while (Wire.available())
215  {
216  values[i] = Wire.read();
217  i--;
218  if (i == 0)
219  break;
220  }
221  delay(100);
222  if(ret == 0)
223  return (1); // Unsuccessful
224  else
225  return(0); // Successful
226 }
227 
228 
229 // Read a block of data, no command byte, reads length number of bytes and stores it in values.
230 int8_t i2c_read_block_data(uint8_t address, uint8_t length, uint8_t *values)
231 {
232  uint8_t i = (length-1);
233  int8_t ret = 0;
234 
235  ret = Wire.requestFrom((uint8_t)address, (uint8_t)length, (uint8_t)true);
236 
237  while (Wire.available())
238  {
239  values[i] = Wire.read();
240  i--;
241  if (i == 0)
242  break;
243  }
244  delay(100);
245  if(ret == 0)
246  return (1); // Unsuccessful
247  else
248  return(0); // Successful
249 }
250 
251 
252 // Write a block of data, starting at register specified by "command" and ending at (command + length - 1)
253 int8_t i2c_write_block_data(uint8_t address, uint8_t command, uint8_t length, uint8_t *values)
254 {
255  int8_t i = length-1;
256  int8_t ret = 0;
257 
258  Wire.beginTransmission(address); // transmit to device
259  Wire.write(byte(command)); // sends instruction byte
260  while (i>=0)
261  {
262  Wire.write(byte(values[i])); // send values
263  i--;
264  }
265  if (Wire.endTransmission()) // stop transmitting
266  {
267  // endTransmission returns zero on success
268  return(1);
269  }
270  return(0);
271 }
272 
273 // Write two command bytes, then receive a block of data
274 int8_t i2c_two_byte_command_read_block(uint8_t address, uint16_t command, uint8_t length, uint8_t *values)
275 {
276  int8_t ret = 0;
277  union
278  {
279  uint8_t b[2];
280  uint16_t w;
281  } comm;
282  comm.w = command;
283  uint8_t i = (length-1);
284  uint8_t readBack = 0;
285 
286 #if defined(ARDUINO_ARCH_SAM)
287  //Wire.beginTransmission(address);
288  readBack = Wire.requestFrom((uint8_t)address, (uint8_t)length, (uint32_t)command, (uint8_t)2, (uint8_t)false);
289 #elif defined(ARDUINO_ARCH_SAMD) || defined(ARDUINO_ARCH_AVR)
290  Wire.beginTransmission(address);
291  Wire.write(byte(comm.b[1]));
292  Wire.write(byte(comm.b[0]));
293 
294  if (Wire.endTransmission(false)) // endTransmission(false) is a repeated start
295  {
296  // endTransmission returns zero on success
297  Wire.endTransmission();
298  return(1);
299  }
300  readBack = Wire.requestFrom((uint8_t)address, (uint8_t)length, (uint8_t)true);
301 #endif
302 
303  if (readBack == length)
304  {
305  while (Wire.available())
306  {
307  values[i] = Wire.read();
308  if (i == 0)
309  break;
310  i--;
311  }
312  return (0);
313  }
314  else
315  {
316  return (1);
317  }
318 }
319 
320 // Initializes Linduino I2C port.
321 // Before communicating to the I2C port throught the QuikEval connector, you must also run
322 // quikeval_I2C_connect to connect the I2C port to the QuikEval connector throught the
323 // QuikEval MUX (and disconnect SPI).
325 {
326  i2c_enable(); //! 1) Enable the I2C port;
327 }
328 
329 // Switch MUX to connect I2C pins to QuikEval connector.
330 // This will disconnect SPI pins.
332 {
333  // Enable I2C
334  pinMode(QUIKEVAL_MUX_MODE_PIN, OUTPUT); //! 1) Set Mux pin as an output
335  if (digitalRead(QUIKEVAL_MUX_MODE_PIN) == LOW) //! 2) If pin is already high, do nothing
336  {
337  digitalWrite(QUIKEVAL_MUX_MODE_PIN, HIGH); //! 3) Set the Mux pin to high
338  delay(55); //! 4) And wait for LTC4315 to connect (required for rev B)
339  }
340 }
341 
342 // Setup the hardware I2C interface.
343 // i2c_enable or quikeval_I2C_init must be called before using any of the other I2C routines.
345 {
346  Wire.begin();
347 }
348 
349 /*
350 
351 // Write start bit to the hardware I2C port
352 // return 0 if successful, 1 if not successful
353 int8_t i2c_start()
354 {
355  uint8_t result;
356  uint16_t timeout;
357  TWCR=(1<<TWINT) | (1<<TWSTA) | (1<<TWEN); //! 1) I2C start
358  for (timeout = 0; timeout < HW_I2C_TIMEOUT; timeout++) //! 2) START the timeout loop
359  {
360  _delay_us(1);
361  if (TWCR & (1 << TWINT)) break; //! 3) Check the TWINT bit in TWCR
362  }
363  result=(TWSR & 0xF8); //! 4) Mask the status
364  if ((result == STATUS_START) || (result == STATUS_REPEATED_START))
365  return(0); //! 5) Return status
366  else
367  return(1);
368 }
369 
370 // Write a repeat start bit to the hardware I2C port
371 // return 0 if successful, 1 if not successful
372 int8_t i2c_repeated_start()
373 {
374  uint8_t result;
375  uint16_t timeout;
376  TWCR=(1<<TWINT) | (1<<TWSTA) | (1<<TWEN); //! 1) I2C repeated start
377  for (timeout = 0; timeout < HW_I2C_TIMEOUT; timeout++) //! 2) START the timeout loop
378  {
379  _delay_us(1);
380  if (TWCR & (1 << TWINT)) break; //! 3) Check the TWINT bit in TWCR
381  }
382  result=(TWSR & 0xF8); //! 4) Mask the status
383  if (result == STATUS_REPEATED_START)
384  return(0); //! 5) Return status
385  else
386  return(1);
387 }
388 // Write stop bit to the hardware I2C port
389 void i2c_stop()
390 {
391  TWCR=(1<<TWINT) | (1<<TWEN) | (1<<TWSTO); //! 1) I2C stop
392  while (TWCR & (1<<TWSTO)); //! 2) Wait for stop to complete
393 }
394 
395 // Send a data byte to hardware I2C port
396 // return 0 if successful, 1 if not successful
397 int8_t i2c_write(uint8_t data)
398 {
399  uint8_t result;
400  uint16_t timeout;
401  TWDR = data; //! 1) Load data register
402  TWCR =(1<<TWINT) | (1<<TWEN); //! 2) START transaction
403  for (timeout = 0; timeout < HW_I2C_TIMEOUT; timeout++) //! 3) START the timeout loop
404  {
405  _delay_us(1);
406  if (TWCR & (1 << TWINT)) break; //! 4) Check the TWINT bit in TWCR
407  }
408  result=(TWSR & 0xF8); //! 5) Update status
409  // For a generic write, need to consider all three of these cases (processor specific, some may not be this detailed.)
410  if ((result == STATUS_WRITE_ACK) || (result == STATUS_ADDRESS_WRITE_ACK) || (result == STATUS_ADDRESS_READ_ACK))
411  return(0); //! 6) Return status
412  else
413  return(1);
414 }
415 // Read a data byte from the hardware I2C port.
416 // Returns the data byte read.
417 uint8_t i2c_read(int8_t ack)
418 {
419  uint8_t result;
420  uint8_t return_value = 1;
421  uint16_t timeout;
422  uint8_t data;
423  if (ack == 0)
424  {
425  TWCR=(1<<TWINT) | (1<<TWEN) | (1<<TWEA); //! 1) START transaction with ack
426  for (timeout = 0; timeout < HW_I2C_TIMEOUT; timeout++) //! 2) START timeout loop
427  {
428  _delay_us(1);
429  if (TWCR & (1 << TWINT)) break; //! 3) Check the TWINT bit in TWCR
430  }
431  data = TWDR; //! 4) Get data
432  result = TWSR & 0xF8; //! 5) Update status
433  if (result == STATUS_READ_ACK) return_value = 0;
434  }
435  else
436  {
437  TWCR=(1<<TWINT) | (1<<TWEN); //! 6) START transaction with NACK
438  for (timeout = 0; timeout < HW_I2C_TIMEOUT; timeout++)
439  {
440  _delay_us(1);
441  if (TWCR & (1 << TWINT)) break; //! 7) Check the TWINT bit in TWCR
442  }
443  data = TWDR; //! 8) Get data
444  result = TWSR & 0xF8; //! 9) Update status
445  if (result == STATUS_READ_NACK) return_value = 0;
446  }
447  return(data);
448 }
449 
450 // Poll the I2C port and look for an acknowledge
451 // Returns 0 if successful, 1 if not successful
452 int8_t i2c_poll(uint8_t i2c_address)
453 
454 {
455  int8_t ack=0;
456  ack |= i2c_start(); //! 1) I2C start
457  ack |= i2c_write((i2c_address<<1) | I2C_WRITE_BIT); //! 2) I2C address + !write
458  i2c_stop(); //! 3) I2C stop
459  return(ack); //! 4) Return ack status
460 }
461 */
int8_t i2c_read_block_data(uint8_t address, uint8_t command, uint8_t length, uint8_t *values)
Read a block of data, starting at register specified by "command" and ending at (command + length - 1...
int8_t i2c_write_word_data(uint8_t address, uint8_t command, uint16_t value)
Write a 16-bit word of data to register specified by "command".
long ret
void quikeval_I2C_connect(void)
Switch MUX to connect I2C pins to QuikEval connector.
Header File for Linduino Libraries and Demo Code.
#define QUIKEVAL_MUX_MODE_PIN
QUIKEVAL_MUX_MODE_PIN defines the control pin for the QuikEval MUX.
Definition: Linduino.h:58
int8_t i2c_two_byte_command_read_block(uint8_t address, uint16_t command, uint8_t length, uint8_t *values)
Write a two command bytes, then receive a block of data.
int8_t i2c_read_byte(uint8_t address, uint8_t *value)
LT_I2C_Wire: I2C Routines based on Wire library to communicate with Arduino based boards...
Definition: LT_I2C_Wire.cpp:72
void i2c_enable()
i2c_enable or quikeval_I2C_init must be called before using any of the other I2C routines.
static uint8_t address
Definition: DC2091A.ino:83
union LT_union_int32_4bytes data
Definition: DC2094A.ino:138
int8_t i2c_read_byte_data(uint8_t address, uint8_t command, uint8_t *value)
Read a byte of data at register specified by "command", store in "value".
LT_I2C: Routines to communicate with ATmega328P&#39;s hardware I2C port.
void quikeval_I2C_init(void)
Initializes Linduino I2C port.
int8_t i2c_write_byte_data(uint8_t address, uint8_t command, uint8_t value)
Write a byte of data to register specified by "command".
int8_t i2c_write_block_data(uint8_t address, uint8_t command, uint8_t length, uint8_t *values)
Write a block of data, starting at register specified by "command" and ending at (command + length - ...
int8_t i2c_write_byte(uint8_t address, uint8_t value)
Write "value" byte to device at "address".
Definition: LT_I2C_Wire.cpp:91
int8_t i2c_read_word_data(uint8_t address, uint8_t command, uint16_t *value)
Read a 16-bit word of data from register specified by "command".
static int i
Definition: DC2430A.ino:184
static uint8_t values[4]
Definition: DC2218A.ino:117