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
twi.c
00001 /* 00002 twi.c - 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 Modified 2012 by Todd Krein (todd@krein.org) to implement repeated starts 00016 */ 00017 00018 #if defined(__AVR__) 00019 #include <math.h> 00020 #include <stdlib.h> 00021 #include <inttypes.h> 00022 #include <avr/io.h> 00023 #include <avr/interrupt.h> 00024 #include <compat/twi.h> 00025 #include "Arduino.h" // for digitalWrite 00026 00027 00028 #ifndef cbi 00029 #define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit)) 00030 #endif 00031 00032 #ifndef sbi 00033 #define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit)) 00034 #endif 00035 00036 #include "pins_arduino.h" 00037 #include "twi.h" 00038 00039 static volatile uint8_t twi_state; 00040 static volatile uint8_t twi_slarw; 00041 static volatile uint8_t twi_sendStop; // should the transaction end with a stop 00042 static volatile uint8_t twi_inRepStart; // in the middle of a repeated start 00043 00044 static void (*twi_onSlaveTransmit)(void); 00045 static void (*twi_onSlaveReceive)(uint8_t*, int); 00046 00047 static uint8_t twi_masterBuffer[TWI_BUFFER_LENGTH]; 00048 static volatile uint8_t twi_masterBufferIndex; 00049 static volatile uint8_t twi_masterBufferLength; 00050 00051 static uint8_t twi_txBuffer[TWI_BUFFER_LENGTH]; 00052 static volatile uint8_t twi_txBufferIndex; 00053 static volatile uint8_t twi_txBufferLength; 00054 00055 static uint8_t twi_rxBuffer[TWI_BUFFER_LENGTH]; 00056 static volatile uint8_t twi_rxBufferIndex; 00057 00058 static volatile uint8_t twi_error; 00059 00060 /* 00061 * Function twi_init 00062 * Desc readys twi pins and sets twi bitrate 00063 * Input none 00064 * Output none 00065 */ 00066 void twi_init(void) 00067 { 00068 // initialize state 00069 twi_state = TWI_READY; 00070 twi_sendStop = true; // default value 00071 twi_inRepStart = false; 00072 00073 // activate internal pullups for twi. 00074 digitalWrite(SDA, 1); 00075 digitalWrite(SCL, 1); 00076 00077 // initialize twi prescaler and bit rate 00078 cbi(TWSR, TWPS0); 00079 cbi(TWSR, TWPS1); 00080 TWBR = ((F_CPU / TWI_FREQ) - 16) / 2; 00081 00082 /* twi bit rate formula from atmega128 manual pg 204 00083 SCL Frequency = CPU Clock Frequency / (16 + (2 * TWBR)) 00084 note: TWBR should be 10 or higher for master mode 00085 It is 72 for a 16mhz Wiring board with 100kHz TWI */ 00086 00087 // enable twi module, acks, and twi interrupt 00088 TWCR = _BV(TWEN) | _BV(TWIE) | _BV(TWEA); 00089 } 00090 00091 /* 00092 * Function twi_slaveInit 00093 * Desc sets slave address and enables interrupt 00094 * Input none 00095 * Output none 00096 */ 00097 void twi_setAddress(uint8_t address) 00098 { 00099 // set twi slave address (skip over TWGCE bit) 00100 TWAR = address << 1; 00101 } 00102 00103 /* 00104 * Function twi_readFrom 00105 * Desc attempts to become twi bus master and read a 00106 * series of bytes from a device on the bus 00107 * Input address: 7bit i2c device address 00108 * data: pointer to byte array 00109 * length: number of bytes to read into array 00110 * sendStop: Boolean indicating whether to send a stop at the end 00111 * Output number of bytes read 00112 */ 00113 uint8_t twi_readFrom(uint8_t address, uint8_t* data, uint8_t length, uint8_t sendStop) 00114 { 00115 uint8_t i; 00116 00117 // ensure data will fit into buffer 00118 if(TWI_BUFFER_LENGTH < length){ 00119 return 0; 00120 } 00121 00122 // wait until twi is ready, become master receiver 00123 while(TWI_READY != twi_state){ 00124 continue; 00125 } 00126 twi_state = TWI_MRX; 00127 twi_sendStop = sendStop; 00128 // reset error state (0xFF.. no error occured) 00129 twi_error = 0xFF; 00130 00131 // initialize buffer iteration vars 00132 twi_masterBufferIndex = 0; 00133 twi_masterBufferLength = length-1; // This is not intuitive, read on... 00134 // On receive, the previously configured ACK/NACK setting is transmitted in 00135 // response to the received byte before the interrupt is signalled. 00136 // Therefor we must actually set NACK when the _next_ to last byte is 00137 // received, causing that NACK to be sent in response to receiving the last 00138 // expected byte of data. 00139 00140 // build sla+w, slave device address + w bit 00141 twi_slarw = TW_READ; 00142 twi_slarw |= address << 1; 00143 00144 if (true == twi_inRepStart) { 00145 // if we're in the repeated start state, then we've already sent the start, 00146 // (@@@ we hope), and the TWI statemachine is just waiting for the address byte. 00147 // We need to remove ourselves from the repeated start state before we enable interrupts, 00148 // since the ISR is ASYNC, and we could get confused if we hit the ISR before cleaning 00149 // up. Also, don't enable the START interrupt. There may be one pending from the 00150 // repeated start that we sent outselves, and that would really confuse things. 00151 twi_inRepStart = false; // remember, we're dealing with an ASYNC ISR 00152 TWDR = twi_slarw; 00153 TWCR = _BV(TWINT) | _BV(TWEA) | _BV(TWEN) | _BV(TWIE); // enable INTs, but not START 00154 } 00155 else 00156 // send start condition 00157 TWCR = _BV(TWEN) | _BV(TWIE) | _BV(TWEA) | _BV(TWINT) | _BV(TWSTA); 00158 00159 // wait for read operation to complete 00160 while(TWI_MRX == twi_state){ 00161 continue; 00162 } 00163 00164 if (twi_masterBufferIndex < length) 00165 length = twi_masterBufferIndex; 00166 00167 // copy twi buffer to data 00168 for(i = 0; i < length; ++i){ 00169 data[i] = twi_masterBuffer[i]; 00170 } 00171 00172 return length; 00173 } 00174 00175 /* 00176 * Function twi_writeTo 00177 * Desc attempts to become twi bus master and write a 00178 * series of bytes to a device on the bus 00179 * Input address: 7bit i2c device address 00180 * data: pointer to byte array 00181 * length: number of bytes in array 00182 * wait: boolean indicating to wait for write or not 00183 * sendStop: boolean indicating whether or not to send a stop at the end 00184 * Output 0 .. success 00185 * 1 .. length to long for buffer 00186 * 2 .. address send, NACK received 00187 * 3 .. data send, NACK received 00188 * 4 .. other twi error (lost bus arbitration, bus error, ..) 00189 */ 00190 uint8_t twi_writeTo(uint8_t address, uint8_t* data, uint8_t length, uint8_t wait, uint8_t sendStop) 00191 { 00192 uint8_t i; 00193 00194 // ensure data will fit into buffer 00195 if(TWI_BUFFER_LENGTH < length){ 00196 return 1; 00197 } 00198 00199 // wait until twi is ready, become master transmitter 00200 while(TWI_READY != twi_state){ 00201 continue; 00202 } 00203 twi_state = TWI_MTX; 00204 twi_sendStop = sendStop; 00205 // reset error state (0xFF.. no error occured) 00206 twi_error = 0xFF; 00207 00208 // initialize buffer iteration vars 00209 twi_masterBufferIndex = 0; 00210 twi_masterBufferLength = length; 00211 00212 // copy data to twi buffer 00213 for(i = 0; i < length; ++i){ 00214 twi_masterBuffer[i] = data[i]; 00215 } 00216 00217 // build sla+w, slave device address + w bit 00218 twi_slarw = TW_WRITE; 00219 twi_slarw |= address << 1; 00220 00221 // if we're in a repeated start, then we've already sent the START 00222 // in the ISR. Don't do it again. 00223 // 00224 if (true == twi_inRepStart) { 00225 // if we're in the repeated start state, then we've already sent the start, 00226 // (@@@ we hope), and the TWI statemachine is just waiting for the address byte. 00227 // We need to remove ourselves from the repeated start state before we enable interrupts, 00228 // since the ISR is ASYNC, and we could get confused if we hit the ISR before cleaning 00229 // up. Also, don't enable the START interrupt. There may be one pending from the 00230 // repeated start that we sent outselves, and that would really confuse things. 00231 twi_inRepStart = false; // remember, we're dealing with an ASYNC ISR 00232 TWDR = twi_slarw; 00233 TWCR = _BV(TWINT) | _BV(TWEA) | _BV(TWEN) | _BV(TWIE); // enable INTs, but not START 00234 } 00235 else 00236 // send start condition 00237 TWCR = _BV(TWINT) | _BV(TWEA) | _BV(TWEN) | _BV(TWIE) | _BV(TWSTA); // enable INTs 00238 00239 // wait for write operation to complete 00240 while(wait && (TWI_MTX == twi_state)){ 00241 continue; 00242 } 00243 00244 if (twi_error == 0xFF) 00245 return 0; // success 00246 else if (twi_error == TW_MT_SLA_NACK) 00247 return 2; // error: address send, nack received 00248 else if (twi_error == TW_MT_DATA_NACK) 00249 return 3; // error: data send, nack received 00250 else 00251 return 4; // other twi error 00252 } 00253 00254 /* 00255 * Function twi_transmit 00256 * Desc fills slave tx buffer with data 00257 * must be called in slave tx event callback 00258 * Input data: pointer to byte array 00259 * length: number of bytes in array 00260 * Output 1 length too long for buffer 00261 * 2 not slave transmitter 00262 * 0 ok 00263 */ 00264 uint8_t twi_transmit(const uint8_t* data, uint8_t length) 00265 { 00266 uint8_t i; 00267 00268 // ensure data will fit into buffer 00269 if(TWI_BUFFER_LENGTH < length){ 00270 return 1; 00271 } 00272 00273 // ensure we are currently a slave transmitter 00274 if(TWI_STX != twi_state){ 00275 return 2; 00276 } 00277 00278 // set length and copy data into tx buffer 00279 twi_txBufferLength = length; 00280 for(i = 0; i < length; ++i){ 00281 twi_txBuffer[i] = data[i]; 00282 } 00283 00284 return 0; 00285 } 00286 00287 /* 00288 * Function twi_attachSlaveRxEvent 00289 * Desc sets function called before a slave read operation 00290 * Input function: callback function to use 00291 * Output none 00292 */ 00293 void twi_attachSlaveRxEvent( void (*function)(uint8_t*, int) ) 00294 { 00295 twi_onSlaveReceive = function; 00296 } 00297 00298 /* 00299 * Function twi_attachSlaveTxEvent 00300 * Desc sets function called before a slave write operation 00301 * Input function: callback function to use 00302 * Output none 00303 */ 00304 void twi_attachSlaveTxEvent( void (*function)(void) ) 00305 { 00306 twi_onSlaveTransmit = function; 00307 } 00308 00309 /* 00310 * Function twi_reply 00311 * Desc sends byte or readys receive line 00312 * Input ack: byte indicating to ack or to nack 00313 * Output none 00314 */ 00315 void twi_reply(uint8_t ack) 00316 { 00317 // transmit master read ready signal, with or without ack 00318 if(ack){ 00319 TWCR = _BV(TWEN) | _BV(TWIE) | _BV(TWINT) | _BV(TWEA); 00320 }else{ 00321 TWCR = _BV(TWEN) | _BV(TWIE) | _BV(TWINT); 00322 } 00323 } 00324 00325 /* 00326 * Function twi_stop 00327 * Desc relinquishes bus master status 00328 * Input none 00329 * Output none 00330 */ 00331 void twi_stop(void) 00332 { 00333 // send stop condition 00334 TWCR = _BV(TWEN) | _BV(TWIE) | _BV(TWEA) | _BV(TWINT) | _BV(TWSTO); 00335 00336 // wait for stop condition to be exectued on bus 00337 // TWINT is not set after a stop condition! 00338 while(TWCR & _BV(TWSTO)){ 00339 continue; 00340 } 00341 00342 // update twi state 00343 twi_state = TWI_READY; 00344 } 00345 00346 /* 00347 * Function twi_releaseBus 00348 * Desc releases bus control 00349 * Input none 00350 * Output none 00351 */ 00352 void twi_releaseBus(void) 00353 { 00354 // release bus 00355 TWCR = _BV(TWEN) | _BV(TWIE) | _BV(TWEA) | _BV(TWINT); 00356 00357 // update twi state 00358 twi_state = TWI_READY; 00359 } 00360 00361 SIGNAL(TWI_vect) 00362 { 00363 switch(TW_STATUS){ 00364 // All Master 00365 case TW_START: // sent start condition 00366 case TW_REP_START: // sent repeated start condition 00367 // copy device address and r/w bit to output register and ack 00368 TWDR = twi_slarw; 00369 twi_reply(1); 00370 break; 00371 00372 // Master Transmitter 00373 case TW_MT_SLA_ACK: // slave receiver acked address 00374 case TW_MT_DATA_ACK: // slave receiver acked data 00375 // if there is data to send, send it, otherwise stop 00376 if(twi_masterBufferIndex < twi_masterBufferLength){ 00377 // copy data to output register and ack 00378 TWDR = twi_masterBuffer[twi_masterBufferIndex++]; 00379 twi_reply(1); 00380 }else{ 00381 if (twi_sendStop) 00382 twi_stop(); 00383 else { 00384 twi_inRepStart = true; // we're gonna send the START 00385 // don't enable the interrupt. We'll generate the start, but we 00386 // avoid handling the interrupt until we're in the next transaction, 00387 // at the point where we would normally issue the start. 00388 TWCR = _BV(TWINT) | _BV(TWSTA)| _BV(TWEN) ; 00389 twi_state = TWI_READY; 00390 } 00391 } 00392 break; 00393 case TW_MT_SLA_NACK: // address sent, nack received 00394 twi_error = TW_MT_SLA_NACK; 00395 twi_stop(); 00396 break; 00397 case TW_MT_DATA_NACK: // data sent, nack received 00398 twi_error = TW_MT_DATA_NACK; 00399 twi_stop(); 00400 break; 00401 case TW_MT_ARB_LOST: // lost bus arbitration 00402 twi_error = TW_MT_ARB_LOST; 00403 twi_releaseBus(); 00404 break; 00405 00406 // Master Receiver 00407 case TW_MR_DATA_ACK: // data received, ack sent 00408 // put byte into buffer 00409 twi_masterBuffer[twi_masterBufferIndex++] = TWDR; 00410 case TW_MR_SLA_ACK: // address sent, ack received 00411 // ack if more bytes are expected, otherwise nack 00412 if(twi_masterBufferIndex < twi_masterBufferLength){ 00413 twi_reply(1); 00414 }else{ 00415 twi_reply(0); 00416 } 00417 break; 00418 case TW_MR_DATA_NACK: // data received, nack sent 00419 // put final byte into buffer 00420 twi_masterBuffer[twi_masterBufferIndex++] = TWDR; 00421 if (twi_sendStop) 00422 twi_stop(); 00423 else { 00424 twi_inRepStart = true; // we're gonna send the START 00425 // don't enable the interrupt. We'll generate the start, but we 00426 // avoid handling the interrupt until we're in the next transaction, 00427 // at the point where we would normally issue the start. 00428 TWCR = _BV(TWINT) | _BV(TWSTA)| _BV(TWEN) ; 00429 twi_state = TWI_READY; 00430 } 00431 break; 00432 case TW_MR_SLA_NACK: // address sent, nack received 00433 twi_stop(); 00434 break; 00435 // TW_MR_ARB_LOST handled by TW_MT_ARB_LOST case 00436 00437 // Slave Receiver 00438 case TW_SR_SLA_ACK: // addressed, returned ack 00439 case TW_SR_GCALL_ACK: // addressed generally, returned ack 00440 case TW_SR_ARB_LOST_SLA_ACK: // lost arbitration, returned ack 00441 case TW_SR_ARB_LOST_GCALL_ACK: // lost arbitration, returned ack 00442 // enter slave receiver mode 00443 twi_state = TWI_SRX; 00444 // indicate that rx buffer can be overwritten and ack 00445 twi_rxBufferIndex = 0; 00446 twi_reply(1); 00447 break; 00448 case TW_SR_DATA_ACK: // data received, returned ack 00449 case TW_SR_GCALL_DATA_ACK: // data received generally, returned ack 00450 // if there is still room in the rx buffer 00451 if(twi_rxBufferIndex < TWI_BUFFER_LENGTH){ 00452 // put byte in buffer and ack 00453 twi_rxBuffer[twi_rxBufferIndex++] = TWDR; 00454 twi_reply(1); 00455 }else{ 00456 // otherwise nack 00457 twi_reply(0); 00458 } 00459 break; 00460 case TW_SR_STOP: // stop or repeated start condition received 00461 // put a null char after data if there's room 00462 if(twi_rxBufferIndex < TWI_BUFFER_LENGTH){ 00463 twi_rxBuffer[twi_rxBufferIndex] = '\0'; 00464 } 00465 // sends ack and stops interface for clock stretching 00466 //twi_stop(); // Arduino issue #66 00467 // callback to user defined callback 00468 twi_onSlaveReceive(twi_rxBuffer, twi_rxBufferIndex); 00469 // since we submit rx buffer to "wire" library, we can reset it 00470 twi_rxBufferIndex = 0; 00471 // ack future responses and leave slave receiver state 00472 twi_releaseBus(); 00473 break; 00474 case TW_SR_DATA_NACK: // data received, returned nack 00475 case TW_SR_GCALL_DATA_NACK: // data received generally, returned nack 00476 // nack back at master 00477 twi_reply(0); 00478 break; 00479 00480 // Slave Transmitter 00481 case TW_ST_SLA_ACK: // addressed, returned ack 00482 case TW_ST_ARB_LOST_SLA_ACK: // arbitration lost, returned ack 00483 // enter slave transmitter mode 00484 twi_state = TWI_STX; 00485 // ready the tx buffer index for iteration 00486 twi_txBufferIndex = 0; 00487 // set tx buffer length to be zero, to verify if user changes it 00488 twi_txBufferLength = 0; 00489 // request for txBuffer to be filled and length to be set 00490 // note: user must call twi_transmit(bytes, length) to do this 00491 twi_onSlaveTransmit(); 00492 // if they didn't change buffer & length, initialize it 00493 if(0 == twi_txBufferLength){ 00494 twi_txBufferLength = 1; 00495 twi_txBuffer[0] = 0x00; 00496 } 00497 // transmit first byte from buffer, fall 00498 case TW_ST_DATA_ACK: // byte sent, ack returned 00499 // copy data to output register 00500 TWDR = twi_txBuffer[twi_txBufferIndex++]; 00501 // if there is more to send, ack, otherwise nack 00502 if(twi_txBufferIndex < twi_txBufferLength){ 00503 twi_reply(1); 00504 }else{ 00505 twi_reply(0); 00506 } 00507 break; 00508 case TW_ST_DATA_NACK: // received nack, we are done 00509 case TW_ST_LAST_DATA: // received ack, but we are done already! 00510 // ack future responses 00511 twi_reply(1); 00512 // leave slave receiver state 00513 twi_state = TWI_READY; 00514 break; 00515 00516 // All 00517 case TW_NO_INFO: // no state information 00518 break; 00519 case TW_BUS_ERROR: // bus error, illegal stop/start 00520 twi_error = TW_BUS_ERROR; 00521 twi_stop(); 00522 break; 00523 } 00524 } 00525 #endif // __AVR__
Generated on Sat Jul 16 2022 20:55:16 by
1.7.2