atMETEO
An ATmega based weather station
i2c.h
Go to the documentation of this file.
1 /*
2  * atMETEO - An ATmega based weather station
3  * Copyright (C) 2014-2015 Christian Fetzer
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 2 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License along
16  * with this program; if not, write to the Free Software Foundation, Inc.,
17  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18  */
19 
20 #pragma once
21 
38 #include <inttypes.h> // AVR toolchain doesn't offer cinttypes header
39 
40 #ifndef F_CPU
41 #error "F_CPU not defined for i2c.h"
42 #endif
43 
44 extern "C" {
45  #include <external/i2cmaster/i2cmaster.h>
46 }
47 
48 namespace Avr
49 {
50 
78 class I2c
79 {
80 public:
86  static I2c& instance()
87  {
88  return s_instance;
89  }
90 
100  void beginTransmission(uint8_t address)
101  {
102  m_bufferIndex = 0;
103 
104  i2c_start((address << 1) | I2C_WRITE);
105  }
106 
114  void write(uint8_t byte)
115  {
116  if (m_bufferIndex == c_bufferSize)
117  return;
118 
119  m_buffer[m_bufferIndex++] = byte;
120  }
121 
132  void endTransmission(bool stop = true)
133  {
134  for (uint8_t index = 0; index < m_bufferIndex; ++index) {
135  if (i2c_write(m_buffer[index]) != 0)
136  return;
137  }
138 
139  if (stop)
140  i2c_stop();
141  }
142 
156  uint8_t requestFrom(uint8_t address, uint8_t quantity, bool stop = true)
157  {
158  quantity = Sensors::min(quantity, c_bufferSize);
159  if (quantity == 0)
160  return 0;
161 
162  if (i2c_start((address << 1) | I2C_READ) != 0)
163  return 0;
164 
165  m_bufferIndex = 0;
166  while (--quantity > 0) {
167  m_buffer[m_bufferIndex++] = i2c_readAck();
168  }
169  m_buffer[m_bufferIndex++] = i2c_readNak();
170  m_bufferReadIndex = 0;
171 
172  if (stop)
173  i2c_stop();
174 
175  return m_bufferIndex;
176  }
177 
184  uint8_t read()
185  {
186  if (m_bufferReadIndex == m_bufferIndex)
187  return 0;
188 
189  return m_buffer[m_bufferReadIndex++];
190  }
191 
192 private:
193  static I2c s_instance;
194 
195  static const uint8_t c_bufferSize = 8;
196  uint8_t m_buffer[c_bufferSize];
197  uint8_t m_bufferIndex = 0;
198  uint8_t m_bufferReadIndex = 0;
199 
200  I2c()
201  {
202  i2c_init();
203  }
204 };
205 
206 I2c I2c::s_instance = I2c();
207  // \addtogroup libtarget_i2c
209 
210 } // namespace Avr
uint8_t requestFrom(uint8_t address, uint8_t quantity, bool stop=true)
Request bytes from an I2C (TWI) slave device.
Definition: i2c.h:156
static I2c & instance()
Returns the I2c::I2c instance.
Definition: i2c.h:86
A C++ wrapper for accessing the built-in I2C (TWI) communication interfaces.
Definition: i2c.h:78
uint8_t read()
Reads a byte that was received from a slave device after requesting with requestFrom().
Definition: i2c.h:184
void beginTransmission(uint8_t address)
Starts transmission to I2C (TWI) slave device with given address.
Definition: i2c.h:100
void endTransmission(bool stop=true)
Ends transmission to slave device.
Definition: i2c.h:132
Namespace containing all symbols of the AVR C++ utilities library.
Definition: adc.h:48
T min(T a, T b)
Returns the minimum of the two values a and b.
Definition: utils.h:188
void write(uint8_t byte)
Queues data for transmission to a slave device.
Definition: i2c.h:114