Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: mbed
Wire.cpp
00001 /* 00002 TwoWire.cpp - TWI/I2C library for Wiring & Arduino 00003 Copyright (c) 2006 Nicholas Zambetti. All right reserved. 00004 This library is free software; you can redistribute it and/or 00005 modify it under the terms of the GNU Lesser General Public 00006 License as published by the Free Software Foundation; either 00007 version 2.1 of the License, or (at your option) any later version. 00008 This library is distributed in the hope that it will be useful, 00009 but WITHOUT ANY WARRANTY; without even the implied warranty of 00010 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00011 Lesser General Public License for more details. 00012 You should have received a copy of the GNU Lesser General Public 00013 License along with this library; if not, write to the Free Software 00014 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 00015 00016 Modified 2012 by Todd Krein (todd@krein.org) to implement repeated starts 00017 */ 00018 00019 #if defined(__AVR__) 00020 00021 #include "Wire.h" 00022 00023 extern "C" { 00024 #include <stdlib.h> 00025 #include <string.h> 00026 #include <inttypes.h> 00027 #include "twi.h" 00028 } 00029 00030 00031 // Initialize Class Variables ////////////////////////////////////////////////// 00032 00033 uint8_t TwoWire::rxBuffer[BUFFER_LENGTH]; 00034 uint8_t TwoWire::rxBufferIndex = 0; 00035 uint8_t TwoWire::rxBufferLength = 0; 00036 00037 uint8_t TwoWire::txAddress = 0; 00038 uint8_t TwoWire::txBuffer[BUFFER_LENGTH]; 00039 uint8_t TwoWire::txBufferIndex = 0; 00040 uint8_t TwoWire::txBufferLength = 0; 00041 00042 uint8_t TwoWire::transmitting = 0; 00043 void (*TwoWire::user_onRequest)(void); 00044 void (*TwoWire::user_onReceive)(int); 00045 00046 // Constructors //////////////////////////////////////////////////////////////// 00047 00048 TwoWire::TwoWire() 00049 { 00050 } 00051 00052 // Public Methods ////////////////////////////////////////////////////////////// 00053 00054 void TwoWire::begin(void) 00055 { 00056 rxBufferIndex = 0; 00057 rxBufferLength = 0; 00058 00059 txBufferIndex = 0; 00060 txBufferLength = 0; 00061 00062 twi_init(); 00063 } 00064 00065 void TwoWire::begin(uint8_t address) 00066 { 00067 twi_setAddress(address); 00068 twi_attachSlaveTxEvent(onRequestService); 00069 twi_attachSlaveRxEvent(onReceiveService); 00070 begin(); 00071 } 00072 00073 void TwoWire::begin(int address) 00074 { 00075 begin((uint8_t)address); 00076 } 00077 00078 void TwoWire::end() 00079 { 00080 TWCR &= ~(_BV(TWEN) | _BV(TWIE) | _BV(TWEA)); 00081 digitalWrite(SDA, 0); 00082 digitalWrite(SCL, 0); 00083 } 00084 00085 void TwoWire::setClock(uint32_t frequency) 00086 { 00087 TWBR = ((F_CPU / frequency) - 16) / 2; 00088 } 00089 00090 void TwoWire::setSDA(uint8_t pin) 00091 { 00092 } 00093 00094 void TwoWire::setSCL(uint8_t pin) 00095 { 00096 } 00097 00098 uint8_t TwoWire::requestFrom(uint8_t address, uint8_t quantity, uint8_t sendStop) 00099 { 00100 // clamp to buffer length 00101 if(quantity > BUFFER_LENGTH){ 00102 quantity = BUFFER_LENGTH; 00103 } 00104 // perform blocking read into buffer 00105 uint8_t read = twi_readFrom(address, rxBuffer, quantity, sendStop); 00106 // set rx buffer iterator vars 00107 rxBufferIndex = 0; 00108 rxBufferLength = read; 00109 00110 return read; 00111 } 00112 00113 uint8_t TwoWire::requestFrom(uint8_t address, uint8_t quantity) 00114 { 00115 return requestFrom((uint8_t)address, (uint8_t)quantity, (uint8_t)true); 00116 } 00117 00118 uint8_t TwoWire::requestFrom(int address, int quantity) 00119 { 00120 return requestFrom((uint8_t)address, (uint8_t)quantity, (uint8_t)true); 00121 } 00122 00123 uint8_t TwoWire::requestFrom(int address, int quantity, int sendStop) 00124 { 00125 return requestFrom((uint8_t)address, (uint8_t)quantity, (uint8_t)sendStop); 00126 } 00127 00128 void TwoWire::beginTransmission(uint8_t address) 00129 { 00130 // indicate that we are transmitting 00131 transmitting = 1; 00132 // set address of targeted slave 00133 txAddress = address; 00134 // reset tx buffer iterator vars 00135 txBufferIndex = 0; 00136 txBufferLength = 0; 00137 } 00138 00139 void TwoWire::beginTransmission(int address) 00140 { 00141 beginTransmission((uint8_t)address); 00142 } 00143 00144 // 00145 // Originally, 'endTransmission' was an f(void) function. 00146 // It has been modified to take one parameter indicating 00147 // whether or not a STOP should be performed on the bus. 00148 // Calling endTransmission(false) allows a sketch to 00149 // perform a repeated start. 00150 // 00151 // WARNING: Nothing in the library keeps track of whether 00152 // the bus tenure has been properly ended with a STOP. It 00153 // is very possible to leave the bus in a hung state if 00154 // no call to endTransmission(true) is made. Some I2C 00155 // devices will behave oddly if they do not see a STOP. 00156 // 00157 uint8_t TwoWire::endTransmission(uint8_t sendStop) 00158 { 00159 // transmit buffer (blocking) 00160 int8_t ret = twi_writeTo(txAddress, txBuffer, txBufferLength, 1, sendStop); 00161 // reset tx buffer iterator vars 00162 txBufferIndex = 0; 00163 txBufferLength = 0; 00164 // indicate that we are done transmitting 00165 transmitting = 0; 00166 return ret; 00167 } 00168 00169 // This provides backwards compatibility with the original 00170 // definition, and expected behaviour, of endTransmission 00171 // 00172 uint8_t TwoWire::endTransmission(void) 00173 { 00174 return endTransmission(true); 00175 } 00176 00177 // must be called in: 00178 // slave tx event callback 00179 // or after beginTransmission(address) 00180 size_t TwoWire::write(uint8_t data) 00181 { 00182 if(transmitting){ 00183 // in master transmitter mode 00184 // don't bother if buffer is full 00185 if(txBufferLength >= BUFFER_LENGTH){ 00186 setWriteError(); 00187 return 0; 00188 } 00189 // put byte in tx buffer 00190 txBuffer[txBufferIndex] = data; 00191 ++txBufferIndex; 00192 // update amount in buffer 00193 txBufferLength = txBufferIndex; 00194 }else{ 00195 // in slave send mode 00196 // reply to master 00197 twi_transmit(&data, 1); 00198 } 00199 return 1; 00200 } 00201 00202 // must be called in: 00203 // slave tx event callback 00204 // or after beginTransmission(address) 00205 size_t TwoWire::write(const uint8_t *data, size_t quantity) 00206 { 00207 if(transmitting){ 00208 // in master transmitter mode 00209 for(size_t i = 0; i < quantity; ++i){ 00210 write(data[i]); 00211 } 00212 }else{ 00213 // in slave send mode 00214 // reply to master 00215 twi_transmit(data, quantity); 00216 } 00217 return quantity; 00218 } 00219 00220 // must be called in: 00221 // slave rx event callback 00222 // or after requestFrom(address, numBytes) 00223 int TwoWire::available(void) 00224 { 00225 return rxBufferLength - rxBufferIndex; 00226 } 00227 00228 // must be called in: 00229 // slave rx event callback 00230 // or after requestFrom(address, numBytes) 00231 int TwoWire::read(void) 00232 { 00233 int value = -1; 00234 00235 // get each successive byte on each call 00236 if(rxBufferIndex < rxBufferLength){ 00237 value = rxBuffer[rxBufferIndex]; 00238 ++rxBufferIndex; 00239 } 00240 00241 return value; 00242 } 00243 00244 // must be called in: 00245 // slave rx event callback 00246 // or after requestFrom(address, numBytes) 00247 int TwoWire::peek(void) 00248 { 00249 int value = -1; 00250 00251 if(rxBufferIndex < rxBufferLength){ 00252 value = rxBuffer[rxBufferIndex]; 00253 } 00254 00255 return value; 00256 } 00257 00258 void TwoWire::flush(void) 00259 { 00260 // XXX: to be implemented. 00261 } 00262 00263 // behind the scenes function that is called when data is received 00264 void TwoWire::onReceiveService(uint8_t* inBytes, int numBytes) 00265 { 00266 // don't bother if user hasn't registered a callback 00267 if(!user_onReceive){ 00268 return; 00269 } 00270 // don't bother if rx buffer is in use by a master requestFrom() op 00271 // i know this drops data, but it allows for slight stupidity 00272 // meaning, they may not have read all the master requestFrom() data yet 00273 if(rxBufferIndex < rxBufferLength){ 00274 return; 00275 } 00276 // copy twi rx buffer into local read buffer 00277 // this enables new reads to happen in parallel 00278 for(uint8_t i = 0; i < numBytes; ++i){ 00279 rxBuffer[i] = inBytes[i]; 00280 } 00281 // set rx iterator vars 00282 rxBufferIndex = 0; 00283 rxBufferLength = numBytes; 00284 // alert user program 00285 user_onReceive(numBytes); 00286 } 00287 00288 // behind the scenes function that is called when data is requested 00289 void TwoWire::onRequestService(void) 00290 { 00291 // don't bother if user hasn't registered a callback 00292 if(!user_onRequest){ 00293 return; 00294 } 00295 // reset tx buffer iterator vars 00296 // !!! this will kill any pending pre-master sendTo() activity 00297 txBufferIndex = 0; 00298 txBufferLength = 0; 00299 // alert user program 00300 user_onRequest(); 00301 } 00302 00303 // sets function called on slave write 00304 void TwoWire::onReceive( void (*function)(int) ) 00305 { 00306 user_onReceive = function; 00307 } 00308 00309 // sets function called on slave read 00310 void TwoWire::onRequest( void (*function)(void) ) 00311 { 00312 user_onRequest = function; 00313 } 00314 00315 // Preinstantiate Objects ////////////////////////////////////////////////////// 00316 00317 TwoWire Wire = TwoWire(); 00318 00319 #endif // __AVR__
Generated on Sat Jul 16 2022 20:55:16 by
1.7.2