| 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).
324 void quikeval_I2C_init(void)
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.
331 void quikeval_I2C_connect(void)
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.
344 void i2c_enable()
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 */
i2c_read_block_data
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...
Definition: LT_I2C_Wire.cpp:200
i2c_write_word_data
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".
Definition: LT_I2C_Wire.cpp:176
ret
long ret
Definition: EVAL-AD7124-8.ino:145
quikeval_I2C_connect
void quikeval_I2C_connect(void)
Switch MUX to connect I2C pins to QuikEval connector.
Definition: LT_I2C_Wire.cpp:331
Linduino.h
Header File for Linduino Libraries and Demo Code.
QUIKEVAL_MUX_MODE_PIN
#define QUIKEVAL_MUX_MODE_PIN
QUIKEVAL_MUX_MODE_PIN defines the control pin for the QuikEval MUX.
Definition: Linduino.h:58
i2c_two_byte_command_read_block
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.
Definition: LT_I2C_Wire.cpp:274
i2c_read_byte
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
i2c_enable
void i2c_enable()
i2c_enable or quikeval_I2C_init must be called before using any of the other I2C routines.
Definition: LT_I2C_Wire.cpp:344
address
static uint8_t address
Definition: DC2091A.ino:83
data
union LT_union_int32_4bytes data
Definition: DC2094A.ino:138
i2c_read_byte_data
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".
Definition: LT_I2C_Wire.cpp:104
LT_I2C_Wire.h
LT_I2C: Routines to communicate with ATmega328P&#39;s hardware I2C port.
quikeval_I2C_init
void quikeval_I2C_init(void)
Initializes Linduino I2C port.
Definition: LT_I2C_Wire.cpp:324
i2c_write_byte_data
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".
Definition: LT_I2C_Wire.cpp:127
i2c_write_block_data
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 - ...
Definition: LT_I2C_Wire.cpp:253
i2c_write_byte
int8_t i2c_write_byte(uint8_t address, uint8_t value)
Write "value" byte to device at "address".
Definition: LT_I2C_Wire.cpp:91
i2c_read_word_data
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".
Definition: LT_I2C_Wire.cpp:141
i
static int i
Definition: DC2430A.ino:184
values
static uint8_t values[4]
Definition: DC2218A.ino:117