Update oXs_out_frsky.cpp
[openXsensor.git] / locator_receiver / utility / AvrI2c.h
blob80e4c8fb88556d85c4171fb125d8607cda4bbe7a
1 /* Arduino SSD1306Ascii Library
2 * Copyright (C) 2015 by William Greiman
4 * This file is part of the Arduino SSD1306Ascii Library
6 * This Library is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
11 * This Library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with the Arduino SSD1306Ascii Library. If not, see
18 * <http://www.gnu.org/licenses/>.
20 /**
21 * @file AvrI2c.h
22 * @brief Small fast I2C class for AVR.
24 #ifndef AvrI2c_h
25 #define AvrI2c_h
26 #include <Arduino.h>
28 /** Bit to or with address for read start and read restart */
29 uint8_t const I2C_READ = 1;
31 /** Bit to or with address for write start and write restart */
32 uint8_t const I2C_WRITE = 0;
33 //------------------------------------------------------------------------------
34 // Status codes in TWSR - names are from Atmel TWSR.h with TWSR_ added
36 /** start condition transmitted */
37 uint8_t const TWSR_START = 0x08;
39 /** repeated start condition transmitted */
40 uint8_t const TWSR_REP_START = 0x10;
42 /** slave address plus write bit transmitted, ACK received */
43 uint8_t const TWSR_MTX_ADR_ACK = 0x18;
45 /** data transmitted, ACK received */
46 uint8_t const TWSR_MTX_DATA_ACK = 0x28;
48 /** slave address plus read bit transmitted, ACK received */
49 uint8_t const TWSR_MRX_ADR_ACK = 0x40;
50 //------------------------------------------------------------------------------
51 /**
52 * \class AvrI2c
53 * \brief Hardware I2C master class for AVR.
55 * Uses ATmega TWI hardware port
57 class AvrI2c {
58 public:
59 /**
60 * @brief Initialize prescalar and SLC clock rate.
61 * @param[in] fastMode Fast 400 kHz mode if true else standard 100 kHz mode.
63 void begin(bool fastMode = true) {
64 // Zero prescaler.
65 TWSR = 0;
66 // Set bit rate.
67 setClock(fastMode && F_CPU > 15000000 ? 400000 : 100000);
69 /**
70 * @brief Read a byte and send Ack if more reads follow else
71 Nak to terminate read.
73 * @param[in] last Set true to terminate the read else false.
74 * @return The byte read from the I2C bus.
76 uint8_t read(bool last) {
77 execCmd((1 << TWINT) | (1 << TWEN) | (last ? 0 : (1 << TWEA)));
78 return TWDR;
80 /**
81 * @brief Issue a repeated start condition.
83 * same as start with no stop. Included to document intention.
85 * @param[in] addressRW I2C address with read/write bit.
86 * @return The value true, 1, for success or false, 0, for failure.
88 bool repeatedStart(uint8_t addressRW) {
89 return start(addressRW);
91 /**
92 * @brief Set the I2C bit rate.
94 * @param[in] frequency Desired frequency in Hz.
95 * Valid range for a 16 MHz board is about 40 kHz to 444,000 kHz.
97 void setClock(uint32_t frequency) {
98 TWBR = ((F_CPU / frequency) - 16) / 2;
101 * @brief Issue a start condition.
103 * @param[in] addressRW I2C address with read/write bit.
105 * @return The value true for success or false for failure.
107 bool start(uint8_t addressRW) {
108 // send START condition
109 execCmd((1 << TWINT) | (1 << TWSTA) | (1 << TWEN));
110 if (status() != TWSR_START && status() != TWSR_REP_START) {
111 return false;
113 // send device address and direction
114 TWDR = addressRW;
115 execCmd((1 << TWINT) | (1 << TWEN));
116 if (addressRW & I2C_READ) {
117 return status() == TWSR_MRX_ADR_ACK;
118 } else {
119 return status() == TWSR_MTX_ADR_ACK;
122 /** @return status from last TWI command - useful for library debug */
123 uint8_t status(void) {return status_;}
124 /** Issue a stop condition. */
125 void stop(void) {
126 TWCR = (1 << TWINT) | (1 << TWEN) | (1 << TWSTO);
128 // wait until stop condition is executed and bus released
129 while (TWCR & (1 << TWSTO)) {}
132 * @brief Write a byte.
134 * @param[in] data The byte to send.
136 * @return The value true, 1, if the slave returned an Ack or false for Nak.
138 bool write(uint8_t data) {
139 TWDR = data;
140 execCmd((1 << TWINT) | (1 << TWEN));
141 return status() == TWSR_MTX_DATA_ACK;
144 private:
145 uint8_t status_;
147 void execCmd(uint8_t cmdReg) {
148 // send command
149 TWCR = cmdReg;
150 // wait for command to complete
151 while (!(TWCR & (1 << TWINT))) {}
152 // status bits.
153 status_ = TWSR & 0xF8;
156 #endif // AvrI2c_h