Digital IO
|
00001 /* Arduino DigitalIO Library 00002 * Copyright (C) 2013 by William Greiman 00003 * 00004 * This file is part of the Arduino DigitalIO Library 00005 * 00006 * This Library is free software: you can redistribute it and/or modify 00007 * it under the terms of the GNU General Public License as published by 00008 * the Free Software Foundation, either version 3 of the License, or 00009 * (at your option) any later version. 00010 * 00011 * This Library is distributed in the hope that it will be useful, 00012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00014 * GNU General Public License for more details. 00015 * 00016 * You should have received a copy of the GNU General Public License 00017 * along with the Arduino DigitalIO Library. If not, see 00018 * <http://www.gnu.org/licenses/>. 00019 */ 00028 #include <SoftI2cMaster.h> 00029 //------------------------------------------------------------------------------ 00051 bool I2cMasterBase::transfer(uint8_t addrRW, 00052 void *buf, size_t nbytes, uint8_t option) { 00053 uint8_t* p = reinterpret_cast<uint8_t*>(buf); 00054 if (_state != STATE_REP_START) { 00055 start(); 00056 } 00057 if (!write(addrRW)) { 00058 _state = addrRW & I2C_READ ? STATE_RX_ADDR_NACK : STATE_TX_ADDR_NACK; 00059 return false; 00060 } 00061 _state = addrRW & I2C_READ ? STATE_RX_DATA : STATE_TX_DATA; 00062 return transferContinue(buf, nbytes, option); 00063 } 00064 //------------------------------------------------------------------------------ 00080 bool I2cMasterBase::transferContinue(void *buf, size_t nbytes, uint8_t option) { 00081 uint8_t* p = reinterpret_cast<uint8_t*>(buf); 00082 if (_state == STATE_RX_DATA) { 00083 for (size_t i = 0; i < nbytes; i++) { 00084 p[i] = read(i == (nbytes - 1) && option != I2C_CONTINUE); 00085 } 00086 } else if (_state == STATE_TX_DATA) { 00087 for (size_t i = 0; i < nbytes; i++) { 00088 if (!write(p[i])) { 00089 _state = STATE_TX_DATA_NACK; 00090 return false; 00091 } 00092 } 00093 } else { 00094 return false; 00095 } 00096 if (option == I2C_STOP) { 00097 stop(); 00098 _state = STATE_STOP; 00099 } else if (option == I2C_REP_START) { 00100 start(); 00101 _state = STATE_STOP; 00102 } 00103 return true; 00104 } 00105 //============================================================================== 00106 // WARNING don't change SoftI2cMaster unless you verify the change with a scope 00107 //------------------------------------------------------------------------------ 00115 SoftI2cMaster::SoftI2cMaster(uint8_t sclPin, uint8_t sdaPin) { 00116 begin(sclPin, sdaPin); 00117 } 00118 //------------------------------------------------------------------------------ 00126 void SoftI2cMaster::begin(uint8_t sclPin, uint8_t sdaPin) { 00127 uint8_t port; 00128 00129 // Get bit mask and address of scl registers. 00130 _sclBit = digitalPinToBitMask(sclPin); 00131 port = digitalPinToPort(sclPin); 00132 _sclDDR = portModeRegister(port); 00133 volatile uint8_t* sclOutReg = portOutputRegister(port); 00134 00135 // Get bit mask and address of sda registers. 00136 _sdaBit = digitalPinToBitMask(sdaPin); 00137 port = digitalPinToPort(sdaPin); 00138 _sdaDDR = portModeRegister(port); 00139 _sdaInReg = portInputRegister(port); 00140 volatile uint8_t* sdaOutReg = portOutputRegister(port); 00141 00142 // Clear PORT bit for scl and sda. 00143 uint8_t s = SREG; 00144 noInterrupts(); 00145 *sclOutReg &= ~_sclBit; 00146 *sdaOutReg &= ~_sdaBit; 00147 SREG = s; 00148 00149 // Set scl and sda high. 00150 writeScl(HIGH); 00151 writeSda(HIGH); 00152 } 00153 //------------------------------------------------------------------------------ 00154 /* Read a byte and send ACK if more reads follow else NACK to terminate read. 00155 * 00156 * @param[in] last Set true to terminate the read else false. 00157 * 00158 * @return The byte read from the I2C bus. 00159 */ 00160 uint8_t SoftI2cMaster::read(uint8_t last) { 00161 uint8_t b = 0; 00162 00163 // Set sda to high Z mode for read. 00164 writeSda(HIGH); 00165 // Read a byte. 00166 for (uint8_t i = 0; i < 8; i++) { 00167 // Don't change this loop unless you verify the change with a scope. 00168 b <<= 1; 00169 sclDelay(16); 00170 writeScl(HIGH); 00171 sclDelay(12); 00172 if (readSda()) b |= 1; 00173 writeScl(LOW); 00174 } 00175 // send ACK or NACK 00176 writeSda(last); 00177 sclDelay(12); 00178 writeScl(HIGH); 00179 sclDelay(18); 00180 writeScl(LOW); 00181 writeSda(LOW); 00182 return b; 00183 } 00184 //------------------------------------------------------------------------------ 00185 /* Issue a start condition. */ 00186 void SoftI2cMaster::start() { 00187 if (!readSda()) { 00188 writeSda(HIGH); 00189 writeScl(HIGH); 00190 sclDelay(20); 00191 } 00192 writeSda(LOW); 00193 sclDelay(20); 00194 writeScl(LOW); 00195 } 00196 //------------------------------------------------------------------------------ 00197 /* Issue a stop condition. */ 00198 void SoftI2cMaster::stop(void) { 00199 writeSda(LOW); 00200 sclDelay(20); 00201 writeScl(HIGH); 00202 sclDelay(20); 00203 writeSda(HIGH); 00204 sclDelay(20); 00205 } 00206 //------------------------------------------------------------------------------ 00207 /* 00208 * Write a byte. 00209 * 00210 * @param[in] data The byte to send. 00211 * 00212 * @return The value true, 1, if the slave returned an ACK or false for NACK. 00213 */ 00214 bool SoftI2cMaster::write(uint8_t data) { 00215 // write byte 00216 for (uint8_t m = 0X80; m != 0; m >>= 1) { 00217 // don't change this loop unless you verify the change with a scope 00218 writeSda(m & data); 00219 sclDelay(8); 00220 writeScl(HIGH); 00221 sclDelay(18); 00222 writeScl(LOW); 00223 } 00224 sclDelay(8); 00225 // Go to sda high Z mode for input. 00226 writeSda(HIGH); 00227 writeScl(HIGH); 00228 sclDelay(16); 00229 00230 // Get ACK or NACK. 00231 uint8_t rtn = readSda(); 00232 00233 // pull scl low. 00234 writeScl(LOW); 00235 00236 // Pull sda low. 00237 writeSda(LOW); 00238 return rtn == 0; 00239 }