1 /*
2  * Author: Brendan Le Foll <brendan.le.foll@intel.com>
3  * Copyright (c) 2014 Intel Corporation.
4  *
5  * Permission is hereby granted, free of charge, to any person obtaining
6  * a copy of this software and associated documentation files (the
7  * "Software"), to deal in the Software without restriction, including
8  * without limitation the rights to use, copy, modify, merge, publish,
9  * distribute, sublicense, and/or sell copies of the Software, and to
10  * permit persons to whom the Software is furnished to do so, subject to
11  * the following conditions:
12  *
13  * The above copyright notice and this permission notice shall be
14  * included in all copies or substantial portions of the Software.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20  * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21  * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22  * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23  */
24 
25 #pragma once
26 
27 #include "i2c.h"
28 #include "types.hpp"
29 #include <stdexcept>
30 
31 namespace mraa
32 {
33 
34 /**
35  * @brief API to Inter-Integrated Circuit
36  *
37  * An I2c object represents an i2c master and can talk multiple i2c slaves by
38  * selecting the correct address
39  * @htmlinclude i2c.txt
40  *
41  * @snippet I2c-compass.cpp Interesting
42  */
43 class I2c
44 {
45   public:
46     /**
47      * Instantiates an i2c bus. Multiple instances of the same bus can
48      * exist and the bus is not guarranteed to be on the correct address
49      * before read/write.
50      *
51      * @param bus The i2c bus to use
52      * @param raw Whether to disable pinmapper for your board
53      */
I2c(int bus,bool raw=false)54     I2c(int bus, bool raw = false)
55     {
56         if (raw) {
57             m_i2c = mraa_i2c_init_raw(bus);
58         } else {
59             m_i2c = mraa_i2c_init(bus);
60         }
61         if (m_i2c == NULL) {
62             throw std::invalid_argument("Invalid i2c bus");
63         }
64     }
65 
66     /**
67      * Closes the I2c Bus used. This does not guarrantee the bus will not
68      * be usable by anyone else or communicates this disconnect to any
69      * slaves.
70      */
~I2c()71     ~I2c()
72     {
73         mraa_i2c_stop(m_i2c);
74     }
75 
76     /**
77      * Sets the i2c Frequency for communication. Your board may not support
78      * the set frequency. Anyone can change this at any time and this will
79      * affect every slave on the bus
80      *
81      * @param mode Frequency to set the bus to
82      * @return Result of operation
83      */
84     Result
frequency(I2cMode mode)85     frequency(I2cMode mode)
86     {
87         return (Result) mraa_i2c_frequency(m_i2c, (mraa_i2c_mode_t) mode);
88     }
89 
90     /**
91      * Set the slave to talk to, typically called before every read/write
92      * operation
93      *
94      * @param address Communicate to the i2c slave on this address
95      * @return Result of operation
96      */
97     Result
address(uint8_t address)98     address(uint8_t address)
99     {
100         return (Result) mraa_i2c_address(m_i2c, address);
101     }
102 
103     /**
104      * Read exactly one byte from the bus
105      *
106      * @return char read from the bus
107      */
108     uint8_t
readByte()109     readByte()
110     {
111         return (uint8_t) mraa_i2c_read_byte(m_i2c);
112     }
113 
114     /**
115      * Read length bytes from the bus into *data pointer
116      *
117      * @param data Data to read into
118      * @param length Size of read in bytes to make
119      * @return length of read, should match length
120      */
121     int
read(uint8_t * data,int length)122     read(uint8_t* data, int length)
123     {
124         return mraa_i2c_read(m_i2c, data, length);
125     }
126 
127     /**
128      * Read byte from an i2c register
129      *
130      * @param reg Register to read from
131      * @return char read from register
132      */
133     uint8_t
readReg(uint8_t reg)134     readReg(uint8_t reg)
135     {
136         return mraa_i2c_read_byte_data(m_i2c, reg);
137     }
138 
139     /**
140      * Read word from an i2c register
141      *
142      * @param reg Register to read from
143      * @return char read from register
144      */
145     uint16_t
readWordReg(uint8_t reg)146     readWordReg(uint8_t reg)
147     {
148         return mraa_i2c_read_word_data(m_i2c, reg);
149     }
150 
151     /**
152      * Read length bytes from the bus into *data pointer starting from
153      * an i2c register
154      *
155      * @param reg Register to read from
156      * @param data pointer to the byte array to read data in to
157      * @param length max number of bytes to read
158      * @return length passed to the function or -1
159      */
160     int
readBytesReg(uint8_t reg,uint8_t * data,int length)161     readBytesReg(uint8_t reg, uint8_t* data, int length)
162     {
163         return mraa_i2c_read_bytes_data(m_i2c, reg, data, length);
164     }
165 
166     /**
167      * Write a byte on the bus
168      *
169      * @param data The byte to send on the bus
170      * @return Result of operation
171      */
172     Result
writeByte(uint8_t data)173     writeByte(uint8_t data)
174     {
175         return (Result) mraa_i2c_write_byte(m_i2c, data);
176     }
177 
178     /**
179      * Write length bytes to the bus, the first byte in the array is the
180      * command/register to write
181      *
182      * @param data Buffer to send on the bus, first byte is i2c command
183      * @param length Size of buffer to send
184      * @return Result of operation
185      */
186     Result
write(const uint8_t * data,int length)187     write(const uint8_t* data, int length)
188     {
189         return (Result) mraa_i2c_write(m_i2c, data, length);
190     }
191 
192     /**
193      * Write a byte to an i2c register
194      *
195      * @param reg Register to write to
196      * @param data Value to write to register
197      * @return Result of operation
198      */
199     Result
writeReg(uint8_t reg,uint8_t data)200     writeReg(uint8_t reg, uint8_t data)
201     {
202         return (Result) mraa_i2c_write_byte_data(m_i2c, data, reg);
203     }
204 
205     /**
206      * Write a word to an i2c register
207      *
208      * @param reg Register to write to
209      * @param data Value to write to register
210      * @return Result of operation
211      */
212     Result
writeWordReg(uint8_t reg,uint16_t data)213     writeWordReg(uint8_t reg, uint16_t data)
214     {
215         return (Result) mraa_i2c_write_word_data(m_i2c, data, reg);
216     }
217 
218   private:
219     mraa_i2c_context m_i2c;
220 };
221 }
222